]> git.proxmox.com Git - pve-storage.git/blobdiff - PVE/Storage/Plugin.pm
pbs: backup-ns parameter was renamed to ns
[pve-storage.git] / PVE / Storage / Plugin.pm
index 65cd4ee285066a16e79a2083d09e22bffe7aafed..0a100b7b05a257afa0aab65ae5f9260e9ad0a09a 100644 (file)
@@ -3,6 +3,7 @@ package PVE::Storage::Plugin;
 use strict;
 use warnings;
 
+use Encode qw(decode);
 use Fcntl ':mode';
 use File::chdir;
 use File::Path;
@@ -155,6 +156,13 @@ my $defaultData = {
            optional => 1,
        },
        'prune-backups' => get_standard_option('prune-backups'),
+       'max-protected-backups' => {
+           description => "Maximal number of protected backups per guest. Use '-1' for unlimited.",
+           type => 'integer',
+           minimum => -1,
+           optional => 1,
+           default => "Unlimited for users with Datastore.Allocate privilege, 5 for other users",
+       },
        shared => {
            description => "Mark storage as shared.",
            type => 'boolean',
@@ -1045,26 +1053,43 @@ sub volume_has_feature {
     my ($class, $scfg, $feature, $storeid, $volname, $snapname, $running, $opts) = @_;
 
     my $features = {
-       snapshot => { current => { qcow2 => 1}, snap => { qcow2 => 1} },
-       clone => { base => {qcow2 => 1, raw => 1, vmdk => 1} },
-       template => { current => {qcow2 => 1, raw => 1, vmdk => 1, subvol => 1} },
-       copy => { base => {qcow2 => 1, raw => 1, vmdk => 1},
-                 current => {qcow2 => 1, raw => 1, vmdk => 1},
-                 snap => {qcow2 => 1} },
-       sparseinit => { base => {qcow2 => 1, raw => 1, vmdk => 1},
-                       current => {qcow2 => 1, raw => 1, vmdk => 1} },
-       rename => { current => {qcow2 => 1, raw => 1, vmdk => 1} },
+       snapshot => {
+           current => { qcow2 => 1 },
+           snap => { qcow2 => 1 },
+       },
+       clone => {
+           base => { qcow2 => 1, raw => 1, vmdk => 1 },
+       },
+       template => {
+           current => { qcow2 => 1, raw => 1, vmdk => 1, subvol => 1 },
+       },
+       copy => {
+           base => { qcow2 => 1, raw => 1, vmdk => 1 },
+           current => { qcow2 => 1, raw => 1, vmdk => 1 },
+           snap => { qcow2 => 1 },
+       },
+       sparseinit => {
+           base => { qcow2 => 1, raw => 1, vmdk => 1 },
+           current => { qcow2 => 1, raw => 1, vmdk => 1 },
+       },
+       rename => {
+           current => {qcow2 => 1, raw => 1, vmdk => 1},
+       },
     };
 
-    # clone_image creates a qcow2 volume
-    return 0 if $feature eq 'clone' &&
-               defined($opts->{valid_target_formats}) &&
-               !(grep { $_ eq 'qcow2' } @{$opts->{valid_target_formats}});
+    if ($feature eq 'clone') {
+       if (
+           defined($opts->{valid_target_formats})
+           && !(grep { $_ eq 'qcow2' } @{$opts->{valid_target_formats}})
+       ) {
+           return 0; # clone_image creates a qcow2 volume
+       }
+    } elsif ($feature eq 'rename') {
+       return 0 if $class->can('api') && $class->api() < 10;
+    }
 
-    return 0 if $feature eq 'rename' && $class->can('api') && $class->api() < 10;
 
-    my ($vtype, $name, $vmid, $basename, $basevmid, $isBase, $format) =
-       $class->parse_volname($volname);
+    my ($vtype, $name, $vmid, $basename, $basevmid, $isBase, $format) = $class->parse_volname($volname);
 
     my $key = undef;
     if($snapname){
@@ -1164,6 +1189,7 @@ my $get_subdir_files = sub {
            my $archive_info = eval { PVE::Storage::archive_info($fn) } // {};
 
            $info->{ctime} = $archive_info->{ctime} if defined($archive_info->{ctime});
+           $info->{subtype} = $archive_info->{type} // 'unknown';
 
            if (defined($vmid) || $fn =~ m!\-([1-9][0-9]{2,8})\-[^/]+\.${format}$!) {
                $info->{vmid} = $vmid // $1;
@@ -1172,7 +1198,7 @@ my $get_subdir_files = sub {
            my $notes_fn = $original.NOTES_EXT;
            if (-f $notes_fn) {
                my $notes = PVE::Tools::file_read_firstline($notes_fn);
-               $info->{notes} = $notes if defined($notes);
+               $info->{notes} = eval { decode('UTF-8', $notes, 1) } // $notes if defined($notes);
            }
 
            $info->{protected} = 1 if -e PVE::Storage::protection_file_path($original);