[pve-devel] [PATCH] convert monitor_command to qmp_command - part1
Alexandre Derumier
aderumier at odiso.com
Tue Jun 5 17:59:08 CEST 2012
conversion of
- cd eject
- cd change
- shutdown/stop/pause/resume/
- livemigration
- migrate_set_speed
- migrate_set_downtime
- ballonning
- iothrolle
I have tested all features, don't have see any bugs
I don't have yet convert the hotplug code.
Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
PVE/API2/Qemu.pm | 18 +++++++++--
PVE/QemuMigrate.pm | 42 ++++++++++++--------------
PVE/QemuServer.pm | 82 ++++++++++++++++++++++++++++++++++++---------------
3 files changed, 93 insertions(+), 49 deletions(-)
diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index c172fde..d10db8c 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -673,12 +673,24 @@ my $vmconfig_update_disk = sub {
if (PVE::QemuServer::drive_is_cdrom($drive)) { # cdrom
if (PVE::QemuServer::check_running($vmid)) {
+ my $ejectcmd = {};
+ $ejectcmd->{execute} = "eject";
+ $ejectcmd->{arguments}->{force} = bless( do{\(my $o = 1)}, 'JSON::XS::Boolean' );
+ $ejectcmd->{arguments}->{device} = "drive-$opt";
+
if ($drive->{file} eq 'none') {
- PVE::QemuServer::vm_monitor_command($vmid, "eject -f drive-$opt", 0);
+ PVE::QemuServer::vm_qmp_command($vmid, $ejectcmd, 0);
} else {
+ PVE::QemuServer::vm_qmp_command($vmid, $ejectcmd, 0); #force eject if locked
my $path = PVE::QemuServer::get_iso_path($storecfg, $vmid, $drive->{file});
- PVE::QemuServer::vm_monitor_command($vmid, "eject -f drive-$opt", 0); #force eject if locked
- PVE::QemuServer::vm_monitor_command($vmid, "change drive-$opt \"$path\"", 0) if $path;
+
+ if($path) {
+ my $changecmd = {};
+ $changecmd->{execute} = "change";
+ $changecmd->{arguments}->{device} = "drive-$opt";
+ $changecmd->{arguments}->{target} = $path;
+ PVE::QemuServer::vm_qmp_command($vmid, $changecmd, 0);
+ }
}
}
diff --git a/PVE/QemuMigrate.pm b/PVE/QemuMigrate.pm
index 0dc81a5..2a3d3a5 100644
--- a/PVE/QemuMigrate.pm
+++ b/PVE/QemuMigrate.pm
@@ -324,29 +324,28 @@ sub phase2 {
# start migration
my $start = time();
+ my $migratecommand->{execute} = "migrate";
+ $migratecommand->{arguments}->{uri} = "tcp:localhost:$lport";
+ my $merr = PVE::QemuServer::vm_qmp_command($vmid, $migratecommand, 1);
- my $merr = PVE::QemuServer::vm_monitor_command($vmid, "migrate -d \"tcp:localhost:$lport\"", 1);
-
- my $lstat = '';
while (1) {
sleep (2);
- my $stat = PVE::QemuServer::vm_monitor_command($vmid, "info migrate", 1);
- if ($stat =~ m/^Migration status: (active|completed|failed|cancelled)$/im) {
+ my $stat = PVE::QemuServer::vm_qmp_command($vmid, "query-migrate", 1);
+
+ if ($stat->{status} =~ m/^(active|completed|failed|cancelled)$/im) {
$merr = undef;
- my $ms = $1;
-
- if ($stat ne $lstat) {
- if ($ms eq 'active') {
- my ($trans, $rem, $total) = (0, 0, 0);
- $trans = $1 if $stat =~ m/^transferred ram: (\d+) kbytes$/im;
- $rem = $1 if $stat =~ m/^remaining ram: (\d+) kbytes$/im;
- $total = $1 if $stat =~ m/^total ram: (\d+) kbytes$/im;
-
- $self->log('info', "migration status: $ms (transferred ${trans}KB, " .
- "remaining ${rem}KB), total ${total}KB)");
- } else {
- $self->log('info', "migration status: $ms");
- }
+ my $ms = $stat->{status};
+
+ if ($ms eq 'active') {
+ my ($trans, $rem, $total) = (0, 0, 0);
+ $trans = sprintf "%.2f", $stat->{ram}->{transferred}/1024 if $stat->{ram}->{transferred};
+ $rem = sprintf "%.2f", $stat->{ram}->{remaining}/1024 if $stat->{ram}->{remaining};
+ $total = sprintf "%.2f", $stat->{ram}->{total}/1024 if $stat->{ram}->{total};
+
+ $self->log('info', "migration status: $ms (transferred ${trans}KB, " .
+ "remaining ${rem}KB), total ${total}KB)");
+ } else {
+ $self->log('info', "migration status: $ms");
}
if ($ms eq 'completed') {
@@ -363,10 +362,9 @@ sub phase2 {
last if $ms ne 'active';
} else {
- die $merr if $merr;
- die "unable to parse migration status '$stat' - aborting\n";
+ die $merr->{desc} if $merr->{desc};
+ die "unable to parse migration status '$stat->{status}' - aborting\n";
}
- $lstat = $stat;
};
}
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 47c122e..c608312 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -2593,7 +2593,17 @@ sub qemu_block_set_io_throttle {
$iops_rd = 0 if !$iops_rd;
$iops_wr = 0 if !$iops_wr;
- my $ret = vm_monitor_command($vmid, "block_set_io_throttle $deviceid $bps $bps_rd $bps_wr $iops $iops_rd $iops_wr");
+ my $cmd = {};
+ $cmd->{execute} = "block_set_io_throttle";
+ $cmd->{arguments}->{device} = $deviceid;
+ $cmd->{arguments}->{bps} = $bps;
+ $cmd->{arguments}->{bps_rd} = $bps_rd;
+ $cmd->{arguments}->{bps_wr} = $bps_wr;
+ $cmd->{arguments}->{iops} = $iops;
+ $cmd->{arguments}->{iops_rd} = $iops_rd;
+ $cmd->{arguments}->{iops_wr} = $iops_wr;
+
+ my $ret = vm_qmp_command($vmid, $cmd);
$ret =~ s/^\s+//;
return 1 if $ret eq "";
syslog("err", "error setting block_set_io_throttle: $ret");
@@ -2653,7 +2663,7 @@ sub vm_start {
} else {
unlink $statefile;
# fixme: send resume - is that necessary ?
- eval { vm_monitor_command($vmid, "cont"); };
+ eval { vm_qmp_command($vmid, "cont"); };
}
}
@@ -2662,31 +2672,38 @@ sub vm_start {
my $migrate_speed = $defaults->{migrate_speed} || 8192;
$migrate_speed = $conf->{migrate_speed} || $migrate_speed;
eval {
- my $cmd = "migrate_set_speed ${migrate_speed}m";
- vm_monitor_command($vmid, $cmd);
+ my $cmd = {};
+ $cmd->{execute} = "migrate_set_speed";
+ $cmd->{arguments}->{value} = ($migrate_speed * 1048576); #value in bytes with qmp
+
+ vm_qmp_command($vmid, $cmd);
};
my $migrate_downtime = $defaults->{migrate_downtime};
$migrate_downtime = $conf->{migrate_downtime} if defined($conf->{migrate_downtime});
if (defined($migrate_downtime)) {
- my $cmd = "migrate_set_downtime ${migrate_downtime}";
- eval { vm_monitor_command($vmid, $cmd); };
+ my $cmd = {};
+ $cmd->{execute} = "migrate_set_downtime";
+ $cmd->{arguments}->{value} = $migrate_downtime;
+
+ eval { vm_qmp_command($vmid, $cmd); };
}
vm_balloonset($vmid, $conf->{balloon}) if $conf->{balloon};
-
+
+ vm_qmp_command($vmid,"query-commands");
});
}
my $qmp_read_avail = sub {
- my ($fh, $timeout) = @_;
+ my ($fh, $timeout, $returnerror) = @_;
my $sel = new IO::Select;
$sel->add($fh);
my $res = '';
my $buf;
-
+ $timeout = 3600;
my @ready;
while (scalar (@ready = $sel->can_read($timeout))) {
my $count;
@@ -2702,8 +2719,18 @@ my $qmp_read_avail = sub {
}
die "qmp read timeout\n" if !scalar(@ready);
- my $obj = from_json($res);
- return $obj;
+ my @jsons = split("\n", $res);
+ my $obj = {};
+ my $event = '';
+ foreach my $json (@jsons) {
+ my $obj = from_json($json);
+ $event = $obj->{event} if exists $obj->{event};
+
+ return $obj->{error} if exists $obj->{error} && $returnerror;
+ die $obj->{error}->{desc} if exists $obj->{error}->{desc};
+ return $obj->{QMP} if exists $obj->{QMP};
+ return $obj->{"return"} if exists $obj->{"return"};
+ }
};
sub __read_avail {
@@ -2831,6 +2858,9 @@ sub vm_qmp_command {
# hack: migrate sometime blocks the monitor (when migrate_downtime
# is set)
+ if (ref($cmdstr) eq "HASH") {
+ $timeout = 60*60 if ($cmdstr->{execute} =~ m/(migrate)$/);
+ }
#if ($cmdstr =~ m/^(info\s+migrate|migrate\s)/) {
# $timeout = 60*60; # 1 hour
#}
@@ -2838,7 +2868,7 @@ sub vm_qmp_command {
# read banner;
my $data = &$qmp_read_avail($sock, $timeout);
# '{"QMP": {"version": {"qemu": {"micro": 93, "minor": 0, "major": 1}, "package": " (qemu-kvm-devel)"}, "capabilities": []}} ';
- die "got unexpected qemu qmp banner\n" if !$data->{QMP};
+ die "got unexpected qemu qmp banner\n" if !$data;
my $sel = new IO::Select;
$sel->add($sock);
@@ -2857,18 +2887,19 @@ sub vm_qmp_command {
$res = &$qmp_read_avail($sock, $timeout);
# res = '{"return": {}}
- die "qmp negociation error\n" if !$res->{return};
+ die "qmp negociation error\n" if !$res;
$timeout = 20;
my $fullcmd;
+ my $returnerror;
if (ref($cmdstr) eq "HASH") {
#generate json from hash for complex cmd
$fullcmd = to_json($cmdstr);
-
- if ($fullcmd->{execute} =~ m/^(info\s+migrate|migrate\s)/) {
+ if ($cmdstr->{execute} =~ m/(migrate)$/) {
$timeout = 60*60; # 1 hour
- } elsif ($fullcmd->{execute} =~ m/^(eject|change)/) {
+ $returnerror = 1;
+ } elsif ($cmdstr->{execute} =~ m/^(eject|change)/) {
$timeout = 60; # note: cdrom mount command is slow
}
} else {
@@ -2883,8 +2914,8 @@ sub vm_qmp_command {
if (ref($cmdstr) ne "HASH") {
return if ($cmdstr eq 'q') || ($cmdstr eq 'quit');
}
-
- $res = &$qmp_read_avail($sock, $timeout);
+
+ $res = &$qmp_read_avail($sock, $timeout, $returnerror);
};
my $err = $@;
@@ -2918,7 +2949,7 @@ sub vm_reset {
check_lock($conf) if !$skiplock;
- vm_monitor_command($vmid, "system_reset");
+ vm_qmp_command($vmid, "system_reset");
});
}
@@ -2982,9 +3013,9 @@ sub vm_stop {
eval {
if ($shutdown) {
- vm_monitor_command($vmid, "system_powerdown", $nocheck);
+ vm_qmp_command($vmid, "system_powerdown", $nocheck);
} else {
- vm_monitor_command($vmid, "quit", $nocheck);
+ vm_qmp_command($vmid, "quit", $nocheck);
}
};
my $err = $@;
@@ -3044,7 +3075,7 @@ sub vm_suspend {
check_lock($conf) if !$skiplock;
- vm_monitor_command($vmid, "stop");
+ vm_qmp_command($vmid, "stop");
});
}
@@ -3057,7 +3088,7 @@ sub vm_resume {
check_lock($conf) if !$skiplock;
- vm_monitor_command($vmid, "cont");
+ vm_qmp_command($vmid, "cont");
});
}
@@ -3210,8 +3241,11 @@ sub print_pci_addr {
sub vm_balloonset {
my ($vmid, $value) = @_;
+ my $cmd = {};
+ $cmd->{execute} = "balloon";
+ $cmd->{arguments}->{value} = $value;
- vm_monitor_command($vmid, "balloon $value");
+ vm_qmp_command($vmid, $cmd);
}
# vzdump restore implementaion
--
1.7.2.5
More information about the pve-devel
mailing list