|
|
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 |
|