we need to unprotect more snapshots than just the base one, since we
allow linked clones of regular VM snapshots. unprotection will only work
if no linked clones exist anymore.

Signed-off-by: Fabian Grünbichler <f.gruenbich...@proxmox.com>
---
it's still rather ugly if such a linked clone exists, since unprotection
and thus deletion will fail, but the VM config is gone. at least with
this patch, "pvesm free storage:image" will work after
removing/flattening all the linked clones ;)

alternatively we could iterate over all snapshots in vm_destroy and
attempt to delete them (which will unprotect them in case of RBD),
leaving non-PVE-managed snapshots untouched.

 PVE/Storage/RBDPlugin.pm | 39 +++++++++++++++++++++++++++++++++++----
 1 file changed, 35 insertions(+), 4 deletions(-)

diff --git a/PVE/Storage/RBDPlugin.pm b/PVE/Storage/RBDPlugin.pm
index 10b54e5..2ead5de 100644
--- a/PVE/Storage/RBDPlugin.pm
+++ b/PVE/Storage/RBDPlugin.pm
@@ -227,6 +227,38 @@ sub rbd_ls {
     return $list;
 }
 
+sub rbd_ls_snap {
+    my ($scfg, $storeid, $name) = @_;
+
+    my $cmd = &$rbd_cmd($scfg, $storeid, 'snap', 'ls', $name, '--format', 
'json');
+
+    my $raw = '';
+    run_rbd_command($cmd, errmsg => "rbd error", errfunc => sub {}, outfunc => 
sub { $raw .= shift; });
+
+    my $list;
+    if ($raw =~ m/^(\[.*\])$/s) { # untaint
+       $list = eval { JSON::decode_json($1) };
+       die "invalid JSON output from 'rbd snap ls $name': $@\n" if $@;
+    } else {
+       die "got unexpected data from 'rbd snap ls $name': '$raw'\n";
+    }
+
+    $list = [] if !defined($list);
+
+    my $res = {};
+    foreach my $el (@$list) {
+       my $snap = $el->{name};
+       my $protected = defined($el->{protected}) && $el->{protected} eq "true" 
? 1 : undef;
+       $res->{$snap} = {
+           name => $snap,
+           id => $el->{id} // undef,
+           size => $el->{size} // 0,
+           protected => $protected,
+       };
+    }
+    return $res;
+}
+
 sub rbd_volume_info {
     my ($scfg, $storeid, $volname, $snap) = @_;
 
@@ -483,10 +515,9 @@ sub free_image {
     my ($vtype, $name, $vmid, undef, undef, undef) =
        $class->parse_volname($volname);
 
-    if ($isBase) {
-       my $snap = '__base__';
-       my (undef, undef, undef, $protected) = rbd_volume_info($scfg, $storeid, 
$name, $snap);
-       if ($protected){
+    my $snaps = rbd_ls_snap($scfg, $storeid, $name);
+    foreach my $snap (keys %$snaps) {
+       if ($snaps->{$snap}->{protected}) {
            my $cmd = &$rbd_cmd($scfg, $storeid, 'snap', 'unprotect', $name, 
'--snap', $snap);
            run_rbd_command($cmd, errmsg => "rbd unprotect $name snap '$snap' 
error");
        }
-- 
2.20.1


_______________________________________________
pve-devel mailing list
pve-devel@pve.proxmox.com
https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to