]> git.proxmox.com Git - pve-storage.git/blobdiff - PVE/Storage.pm
pbs: allow setting up a master key
[pve-storage.git] / PVE / Storage.pm
index c1a21b43d96adfa7e587c87b2b3828fa57df1d85..122c3e958fdbc975d7c65eac559177d4da3d0958 100755 (executable)
@@ -103,8 +103,6 @@ if ( -d '/usr/share/perl5/PVE/Storage/Custom' ) {
 # initialize all plugins
 PVE::Storage::Plugin->init();
 
-my $UDEVADM = '/sbin/udevadm';
-
 our $iso_extension_re = qr/\.(?:iso|img)/i;
 
 #  PVE::Storage utility functions
@@ -498,8 +496,15 @@ sub check_volume_access {
     return undef;
 }
 
-my $volume_is_base_and_used__no_lock = sub {
-    my ($scfg, $storeid, $plugin, $volname) = @_;
+# NOTE: this check does not work for LVM-thin, where the clone -> base
+# reference is not encoded in the volume ID.
+# see note in PVE::Storage::LvmThinPlugin for details.
+sub volume_is_base_and_used {
+    my ($cfg, $volid) = @_;
+
+    my ($storeid, $volname) = parse_volume_id($volid);
+    my $scfg = storage_config($cfg, $storeid);
+    my $plugin = PVE::Storage::Plugin->lookup($scfg->{type});
 
     my ($vtype, $name, $vmid, undef, undef, $isBase, undef) =
        $plugin->parse_volname($volname);
@@ -522,21 +527,6 @@ my $volume_is_base_and_used__no_lock = sub {
        }
     }
     return 0;
-};
-
-# NOTE: this check does not work for LVM-thin, where the clone -> base
-# reference is not encoded in the volume ID.
-# see note in PVE::Storage::LvmThinPlugin for details.
-sub volume_is_base_and_used {
-    my ($cfg, $volid) = @_;
-
-    my ($storeid, $volname) = parse_volume_id($volid);
-    my $scfg = storage_config($cfg, $storeid);
-    my $plugin = PVE::Storage::Plugin->lookup($scfg->{type});
-
-    $plugin->cluster_lock_storage($storeid, $scfg->{shared}, undef, sub {
-       return &$volume_is_base_and_used__no_lock($scfg, $storeid, $plugin, $volname);
-    });
 }
 
 # try to map a filesystem path to a volume identifier
@@ -619,22 +609,22 @@ sub path {
 }
 
 sub abs_filesystem_path {
-    my ($cfg, $volid) = @_;
+    my ($cfg, $volid, $allow_blockdev) = @_;
 
     my $path;
     if (parse_volume_id ($volid, 1)) {
        activate_volumes($cfg, [ $volid ]);
        $path = PVE::Storage::path($cfg, $volid);
     } else {
-       if (-f $volid) {
+       if (-f $volid || ($allow_blockdev && -b $volid)) {
            my $abspath = abs_path($volid);
            if ($abspath && $abspath =~ m|^(/.+)$|) {
                $path = $1; # untaint any path
            }
        }
     }
-
-    die "can't find file '$volid'\n" if !($path && -f $path);
+    die "can't find file '$volid'\n"
+       if !($path && (-f $path || ($allow_blockdev && -b $path)));
 
     return $path;
 }
@@ -768,8 +758,14 @@ sub storage_migrate {
                or die "receive command failed: $!\n";
            close($input);
 
-           my ($ip) = <$info> =~ /^($PVE::Tools::IPRE)$/ or die "no tunnel IP received\n";
-           my ($port) = <$info> =~ /^(\d+)$/ or die "no tunnel port received\n";
+           my $try_ip = <$info> // '';
+           my ($ip) = $try_ip =~ /^($PVE::Tools::IPRE)$/ # untaint
+               or die "no tunnel IP received, got '$try_ip'\n";
+
+           my $try_port = <$info> // '';
+           my ($port) = $try_port =~ /^(\d+)$/ # untaint
+               or die "no tunnel port received, got '$try_port'\n";
+
            my $socket = IO::Socket::IP->new(PeerHost => $ip, PeerPort => $port, Type => SOCK_STREAM)
                or die "failed to connect to tunnel at $ip:$port\n";
            # we won't be reading from the socket
@@ -920,7 +916,7 @@ sub vdisk_free {
     $plugin->cluster_lock_storage($storeid, $scfg->{shared}, undef, sub {
        # LVM-thin allows deletion of still referenced base volumes!
        die "base volume '$volname' is still in use by linked clones\n"
-           if &$volume_is_base_and_used__no_lock($scfg, $storeid, $plugin, $volname);
+           if volume_is_base_and_used($cfg, $volid);
 
        my (undef, undef, undef, undef, undef, $isBase, $format) =
            $plugin->parse_volname($volname);
@@ -936,7 +932,7 @@ sub vdisk_free {
 }
 
 sub vdisk_list {
-    my ($cfg, $storeid, $vmid, $vollist) = @_;
+    my ($cfg, $storeid, $vmid, $vollist, $ctype) = @_;
 
     my $ids = $cfg->{ids};
 
@@ -959,6 +955,7 @@ sub vdisk_list {
            next if $storeid && $storeid ne $sid;
            next if !storage_check_enabled($cfg, $sid, undef, 1);
            my $content = $ids->{$sid}->{content};
+           next if defined($ctype) && !$content->{$ctype};
            next if !($content->{rootdir} || $content->{images});
            push @$storage_list, $sid;
        }
@@ -968,7 +965,10 @@ sub vdisk_list {
 
     activate_storage_list($cfg, $storage_list, $cache);
 
-    foreach my $sid (keys %$ids) {
+    # FIXME PVE 7.0: only scan storages with the correct content types
+    my $scan = defined($ctype) ? $storage_list : [ keys %{$ids} ];
+
+    foreach my $sid (@{$scan}) {
        next if $storeid && $storeid ne $sid;
        next if !storage_check_enabled($cfg, $sid, undef, 1);
 
@@ -1075,8 +1075,7 @@ sub activate_storage {
 
     # only call udevsettle if there are events
     if ($newseq > $cache->{uevent_seqnum}) {
-       my $timeout = 30;
-       system ("$UDEVADM settle --timeout=$timeout"); # ignore errors
+       system ("udevadm settle --timeout=30"); # ignore errors
        $cache->{uevent_seqnum} = $newseq;
     }
 
@@ -1697,8 +1696,8 @@ sub prune_mark_backup_group {
     $prune_mark->($prune_list, $keep->{'keep-weekly'}, sub {
        my ($ctime) = @_;
        my ($sec, $min, $hour, $day, $month, $year) = localtime($ctime);
-       my $iso_week = int(strftime("%V", $sec, $min, $hour, $day, $month - 1, $year - 1900));
-       my $iso_week_year = int(strftime("%G", $sec, $min, $hour, $day, $month - 1, $year - 1900));
+       my $iso_week = int(strftime("%V", $sec, $min, $hour, $day, $month, $year));
+       my $iso_week_year = int(strftime("%G", $sec, $min, $hour, $day, $month, $year));
        return "$iso_week/$iso_week_year";
     });
     $prune_mark->($prune_list, $keep->{'keep-monthly'}, sub {