zfspool: add blockers parameter to volume_snapshot_is_possible

useful for rollback, so that only the required replication snapshots
can be removed, and it's possible to abort early without deleting any
replication snapshots if there are other non-replication snasphots
blocking rollback.

Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
This commit is contained in:
Fabian Ebner
2021-08-12 13:01:01 +02:00
committed by Fabian Grünbichler
parent ac5c1af57c
commit 9a5d50950c
4 changed files with 24 additions and 10 deletions

View File

@ -269,13 +269,13 @@ sub volume_resize {
} }
sub volume_rollback_is_possible { sub volume_rollback_is_possible {
my ($cfg, $volid, $snap) = @_; my ($cfg, $volid, $snap, $blockers) = @_;
my ($storeid, $volname) = parse_volume_id($volid, 1); my ($storeid, $volname) = parse_volume_id($volid, 1);
if ($storeid) { if ($storeid) {
my $scfg = storage_config($cfg, $storeid); my $scfg = storage_config($cfg, $storeid);
my $plugin = PVE::Storage::Plugin->lookup($scfg->{type}); my $plugin = PVE::Storage::Plugin->lookup($scfg->{type});
return $plugin->volume_rollback_is_possible($scfg, $storeid, $volname, $snap); return $plugin->volume_rollback_is_possible($scfg, $storeid, $volname, $snap, $blockers);
} elsif ($volid =~ m|^(/.+)$| && -e $volid) { } elsif ($volid =~ m|^(/.+)$| && -e $volid) {
die "snapshot rollback file/device '$volid' is not possible\n"; die "snapshot rollback file/device '$volid' is not possible\n";
} else { } else {

View File

@ -516,7 +516,7 @@ sub volume_snapshot {
} }
sub volume_rollback_is_possible { sub volume_rollback_is_possible {
my ($class, $scfg, $storeid, $volname, $snap) = @_; my ($class, $scfg, $storeid, $volname, $snap, $blockers) = @_;
return 1; return 1;
} }

View File

@ -948,8 +948,11 @@ sub volume_snapshot {
return undef; return undef;
} }
# Asserts that a rollback to $snap on $volname is possible.
# If certain snapshots are preventing the rollback and $blockers is an array
# reference, the snapshot names can be pushed onto $blockers prior to dying.
sub volume_rollback_is_possible { sub volume_rollback_is_possible {
my ($class, $scfg, $storeid, $volname, $snap) = @_; my ($class, $scfg, $storeid, $volname, $snap, $blockers) = @_;
return 1; return 1;
} }

View File

@ -483,18 +483,29 @@ sub volume_snapshot_rollback {
} }
sub volume_rollback_is_possible { sub volume_rollback_is_possible {
my ($class, $scfg, $storeid, $volname, $snap) = @_; my ($class, $scfg, $storeid, $volname, $snap, $blockers) = @_;
# can't use '-S creation', because zfs list won't reverse the order when the # can't use '-S creation', because zfs list won't reverse the order when the
# creation time is the same second, breaking at least our tests. # creation time is the same second, breaking at least our tests.
my $snapshots = $class->zfs_get_sorted_snapshot_list($scfg, $volname, ['-s', 'creation']); my $snapshots = $class->zfs_get_sorted_snapshot_list($scfg, $volname, ['-s', 'creation']);
my $recentsnap = $snapshots->[-1];
die "can't rollback, no snapshots exist at all\n" my $found;
if !defined($recentsnap); $blockers //= []; # not guaranteed to be set by caller
for my $snapshot ($snapshots->@*) {
if ($snapshot eq $snap) {
$found = 1;
} elsif ($found) {
push $blockers->@*, $snapshot;
}
}
die "can't rollback, '$snap' is not most recent snapshot\n" my $volid = "${storeid}:${volname}";
if $snap ne $recentsnap;
die "can't rollback, snapshot '$snap' does not exist on '$volid'\n"
if !$found;
die "can't rollback, '$snap' is not most recent snapshot on '$volid'\n"
if scalar($blockers->@*) > 0;
return 1; return 1;
} }