From: Peter Krempa <[email protected]>

Locking the <lease> on hotplug into a paused VM will prevent the VM from
being resumed since the resource is already locked:

 $ virsh start cd --paused
 Domain 'cd' started
 $ virsh attach-device --live cd lease2.xml
 Device attached successfully
 $ virsh resume cd
 error: Failed to resume domain 'cd'
 error: resource busy: Lockspace resource 'qw2' is locked

Don't lock the <lease>, just insert it when the VM is paused. Similarly
don't try to unlock it on hot-unplug when the VM is paused and thus the
resource is unlocked.

Closes: https://gitlab.com/libvirt/libvirt/-/work_items/877
Signed-off-by: Peter Krempa <[email protected]>
---
 src/qemu/qemu_hotplug.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 3d25b4c7d0..31726daf62 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -3421,8 +3421,12 @@ qemuDomainAttachLease(virQEMUDriver *driver,
 {
     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);

-    if (virDomainLockLeaseAttach(driver->lockManager, cfg->uri, vm, lease) < 0)
-        return -1;
+    /* If the VM is paused or in another state we don't actually want to
+     * lock the lease yet. It will be done when the VM is resumed */
+    if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
+        if (virDomainLockLeaseAttach(driver->lockManager, cfg->uri, vm, lease) 
< 0)
+            return -1;
+    }

     virDomainLeaseInsert(vm->def, lease);

@@ -6462,8 +6466,12 @@ qemuDomainDetachDeviceLease(virQEMUDriver *driver,
         return -1;
     }

-    if (virDomainLockLeaseDetach(driver->lockManager, vm, lease) < 0)
-        return -1;
+    /* If the VM is paused or in another state we don't actually want to
+     * release the lease because it's no longer locked. */
+    if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
+        if (virDomainLockLeaseDetach(driver->lockManager, vm, lease) < 0)
+            return -1;
+    }

     det_lease = virDomainLeaseRemoveAt(vm->def, idx);
     virDomainLeaseDefFree(det_lease);
-- 
2.54.0

Reply via email to