From f25852c27e29a5c85016bcb0a626c680bbc33c4d Mon Sep 17 00:00:00 2001 From: Tim Marx Date: Fri, 28 Jun 2019 15:13:45 +0200 Subject: [PATCH] migrate: handle storage not selected manually in storage config e.g. local storage was considered not allowed for offline migration even if it is available on all nodes, this should now be fixed as it is now considered available on all nodes if a local storage isn't restricted to a specific subset of the available nodes. The user is responseable to make sure that the datacenter storage config reflects the actual setup, so there is no additional check for local storages which aren't available on all nodes if they are not explicitly marked at datacenter level. Signed-off-by: Tim Marx --- PVE/API2/Qemu.pm | 22 +++++++++++++++++----- PVE/QemuServer.pm | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm index c9b2f67..1c4e07b 100644 --- a/PVE/API2/Qemu.pm +++ b/PVE/API2/Qemu.pm @@ -3163,7 +3163,12 @@ __PACKAGE__->register_method({ allowed_nodes => { type => 'array', optional => 1, - description => "List nodes allowed for offline migration with same local storage as source node, only passed if VM is offline" + description => "List nodes allowed for offline migration, only passed if VM is offline" + }, + not_allowed_nodes => { + type => 'object', + optional => 1, + description => "List not allowed nodes with additional informations, only passed if VM is offline" }, local_disks => { type => 'array', @@ -3204,11 +3209,18 @@ __PACKAGE__->register_method({ # if vm is not running, return target nodes where local storage is available # for offline migration if (!$res->{running}) { - my $shared_nodes = PVE::QemuServer::shared_nodes($vmconf, $storecfg); - - delete $shared_nodes->{$localnode} if $shared_nodes->{$localnode}; + $res->{allowed_nodes} = []; + my $checked_nodes = PVE::QemuServer::check_local_storage_availability($vmconf, $storecfg); + + delete $checked_nodes->{$localnode} if $checked_nodes->{$localnode}; + foreach my $node (keys %$checked_nodes) { + if (!defined $checked_nodes->{$node}->{not_available_storages}){ + push @{$res->{allowed_nodes}}, $node; + delete $checked_nodes->{$node}; + } - $res->{allowed_nodes} = [ keys %$shared_nodes ]; + } + $res->{not_allowed_nodes} = $checked_nodes; } diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm index fbfc3fb..1f3234f 100644 --- a/PVE/QemuServer.pm +++ b/PVE/QemuServer.pm @@ -2924,6 +2924,39 @@ sub shared_nodes { return $nodehash } +sub check_local_storage_availability { + my ($conf, $storecfg) = @_; + + my $nodelist = PVE::Cluster::get_nodelist(); + my $nodehash = { map { $_ => {} } @$nodelist }; + + foreach_drive($conf, sub { + my ($ds, $drive) = @_; + + my $volid = $drive->{file}; + return if !$volid; + + my ($storeid, $volname) = PVE::Storage::parse_volume_id($volid, 1); + if ($storeid) { + my $scfg = PVE::Storage::storage_config($storecfg, $storeid); + + if ($scfg->{disable}) { + foreach my $node (keys %$nodehash) { + push @{$nodehash->{$node}->{not_available_storages}}, $storeid; + } + } elsif (my $avail = $scfg->{nodes}) { + foreach my $node (keys %$nodehash) { + if (!$avail->{$node}) { + push @{$nodehash->{$node}->{not_available_storages}}, $storeid; + } + } + } + } + }); + + return $nodehash +} + sub check_cmdline { my ($pidfile, $pid) = @_; -- 2.39.2