[pve-devel] [PATCH 03/12] update_vm api : implement pending change

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


0) no change here for delete

1) we write params in pending change if vm is running

 if $running
   $conf->{pending}->{$opt} = $param->{$opt};
 else
    $conf->{$opt} = $param->{$opt};

  and we also create disks

2) we try to hotplug devices first

3) we try to update online values at the end.
   (We need to change value like 'hotplug' after devices hotplug)

If the device is hotplugged or the option can be change online the pending value is removed.

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

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index a0fcd28..add1389 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -669,6 +669,22 @@ my $test_deallocate_drive = sub {
     return undef;
 };
 
+my $is_hotpluggable = sub {
+   my ($opt) = @_;
+
+    #online value change
+    my $hotplug_options = {
+	name => 1,
+	balloon => 1,
+	shares => 1,
+	hotplug => 1,
+	shares => 1,
+	onboot => 1
+    };
+
+    return 1 if $hotplug_options->{$opt};
+};
+
 my $delete_drive = sub {
     my ($conf, $storecfg, $vmid, $key, $drive, $force) = @_;
 
@@ -981,37 +997,89 @@ my $update_vm_api  = sub {
 
 	    my $running = PVE::QemuServer::check_running($vmid);
 
+
+
+	    #load values in pending and create disks
 	    foreach my $opt (keys %$param) { # add/change
 
-		$conf = PVE::QemuServer::load_config($vmid); # update/reload
+		    $conf = PVE::QemuServer::load_config($vmid);
 
-		next if $conf->{$opt} && ($param->{$opt} eq $conf->{$opt}); # skip if nothing changed
+		    if (PVE::QemuServer::valid_drivename($opt)) {
+			my $drive = PVE::QemuServer::parse_drive($opt, $param->{$opt});
+
+			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']);
+			}
+
+			&$create_disks($rpcenv, $authuser, $conf, $storecfg, $vmid, undef, {$opt => $param->{$opt}}, undef, 1);
+		    }else{
+			if($running){
+			     $conf->{pending}->{$opt} = $param->{$opt};
+			     #delete a previous pending delete
+			     delete $conf->{pending}->{del}->{$opt};
+			}else{
+			     $conf->{$opt} = $param->{$opt};
+			}
+		    }
+		    PVE::QemuServer::update_config_nolock($vmid, $conf, 1);
+	    }
+	    
+
+	    #hotplug pending devices first
+	    foreach my $opt (keys %$param){
+
+		next if !defined($conf->{pending}->{$opt});
+	
+		# delete pending if nothing changed
+		if ($conf->{$opt} && $param->{$opt} eq $conf->{$opt}){
+		    delete $conf->{pending}->{$opt};
+		    PVE::QemuServer::update_config_nolock($vmid, $conf, 1);
+		    next;
+		}
 
 		if (PVE::QemuServer::valid_drivename($opt)) {
 
 		    &$vmconfig_update_disk($rpcenv, $authuser, $conf, $storecfg, $vmid,
-					   $opt, $param->{$opt}, $force);
+					   $opt, $force);
 
 		} elsif ($opt =~ m/^net(\d+)$/) { #nics
 
-		    &$vmconfig_update_net($rpcenv, $authuser, $conf, $storecfg, $vmid,
-					  $opt, $param->{$opt});
+		    &$vmconfig_update_net($rpcenv, $authuser, $conf, $storecfg, $vmid, $opt);
 
-		} else {
+		} elsif ($opt eq 'tablet'){
 
-		    if($opt eq 'tablet' && $param->{$opt} == 1){
-			PVE::QemuServer::vm_deviceplug(undef, $conf, $vmid, $opt);
-		    } elsif($opt eq 'tablet' && $param->{$opt} == 0){
+		    if($param->{$opt} == 1){
+			PVE::QemuServer::vm_deviceplug(undef, $conf, $vmid, $opt, $param->{$opt});
+		    } elsif($param->{$opt} == 0){
 			PVE::QemuServer::vm_deviceunplug($vmid, $conf, $opt);
 		    }
-		
-		    if($opt eq 'cores' && $conf->{maxcpus}){
-			PVE::QemuServer::qemu_cpu_hotplug($vmid, $conf, $param->{$opt});
-		    }
 
+		} elsif($opt eq 'cores'){
+
+		    PVE::QemuServer::qemu_cpu_hotplug($vmid, $conf, $param->{$opt});
+		}
+
+		PVE::QemuServer::update_config_nolock($vmid, $conf, 1);
+	    }
+
+	    #then update pending options
+
+	    foreach my $opt (keys %$param){
+
+		next if !defined($conf->{pending}->{$opt});
+
+		next if (PVE::QemuServer::valid_drivename($opt));
+		next if $opt =~ m/^net(\d+)$/;
+		next if $opt eq 'cores' || $opt eq 'tablet';
+
+		if(&$is_hotpluggable($opt)){
 		    $conf->{$opt} = $param->{$opt};
-		    PVE::QemuServer::update_config_nolock($vmid, $conf, 1);
+		    delete $conf->{pending}->{$opt};
 		}
+
+		PVE::QemuServer::update_config_nolock($vmid, $conf, 1);
 	    }
 
 	    # allow manual ballooning if shares is set to zero
-- 
1.7.10.4




More information about the pve-devel mailing list