[pve-devel] [PATCH 09/12] vmconfig_update_net : implement pending change

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


1) if a previous nic exist,
     if they are non-online options (model,mac,queues) , we try to unplug it first.
       [CONF]
       net0: e1000,bridge=vmbr0
       [PENDING]
       net0: virtio,bridge=vmbr0

       ->
       [CONF]
       [PENDING]
       net0: virtio,bridge=vmbr0

     else we apply online change (bridge,tag,firewall)
       [CONF]
       net0: e1000,bridge=vmbr0
       [PENDING]
       net0: e1000,bridge=vmbr10
       ->
       [CONF]
       net0: e1000,bridge=vmbr10

2) we try to hotplug the pending nic
       [CONF]
       [PENDING]
       net0: virtio,bridge=vmbr0

       ->
       [CONF]
       net0: virtio,bridge=vmbr0

in pve-bridge, we need to take value from pending nic on hotplug

Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
 PVE/API2/Qemu.pm |   60 +++++++++++++++++++++++++++++++++++++++---------------
 pve-bridge       |    4 ++++
 2 files changed, 48 insertions(+), 16 deletions(-)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index 9a2c174..774c969 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -790,6 +790,16 @@ my $safe_num_ne = sub {
     return $a != $b;
 };
 
+my $safe_string_ne = sub {
+    my ($a, $b) = @_;
+
+    return 0 if !defined($a) && !defined($b);
+    return 1 if !defined($a);
+    return 1 if !defined($b);
+
+    return $a ne $b;
+};
+
 my $vmconfig_update_disk = sub {
     my ($rpcenv, $authuser, $conf, $storecfg, $vmid, $opt, $force) = @_;
 
@@ -876,43 +886,61 @@ my $vmconfig_update_disk = sub {
 };
 
 my $vmconfig_update_net = sub {
-    my ($rpcenv, $authuser, $conf, $storecfg, $vmid, $opt, $value) = @_;
+    my ($rpcenv, $authuser, $conf, $storecfg, $vmid, $opt) = @_;
 
-    if ($conf->{$opt} && PVE::QemuServer::check_running($vmid)) {
-	my $oldnet = PVE::QemuServer::parse_net($conf->{$opt});
-	my $newnet = PVE::QemuServer::parse_net($value);
+    if ($conf->{$opt}) {
+	my $running = PVE::QemuServer::check_running($vmid);
 
-	if($oldnet->{model} ne $newnet->{model}){
-	    #if model change, we try to hot-unplug
-            die "error hot-unplug $opt for update" if !PVE::QemuServer::vm_deviceunplug($vmid, $conf, $opt);
+	my $oldnet = PVE::QemuServer::parse_net($conf->{$opt});
+	my $newnet = PVE::QemuServer::parse_net($conf->{pending}->{$opt});
+
+	if(&$safe_string_ne($oldnet->{model}, $newnet->{model}) || 
+	   &$safe_string_ne($oldnet->{macaddr}, $newnet->{macaddr}) ||
+	   &$safe_num_ne($oldnet->{queues}, $newnet->{queues})){
+	    #for non online change, we try to hot-unplug
+	    if(!PVE::QemuServer::vm_deviceunplug($vmid, $conf, $opt)){
+		warn "error hot-unplug $opt for update";
+		return;
+	    }
 	}else{
 
 	    if($newnet->{bridge} && $oldnet->{bridge}){
 		my $iface = "tap".$vmid."i".$1 if $opt =~ m/net(\d+)/;
 
-		if($newnet->{rate} ne $oldnet->{rate}){
+		if(&$safe_num_ne($oldnet->{rate}, $newnet->{rate})){
 		    PVE::Network::tap_rate_limit($iface, $newnet->{rate});
 		}
 
-		if(($newnet->{bridge} ne $oldnet->{bridge}) || ($newnet->{tag} ne $oldnet->{tag}) || ($newnet->{firewall} ne $oldnet->{firewall})){
+		if(&$safe_string_ne($oldnet->{bridge}, $newnet->{bridge}) || 
+		   &$safe_num_ne($oldnet->{tag}, $newnet->{tag}) || 
+		   &$safe_num_ne($oldnet->{firewall}, $newnet->{firewall})){
 		    PVE::Network::tap_unplug($iface);
 		    PVE::Network::tap_plug($iface, $newnet->{bridge}, $newnet->{tag}, $newnet->{firewall});
 		}
 
+		$conf->{$opt} = $conf->{pending}->{$opt};
+		delete $conf->{pending}->{$opt};
+		PVE::QemuServer::update_config_nolock($vmid, $conf, 1);
+		return;
+
 	    }else{
+
 		#if bridge/nat mode change, we try to hot-unplug
-		die "error hot-unplug $opt for update" if !PVE::QemuServer::vm_deviceunplug($vmid, $conf, $opt);
+		
+		if(!PVE::QemuServer::vm_deviceunplug($vmid, $conf, $opt)){
+		    warn "error hot-unplug $opt for update";
+		    return;
+		}
 	    }
 	}
 
     }
-    $conf->{$opt} = $value;
-    PVE::QemuServer::update_config_nolock($vmid, $conf, 1);
-    $conf = PVE::QemuServer::load_config($vmid); # update/reload
 
-    my $net = PVE::QemuServer::parse_net($conf->{$opt});
-
-    die "error hotplug $opt" if !PVE::QemuServer::vm_deviceplug($storecfg, $conf, $vmid, $opt, $net);
+    if($conf->{pending}->{$opt}){
+	my $net = PVE::QemuServer::parse_net($conf->{pending}->{$opt});
+	warn "error hotplug $opt" if(!PVE::QemuServer::vm_deviceplug($storecfg, $conf, $vmid, $opt, $net, $conf->{pending}->{$opt}));
+    }
+    
 };
 
 # POST/PUT {vmid}/config implementation
diff --git a/pve-bridge b/pve-bridge
index d6c5eb8..caee33b 100755
--- a/pve-bridge
+++ b/pve-bridge
@@ -20,6 +20,10 @@ my $migratedfrom = $ENV{PVE_MIGRATED_FROM};
 
 my $conf = PVE::QemuServer::load_config($vmid, $migratedfrom);
 
+if ($conf->{pending}->{$netid}){
+    $conf = $conf->{pending};
+}
+
 die "unable to get network config '$netid'\n"
     if !$conf->{$netid};
 
-- 
1.7.10.4




More information about the pve-devel mailing list