]> git.proxmox.com Git - pve-storage.git/blobdiff - PVE/Storage.pm
Diskmanage: also include partitions with get_disks if flag is set
[pve-storage.git] / PVE / Storage.pm
index 18eef46fb217da231eb806cb4e3c43128ab236e1..d8197c30596ed3e407cebfa99f4668f8c28d7140 100755 (executable)
@@ -41,11 +41,11 @@ use PVE::Storage::DRBDPlugin;
 use PVE::Storage::PBSPlugin;
 
 # Storage API version. Increment it on changes in storage API interface.
-use constant APIVER => 7;
+use constant APIVER => 8;
 # Age is the number of versions we're backward compatible with.
 # This is like having 'current=APIVER' and age='APIAGE' in libtool,
 # see https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html
-use constant APIAGE => 6;
+use constant APIAGE => 7;
 
 # load standard plugins
 PVE::Storage::DirPlugin->register();
@@ -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
@@ -129,6 +127,28 @@ sub lock_storage_config {
     }
 }
 
+# FIXME remove maxfiles for PVE 7.0
+my $convert_maxfiles_to_prune_backups = sub {
+    my ($scfg) = @_;
+
+    return if !$scfg;
+
+    my $maxfiles = delete $scfg->{maxfiles};
+
+    if (!defined($scfg->{'prune-backups'}) && defined($maxfiles)) {
+       my $prune_backups;
+       if ($maxfiles) {
+           $prune_backups = { 'keep-last' => $maxfiles };
+       } else { # maxfiles 0 means no limit
+           $prune_backups = { 'keep-all' => 1 };
+       }
+       $scfg->{'prune-backups'} = PVE::JSONSchema::print_property_string(
+           $prune_backups,
+           'prune-backups'
+       );
+    }
+};
+
 sub storage_config {
     my ($cfg, $storeid, $noerr) = @_;
 
@@ -138,6 +158,8 @@ sub storage_config {
 
     die "storage '$storeid' does not exist\n" if (!$noerr && !$scfg);
 
+    $convert_maxfiles_to_prune_backups->($scfg);
+
     return $scfg;
 }
 
@@ -193,6 +215,26 @@ sub file_size_info {
     return PVE::Storage::Plugin::file_size_info($filename, $timeout);
 }
 
+sub get_volume_notes {
+    my ($cfg, $volid, $timeout) = @_;
+
+    my ($storeid, $volname) = parse_volume_id($volid);
+    my $scfg = storage_config($cfg, $storeid);
+    my $plugin = PVE::Storage::Plugin->lookup($scfg->{type});
+
+    return $plugin->get_volume_notes($scfg, $storeid, $volname, $timeout);
+}
+
+sub update_volume_notes {
+    my ($cfg, $volid, $notes, $timeout) = @_;
+
+    my ($storeid, $volname) = parse_volume_id($volid);
+    my $scfg = storage_config($cfg, $storeid);
+    my $plugin = PVE::Storage::Plugin->lookup($scfg->{type});
+
+    $plugin->update_volume_notes($scfg, $storeid, $volname, $notes, $timeout);
+}
+
 sub volume_size_info {
     my ($cfg, $volid, $timeout) = @_;
 
@@ -709,6 +751,13 @@ sub storage_migrate {
     };
 
     volume_snapshot($cfg, $volid, $snapshot) if $migration_snapshot;
+
+    if (defined($snapshot)) {
+       activate_volumes($cfg, [$volid], $snapshot);
+    } else {
+       activate_volumes($cfg, [$volid]);
+    }
+
     eval {
        if ($insecure) {
            my $input = IO::File->new();
@@ -1024,8 +1073,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;
     }
 
@@ -1404,7 +1452,8 @@ sub decompressor_info {
     die "ERROR: archive format not defined\n"
        if !defined($decompressor->{$format});
 
-    my $decomp = $decompressor->{$format}->{$comp} if $comp;
+    my $decomp;
+    $decomp = $decompressor->{$format}->{$comp} if $comp;
 
     my $info = {
        format => $format,
@@ -1594,13 +1643,14 @@ my $prune_mark = sub {
     foreach my $prune_entry (@{$prune_entries}) {
        my $mark = $prune_entry->{mark};
        my $id = $id_func->($prune_entry->{ctime});
+       $already_included->{$id} = 1 if defined($mark) && $mark eq 'keep';
+    }
 
-       next if $already_included->{$id};
+    foreach my $prune_entry (@{$prune_entries}) {
+       my $mark = $prune_entry->{mark};
+       my $id = $id_func->($prune_entry->{ctime});
 
-       if (defined($mark)) {
-           $already_included->{$id} = 1 if $mark eq 'keep';
-           next;
-       }
+       next if defined($mark) || $already_included->{$id};
 
        if (!$newly_included->{$id}) {
            last if scalar(keys %{$newly_included}) >= $keep_count;
@@ -1615,6 +1665,16 @@ my $prune_mark = sub {
 sub prune_mark_backup_group {
     my ($backup_group, $keep) = @_;
 
+    my $keep_all = delete $keep->{'keep-all'};
+
+    if ($keep_all || !scalar(grep {$_ > 0} values %{$keep})) {
+       $keep = { 'keep-all' => 1 } if $keep_all;
+       foreach my $prune_entry (@{$backup_group}) {
+           $prune_entry->{mark} = 'keep';
+       }
+       return;
+    }
+
     my $prune_list = [ sort { $b->{ctime} <=> $a->{ctime} } @{$backup_group} ];
 
     $prune_mark->($prune_list, $keep->{'keep-last'}, sub {
@@ -1634,8 +1694,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 {