]> git.proxmox.com Git - pve-storage.git/blobdiff - PVE/Storage/ZFSPoolPlugin.pm
nfs: check connection: support NFSv4-only servers without rpcbind
[pve-storage.git] / PVE / Storage / ZFSPoolPlugin.pm
index 0f16e7d296d5412fdf4ba2f2f8dcce4029eab292..9fbd1497fc49090de1aa6a9fdda9738f7fd6ff71 100644 (file)
@@ -58,7 +58,7 @@ sub options {
 # static zfs helper methods
 
 sub zfs_parse_zvol_list {
-    my ($text) = @_;
+    my ($text, $pool) = @_;
 
     my $list = ();
 
@@ -73,12 +73,12 @@ sub zfs_parse_zvol_list {
        my @parts = split /\//, $dataset;
        next if scalar(@parts) < 2; # we need pool/name
        my $name = pop @parts;
-       my $pool = join('/', @parts);
+       my $parsed_pool = join('/', @parts);
+       next if $parsed_pool ne $pool;
 
        next unless $name =~ m!^(vm|base|subvol|basevol)-(\d+)-(\S+)$!;
        $zvol->{owner} = $2;
 
-       $zvol->{pool} = $pool;
        $zvol->{name} = $name;
        if ($type eq 'filesystem') {
            if ($refquota eq 'none') {
@@ -254,37 +254,30 @@ sub free_image {
 sub list_images {
     my ($class, $storeid, $scfg, $vmid, $vollist, $cache) = @_;
 
-    $cache->{zfs}->{$storeid} = $class->zfs_list_zvol($scfg)
-       if !$cache->{zfs}->{$storeid};
+    my $zfs_list = $class->zfs_list_zvol($scfg);
 
     my $res = [];
 
-    if (my $dat = $cache->{zfs}->{$storeid}) {
+    for my $info (values $zfs_list->%*) {
+       my $volname = $info->{name};
+       my $parent = $info->{parent};
+       my $owner = $info->{vmid};
 
-       foreach my $image (keys %$dat) {
-
-           my $info = $dat->{$image};
-
-           my $volname = $info->{name};
-           my $parent = $info->{parent};
-           my $owner = $info->{vmid};
-
-           if ($parent && $parent =~ m/^(\S+)\@__base__$/) {
-               my ($basename) = ($1);
-               $info->{volid} = "$storeid:$basename/$volname";
-           } else {
-               $info->{volid} = "$storeid:$volname";
-           }
-
-           if ($vollist) {
-               my $found = grep { $_ eq $info->{volid} } @$vollist;
-               next if !$found;
-           } else {
-               next if defined ($vmid) && ($owner ne $vmid);
-           }
+       if ($parent && $parent =~ m/^(\S+)\@__base__$/) {
+           my ($basename) = ($1);
+           $info->{volid} = "$storeid:$basename/$volname";
+       } else {
+           $info->{volid} = "$storeid:$volname";
+       }
 
-           push @$res, $info;
+       if ($vollist) {
+           my $found = grep { $_ eq $info->{volid} } @$vollist;
+           next if !$found;
+       } else {
+           next if defined ($vmid) && ($owner ne $vmid);
        }
+
+       push @$res, $info;
     }
     return $res;
 }
@@ -384,17 +377,17 @@ sub zfs_list_zvol {
        'name,volsize,origin,type,refquota',
        '-t',
        'volume,filesystem',
-       '-Hrp',
+       '-d1',
+       '-Hp',
        $scfg->{pool},
     );
-    my $zvols = zfs_parse_zvol_list($text);
-    return undef if !$zvols;
+    # It's still required to have zfs_parse_zvol_list filter by pool, because -d1 lists
+    # $scfg->{pool} too and while unlikely, it could be named to be mistaken for a volume.
+    my $zvols = zfs_parse_zvol_list($text, $scfg->{pool});
+    return {} if !$zvols;
 
-    my $list = ();
+    my $list = {};
     foreach my $zvol (@$zvols) {
-       # The "pool" in $scfg is not the same as ZFS pool, so it's necessary to filter here.
-       next if $scfg->{pool} ne $zvol->{pool};
-
        my $name = $zvol->{name};
        my $parent = $zvol->{origin};
        if($zvol->{origin} && $zvol->{origin} =~ m/^$scfg->{pool}\/(\S+)$/){