]> git.proxmox.com Git - qemu-server.git/commitdiff
fix unused disk handling
authorDietmar Maurer <dietmar@proxmox.com>
Tue, 28 May 2013 10:02:29 +0000 (12:02 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Tue, 28 May 2013 10:08:45 +0000 (12:08 +0200)
Show unused disks even if disk is used inside snapshots. But do not allow
to remove those disks.

PVE/API2/Qemu.pm
PVE/QemuServer.pm

index 2df6d88c8b3206e6faec30f15fc4bea439bbc9f1..3526e44b9e6f1149afc2808d6c2874dadc80ab0f 100644 (file)
@@ -660,10 +660,19 @@ my $delete_drive = sub {
 
     if (!PVE::QemuServer::drive_is_cdrom($drive)) {
        my $volid = $drive->{file};
+
        if (&$vm_is_volid_owner($storecfg, $vmid, $volid)) {
-           if ($force || $key =~ m/^unused/) {
-               # fixme: aliases!!
-               eval { PVE::Storage::vdisk_free($storecfg, $volid); };
+           if ($force || $key =~ m/^unused/) {    
+               eval { 
+                   # check if the disk is really unused 
+                   my $used_paths = PVE::QemuServer::get_used_paths($vmid, $storecfg, $conf, 1, $key);
+                   my $path = PVE::Storage::path($storecfg, $volid); 
+
+                   die "unable to delete '$volid' - volume is still in use (snapshot?)\n"
+                       if $used_paths->{$path};
+
+                   PVE::Storage::vdisk_free($storecfg, $volid); 
+               };
                die $@ if $@;
            } else {
                PVE::QemuServer::add_unused_volume($conf, $volid, $vmid);
index db767d664c0bdd0d0b565ce57d4877a7c0e3c8d1..666e2826f99db36f077cb75b9fe5bf43ea7dcb28 100644 (file)
@@ -1696,9 +1696,8 @@ sub write_vm_config {
 
     my $used_volids = {};
 
-    # fixme: allow to add unused disk even if disk is used inside snapshot
     my $cleanup_config = sub {
-       my ($cref) = @_;
+       my ($cref, $snapname) = @_;
 
        foreach my $key (keys %$cref) {
            next if $key eq 'digest' || $key eq 'description' || $key eq 'snapshots' ||
@@ -1709,7 +1708,7 @@ sub write_vm_config {
 
            $cref->{$key} = $value;
 
-           if (valid_drivename($key)) {
+           if (!$snapname && valid_drivename($key)) {
                my $drive = parse_drive($key, $value);
                $used_volids->{$drive->{file}} = 1 if $drive && $drive->{file};
            }
@@ -1718,7 +1717,7 @@ sub write_vm_config {
 
     &$cleanup_config($conf);
     foreach my $snapname (keys %{$conf->{snapshots}}) {
-       &$cleanup_config($conf->{snapshots}->{$snapname});
+       &$cleanup_config($conf->{snapshots}->{$snapname}, $snapname);
     }
 
     # remove 'unusedX' settings if we re-add a volume
@@ -3614,6 +3613,47 @@ sub scan_volids {
     return $volid_hash;
 }
 
+sub get_used_paths {
+    my ($vmid, $storecfg, $conf, $scan_snapshots, $skip_drive) = @_;
+
+    my $used_path = {};
+
+    my $scan_config = sub {
+       my ($cref, $snapname) = @_;
+
+       foreach my $key (keys %$cref) {
+           my $value = $cref->{$key};
+           if (valid_drivename($key)) {
+               next if $skip_drive && $key eq $skip_drive;
+               my $drive = parse_drive($key, $value);
+               next if !$drive || !$drive->{file} || drive_is_cdrom($drive);
+               if ($drive->{file} =~ m!^/!) {
+                   $used_path->{$drive->{file}}++; # = 1;
+               } else {
+                   my ($storeid, $volname) = PVE::Storage::parse_volume_id($drive->{file}, 1);
+                   next if !$storeid;
+                   my $scfg = PVE::Storage::storage_config($storecfg, $storeid, 1);
+                   next if !$scfg;
+                   my $path = PVE::Storage::path($storecfg, $drive->{file}, $snapname);
+                   $used_path->{$path}++; # = 1;
+               }
+           }
+       }
+    };
+
+    &$scan_config($conf);
+
+    undef $skip_drive;
+
+    if ($scan_snapshots) {
+       foreach my $snapname (keys %{$conf->{snapshots}}) {
+           &$scan_config($conf->{snapshots}->{$snapname}, $snapname);
+       }
+    }
+
+    return $used_path;
+}
+
 sub update_disksize {
     my ($vmid, $conf, $volid_hash) = @_;