From 2e953867ad841483d718bf555b14eb5ea0152377 Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Mon, 11 Apr 2016 15:19:46 +0200 Subject: [PATCH] Fix #848: deactivate old volume after clone before deletion Otherwise some move operations will fail to delete the old disk (eg. when moving from ceph to local storage). Note that in order for the deactivation to succeed we need to make sure qemu has closed its file descriptors, so we need to wait for the job to disappear the same way we do in $cancel_job(). Factored the waiting out into $finish_job(). --- PVE/API2/Qemu.pm | 5 ++++- PVE/QemuServer.pm | 21 ++++++++++++++------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm index 8bb68a48..409653ab 100644 --- a/PVE/API2/Qemu.pm +++ b/PVE/API2/Qemu.pm @@ -2502,7 +2502,10 @@ __PACKAGE__->register_method({ PVE::QemuConfig->add_unused_volume($conf, $old_volid); PVE::QemuConfig->write_config($vmid, $conf); } else { - eval { PVE::Storage::vdisk_free($storecfg, $old_volid); }; + eval { + PVE::Storage::deactivate_volumes($storecfg, [$old_volid]); + PVE::Storage::vdisk_free($storecfg, $old_volid); + }; warn $@ if $@; } } diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm index b61974da..2d8da435 100644 --- a/PVE/QemuServer.pm +++ b/PVE/QemuServer.pm @@ -5923,6 +5923,15 @@ sub qemu_drive_mirror { print "drive mirror is starting (scanning bitmap) : this step can take some minutes/hours, depend of disk size and storage speed\n"; + my $finish_job = sub { + while (1) { + my $stats = vm_mon_cmd($vmid, "query-block-jobs"); + my $stat = @$stats[0]; + last if !$stat; + sleep 1; + } + }; + eval { vm_mon_cmd($vmid, "drive-mirror", %$opts); while (1) { @@ -5949,7 +5958,10 @@ sub qemu_drive_mirror { # try to switch the disk if source and destination are on the same guest eval { vm_mon_cmd($vmid, "block-job-complete", device => "drive-$drive") }; - last if !$@; + if (!$@) { + &$finish_job(); + last; + } die $@ if $@ !~ m/cannot be completed/; } sleep 1; @@ -5961,12 +5973,7 @@ sub qemu_drive_mirror { my $cancel_job = sub { vm_mon_cmd($vmid, "block-job-cancel", device => "drive-$drive"); - while (1) { - my $stats = vm_mon_cmd($vmid, "query-block-jobs"); - my $stat = @$stats[0]; - last if !$stat; - sleep 1; - } + &$finish_job(); }; if ($err) {