cleanup update_vm - always reload config

And moved parameter parsing code to top.
This commit is contained in:
Dietmar Maurer 2012-02-02 08:35:11 +01:00
parent 0532bc6391
commit 1e68cb191a

View File

@ -620,6 +620,12 @@ __PACKAGE__->register_method({
die "no options specified\n" if !$delete_str && !scalar(keys %$param); die "no options specified\n" if !$delete_str && !scalar(keys %$param);
my $storecfg = PVE::Storage::config();
&$resolve_cdrom_alias($param);
# now try to verify all parameters
my @delete = (); my @delete = ();
foreach my $opt (PVE::Tools::split_list($delete_str)) { foreach my $opt (PVE::Tools::split_list($delete_str)) {
$opt = 'ide2' if $opt eq 'cdrom'; $opt = 'ide2' if $opt eq 'cdrom';
@ -633,9 +639,23 @@ __PACKAGE__->register_method({
push @delete, $opt; push @delete, $opt;
} }
my $storecfg = PVE::Storage::config(); my $drive_hash = {};
my $net_hash = {};
foreach my $opt (keys %$param) {
if (PVE::QemuServer::valid_drivename($opt)) {
# cleanup drive path
my $drive = PVE::QemuServer::parse_drive($opt, $param->{$opt});
PVE::QemuServer::cleanup_drive_path($opt, $storecfg, $drive);
$param->{$opt} = PVE::QemuServer::print_drive($vmid, $drive);
$drive_hash->{$opt} = $drive;
} elsif ($opt =~ m/^net(\d+)$/) {
# add macaddr
my $net = PVE::QemuServer::parse_net($param->{$opt});
$param->{$opt} = PVE::QemuServer::print_net($net);
$net_hash->{$opt} = $net;
}
}
&$resolve_cdrom_alias($param);
my $updatefn = sub { my $updatefn = sub {
@ -651,13 +671,14 @@ __PACKAGE__->register_method({
#delete #delete
foreach my $opt (@delete) { foreach my $opt (@delete) {
$conf = PVE::QemuServer::load_config($vmid); # update/reload
next if !defined($conf->{$opt}); next if !defined($conf->{$opt});
die "error hot-unplug $opt" if !PVE::QemuServer::vm_deviceunplug($vmid, $conf, $opt); die "error hot-unplug $opt" if !PVE::QemuServer::vm_deviceunplug($vmid, $conf, $opt);
#drive #drive
if (PVE::QemuServer::valid_drivename($opt)) { if (my $drive = $drive_hash->{$opt}) {
my $drive = PVE::QemuServer::parse_drive($opt, $conf->{$opt});
#hdd #hdd
if (!PVE::QemuServer::drive_is_cdrom($drive)) { if (!PVE::QemuServer::drive_is_cdrom($drive)) {
my $volid = $drive->{file}; my $volid = $drive->{file};
@ -677,7 +698,7 @@ __PACKAGE__->register_method({
} }
} }
} elsif ($opt =~ m/^unused/) { } elsif ($opt =~ m/^unused/) {
my $drive = PVE::QemuServer::parse_drive($opt, $conf->{$opt}); my $drive = PVE::QemuServer::parse_drive($opt, $conf->{$opt});
my $volid = $drive->{file}; my $volid = $drive->{file};
eval { PVE::Storage::vdisk_free($storecfg, $volid); }; eval { PVE::Storage::vdisk_free($storecfg, $volid); };
# fixme: log ? # fixme: log ?
@ -690,28 +711,21 @@ __PACKAGE__->register_method({
#add #add
foreach my $opt (keys %$param) { foreach my $opt (keys %$param) {
$conf = PVE::QemuServer::load_config($vmid); # update/reload
#drives #drives
if (PVE::QemuServer::valid_drivename($opt)) { if (my $drive = $drive_hash->{$opt}) {
my $drive = PVE::QemuServer::parse_drive($opt, $param->{$opt});
raise_param_exc({ $opt => "unable to parse drive options" }) if !$drive;
PVE::QemuServer::cleanup_drive_path($opt, $storecfg, $drive);
$param->{$opt} = PVE::QemuServer::print_drive($vmid, $drive);
#cdrom #cdrom
if (PVE::QemuServer::drive_is_cdrom($drive) && PVE::QemuServer::check_running($vmid)) { if (PVE::QemuServer::drive_is_cdrom($drive) && PVE::QemuServer::check_running($vmid)) {
if ($drive->{file} eq 'none') { if ($drive->{file} eq 'none') {
PVE::QemuServer::vm_monitor_command($vmid, "eject -f drive-$opt", 0); PVE::QemuServer::vm_monitor_command($vmid, "eject -f drive-$opt", 0);
#delete $param->{$opt}; #delete $param->{$opt};
} } else {
else {
my $path = PVE::QemuServer::get_iso_path($storecfg, $vmid, $drive->{file}); my $path = PVE::QemuServer::get_iso_path($storecfg, $vmid, $drive->{file});
PVE::QemuServer::vm_monitor_command($vmid, "eject -f drive-$opt", 0); #force eject if locked PVE::QemuServer::vm_monitor_command($vmid, "eject -f drive-$opt", 0); #force eject if locked
PVE::QemuServer::vm_monitor_command($vmid, "change drive-$opt \"$path\"", 0) if $path; PVE::QemuServer::vm_monitor_command($vmid, "change drive-$opt \"$path\"", 0) if $path;
} }
} } else { #hdd
#hdd
else {
#swap drive #swap drive
if ($conf->{$opt}){ if ($conf->{$opt}){
my $old_drive = PVE::QemuServer::parse_drive($opt, $conf->{$opt}); my $old_drive = PVE::QemuServer::parse_drive($opt, $conf->{$opt});
@ -735,25 +749,27 @@ __PACKAGE__->register_method({
die "error hotplug $opt - put disk in unused"; die "error hotplug $opt - put disk in unused";
} }
} }
}
#nics PVE::QemuServer::change_config_nolock($vmid, { $opt => $param->{$opt} }, {}, 1);
my $net = undef;
if ($opt =~ m/^net(\d+)$/) { } elsif (my $net = $net_hash->{$opt}) { #nics
$net = PVE::QemuServer::parse_net($param->{$opt});
$param->{$opt} = PVE::QemuServer::print_net($net);
#if online update, then unplug first #if online update, then unplug first
die "error hot-unplug $opt for update" if $conf->{$opt} && !PVE::QemuServer::vm_deviceunplug($vmid, $conf, $opt); die "error hot-unplug $opt for update" if $conf->{$opt} &&
} !PVE::QemuServer::vm_deviceunplug($vmid, $conf, $opt);
PVE::QemuServer::change_config_nolock($vmid, { $opt => $param->{$opt} }, {}, 1); PVE::QemuServer::change_config_nolock($vmid, { $opt => $param->{$opt} }, {}, 1);
#nic hotplug after config write as we need it for pve-bridge script #nic hotplug after config write as we need it for pve-bridge script
if (defined ($net)) {
if(!PVE::QemuServer::vm_deviceplug($storecfg, $conf, $vmid, $opt, $net)) { if(!PVE::QemuServer::vm_deviceplug($storecfg, $conf, $vmid, $opt, $net)) {
#rewrite conf to remove nic if hotplug fail #rewrite conf to remove nic if hotplug fail
PVE::QemuServer::change_config_nolock($vmid, {}, { $opt => 1 }, 1); PVE::QemuServer::change_config_nolock($vmid, {}, { $opt => 1 }, 1);
die "error hotplug $opt"; die "error hotplug $opt";
} }
} else {
PVE::QemuServer::change_config_nolock($vmid, { $opt => $param->{$opt} }, {}, 1);
} }
} }
}; };