From 0231e37a53b07cc04dd46ff69076cf76ebe895bb Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Fri, 18 Jan 2013 14:33:51 +0000 Subject: [PATCH] Fix race condition when destroying guests When running virDomainDestroy, we need to make sure that no other background thread cleans up the domain while we're doing our work. This can happen if we release the domain object while in the middle of work, because the monitor might detect EOF in this window. For this reason we have a 'beingDestroyed' flag to stop the monitor from doing its normal cleanup. Unfortunately this flag was only being used to protect qemuDomainBeginJob, and not qemuProcessKill This left open a race condition where either libvirtd could crash, or alternatively report bogus error messages about the domain already having been destroyed to the caller Signed-off-by: Daniel P. Berrange (cherry picked from commit 81621f3e6e45e8681cc18ae49404736a0e772a11) Conflicts: src/qemu/qemu_driver.c --- src/qemu/qemu_driver.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 305db18b58..6289a8d3b8 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1816,6 +1816,12 @@ qemuDomainDestroyFlags(virDomainPtr dom, qemuDomainSetFakeReboot(driver, vm, false); + + /* We need to prevent monitor EOF callback from doing our work (and sending + * misleading events) while the vm is unlocked inside BeginJob/ProcessKill API + */ + priv->beingDestroyed = true; + /* Although qemuProcessStop does this already, there may * be an outstanding job active. We want to make sure we * can kill the process even if a job is active. Killing @@ -1825,17 +1831,16 @@ qemuDomainDestroyFlags(virDomainPtr dom, if (qemuProcessKill(driver, vm, 0) < 0) { qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", _("failed to kill qemu process with SIGTERM")); + priv->beingDestroyed = false; goto cleanup; } } else { - ignore_value(qemuProcessKill(driver, vm, VIR_QEMU_PROCESS_KILL_FORCE)); + if (qemuProcessKill(driver, vm, VIR_QEMU_PROCESS_KILL_FORCE) < 0) { + priv->beingDestroyed = false; + goto cleanup; + } } - /* We need to prevent monitor EOF callback from doing our work (and sending - * misleading events) while the vm is unlocked inside BeginJob API - */ - priv->beingDestroyed = true; - if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_DESTROY) < 0) goto cleanup;