]> xenbits.xensource.com Git - libvirt.git/commitdiff
Fix race condition when destroying guests
authorDaniel P. Berrange <berrange@redhat.com>
Fri, 18 Jan 2013 14:33:51 +0000 (14:33 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Fri, 18 Jan 2013 15:45:38 +0000 (15:45 +0000)
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 <berrange@redhat.com>
src/qemu/qemu_driver.c

index d544dfc767a9cf177207ae749bd0b9ff2131d5f1..44f233d4045ba7b4dec591b2c07dc0cf05265164 100644 (file)
@@ -2121,24 +2121,29 @@ 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
      * it now means the job will be released
      */
     if (flags & VIR_DOMAIN_DESTROY_GRACEFUL) {
-        if (qemuProcessKill(driver, vm, 0) < 0)
+        if (qemuProcessKill(driver, vm, 0) < 0) {
+            priv->beingDestroyed = false;
             goto cleanup;
+        }
     } else {
-        if (qemuProcessKill(driver, vm, VIR_QEMU_PROCESS_KILL_FORCE) < 0)
+        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;