[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