[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