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