9119d9
From 0e943a1b117ea13b530236f94a0bc22a831eefeb Mon Sep 17 00:00:00 2001
9119d9
Message-Id: <0e943a1b117ea13b530236f94a0bc22a831eefeb@dist-git>
9119d9
From: Martin Kletzander <mkletzan@redhat.com>
9119d9
Date: Tue, 4 Nov 2014 11:02:52 +0100
9119d9
Subject: [PATCH] qemu: avoid rare race when undefining domain
9119d9
9119d9
When one domain is being undefined and at the same time started, for
9119d9
example, there is a possibility of a rare problem occuring.
9119d9
9119d9
 - Thread 1 does virDomainUndefine(), has the lock, checks that the
9119d9
   domain is active and because it's not, calls
9119d9
   virDomainObjListRemove().
9119d9
9119d9
 - Thread 2 does virDomainCreate() and tries to lock the domain.
9119d9
9119d9
 - Thread 1 needs to lock domain list in order to remove the domain from
9119d9
   it, but must unlock domain first (proper order is to lock domain list
9119d9
   first and the domain itself second).
9119d9
9119d9
 - Thread 2 grabs the lock, starts the domain and releases the lock.
9119d9
9119d9
 - Thread 1 grabs the lock and removes the domain from list.
9119d9
9119d9
With this patch:
9119d9
9119d9
 - qemuDomainRemoveInactive() creates a QEMU_JOB_MODIFY if that's
9119d9
   possible, but since it must remove the domain from list either way,
9119d9
   it continues even when starting the job failed.
9119d9
9119d9
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1150505
9119d9
9119d9
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
9119d9
(cherry picked from commit b629c64e5e0a32ef439b8eeb3a697e2cd76f3248)
9119d9
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
9119d9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
9119d9
---
9119d9
 src/qemu/qemu_domain.c | 7 +++++++
9119d9
 1 file changed, 7 insertions(+)
9119d9
9119d9
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
9119d9
index 72d7279..d166269 100644
9119d9
--- a/src/qemu/qemu_domain.c
9119d9
+++ b/src/qemu/qemu_domain.c
9119d9
@@ -2391,9 +2391,13 @@ void
9119d9
 qemuDomainRemoveInactive(virQEMUDriverPtr driver,
9119d9
                          virDomainObjPtr vm)
9119d9
 {
9119d9
+    bool haveJob = true;
9119d9
     char *snapDir;
9119d9
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
9119d9
 
9119d9
+    if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
9119d9
+        haveJob = false;
9119d9
+
9119d9
     /* Remove any snapshot metadata prior to removing the domain */
9119d9
     if (qemuDomainSnapshotDiscardAllMetadata(driver, vm) < 0) {
9119d9
         VIR_WARN("unable to remove all snapshots for domain %s",
9119d9
@@ -2410,6 +2414,9 @@ qemuDomainRemoveInactive(virQEMUDriverPtr driver,
9119d9
     }
9119d9
     virDomainObjListRemove(driver->domains, vm);
9119d9
     virObjectUnref(cfg);
9119d9
+
9119d9
+    if (haveJob)
9119d9
+        ignore_value(qemuDomainObjEndJob(driver, vm));
9119d9
 }
9119d9
 
9119d9
 void
9119d9
-- 
9119d9
2.1.3
9119d9