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();
}
}
+# 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) = @_;
die "storage '$storeid' does not exist\n" if (!$noerr && !$scfg);
+ $convert_maxfiles_to_prune_backups->($scfg);
+
return $scfg;
}
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) = @_;
};
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();
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,
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;
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 {