[pve-devel] [PATCH 08/12] vmconfig_update_disk : implement pending change

Alexandre Derumier aderumier at odiso.com
Thu Oct 30 13:40:29 CET 2014


1) if previous device exist:

     if disk is different, we unplug it first
       [CONF]
       virtio0: vm-disk-100-1.raw
       unused0: vm-disk-100-2.raw

       #qm set 100 -virtio0 vm-disk-100-2.raw

       [CONF]
       unused0: vm-disk-100-2.raw
       unused1: vm-disk-100-1.raw
       [PENDING]
       virtio0: vm-disk-100-2.raw

     if disk is the same, we update it
       if disk options pending updates are not online (cache,discard,...), we keep the drive in pending
	       [CONF]
	       virtio0: vm-disk-100-1.raw

	       #qm set 100 -virtio0 vm-disk-100-1.raw,cache=writaback

	       [CONF]
	       virtio0: vm-disk-100-1.raw

	       [PENDING]
	       virtio0: vm-disk-100-1.raw,cache=writeback

       if disk options pending updates are online (throttling), we apply them
	       [CONF]
	       virtio0: vm-disk-100-1.raw

	       #qm set 100 -virtio0 vm-disk-100-1.raw,iops=1000

	       [CONF]
	       virtio0: vm-disk-100-1.raw,iops=1000

2) if drive is cdrom, we apply pending change

3) we try to hotplug pending new drive

       [CONF]
       unused0: vm-disk-100-2.raw
       unused1: vm-disk-100-1.raw
       [PENDING]
       virtio0: vm-disk-100-2.raw

-->hotplug
       [CONF]
       virtio0: vm-disk-100-2.raw
       unused1: vm-disk-100-1.raw

Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
 PVE/API2/Qemu.pm |   85 +++++++++++++++++++++++++++++-------------------------
 1 file changed, 45 insertions(+), 40 deletions(-)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index 9c28eb5..9a2c174 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -791,44 +791,45 @@ my $safe_num_ne = sub {
 };
 
 my $vmconfig_update_disk = sub {
-    my ($rpcenv, $authuser, $conf, $storecfg, $vmid, $opt, $value, $force) = @_;
-
-    my $drive = PVE::QemuServer::parse_drive($opt, $value);
+    my ($rpcenv, $authuser, $conf, $storecfg, $vmid, $opt, $force) = @_;
 
-    if (PVE::QemuServer::drive_is_cdrom($drive)) { #cdrom
-	$rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.CDROM']);
-    } else {
-	$rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.Disk']);
-    }
+    my $running = PVE::QemuServer::check_running($vmid);
+    my $pendingvalue = $conf->{pending}->{$opt};
+    my $drive = PVE::QemuServer::parse_drive($opt, $pendingvalue);
 
     if ($conf->{$opt}) {
 
-	if (my $old_drive = PVE::QemuServer::parse_drive($opt, $conf->{$opt}))  {
+	if (my $old_drive = PVE::QemuServer::parse_drive($opt, $conf->{$opt})) {
 
 	    my $media = $drive->{media} || 'disk';
 	    my $oldmedia = $old_drive->{media} || 'disk';
 	    die "unable to change media type\n" if $media ne $oldmedia;
+	    if (!PVE::QemuServer::drive_is_cdrom($old_drive)){
+	        #swap : unplug and put it in pending unusused
+		if ($drive->{file} ne $old_drive->{file}) {  # delete old disks
+		    &$vmconfig_delete_option($rpcenv, $authuser, $conf, $storecfg, $vmid, $opt, $force);
+		} else { #update existing disk
+
+		    #non hotpluggable value
+		    if (&$safe_num_ne($drive->{discard}, $old_drive->{discard}) || &$safe_string_ne($drive->{cache}, $old_drive->{cache})) {
+			return if $running;
+		    }
 
-	    if (!PVE::QemuServer::drive_is_cdrom($old_drive) &&
-		($drive->{file} ne $old_drive->{file})) {  # delete old disks
-
-		&$vmconfig_delete_option($rpcenv, $authuser, $conf, $storecfg, $vmid, $opt, $force);
-		$conf = PVE::QemuServer::load_config($vmid); # update/reload
-	    }
-
-            if(&$safe_num_ne($drive->{mbps}, $old_drive->{mbps}) ||
-               &$safe_num_ne($drive->{mbps_rd}, $old_drive->{mbps_rd}) ||
-               &$safe_num_ne($drive->{mbps_wr}, $old_drive->{mbps_wr}) ||
-               &$safe_num_ne($drive->{iops}, $old_drive->{iops}) ||
-               &$safe_num_ne($drive->{iops_rd}, $old_drive->{iops_rd}) ||
-               &$safe_num_ne($drive->{iops_wr}, $old_drive->{iops_wr}) ||
-               &$safe_num_ne($drive->{mbps_max}, $old_drive->{mbps_max}) ||
-               &$safe_num_ne($drive->{mbps_rd_max}, $old_drive->{mbps_rd_max}) ||
-               &$safe_num_ne($drive->{mbps_wr_max}, $old_drive->{mbps_wr_max}) ||
-               &$safe_num_ne($drive->{iops_max}, $old_drive->{iops_max}) ||
-               &$safe_num_ne($drive->{iops_rd_max}, $old_drive->{iops_rd_max}) ||
-               &$safe_num_ne($drive->{iops_wr_max}, $old_drive->{iops_wr_max})) {
-               PVE::QemuServer::qemu_block_set_io_throttle($vmid,"drive-$opt",
+		    #apply throttle
+		    if(&$safe_num_ne($drive->{mbps}, $old_drive->{mbps}) ||
+	               &$safe_num_ne($drive->{mbps_rd}, $old_drive->{mbps_rd}) ||
+	               &$safe_num_ne($drive->{mbps_wr}, $old_drive->{mbps_wr}) ||
+	               &$safe_num_ne($drive->{iops}, $old_drive->{iops}) ||
+	               &$safe_num_ne($drive->{iops_rd}, $old_drive->{iops_rd}) ||
+	               &$safe_num_ne($drive->{iops_wr}, $old_drive->{iops_wr}) ||
+	               &$safe_num_ne($drive->{mbps_max}, $old_drive->{mbps_max}) ||
+	               &$safe_num_ne($drive->{mbps_rd_max}, $old_drive->{mbps_rd_max}) ||
+	               &$safe_num_ne($drive->{mbps_wr_max}, $old_drive->{mbps_wr_max}) ||
+	               &$safe_num_ne($drive->{iops_max}, $old_drive->{iops_max}) ||
+	               &$safe_num_ne($drive->{iops_rd_max}, $old_drive->{iops_rd_max}) ||
+	               &$safe_num_ne($drive->{iops_wr_max}, $old_drive->{iops_wr_max})) {
+	               
+	               PVE::QemuServer::qemu_block_set_io_throttle($vmid,"drive-$opt",
 							   ($drive->{mbps} || 0)*1024*1024,
 							   ($drive->{mbps_rd} || 0)*1024*1024,
 							   ($drive->{mbps_wr} || 0)*1024*1024,
@@ -840,21 +841,23 @@ my $vmconfig_update_disk = sub {
 							   ($drive->{mbps_wr_max} || 0)*1024*1024,
 							   $drive->{iops_max} || 0,
 							   $drive->{iops_rd_max} || 0,
-							   $drive->{iops_wr_max} || 0)
-		   if !PVE::QemuServer::drive_is_cdrom($drive);
-            }
+							   $drive->{iops_wr_max} || 0);
+
+		    }
+		    $conf->{$opt} = $conf->{pending}->{$opt};
+		    delete $conf->{pending}->{$opt};
+		    return;
+		}
+	    }
+
 	}
     }
 
-    &$create_disks($rpcenv, $authuser, $conf, $storecfg, $vmid, undef, {$opt => $value});
     PVE::QemuServer::update_config_nolock($vmid, $conf, 1);
 
-    $conf = PVE::QemuServer::load_config($vmid); # update/reload
-    $drive = PVE::QemuServer::parse_drive($opt, $conf->{$opt});
-
     if (PVE::QemuServer::drive_is_cdrom($drive)) { # cdrom
 
-	if (PVE::QemuServer::check_running($vmid)) {
+	if ($running) {
 	    if ($drive->{file} eq 'none') {
 		PVE::QemuServer::vm_mon_cmd($vmid, "eject",force => JSON::true,device => "drive-$opt");
 	    } else {
@@ -863,11 +866,13 @@ my $vmconfig_update_disk = sub {
 		PVE::QemuServer::vm_mon_cmd($vmid, "change",device => "drive-$opt",target => "$path") if $path;
 	    }
 	}
+	$conf->{$opt} = $conf->{pending}->{$opt};
+	delete $conf->{pending}->{$opt};	
 
-    } else { # hotplug new disks
-
-	die "error hotplug $opt" if !PVE::QemuServer::vm_deviceplug($storecfg, $conf, $vmid, $opt, $drive);
+    } elsif (!PVE::QemuServer::vm_deviceplug($storecfg, $conf, $vmid, $opt, $drive, $pendingvalue)){
+	warn "error hotplug $opt";
     }
+
 };
 
 my $vmconfig_update_net = sub {
-- 
1.7.10.4




More information about the pve-devel mailing list