[libvirt] [RFC PATCH] check whether domain is active after qemuDomainObjExitMonitor* returns

Wen Congyang wency at cn.fujitsu.com
Mon Apr 11 05:41:55 UTC 2011


qemu may quited unexpectedly when invoking a monitor command. And priv->mon
will be NULL after qemuDomainObjExitMonitor* returns. So we must not use it.
Unfortunately we still use it, and it will cause libvirtd crashed.

As Eric suggested, qemuDomainObjExitMonitor* should be made to return the value
of vm active after regaining lock, and marked ATTRIBUTE_RETURN_CHECK, to force
all other callers to detect the case of a monitor command completing successfully
but then the VM disappearing in the window between command completion and regaining
the vm lock.

---
 src/qemu/qemu_domain.c    |   24 ++++-
 src/qemu/qemu_domain.h    |    6 +-
 src/qemu/qemu_driver.c    |   87 +++++++++++++----
 src/qemu/qemu_hotplug.c   |  230 ++++++++++++++++++++++++++++-----------------
 src/qemu/qemu_migration.c |   93 +++++++++++++------
 src/qemu/qemu_process.c   |   61 +++++++++---
 6 files changed, 344 insertions(+), 157 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index c2a1f9a..0d40b7e 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -578,7 +578,7 @@ void qemuDomainObjEnterMonitor(virDomainObjPtr obj)
  *
  * Should be paired with an earlier qemuDomainObjEnterMonitor() call
  */
-void qemuDomainObjExitMonitor(virDomainObjPtr obj)
+int qemuDomainObjExitMonitor(virDomainObjPtr obj)
 {
     qemuDomainObjPrivatePtr priv = obj->privateData;
     int refs;
@@ -588,11 +588,20 @@ void qemuDomainObjExitMonitor(virDomainObjPtr obj)
     if (refs > 0)
         qemuMonitorUnlock(priv->mon);
 
+    /* Note: qemu may quited unexpectedly here, and the monitor will be freed.
+     * If it happened, priv->mon will be null.
+     */
+
     virDomainObjLock(obj);
 
     if (refs == 0) {
         priv->mon = NULL;
     }
+
+    if (priv->mon == NULL)
+        return -1;
+    else
+        return 0;
 }
 
 
@@ -621,8 +630,8 @@ void qemuDomainObjEnterMonitorWithDriver(struct qemud_driver *driver,
  *
  * Should be paired with an earlier qemuDomainObjEnterMonitorWithDriver() call
  */
-void qemuDomainObjExitMonitorWithDriver(struct qemud_driver *driver,
-                                        virDomainObjPtr obj)
+int qemuDomainObjExitMonitorWithDriver(struct qemud_driver *driver,
+                                       virDomainObjPtr obj)
 {
     qemuDomainObjPrivatePtr priv = obj->privateData;
     int refs;
@@ -632,12 +641,21 @@ void qemuDomainObjExitMonitorWithDriver(struct qemud_driver *driver,
     if (refs > 0)
         qemuMonitorUnlock(priv->mon);
 
+    /* Note: qemu may quited unexpectedly here, and the monitor will be freed.
+     * If it happened, priv->mon will be null.
+     */
+
     qemuDriverLock(driver);
     virDomainObjLock(obj);
 
     if (refs == 0) {
         priv->mon = NULL;
     }
+
+    if (priv->mon == NULL)
+        return -1;
+    else
+        return 0;
 }
 
 void qemuDomainObjEnterRemoteWithDriver(struct qemud_driver *driver,
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 8258900..92fccda 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -99,11 +99,11 @@ int qemuDomainObjBeginJobWithDriver(struct qemud_driver *driver,
                                     virDomainObjPtr obj) ATTRIBUTE_RETURN_CHECK;
 int qemuDomainObjEndJob(virDomainObjPtr obj) ATTRIBUTE_RETURN_CHECK;
 void qemuDomainObjEnterMonitor(virDomainObjPtr obj);
-void qemuDomainObjExitMonitor(virDomainObjPtr obj);
+int qemuDomainObjExitMonitor(virDomainObjPtr obj) ATTRIBUTE_RETURN_CHECK;
 void qemuDomainObjEnterMonitorWithDriver(struct qemud_driver *driver,
                                          virDomainObjPtr obj);
-void qemuDomainObjExitMonitorWithDriver(struct qemud_driver *driver,
-                                        virDomainObjPtr obj);
+int qemuDomainObjExitMonitorWithDriver(struct qemud_driver *driver,
+                                       virDomainObjPtr obj) ATTRIBUTE_RETURN_CHECK;
 void qemuDomainObjEnterRemoteWithDriver(struct qemud_driver *driver,
                                         virDomainObjPtr obj);
 void qemuDomainObjExitRemoteWithDriver(struct qemud_driver *driver,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 04a5f65..2d41576 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1452,7 +1452,11 @@ static int qemudDomainShutdown(virDomainPtr dom) {
     priv = vm->privateData;
     qemuDomainObjEnterMonitor(vm);
     ret = qemuMonitorSystemPowerdown(priv->mon);
-    qemuDomainObjExitMonitor(vm);
+    if (qemuDomainObjExitMonitor(vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
+    }
 
 endjob:
     if (qemuDomainObjEndJob(vm) == 0)
@@ -1659,7 +1663,11 @@ static int qemudDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
             priv = vm->privateData;
             qemuDomainObjEnterMonitor(vm);
             r = qemuMonitorSetBalloon(priv->mon, newmem);
-            qemuDomainObjExitMonitor(vm);
+            if (qemuDomainObjExitMonitor(vm) < 0) {
+                qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                _("guest unexpectedly quit"));
+                r = -1;
+            }
             qemuAuditMemory(vm, vm->def->mem.cur_balloon, newmem, "update",
                             r == 1);
             if (r < 0)
@@ -1749,7 +1757,11 @@ static int qemudDomainGetInfo(virDomainPtr dom,
             else {
                 qemuDomainObjEnterMonitor(vm);
                 err = qemuMonitorGetBalloonInfo(priv->mon, &balloon);
-                qemuDomainObjExitMonitor(vm);
+                if (qemuDomainObjExitMonitor(vm) < 0) {
+                    qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                    _("guest unexpectedly quit"));
+                    err = -1;
+                }
             }
             if (qemuDomainObjEndJob(vm) == 0) {
                 vm = NULL;
@@ -2524,7 +2536,11 @@ static int qemudDomainHotplugVcpus(virDomainObjPtr vm, unsigned int nvcpus)
     ret = 0;
 
 cleanup:
-    qemuDomainObjExitMonitor(vm);
+    if (qemuDomainObjExitMonitor(vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
+    }
     vm->def->vcpus = vcpus;
     qemuAuditVcpu(vm, oldvcpus, nvcpus, "update", rc == 1);
     return ret;
@@ -3295,7 +3311,11 @@ static char *qemudDomainDumpXML(virDomainPtr dom,
 
             qemuDomainObjEnterMonitorWithDriver(driver, vm);
             err = qemuMonitorGetBalloonInfo(priv->mon, &balloon);
-            qemuDomainObjExitMonitorWithDriver(driver, vm);
+            if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+                qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                _("guest unexpectedly quit"));
+                err = -1;
+            }
             if (qemuDomainObjEndJob(vm) == 0) {
                 vm = NULL;
                 goto cleanup;
@@ -4843,7 +4863,11 @@ qemudDomainBlockStats (virDomainPtr dom,
                                        &stats->wr_req,
                                        &stats->wr_bytes,
                                        &stats->errs);
-    qemuDomainObjExitMonitor(vm);
+    if (qemuDomainObjExitMonitor(vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
+    }
 
 endjob:
     if (qemuDomainObjEndJob(vm) == 0)
@@ -4944,7 +4968,11 @@ qemudDomainMemoryStats (virDomainPtr dom,
         qemuDomainObjPrivatePtr priv = vm->privateData;
         qemuDomainObjEnterMonitor(vm);
         ret = qemuMonitorGetMemoryStats(priv->mon, stats, nr_stats);
-        qemuDomainObjExitMonitor(vm);
+        if (qemuDomainObjExitMonitor(vm) < 0) {
+            qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                            _("guest unexpectedly quit"));
+            ret = -1;
+        }
     } else {
         qemuReportError(VIR_ERR_OPERATION_INVALID,
                         "%s", _("domain is not running"));
@@ -5085,17 +5113,18 @@ qemudDomainMemoryPeek (virDomainPtr dom,
     priv = vm->privateData;
     qemuDomainObjEnterMonitor(vm);
     if (flags == VIR_MEMORY_VIRTUAL) {
-        if (qemuMonitorSaveVirtualMemory(priv->mon, offset, size, tmp) < 0) {
-            qemuDomainObjExitMonitor(vm);
-            goto endjob;
-        }
+        ret = qemuMonitorSaveVirtualMemory(priv->mon, offset, size, tmp);
     } else {
-        if (qemuMonitorSavePhysicalMemory(priv->mon, offset, size, tmp) < 0) {
-            qemuDomainObjExitMonitor(vm);
-            goto endjob;
-        }
+        ret = qemuMonitorSavePhysicalMemory(priv->mon, offset, size, tmp);
     }
-    qemuDomainObjExitMonitor(vm);
+    if (qemuDomainObjExitMonitor(vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
+    }
+
+    if (ret < -1)
+        goto endjob;
 
     /* Read the memory file into buffer. */
     if (saferead (fd, buffer, size) == (ssize_t) -1) {
@@ -5259,7 +5288,11 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
             ret = qemuMonitorGetBlockExtent(priv->mon,
                                             disk->info.alias,
                                             &info->allocation);
-            qemuDomainObjExitMonitor(vm);
+            if (qemuDomainObjExitMonitor(vm) < 0) {
+                qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                _("guest unexpectedly quit"));
+                ret = -1;
+            }
         }
 
         if (qemuDomainObjEndJob(vm) == 0)
@@ -6101,7 +6134,11 @@ qemuDomainSnapshotCreateActive(virConnectPtr conn,
 
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
     ret = qemuMonitorCreateSnapshot(priv->mon, snap->def->name);
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
+    }
 
 cleanup:
     if (resume && virDomainObjIsActive(vm) &&
@@ -6434,7 +6471,11 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
             priv = vm->privateData;
             qemuDomainObjEnterMonitorWithDriver(driver, vm);
             rc = qemuMonitorLoadSnapshot(priv->mon, snap->def->name);
-            qemuDomainObjExitMonitorWithDriver(driver, vm);
+            if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+                qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                _("guest unexpectedly quit"));
+                rc = -1;
+            }
             if (rc < 0)
                 goto endjob;
         }
@@ -6557,7 +6598,7 @@ static int qemuDomainSnapshotDiscard(struct qemud_driver *driver,
         qemuDomainObjEnterMonitorWithDriver(driver, vm);
         /* we continue on even in the face of error */
         qemuMonitorDeleteSnapshot(priv->mon, snap->def->name);
-        qemuDomainObjExitMonitorWithDriver(driver, vm);
+        ignore_value(qemuDomainObjExitMonitorWithDriver(driver, vm));
     }
 
     if (snap == vm->current_snapshot) {
@@ -6770,7 +6811,11 @@ static int qemuDomainMonitorCommand(virDomainPtr domain, const char *cmd,
         goto cleanup;
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
     ret = qemuMonitorArbitraryCommand(priv->mon, cmd, result, hmp);
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
+    }
     if (qemuDomainObjEndJob(vm) == 0) {
         vm = NULL;
         goto cleanup;
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index b03f774..d70e426 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -106,7 +106,11 @@ int qemuDomainChangeEjectableMedia(struct qemud_driver *driver,
     } else {
         ret = qemuMonitorEjectMedia(priv->mon, driveAlias, force);
     }
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
+    }
 
     qemuAuditDisk(vm, origdisk, disk, "update", ret >= 0);
 
@@ -201,7 +205,11 @@ int qemuDomainAttachPciDiskDevice(struct qemud_driver *driver,
             memcpy(&disk->info.addr.pci, &guestAddr, sizeof(guestAddr));
         }
     }
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
+    }
 
     qemuAuditDisk(vm, NULL, disk, "attach", ret >= 0);
 
@@ -277,7 +285,11 @@ int qemuDomainAttachPciControllerDevice(struct qemud_driver *driver,
                                                  type,
                                                  &controller->info.addr.pci);
     }
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
+    }
 
     if (ret == 0) {
         controller->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
@@ -433,7 +445,11 @@ int qemuDomainAttachSCSIDisk(struct qemud_driver *driver,
             memcpy(&disk->info.addr.drive, &driveAddr, sizeof(driveAddr));
         }
     }
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
+    }
 
     qemuAuditDisk(vm, NULL, disk, "attach", ret >= 0);
 
@@ -516,7 +532,11 @@ int qemuDomainAttachUsbMassstorageDevice(struct qemud_driver *driver,
     } else {
         ret = qemuMonitorAddUSBDisk(priv->mon, disk->src);
     }
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
+    }
 
     qemuAuditDisk(vm, NULL, disk, "attach", ret >= 0);
 
@@ -632,21 +652,22 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
     if (qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) &&
         qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
-        if (qemuMonitorAddNetdev(priv->mon, netstr, tapfd, tapfd_name,
-                                 vhostfd, vhostfd_name) < 0) {
-            qemuDomainObjExitMonitorWithDriver(driver, vm);
-            qemuAuditNet(vm, NULL, net, "attach", false);
-            goto cleanup;
-        }
+        ret = qemuMonitorAddNetdev(priv->mon, netstr, tapfd, tapfd_name,
+                                   vhostfd, vhostfd_name);
     } else {
-        if (qemuMonitorAddHostNetwork(priv->mon, netstr, tapfd, tapfd_name,
-                                      vhostfd, vhostfd_name) < 0) {
-            qemuDomainObjExitMonitorWithDriver(driver, vm);
-            qemuAuditNet(vm, NULL, net, "attach", false);
-            goto cleanup;
-        }
+        ret = qemuMonitorAddHostNetwork(priv->mon, netstr, tapfd, tapfd_name,
+                                        vhostfd, vhostfd_name);
     }
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        goto cleanup;
+    }
+
+    qemuAuditNet(vm, NULL, net, "attach", ret >= 0);
+
+    if (ret < 0)
+        goto cleanup;
 
     VIR_FORCE_CLOSE(tapfd);
     VIR_FORCE_CLOSE(vhostfd);
@@ -667,25 +688,26 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
 
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
     if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
-        if (qemuMonitorAddDevice(priv->mon, nicstr) < 0) {
-            qemuDomainObjExitMonitorWithDriver(driver, vm);
-            qemuAuditNet(vm, NULL, net, "attach", false);
-            goto try_remove;
-        }
+        ret = qemuMonitorAddDevice(priv->mon, nicstr);
     } else {
-        if (qemuMonitorAddPCINetwork(priv->mon, nicstr,
-                                     &guestAddr) < 0) {
-            qemuDomainObjExitMonitorWithDriver(driver, vm);
-            qemuAuditNet(vm, NULL, net, "attach", false);
-            goto try_remove;
+        ret = qemuMonitorAddPCINetwork(priv->mon, nicstr,
+                                       &guestAddr);
+        if (ret == 0) {
+            net->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
+            memcpy(&net->info.addr.pci, &guestAddr, sizeof(guestAddr));
         }
-        net->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
-        memcpy(&net->info.addr.pci, &guestAddr, sizeof(guestAddr));
     }
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
+    }
 
     qemuAuditNet(vm, NULL, net, "attach", true);
 
+    if (ret < 0)
+        goto try_remove;
+
     ret = 0;
 
     vm->def->nets[vm->def->nnets++] = net;
@@ -723,7 +745,9 @@ try_remove:
             if (qemuMonitorRemoveNetdev(priv->mon, netdev_name) < 0)
                 VIR_WARN("Failed to remove network backend for netdev %s",
                          netdev_name);
-            qemuDomainObjExitMonitorWithDriver(driver, vm);
+            if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0)
+                qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                _("guest unexpectedly quit"));
             VIR_FREE(netdev_name);
         } else {
             VIR_WARN0("Unable to remove network backend");
@@ -736,7 +760,9 @@ try_remove:
         if (qemuMonitorRemoveHostNetwork(priv->mon, vlan, hostnet_name) < 0)
             VIR_WARN("Failed to remove network backend for vlan %d, net %s",
                      vlan, hostnet_name);
-        qemuDomainObjExitMonitorWithDriver(driver, vm);
+        if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0)
+            qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                            _("guest unexpectedly quit"));
         VIR_FREE(hostnet_name);
     }
     goto cleanup;
@@ -795,7 +821,11 @@ int qemuDomainAttachHostPciDevice(struct qemud_driver *driver,
         qemuDomainObjEnterMonitorWithDriver(driver, vm);
         ret = qemuMonitorAddDeviceWithFd(priv->mon, devstr,
                                          configfd, configfd_name);
-        qemuDomainObjExitMonitorWithDriver(driver, vm);
+        if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+            qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                            _("guest unexpectedly quit"));
+            goto error;
+        }
     } else {
         virDomainDevicePCIAddress guestAddr;
 
@@ -803,7 +833,11 @@ int qemuDomainAttachHostPciDevice(struct qemud_driver *driver,
         ret = qemuMonitorAddPCIHostDevice(priv->mon,
                                           &hostdev->source.subsys.u.pci,
                                           &guestAddr);
-        qemuDomainObjExitMonitorWithDriver(driver, vm);
+        if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+            qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                            _("guest unexpectedly quit"));
+            goto error;
+        }
 
         hostdev->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
         memcpy(&hostdev->info.addr.pci, &guestAddr, sizeof(guestAddr));
@@ -886,7 +920,11 @@ int qemuDomainAttachHostUsbDevice(struct qemud_driver *driver,
         ret = qemuMonitorAddUSBDeviceExact(priv->mon,
                                            hostdev->source.subsys.u.usb.bus,
                                            hostdev->source.subsys.u.usb.device);
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
+    }
     qemuAuditHostdev(vm, hostdev, "attach", ret == 0);
     if (ret < 0)
         goto error;
@@ -1145,25 +1183,27 @@ int qemuDomainDetachPciDiskDevice(struct qemud_driver *driver,
 
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
     if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
-        if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
-            qemuDomainObjExitMonitor(vm);
-            goto cleanup;
-        }
+        ret = qemuMonitorDelDevice(priv->mon, detach->info.alias);
     } else {
-        if (qemuMonitorRemovePCIDevice(priv->mon,
-                                       &detach->info.addr.pci) < 0) {
-            qemuDomainObjExitMonitor(vm);
-            goto cleanup;
-        }
+        ret = qemuMonitorRemovePCIDevice(priv->mon,
+                                         &detach->info.addr.pci);
     }
 
     /* disconnect guest from host device */
-    qemuMonitorDriveDel(priv->mon, drivestr);
+    if (ret == 0)
+        qemuMonitorDriveDel(priv->mon, drivestr);
 
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+    if (qemuDomainObjExitMonitor(vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
+    }
 
     qemuAuditDisk(vm, detach, NULL, "detach", ret >= 0);
 
+    if (ret < 0)
+        goto cleanup;
+
     if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE) &&
         qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &detach->info) < 0)
         VIR_WARN("Unable to release PCI address on %s", dev->data.disk->src);
@@ -1235,18 +1275,23 @@ int qemuDomainDetachDiskDevice(struct qemud_driver *driver,
     }
 
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
-    if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
-        qemuDomainObjExitMonitor(vm);
-        goto cleanup;
-    }
+    ret = qemuMonitorDelDevice(priv->mon, detach->info.alias);
 
     /* disconnect guest from host device */
-    qemuMonitorDriveDel(priv->mon, drivestr);
+    if (ret == 0)
+        qemuMonitorDriveDel(priv->mon, drivestr);
 
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
+    }
 
     qemuAuditDisk(vm, detach, NULL, "detach", ret >= 0);
 
+    if (ret < 0)
+        goto cleanup;
+
     virDomainDiskRemove(vm->def, i);
 
     virDomainDiskDefFree(detach);
@@ -1364,18 +1409,19 @@ int qemuDomainDetachPciControllerDevice(struct qemud_driver *driver,
 
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
     if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
-        if (qemuMonitorDelDevice(priv->mon, detach->info.alias)) {
-            qemuDomainObjExitMonitor(vm);
-            goto cleanup;
-        }
+        ret = qemuMonitorDelDevice(priv->mon, detach->info.alias);
     } else {
-        if (qemuMonitorRemovePCIDevice(priv->mon,
-                                       &detach->info.addr.pci) < 0) {
-            qemuDomainObjExitMonitor(vm);
-            goto cleanup;
-        }
+        ret = qemuMonitorRemovePCIDevice(priv->mon,
+                                         &detach->info.addr.pci);
+    }
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
     }
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+    if (ret < 0)
+        goto cleanup;
 
     if (vm->def->ncontrollers > 1) {
         memmove(vm->def->controllers + i,
@@ -1452,35 +1498,31 @@ int qemuDomainDetachNetDevice(struct qemud_driver *driver,
 
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
     if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
-        if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
-            qemuDomainObjExitMonitor(vm);
-            qemuAuditNet(vm, detach, NULL, "detach", false);
-            goto cleanup;
-        }
+        ret = qemuMonitorDelDevice(priv->mon, detach->info.alias);
     } else {
-        if (qemuMonitorRemovePCIDevice(priv->mon,
-                                       &detach->info.addr.pci) < 0) {
-            qemuDomainObjExitMonitorWithDriver(driver, vm);
-            qemuAuditNet(vm, detach, NULL, "detach", false);
-            goto cleanup;
-        }
+        ret = qemuMonitorRemovePCIDevice(priv->mon,
+                                         &detach->info.addr.pci);
     }
 
+    if (ret < 0)
+        goto exitmonitor;
+
     if (qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) &&
         qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
-        if (qemuMonitorRemoveNetdev(priv->mon, hostnet_name) < 0) {
-            qemuDomainObjExitMonitorWithDriver(driver, vm);
-            qemuAuditNet(vm, detach, NULL, "detach", false);
-            goto cleanup;
-        }
+        ret = qemuMonitorRemoveNetdev(priv->mon, hostnet_name);
     } else {
-        if (qemuMonitorRemoveHostNetwork(priv->mon, vlan, hostnet_name) < 0) {
-            qemuDomainObjExitMonitorWithDriver(driver, vm);
-            qemuAuditNet(vm, detach, NULL, "detach", false);
-            goto cleanup;
-        }
+        ret = qemuMonitorRemoveHostNetwork(priv->mon, vlan, hostnet_name);
     }
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+exitmonitor:
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
+    }
+
+    if (ret < 0)
+        goto cleanup;
 
     qemuAuditNet(vm, detach, NULL, "detach", true);
 
@@ -1582,7 +1624,11 @@ int qemuDomainDetachHostPciDevice(struct qemud_driver *driver,
     } else {
         ret = qemuMonitorRemovePCIDevice(priv->mon, &detach->info.addr.pci);
     }
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
+    }
     qemuAuditHostdev(vm, detach, "detach", ret == 0);
     if (ret < 0)
         return -1;
@@ -1681,7 +1727,11 @@ int qemuDomainDetachHostUsbDevice(struct qemud_driver *driver,
 
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
     ret = qemuMonitorDelDevice(priv->mon, detach->info.alias);
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
+    }
     qemuAuditHostdev(vm, detach, "detach", ret == 0);
     if (ret < 0)
         return -1;
@@ -1798,7 +1848,11 @@ qemuDomainChangeGraphicsPasswords(struct qemud_driver *driver,
     }
 
 cleanup:
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
+    }
 
     return ret;
 }
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 43741e1..cc8f428 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -125,7 +125,11 @@ qemuMigrationWaitForCompletion(struct qemud_driver *driver, virDomainObjPtr vm)
             VIR_DEBUG0("Cancelling job at client request");
             qemuDomainObjEnterMonitorWithDriver(driver, vm);
             rc = qemuMonitorMigrateCancel(priv->mon);
-            qemuDomainObjExitMonitorWithDriver(driver, vm);
+            if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+                qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                _("guest unexpectedly quit"));
+                rc = -1;
+            }
             if (rc < 0) {
                 VIR_WARN0("Unable to cancel job");
             }
@@ -142,7 +146,11 @@ qemuMigrationWaitForCompletion(struct qemud_driver *driver, virDomainObjPtr vm)
             VIR_DEBUG("Setting migration downtime to %llums", ms);
             qemuDomainObjEnterMonitorWithDriver(driver, vm);
             rc = qemuMonitorSetMigrationDowntime(priv->mon, ms);
-            qemuDomainObjExitMonitorWithDriver(driver, vm);
+            if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+                qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                _("guest unexpectedly quit"));
+                rc = -1;
+            }
             if (rc < 0)
                 VIR_WARN0("Unable to set migration downtime");
         } else if (priv->jobSignals & QEMU_JOB_SIGNAL_MIGRATE_SPEED) {
@@ -153,7 +161,11 @@ qemuMigrationWaitForCompletion(struct qemud_driver *driver, virDomainObjPtr vm)
             VIR_DEBUG("Setting migration bandwidth to %luMbs", bandwidth);
             qemuDomainObjEnterMonitorWithDriver(driver, vm);
             rc = qemuMonitorSetMigrationSpeed(priv->mon, bandwidth);
-            qemuDomainObjExitMonitorWithDriver(driver, vm);
+            if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+                qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                _("guest unexpectedly quit"));
+                rc = -1;
+            }
             if (rc < 0)
                 VIR_WARN0("Unable to set migration speed");
         }
@@ -173,7 +185,11 @@ qemuMigrationWaitForCompletion(struct qemud_driver *driver, virDomainObjPtr vm)
                                            &memProcessed,
                                            &memRemaining,
                                            &memTotal);
-        qemuDomainObjExitMonitorWithDriver(driver, vm);
+        if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+            qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                            _("guest unexpectedly quit"));
+            rc = -1;
+        }
 
         if (rc < 0) {
             priv->jobInfo.type = VIR_DOMAIN_JOB_FAILED;
@@ -608,24 +624,31 @@ static int doNativeMigrate(struct qemud_driver *driver,
     }
 
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
-    if (resource > 0 &&
-        qemuMonitorSetMigrationSpeed(priv->mon, resource) < 0) {
-        qemuDomainObjExitMonitorWithDriver(driver, vm);
-        goto cleanup;
+    if (resource > 0) {
+        ret = qemuMonitorSetMigrationSpeed(priv->mon, resource);
     }
 
+    if (ret < 0)
+        goto exitmonitor;
+
     if (flags & VIR_MIGRATE_NON_SHARED_DISK)
         background_flags |= QEMU_MONITOR_MIGRATE_NON_SHARED_DISK;
 
     if (flags & VIR_MIGRATE_NON_SHARED_INC)
         background_flags |= QEMU_MONITOR_MIGRATE_NON_SHARED_INC;
 
-    if (qemuMonitorMigrateToHost(priv->mon, background_flags, uribits->server,
-                                 uribits->port) < 0) {
-        qemuDomainObjExitMonitorWithDriver(driver, vm);
-        goto cleanup;
+    ret = qemuMonitorMigrateToHost(priv->mon, background_flags, uribits->server,
+                                   uribits->port);
+
+exitmonitor:
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
     }
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+    if (ret < 0)
+        goto cleanup;
 
     if (qemuMigrationWaitForCompletion(driver, vm) < 0)
         goto cleanup;
@@ -824,7 +847,11 @@ static int doTunnelMigrate(struct qemud_driver *driver,
     } else {
         internalret = -1;
     }
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        internalret = -1;
+    }
     if (internalret < 0) {
         qemuReportError(VIR_ERR_OPERATION_FAILED,
                         "%s", _("tunnelled migration monitor command failed"));
@@ -844,15 +871,16 @@ static int doTunnelMigrate(struct qemud_driver *driver,
      * rather failed later on.  Check the output of "info migrate"
      */
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
-    if (qemuMonitorGetMigrationStatus(priv->mon,
-                                      &status,
-                                      &transferred,
-                                      &remaining,
-                                      &total) < 0) {
-        qemuDomainObjExitMonitorWithDriver(driver, vm);
-        goto cancel;
+    retval = qemuMonitorGetMigrationStatus(priv->mon,
+                                           &status,
+                                           &transferred,
+                                           &remaining,
+                                           &total);
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        retval = -1;
     }
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
 
     if (status == QEMU_MONITOR_MIGRATION_STATUS_ERROR) {
         qemuReportError(VIR_ERR_OPERATION_FAILED,
@@ -875,7 +903,10 @@ cancel:
     if (retval != 0 && virDomainObjIsActive(vm)) {
         qemuDomainObjEnterMonitorWithDriver(driver, vm);
         qemuMonitorMigrateCancel(priv->mon);
-        qemuDomainObjExitMonitorWithDriver(driver, vm);
+        if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+            qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                            _("guest unexpectedly quit"));
+        }
     }
 
 finish:
@@ -1372,12 +1403,12 @@ qemuMigrationToFile(struct qemud_driver *driver, virDomainObjPtr vm,
             if (virSetCloseExec(pipeFD[1]) < 0) {
                 virReportSystemError(errno, "%s",
                                      _("Unable to set cloexec flag"));
-                qemuDomainObjExitMonitorWithDriver(driver, vm);
-                goto cleanup;
+                rc = -1;
+                goto exitmonitor;
             }
             if (virCommandRunAsync(cmd, NULL) < 0) {
-                qemuDomainObjExitMonitorWithDriver(driver, vm);
-                goto cleanup;
+                rc = -1;
+                goto exitmonitor;
             }
             rc = qemuMonitorMigrateToFd(priv->mon,
                                         QEMU_MONITOR_MIGRATE_BACKGROUND,
@@ -1391,7 +1422,13 @@ qemuMigrationToFile(struct qemud_driver *driver, virDomainObjPtr vm,
                                           args, path, offset);
         }
     }
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+exitmonitor:
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        rc = -1;
+    }
 
     if (rc < 0)
         goto cleanup;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 9ada24d..4ca70bc 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -662,7 +662,11 @@ qemuConnectMonitor(struct qemud_driver *driver, virDomainObjPtr vm)
 
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
     ret = qemuMonitorSetCapabilities(priv->mon);
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
+    }
 
 error:
 
@@ -1070,7 +1074,11 @@ qemuProcessWaitForMonitor(struct qemud_driver* driver,
     priv = vm->privateData;
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
     ret = qemuMonitorGetPtyPaths(priv->mon, paths);
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
+    }
 
     VIR_DEBUG("qemuMonitorGetPtyPaths returned %i", ret);
     if (ret == 0)
@@ -1122,11 +1130,15 @@ qemuProcessDetectVcpuPIDs(struct qemud_driver *driver,
     /* What follows is now all KVM specific */
 
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
-    if ((ncpupids = qemuMonitorGetCPUInfo(priv->mon, &cpupids)) < 0) {
-        qemuDomainObjExitMonitorWithDriver(driver, vm);
-        return -1;
+    ncpupids = qemuMonitorGetCPUInfo(priv->mon, &cpupids);
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ncpupids = -1;
     }
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+    if (ncpupids < 0)
+        return -1;
 
     /* Treat failure to get VCPU<->PID mapping as non-fatal */
     if (ncpupids == 0)
@@ -1322,7 +1334,11 @@ qemuProcessInitPasswords(virConnectPtr conn,
             qemuDomainObjEnterMonitorWithDriver(driver, vm);
             ret = qemuMonitorSetDrivePassphrase(priv->mon, alias, secret);
             VIR_FREE(secret);
-            qemuDomainObjExitMonitorWithDriver(driver, vm);
+            if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+                qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                _("guest unexpectedly quit"));
+                ret = -1;
+            }
             if (ret < 0)
                 goto cleanup;
         }
@@ -1713,7 +1729,12 @@ qemuProcessInitPCIAddresses(struct qemud_driver *driver,
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
     naddrs = qemuMonitorGetAllPCIAddresses(priv->mon,
                                            &addrs);
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        VIR_FREE(addrs);
+        return -1;
+    }
 
     ret = qemuProcessDetectPCIAddresses(vm, addrs, naddrs);
 
@@ -1890,7 +1911,11 @@ qemuProcessStartCPUs(struct qemud_driver *driver, virDomainObjPtr vm,
 
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
     ret = qemuMonitorStartCPUs(priv->mon, conn);
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
+    }
     if (ret == 0) {
         vm->state = VIR_DOMAIN_RUNNING;
     }
@@ -1908,7 +1933,11 @@ int qemuProcessStopCPUs(struct qemud_driver *driver, virDomainObjPtr vm)
     vm->state = VIR_DOMAIN_PAUSED;
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
     ret = qemuMonitorStopCPUs(priv->mon);
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
+    }
     if (ret < 0) {
         vm->state = oldState;
     }
@@ -2389,11 +2418,15 @@ int qemuProcessStart(virConnectPtr conn,
     VIR_DEBUG0("Setting initial memory amount");
     cur_balloon = vm->def->mem.cur_balloon;
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
-    if (qemuMonitorSetBalloon(priv->mon, cur_balloon) < 0) {
-        qemuDomainObjExitMonitorWithDriver(driver, vm);
-        goto cleanup;
+    ret = qemuMonitorSetBalloon(priv->mon, cur_balloon);
+    if (qemuDomainObjExitMonitorWithDriver(driver, vm) < 0) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("guest unexpectedly quit"));
+        ret = -1;
     }
-    qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+    if (ret < 0)
+        goto cleanup;
 
     if (!start_paused) {
         VIR_DEBUG0("Starting domain CPUs");
-- 
1.7.1




More information about the libvir-list mailing list