[pve-devel] [PATCH v6 20/22] vmconfig_hotplug_pending : add update_disk

Dietmar Maurer dietmar at proxmox.com
Tue Nov 25 12:24:27 CET 2014


Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
Signed-off-by: Dietmar Maurer <dietmar at proxmox.com>
---
 PVE/API2/Qemu.pm  |   94 ++---------------------------------------------------
 PVE/QemuServer.pm |   92 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 94 insertions(+), 92 deletions(-)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index ea045c9..064d7ad 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -807,96 +807,6 @@ my $vmconfig_delete_option = sub {
     PVE::QemuServer::update_config_nolock($vmid, $conf, 1);
 };
 
-my $safe_num_ne = sub {
-    my ($a, $b) = @_;
-
-    return 0 if !defined($a) && !defined($b);
-    return 1 if !defined($a);
-    return 1 if !defined($b);
-
-    return $a != $b;
-};
-
-my $vmconfig_update_disk = sub {
-    my ($rpcenv, $authuser, $conf, $storecfg, $vmid, $opt, $value, $force) = @_;
-
-    my $drive = PVE::QemuServer::parse_drive($opt, $value);
-
-    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']);
-    }
-
-    if ($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) &&
-		($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",
-							   ($drive->{mbps} || 0)*1024*1024,
-							   ($drive->{mbps_rd} || 0)*1024*1024,
-							   ($drive->{mbps_wr} || 0)*1024*1024,
-							   $drive->{iops} || 0,
-							   $drive->{iops_rd} || 0,
-							   $drive->{iops_wr} || 0,
-							   ($drive->{mbps_max} || 0)*1024*1024,
-							   ($drive->{mbps_rd_max} || 0)*1024*1024,
-							   ($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);
-            }
-	}
-    }
-
-    &$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 ($drive->{file} eq 'none') {
-		PVE::QemuServer::vm_mon_cmd($vmid, "eject",force => JSON::true,device => "drive-$opt");
-	    } else {
-		my $path = PVE::QemuServer::get_iso_path($storecfg, $vmid, $drive->{file});
-		PVE::QemuServer::vm_mon_cmd($vmid, "eject",force => JSON::true,device => "drive-$opt"); #force eject if locked
-		PVE::QemuServer::vm_mon_cmd($vmid, "change",device => "drive-$opt",target => "$path") if $path;
-	    }
-	}
-
-    } else { # hotplug new disks
-
-	die "error hotplug $opt" if !PVE::QemuServer::vm_deviceplug($storecfg, $conf, $vmid, $opt, $drive);
-    }
-};
-
 # POST/PUT {vmid}/config implementation
 #
 # The original API used PUT (idempotent) an we assumed that all operations
@@ -1083,8 +993,8 @@ my $update_vm_api  = sub {
 
 		if (PVE::QemuServer::valid_drivename($opt)) {
 
-		    &$vmconfig_update_disk($rpcenv, $authuser, $conf, $storecfg, $vmid,
-					   $opt, $param->{$opt}, $force);
+		    #&$vmconfig_update_disk($rpcenv, $authuser, $conf, $storecfg, $vmid,
+		    #			   $opt, $param->{$opt}, $force);
 
 		} elsif ($opt =~ m/^net(\d+)$/) { #nics
 
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 243d069..4a44ac8 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -3546,6 +3546,8 @@ sub vmconfig_hotplug_pending {
 	    } elsif ($opt =~ m/^net(\d+)$/) {
 		die "skip\n" if !$hotplug;
 		vm_deviceunplug($vmid, $conf, $opt);
+	    } elsif (valid_drivename($opt)) {
+		die "skip\n"; # we do not allow to hot-remove disk?		
 	    } else {
 		die "skip\n";
 	    }
@@ -3583,6 +3585,9 @@ sub vmconfig_hotplug_pending {
 	    } elsif ($opt =~ m/^net(\d+)$/) { 
 		# some changes can be done without hotplug
 		vmconfig_update_net($storecfg, $conf, $vmid, $opt, $value);
+	    } elsif (valid_drivename($opt)) {
+		# some changes can be done without hotplug
+		vmconfig_update_disk($storecfg, $conf, $vmid, $opt, $value, 1);
 	    } else {
 		die "skip\n";  # skip non-hot-pluggable options
 	    }
@@ -3700,6 +3705,93 @@ sub vmconfig_update_net {
     vm_deviceplug($storecfg, $conf, $vmid, $opt, $newnet);
 }
 
+sub vmconfig_update_disk {
+    my ($storecfg, $conf, $vmid, $opt, $value, $force) = @_;
+
+    # fixme: do we need force?
+
+    my $drive = parse_drive($opt, $value);
+
+    if ($conf->{$opt}) {
+
+	if (my $old_drive = 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 (!drive_is_cdrom($old_drive)) {
+
+		if ($drive->{file} ne $old_drive->{file}) {  
+
+		    die "skip\n" if !$conf->{hotplug};
+
+		    # unplug and register as unused
+		    vm_deviceunplug($vmid, $conf, $opt);
+		    vmconfig_register_unused_drive($storecfg, $vmid, $conf, $old_drive)
+       
+		} else {
+		    # update existing disk
+
+		    # skip non hotpluggable value
+		    if (&$safe_num_ne($drive->{discard}, $old_drive->{discard}) || 
+			&$safe_string_ne($drive->{cache}, $old_drive->{cache})) {
+			die "skip\n";
+		    }
+
+		    # 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})) {
+			
+			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,
+						   $drive->{iops} || 0,
+						   $drive->{iops_rd} || 0,
+						   $drive->{iops_wr} || 0,
+						   ($drive->{mbps_max} || 0)*1024*1024,
+						   ($drive->{mbps_rd_max} || 0)*1024*1024,
+						   ($drive->{mbps_wr_max} || 0)*1024*1024,
+						   $drive->{iops_max} || 0,
+						   $drive->{iops_rd_max} || 0,
+						   $drive->{iops_wr_max} || 0);
+
+		    }
+		    
+		    return 1;
+	        }
+	    }
+	}
+    }
+
+    if (drive_is_cdrom($drive)) { # cdrom
+
+	if ($drive->{file} eq 'none') {
+	    vm_mon_cmd($vmid, "eject",force => JSON::true,device => "drive-$opt");
+	} else {
+	    my $path = get_iso_path($storecfg, $vmid, $drive->{file});
+	    vm_mon_cmd($vmid, "eject", force => JSON::true,device => "drive-$opt"); # force eject if locked
+	    vm_mon_cmd($vmid, "change", device => "drive-$opt",target => "$path") if $path;
+	}
+
+    } else { 
+	die "skip\n" if !$conf->{hotplug};
+	# hotplug new disks
+	vm_deviceplug($storecfg, $conf, $vmid, $opt, $drive);
+    }
+}
+
 sub vm_start {
     my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom, $paused, $forcemachine, $spice_ticket) = @_;
 
-- 
1.7.10.4




More information about the pve-devel mailing list