mirror of
https://git.proxmox.com/git/qemu-server
synced 2025-05-29 07:10:36 +00:00
vmconfig_hotplug_pending : add update_net
Signed-off-by: Alexandre Derumier <aderumier@odiso.com> Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
This commit is contained in:
parent
e56beedaba
commit
3eec576714
@ -897,46 +897,6 @@ my $vmconfig_update_disk = sub {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
my $vmconfig_update_net = sub {
|
|
||||||
my ($rpcenv, $authuser, $conf, $storecfg, $vmid, $opt, $value) = @_;
|
|
||||||
|
|
||||||
if ($conf->{$opt} && PVE::QemuServer::check_running($vmid)) {
|
|
||||||
my $oldnet = PVE::QemuServer::parse_net($conf->{$opt});
|
|
||||||
my $newnet = PVE::QemuServer::parse_net($value);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}else{
|
|
||||||
|
|
||||||
if($newnet->{bridge} && $oldnet->{bridge}){
|
|
||||||
my $iface = "tap".$vmid."i".$1 if $opt =~ m/net(\d+)/;
|
|
||||||
|
|
||||||
if($newnet->{rate} ne $oldnet->{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})){
|
|
||||||
PVE::Network::tap_unplug($iface);
|
|
||||||
PVE::Network::tap_plug($iface, $newnet->{bridge}, $newnet->{tag}, $newnet->{firewall});
|
|
||||||
}
|
|
||||||
|
|
||||||
}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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
$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);
|
|
||||||
};
|
|
||||||
|
|
||||||
# POST/PUT {vmid}/config implementation
|
# POST/PUT {vmid}/config implementation
|
||||||
#
|
#
|
||||||
# The original API used PUT (idempotent) an we assumed that all operations
|
# The original API used PUT (idempotent) an we assumed that all operations
|
||||||
@ -1128,8 +1088,8 @@ my $update_vm_api = sub {
|
|||||||
|
|
||||||
} elsif ($opt =~ m/^net(\d+)$/) { #nics
|
} elsif ($opt =~ m/^net(\d+)$/) { #nics
|
||||||
|
|
||||||
&$vmconfig_update_net($rpcenv, $authuser, $conf, $storecfg, $vmid,
|
# &$vmconfig_update_net($rpcenv, $authuser, $conf, $storecfg, $vmid,
|
||||||
$opt, $param->{$opt});
|
# $opt, $param->{$opt});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
@ -3153,6 +3153,7 @@ sub vm_devices_list {
|
|||||||
return $devices;
|
return $devices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# fixme: this should raise exceptions on error!
|
||||||
sub vm_deviceplug {
|
sub vm_deviceplug {
|
||||||
my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
|
my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
|
||||||
|
|
||||||
@ -3194,7 +3195,7 @@ sub vm_deviceplug {
|
|||||||
return undef if !qemu_findorcreatescsihw($storecfg,$conf, $vmid, $device);
|
return undef if !qemu_findorcreatescsihw($storecfg,$conf, $vmid, $device);
|
||||||
return undef if !qemu_driveadd($storecfg, $vmid, $device);
|
return undef if !qemu_driveadd($storecfg, $vmid, $device);
|
||||||
my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
|
my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
|
||||||
if(!qemu_deviceadd($vmid, $devicefull)) {
|
if(!qemu_deviceadd($vmid, $devicefull)) { # fixme: use qemu_deviceaddverify?
|
||||||
qemu_drivedel($vmid, $deviceid);
|
qemu_drivedel($vmid, $deviceid);
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
@ -3222,6 +3223,7 @@ sub vm_deviceplug {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# fixme: this should raise exceptions on error!
|
||||||
sub vm_deviceunplug {
|
sub vm_deviceunplug {
|
||||||
my ($vmid, $conf, $deviceid) = @_;
|
my ($vmid, $conf, $deviceid) = @_;
|
||||||
|
|
||||||
@ -3641,6 +3643,9 @@ sub vmconfig_hotplug_pending {
|
|||||||
} elsif ($opt eq 'cores') {
|
} elsif ($opt eq 'cores') {
|
||||||
die "skip\n" if !$hotplug;
|
die "skip\n" if !$hotplug;
|
||||||
qemu_cpu_hotplug($vmid, $conf, 1);
|
qemu_cpu_hotplug($vmid, $conf, 1);
|
||||||
|
} elsif ($opt =~ m/^net(\d+)$/) {
|
||||||
|
die "skip\n" if !$hotplug;
|
||||||
|
vm_deviceunplug($vmid, $conf, $opt);
|
||||||
} else {
|
} else {
|
||||||
die "skip\n";
|
die "skip\n";
|
||||||
}
|
}
|
||||||
@ -3675,6 +3680,9 @@ sub vmconfig_hotplug_pending {
|
|||||||
# allow manual ballooning if shares is set to zero
|
# allow manual ballooning if shares is set to zero
|
||||||
my $balloon = $conf->{pending}->{balloon} || $conf->{memory} || $defaults->{memory};
|
my $balloon = $conf->{pending}->{balloon} || $conf->{memory} || $defaults->{memory};
|
||||||
vm_mon_cmd($vmid, "balloon", value => $balloon*1024*1024);
|
vm_mon_cmd($vmid, "balloon", value => $balloon*1024*1024);
|
||||||
|
} elsif ($opt =~ m/^net(\d+)$/) {
|
||||||
|
# some changes can be done without hotplug
|
||||||
|
vmconfig_update_net($storecfg, $conf, $vmid, $opt, $value);
|
||||||
} else {
|
} else {
|
||||||
die "skip\n"; # skip non-hot-pluggable options
|
die "skip\n"; # skip non-hot-pluggable options
|
||||||
}
|
}
|
||||||
@ -3735,6 +3743,63 @@ sub vmconfig_apply_pending {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 $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;
|
||||||
|
};
|
||||||
|
|
||||||
|
sub vmconfig_update_net {
|
||||||
|
my ($storecfg, $conf, $vmid, $opt, $value) = @_;
|
||||||
|
|
||||||
|
my $newnet = parse_net($value);
|
||||||
|
|
||||||
|
if ($conf->{$opt}) {
|
||||||
|
my $oldnet = parse_net($conf->{$opt});
|
||||||
|
|
||||||
|
if (&$safe_string_ne($oldnet->{model}, $newnet->{model}) ||
|
||||||
|
&$safe_string_ne($oldnet->{macaddr}, $newnet->{macaddr}) ||
|
||||||
|
&$safe_num_ne($oldnet->{queues}, $newnet->{queues}) ||
|
||||||
|
!($newnet->{bridge} && $oldnet->{bridge})) { # bridge/nat mode change
|
||||||
|
|
||||||
|
# for non online change, we try to hot-unplug
|
||||||
|
die "skip\n" if !$conf->{hotplug};
|
||||||
|
vm_deviceunplug($vmid, $conf, $opt);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
die "internal error" if $opt !~ m/net(\d+)/;
|
||||||
|
my $iface = "tap${vmid}i$1";
|
||||||
|
|
||||||
|
if (&$safe_num_ne($oldnet->{rate}, $newnet->{rate})) {
|
||||||
|
PVE::Network::tap_rate_limit($iface, $newnet->{rate});
|
||||||
|
}
|
||||||
|
|
||||||
|
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});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_deviceplug($storecfg, $conf, $vmid, $opt, $newnet);
|
||||||
|
}
|
||||||
|
|
||||||
sub vm_start {
|
sub vm_start {
|
||||||
my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom, $paused, $forcemachine, $spice_ticket) = @_;
|
my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom, $paused, $forcemachine, $spice_ticket) = @_;
|
||||||
|
|
||||||
|
10
pve-bridge
10
pve-bridge
@ -20,10 +20,14 @@ my $migratedfrom = $ENV{PVE_MIGRATED_FROM};
|
|||||||
|
|
||||||
my $conf = PVE::QemuServer::load_config($vmid, $migratedfrom);
|
my $conf = PVE::QemuServer::load_config($vmid, $migratedfrom);
|
||||||
|
|
||||||
die "unable to get network config '$netid'\n"
|
my $netconf = $conf->{$netid};
|
||||||
if !$conf->{$netid};
|
|
||||||
|
|
||||||
my $net = PVE::QemuServer::parse_net($conf->{$netid});
|
$netconf = $conf->{pending}->{$netid} if !$migratedfrom && defined($conf->{pending}->{$netid});
|
||||||
|
|
||||||
|
die "unable to get network config '$netid'\n"
|
||||||
|
if !defined($netconf);
|
||||||
|
|
||||||
|
my $net = PVE::QemuServer::parse_net($netconf);
|
||||||
die "unable to parse network config '$netid'\n" if !$net;
|
die "unable to parse network config '$netid'\n" if !$net;
|
||||||
|
|
||||||
PVE::Network::tap_create($iface, $net->{bridge});
|
PVE::Network::tap_create($iface, $net->{bridge});
|
||||||
|
Loading…
Reference in New Issue
Block a user