},
},
returns => {
- type => 'boolean'
+ type => "object",
+ properties => {
+ hasFeature => { type => 'boolean' },
+ nodes => {
+ type => 'array',
+ items => { type => 'string' },
+ }
+ },
},
code => sub {
my ($param) = @_;
}
my $storecfg = PVE::Storage::config();
- my $hasfeature = PVE::QemuServer::has_feature($feature, $conf, $storecfg, $snapname, $running);
- my $res = $hasfeature ? 1 : 0 ;
- return $res;
+ my $nodelist = PVE::QemuServer::shared_nodes($conf, $storecfg);
+ my $hasFeature = PVE::QemuServer::has_feature($feature, $conf, $storecfg, $snapname, $running);
+
+ return {
+ hasFeature => $hasFeature,
+ nodes => [ keys %$nodelist ],
+ };
}});
__PACKAGE__->register_method({
return $loc_res;
}
-# check is used storages are available on all nodes (use by migrate)
+# check if used storages are available on all nodes (use by migrate)
sub check_storage_availability {
my ($storecfg, $conf, $node) = @_;
});
}
+# list nodes where all VM images are available (used by has_feature API)
+sub shared_nodes {
+ my ($conf, $storecfg) = @_;
+
+ my $nodelist = PVE::Cluster::get_nodelist();
+ my $nodehash = { map { $_ => 1 } @$nodelist };
+ my $nodename = PVE::INotify::nodename();
+
+ 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}) {
+ $nodehash = {};
+ } elsif (my $avail = $scfg->{nodes}) {
+ foreach my $node (keys %$nodehash) {
+ delete $nodehash->{$node} if !$avail->{$node};
+ }
+ } elsif (!$scfg->{shared}) {
+ foreach my $node (keys %$nodehash) {
+ delete $nodehash->{$node} if $node ne $nodename
+ }
+ }
+ }
+ });
+
+ return $nodehash
+}
+
sub check_lock {
my ($conf) = @_;
sub has_feature {
my ($feature, $conf, $storecfg, $snapname, $running) = @_;
- my $err = undef;
+ my $err;
foreach_drive($conf, sub {
my ($ds, $drive) = @_;
$err = 1 if !PVE::Storage::volume_has_feature($storecfg, $feature, $volid, $snapname, $running);
});
- return 1 if !$err;
+ return $err ? 0 : 1;
}
sub template_create {