]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Make checks for inactive QEMU guest more robust
authorDaniel P. Berrange <berrange@redhat.com>
Thu, 10 Jun 2010 14:07:21 +0000 (15:07 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Wed, 23 Jun 2010 13:08:05 +0000 (14:08 +0100)
Before issuing monitor commands it is neccessary to check whether
the guest is still running. Most places use virDomainIsActive()
correctly, but a few relied on 'priv->mon != NULL'. In theory
these should be equivalent, but the release of the last reference
count on priv->mon can be delayed a small amount of time until
the event handler is finally deregistered. A further ref counting
bug also means that priv->mon might be never released. In such a
case, code could mistakenly issue a monitor command and wait for
a response that will never arrive, effectively leaving the QEMU
driver waiting on virCondWait() forever..

To protect against these possibilities, make sure all code uses
virDomainIsActive(), not 'priv->mon != NULL'

* src/qemu/qemu_driver.c: Replace 'priv->mon != NULL' with
  calls to 'priv->mon != NULL'()

src/qemu/qemu_driver.c

index 8ce47fea1d5fcc198799bf493df97b25d0263417..3f91e9fdb10c58ac25ef558ba7e561912a58c276 100644 (file)
@@ -5219,7 +5219,7 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
 endjob:
     if (vm) {
         if (ret != 0) {
-            if (header.was_running && priv->mon) {
+            if (header.was_running && virDomainObjIsActive(vm)) {
                 qemuDomainObjEnterMonitorWithDriver(driver, vm);
                 rc = qemuMonitorStartCPUs(priv->mon, dom->conn);
                 qemuDomainObjExitMonitorWithDriver(driver, vm);
@@ -5531,7 +5531,7 @@ endjob:
     /* Since the monitor is always attached to a pty for libvirt, it
        will support synchronous operations so we always get here after
        the migration is complete.  */
-    else if (resume && paused && priv->mon) {
+    else if (resume && paused && virDomainObjIsActive(vm)) {
         qemuDomainObjEnterMonitorWithDriver(driver, vm);
         if (qemuMonitorStartCPUs(priv->mon, dom->conn) < 0) {
             if (virGetLastError() == NULL)
@@ -7657,7 +7657,7 @@ cleanup:
     return ret;
 
 try_remove:
-    if (!priv->mon)
+    if (!virDomainObjIsActive(vm))
         goto cleanup;
 
     if (vlan < 0) {
@@ -7689,7 +7689,7 @@ try_remove:
     goto cleanup;
 
 try_tapfd_close:
-    if (!priv->mon)
+    if (!virDomainObjIsActive(vm))
         goto cleanup;
 
     if (tapfd_name) {
@@ -10743,7 +10743,7 @@ static int doTunnelMigrate(virDomainPtr dom,
     retval = doTunnelSendAll(st, client_sock);
 
 cancel:
-    if (retval != 0 && priv->mon) {
+    if (retval != 0 && virDomainObjIsActive(vm)) {
         qemuDomainObjEnterMonitorWithDriver(driver, vm);
         qemuMonitorMigrateCancel(priv->mon);
         qemuDomainObjExitMonitorWithDriver(driver, vm);