Previously, foreach_drive iterated over all configuration keys (in a random order) and checked whether the current key is a valid drive name. Instead, we now iterate over a list of valid drive names (with deterministic order) and check whether a drive with such a name exists in the configuration.
Also rename the two involved methods from valid_drive_name to is_valid_drive_name (for the check) and from disknames to valid_drive_names (for the list of valid keys), for consistency. These two were only used in the qemu-server code base. --- This makes the behaviour more similar to PVE::LXC::Config-> foreach_mountpoint, and should also be more efficient. PVE/API2/Qemu.pm | 20 ++++++++++---------- PVE/QemuServer.pm | 30 +++++++++++++++--------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm index efac2c7..0be373c 100644 --- a/PVE/API2/Qemu.pm +++ b/PVE/API2/Qemu.pm @@ -182,7 +182,7 @@ my $check_vm_modify_config_perm = sub { foreach my $opt (@$key_list) { # disk checks need to be done somewhere else - next if PVE::QemuServer::valid_drivename($opt); + next if PVE::QemuServer::is_valid_drivename($opt); if ($opt eq 'sockets' || $opt eq 'cores' || $opt eq 'cpu' || $opt eq 'smp' || $opt eq 'vcpus' || @@ -371,7 +371,7 @@ __PACKAGE__->register_method({ &$check_vm_modify_config_perm($rpcenv, $authuser, $vmid, $pool, [ keys %$param]); foreach my $opt (keys %$param) { - if (PVE::QemuServer::valid_drivename($opt)) { + if (PVE::QemuServer::is_valid_drivename($opt)) { my $drive = PVE::QemuServer::parse_drive($opt, $param->{$opt}); raise_param_exc({ $opt => "unable to parse drive options" }) if !$drive; @@ -441,7 +441,7 @@ __PACKAGE__->register_method({ $vollist = &$create_disks($rpcenv, $authuser, $conf, $storecfg, $vmid, $pool, $param, $storage); # try to be smart about bootdisk - my @disks = PVE::QemuServer::disknames(); + my @disks = PVE::QemuServer::valid_drive_names(); my $firstdisk; foreach my $ds (reverse @disks) { next if !$conf->{$ds}; @@ -851,7 +851,7 @@ my $update_vm_api = sub { } foreach my $opt (keys %$param) { - if (PVE::QemuServer::valid_drivename($opt)) { + if (PVE::QemuServer::is_valid_drivename($opt)) { # cleanup drive path my $drive = PVE::QemuServer::parse_drive($opt, $param->{$opt}); PVE::QemuServer::cleanup_drive_path($opt, $storecfg, $drive); @@ -915,7 +915,7 @@ my $update_vm_api = sub { delete $conf->{$opt}; PVE::QemuServer::write_config($vmid, $conf); } - } elsif (PVE::QemuServer::valid_drivename($opt)) { + } elsif (PVE::QemuServer::is_valid_drivename($opt)) { &$check_protection($conf, "can't remove drive '$opt'"); $rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.Disk']); PVE::QemuServer::vmconfig_register_unused_drive($storecfg, $vmid, $conf, PVE::QemuServer::parse_drive($opt, $conf->{pending}->{$opt})) @@ -933,7 +933,7 @@ my $update_vm_api = sub { $conf = PVE::QemuServer::load_config($vmid); # update/reload next if defined($conf->{pending}->{$opt}) && ($param->{$opt} eq $conf->{pending}->{$opt}); # skip if nothing changed - if (PVE::QemuServer::valid_drivename($opt)) { + if (PVE::QemuServer::is_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']); @@ -2228,7 +2228,7 @@ __PACKAGE__->register_method({ my $net = PVE::QemuServer::parse_net($value); $net->{macaddr} = PVE::Tools::random_ether_addr(); $newconf->{$opt} = PVE::QemuServer::print_net($net); - } elsif (PVE::QemuServer::valid_drivename($opt)) { + } elsif (PVE::QemuServer::is_valid_drivename($opt)) { my $drive = PVE::QemuServer::parse_drive($opt, $value); die "unable to parse drive options for '$opt'\n" if !$drive; if (PVE::QemuServer::drive_is_cdrom($drive)) { @@ -2365,7 +2365,7 @@ __PACKAGE__->register_method({ disk => { type => 'string', description => "The disk you want to move.", - enum => [ PVE::QemuServer::disknames() ], + enum => [ PVE::QemuServer::valid_drive_names() ], }, storage => get_standard_option('pve-storage-id', { description => "Target storage.", @@ -2657,7 +2657,7 @@ __PACKAGE__->register_method({ disk => { type => 'string', description => "The disk you want to resize.", - enum => [PVE::QemuServer::disknames()], + enum => [PVE::QemuServer::valid_drive_names()], }, size => { type => 'string', @@ -3115,7 +3115,7 @@ __PACKAGE__->register_method({ optional => 1, type => 'string', description => "If you want to convert only 1 disk to base image.", - enum => [PVE::QemuServer::disknames()], + enum => [PVE::QemuServer::valid_drive_names()], }, }, diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm index 92b0e6a..17b43d2 100644 --- a/PVE/QemuServer.pm +++ b/PVE/QemuServer.pm @@ -899,7 +899,7 @@ sub kvm_user_version { my $kernel_has_vhost_net = -c '/dev/vhost-net'; -sub disknames { +sub valid_drive_names { # order is important - used to autoselect boot disk return ((map { "ide$_" } (0 .. ($MAX_IDE_DISKS - 1))), (map { "scsi$_" } (0 .. ($MAX_SCSI_DISKS - 1))), @@ -907,7 +907,7 @@ sub disknames { (map { "sata$_" } (0 .. ($MAX_SATA_DISKS - 1)))); } -sub valid_drivename { +sub is_valid_drivename { my $dev = shift; return defined($drivename_hash->{$dev}); @@ -1731,7 +1731,7 @@ PVE::JSONSchema::register_format('pve-qm-bootdisk', \&verify_bootdisk); sub verify_bootdisk { my ($value, $noerr) = @_; - return $value if valid_drivename($value); + return $value if is_valid_drivename($value); return undef if $noerr; @@ -2160,7 +2160,7 @@ sub write_vm_config { $cref->{$key} = $value; - if (!$snapname && valid_drivename($key)) { + if (!$snapname && is_valid_drivename($key)) { my $drive = parse_drive($key, $value); $used_volids->{$drive->{file}} = 1 if $drive && $drive->{file}; } @@ -2424,7 +2424,7 @@ sub disksize { my $bootdisk = $conf->{bootdisk}; return undef if !$bootdisk; - return undef if !valid_drivename($bootdisk); + return undef if !is_valid_drivename($bootdisk); return undef if !$conf->{$bootdisk}; @@ -2685,8 +2685,8 @@ sub foreach_reverse_dimm { sub foreach_drive { my ($conf, $func) = @_; - foreach my $ds (keys %$conf) { - next if !valid_drivename($ds); + foreach my $ds (valid_drive_names()) { + next if !defined($conf->{$ds}); my $drive = parse_drive($ds, $conf->{$ds}); next if !$drive; @@ -3725,7 +3725,7 @@ sub qemu_deletescsihw { my $devices_list = vm_devices_list($vmid); foreach my $opt (keys %{$devices_list}) { - if (PVE::QemuServer::valid_drivename($opt)) { + if (PVE::QemuServer::is_valid_drivename($opt)) { my $drive = PVE::QemuServer::parse_drive($opt, $conf->{$opt}); if($drive->{interface} eq 'scsi' && $drive->{index} < (($maxdev-1)*($controller+1))) { return 1; @@ -4161,7 +4161,7 @@ sub vmconfig_hotplug_pending { } elsif ($opt =~ m/^net(\d+)$/) { die "skip\n" if !$hotplug_features->{network}; vm_deviceunplug($vmid, $conf, $opt); - } elsif (valid_drivename($opt)) { + } elsif (is_valid_drivename($opt)) { die "skip\n" if !$hotplug_features->{disk} || $opt =~ m/(ide|sata)(\d+)/; vm_deviceunplug($vmid, $conf, $opt); vmconfig_delete_or_detach_drive($vmid, $storecfg, $conf, $opt, $force); @@ -4218,7 +4218,7 @@ sub vmconfig_hotplug_pending { # some changes can be done without hotplug vmconfig_update_net($storecfg, $conf, $hotplug_features->{network}, $vmid, $opt, $value); - } elsif (valid_drivename($opt)) { + } elsif (is_valid_drivename($opt)) { # some changes can be done without hotplug vmconfig_update_disk($storecfg, $conf, $hotplug_features->{disk}, $vmid, $opt, $value, 1); @@ -4297,7 +4297,7 @@ sub vmconfig_apply_pending { if (!defined($conf->{$opt})) { vmconfig_undelete_pending_option($conf, $opt); write_config($vmid, $conf); - } elsif (valid_drivename($opt)) { + } elsif (is_valid_drivename($opt)) { vmconfig_delete_or_detach_drive($vmid, $storecfg, $conf, $opt, $force); vmconfig_undelete_pending_option($conf, $opt); delete $conf->{$opt}; @@ -4316,7 +4316,7 @@ sub vmconfig_apply_pending { if (defined($conf->{$opt}) && ($conf->{$opt} eq $conf->{pending}->{$opt})) { # skip if nothing changed - } elsif (valid_drivename($opt)) { + } elsif (is_valid_drivename($opt)) { vmconfig_register_unused_drive($storecfg, $vmid, $conf, parse_drive($opt, $conf->{$opt})) if defined($conf->{$opt}); $conf->{$opt} = $conf->{pending}->{$opt}; @@ -5293,7 +5293,7 @@ sub is_volume_in_use { foreach my $key (keys %$cref) { my $value = $cref->{$key}; - if (valid_drivename($key)) { + if (is_valid_drivename($key)) { next if $skip_drive && $key eq $skip_drive; my $drive = parse_drive($key, $value); next if !$drive || !$drive->{file} || drive_is_cdrom($drive); @@ -5339,7 +5339,7 @@ sub update_disksize { # update size info foreach my $opt (keys %$conf) { - if (valid_drivename($opt)) { + if (is_valid_drivename($opt)) { my $drive = parse_drive($opt, $conf->{$opt}); my $volid = $drive->{file}; next if !$volid; @@ -5849,7 +5849,7 @@ sub foreach_writable_storage { my $sidhash = {}; foreach my $ds (keys %$conf) { - next if !valid_drivename($ds); + next if !is_valid_drivename($ds); my $drive = parse_drive($ds, $conf->{$ds}); next if !$drive; -- 2.1.4 _______________________________________________ pve-devel mailing list pve-devel@pve.proxmox.com http://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel