]> git.proxmox.com Git - pve-common.git/blobdiff - src/PVE/AbstractConfig.pm
refactor delete_snapshot for readability
[pve-common.git] / src / PVE / AbstractConfig.pm
index 0799c8b3064dc23c6d1fcec1f39d31d0d972c1eb..7395768bc3b9e0e50aac4982b0769f140f448580 100644 (file)
@@ -239,7 +239,7 @@ sub __snapshot_create_vol_snapshot {
 
 # Remove a drive from the snapshot config.
 sub __snapshot_delete_remove_drive {
-    my ($class, $snap, $remove_drive) = @_;
+    my ($class, $snap, $drive) = @_;
 
     die "abstract method - implement me\n";
 }
@@ -286,6 +286,13 @@ sub __snapshot_rollback_vm_start {
     die "abstract method - implement me\n";
 }
 
+# Get list of volume IDs which are referenced in $conf, but not in $snap.
+sub __snapshot_rollback_get_unused {
+    my ($class, $conf, $snap) = @_;
+
+    die "abstract method - implement me\n";
+}
+
 # Iterate over all configured volumes, calling $func for each key/value pair.
 sub __snapshot_foreach_volume {
     my ($class, $conf, $func) = @_;
@@ -461,6 +468,9 @@ sub snapshot_delete {
     my $snap;
     my $unused = [];
 
+    $class->set_lock($vmid, 'snapshot-delete')
+       if (!$drivehash); # doesn't already have a 'snapshot' lock
+
     my $unlink_parent = sub {
        my ($confref, $new_parent) = @_;
 
@@ -473,55 +483,39 @@ sub snapshot_delete {
        }
     };
 
-    my $updatefn =  sub {
-       my ($remove_drive) = @_;
+    my $remove_drive = sub {
+       my ($drive) = @_;
 
        my $conf = $class->load_config($vmid);
+       $snap = $conf->{snapshots}->{$snapname};
+       die "snapshot '$snapname' does not exist\n" if !defined($snap);
 
-       if (!$drivehash) {
-           $class->check_lock($conf);
-           die "you can't delete a snapshot if vm is a template\n"
-               if $class->is_template($conf);
-       }
+       $class->__snapshot_delete_remove_drive($snap, $drive);
 
-       $snap = $conf->{snapshots}->{$snapname};
+       $class->write_config($vmid, $conf);
+    };
 
-       die "snapshot '$snapname' does not exist\n" if !defined($snap);
+    #prepare
+    $class->lock_config($vmid, sub {
+       my $conf = $class->load_config($vmid);
 
-       # remove parent refs
-       if (!$prepare) {
-           &$unlink_parent($conf, $snap->{parent});
-           foreach my $sn (keys %{$conf->{snapshots}}) {
-               next if $sn eq $snapname;
-               &$unlink_parent($conf->{snapshots}->{$sn}, $snap->{parent});
-           }
-       }
+       die "you can't delete a snapshot if vm is a template\n"
+           if $class->is_template($conf);
 
-       if ($remove_drive) {
-           $class->__snapshot_delete_remove_drive($snap, $remove_drive);
-       }
+       $snap = $conf->{snapshots}->{$snapname};
+       die "snapshot '$snapname' does not exist\n" if !defined($snap);
 
-       if ($prepare) {
-           $snap->{snapstate} = 'delete';
-       } else {
-           delete $conf->{snapshots}->{$snapname};
-           delete $conf->{lock} if $drivehash;
-           foreach my $volid (@$unused) {
-               $class->add_unused_volume($conf, $volid);
-           }
-       }
+       $snap->{snapstate} = 'delete';
 
        $class->write_config($vmid, $conf);
-    };
-
-    $class->lock_config($vmid, $updatefn);
+    });
 
     # now remove vmstate file
     if ($snap->{vmstate}) {
        $class->__snapshot_delete_vmstate_file($snap, $force);
 
        # save changes (remove vmstate from snapshot)
-       $class->lock_config($vmid, $updatefn, 'vmstate') if !$force;
+       $class->lock_config($vmid, $remove_drive, 'vmstate') if !$force;
     };
 
     # now remove all volume snapshots
@@ -537,13 +531,32 @@ sub snapshot_delete {
            }
        }
 
-       # save changes (remove mp from snapshot)
-       $class->lock_config($vmid, $updatefn, $vs) if !$force;
+       # save changes (remove drive from snapshot)
+       $class->lock_config($vmid, $remove_drive, $vs) if !$force;
     });
 
     # now cleanup config
-    $prepare = 0;
-    $class->lock_config($vmid, $updatefn);
+    $class->lock_config($vmid, sub {
+       my $conf = $class->load_config($vmid);
+       $snap = $conf->{snapshots}->{$snapname};
+       die "snapshot '$snapname' does not exist\n" if !defined($snap);
+
+       # remove parent refs
+       &$unlink_parent($conf, $snap->{parent});
+       foreach my $sn (keys %{$conf->{snapshots}}) {
+           next if $sn eq $snapname;
+           &$unlink_parent($conf->{snapshots}->{$sn}, $snap->{parent});
+       }
+
+
+       delete $conf->{snapshots}->{$snapname};
+       delete $conf->{lock};
+       foreach my $volid (@$unused) {
+           $class->add_unused_volume($conf, $volid);
+       }
+
+       $class->write_config($vmid, $conf);
+    });
 }
 
 # Rolls back to a given snapshot.
@@ -603,6 +616,12 @@ sub snapshot_rollback {
        my $forcemachine;
 
        if (!$prepare) {
+           my $unused = $class->__snapshot_rollback_get_unused($conf, $snap);
+
+           foreach my $volid (@$unused) {
+               $class->add_unused_volume($conf, $volid);
+           }
+
            my $has_machine_config = defined($conf->{machine});
 
            # copy snapshot config to current config