render / rpms / libvirt

Forked from rpms/libvirt 10 months ago
Clone
43fe83
From c4255703d236874c2cb0f7f5a636315310b440ca Mon Sep 17 00:00:00 2001
43fe83
Message-Id: <c4255703d236874c2cb0f7f5a636315310b440ca.1380112457.git.jdenemar@redhat.com>
43fe83
From: Eric Blake <eblake@redhat.com>
43fe83
Date: Mon, 23 Sep 2013 11:10:05 -0600
43fe83
Subject: [PATCH] qemu: don't leave shutdown inhibited on attach failure
43fe83
43fe83
https://bugzilla.redhat.com/show_bug.cgi?id=1010617
43fe83
43fe83
While debugging a failure of 'virsh qemu-attach', I noticed that
43fe83
we were leaking the count of active domains on failure.  This
43fe83
means that a libvirtd session that is supposed to quit after
43fe83
active domains disappear will hang around forever.
43fe83
43fe83
* src/qemu/qemu_process.c (qemuProcessAttach): Undo count of
43fe83
active domains on failure.
43fe83
43fe83
Signed-off-by: Eric Blake <eblake@redhat.com>
43fe83
(cherry picked from commit 93e599750e5d5fff49c41a7f91570498a4b6de71)
43fe83
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
43fe83
---
43fe83
 src/qemu/qemu_process.c | 65 ++++++++++++++++++++++++++-----------------------
43fe83
 1 file changed, 34 insertions(+), 31 deletions(-)
43fe83
43fe83
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
43fe83
index 1d8df58..843ff76 100644
43fe83
--- a/src/qemu/qemu_process.c
43fe83
+++ b/src/qemu/qemu_process.c
43fe83
@@ -4334,6 +4334,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
43fe83
     const char *model;
43fe83
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
43fe83
     virCapsPtr caps = NULL;
43fe83
+    bool active = false;
43fe83
 
43fe83
     VIR_DEBUG("Beginning VM attach process");
43fe83
 
43fe83
@@ -4345,7 +4346,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
43fe83
     }
43fe83
 
43fe83
     if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
43fe83
-        goto cleanup;
43fe83
+        goto error;
43fe83
 
43fe83
     /* Do this upfront, so any part of the startup process can add
43fe83
      * runtime state to vm->def that won't be persisted. This let's us
43fe83
@@ -4353,60 +4354,59 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
43fe83
      */
43fe83
     VIR_DEBUG("Setting current domain def as transient");
43fe83
     if (virDomainObjSetDefTransient(caps, driver->xmlopt, vm, true) < 0)
43fe83
-        goto cleanup;
43fe83
+        goto error;
43fe83
 
43fe83
     vm->def->id = qemuDriverAllocateID(driver);
43fe83
 
43fe83
     if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback)
43fe83
         driver->inhibitCallback(true, driver->inhibitOpaque);
43fe83
+    active = true;
43fe83
 
43fe83
     if (virFileMakePath(cfg->logDir) < 0) {
43fe83
         virReportSystemError(errno,
43fe83
                              _("cannot create log directory %s"),
43fe83
                              cfg->logDir);
43fe83
-        goto cleanup;
43fe83
+        goto error;
43fe83
     }
43fe83
 
43fe83
     VIR_FREE(priv->pidfile);
43fe83
     if (VIR_STRDUP(priv->pidfile, pidfile) < 0)
43fe83
-        goto cleanup;
43fe83
+        goto error;
43fe83
 
43fe83
     VIR_DEBUG("Detect security driver config");
43fe83
     sec_managers = virSecurityManagerGetNested(driver->securityManager);
43fe83
-    if (sec_managers == NULL) {
43fe83
-        goto cleanup;
43fe83
-    }
43fe83
+    if (sec_managers == NULL)
43fe83
+        goto error;
43fe83
 
43fe83
     for (i = 0; sec_managers[i]; i++) {
43fe83
         model = virSecurityManagerGetModel(sec_managers[i]);
43fe83
         seclabeldef = virDomainDefGetSecurityLabelDef(vm->def, model);
43fe83
-        if (seclabeldef == NULL) {
43fe83
-            goto cleanup;
43fe83
-        }
43fe83
+        if (seclabeldef == NULL)
43fe83
+            goto error;
43fe83
         seclabeldef->type = VIR_DOMAIN_SECLABEL_STATIC;
43fe83
         if (VIR_ALLOC(seclabel) < 0)
43fe83
-            goto cleanup;
43fe83
+            goto error;
43fe83
         if (virSecurityManagerGetProcessLabel(driver->securityManager,
43fe83
                                               vm->def, vm->pid, seclabel) < 0)
43fe83
-            goto cleanup;
43fe83
+            goto error;
43fe83
 
43fe83
         if (VIR_STRDUP(seclabeldef->model, model) < 0)
43fe83
-            goto cleanup;
43fe83
+            goto error;
43fe83
 
43fe83
         if (VIR_STRDUP(seclabeldef->label, seclabel->label) < 0)
43fe83
-            goto cleanup;
43fe83
+            goto error;
43fe83
         VIR_FREE(seclabel);
43fe83
     }
43fe83
 
43fe83
     VIR_DEBUG("Creating domain log file");
43fe83
     if ((logfile = qemuDomainCreateLog(driver, vm, false)) < 0)
43fe83
-        goto cleanup;
43fe83
+        goto error;
43fe83
 
43fe83
     VIR_DEBUG("Determining emulator version");
43fe83
     virObjectUnref(priv->qemuCaps);
43fe83
     if (!(priv->qemuCaps = virQEMUCapsCacheLookupCopy(driver->qemuCapsCache,
43fe83
                                                       vm->def->emulator)))
43fe83
-        goto cleanup;
43fe83
+        goto error;
43fe83
 
43fe83
     VIR_DEBUG("Preparing monitor state");
43fe83
     priv->monConfig = monConfig;
43fe83
@@ -4425,11 +4425,11 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
43fe83
     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
43fe83
         VIR_DEBUG("Assigning domain PCI addresses");
43fe83
         if ((qemuDomainAssignAddresses(vm->def, priv->qemuCaps, vm)) < 0)
43fe83
-            goto cleanup;
43fe83
+            goto error;
43fe83
     }
43fe83
 
43fe83
     if ((timestamp = virTimeStringNow()) == NULL) {
43fe83
-        goto cleanup;
43fe83
+        goto error;
43fe83
     } else {
43fe83
         if (safewrite(logfile, timestamp, strlen(timestamp)) < 0 ||
43fe83
             safewrite(logfile, ATTACH_POSTFIX, strlen(ATTACH_POSTFIX)) < 0) {
43fe83
@@ -4446,7 +4446,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
43fe83
 
43fe83
     VIR_DEBUG("Waiting for monitor to show up");
43fe83
     if (qemuProcessWaitForMonitor(driver, vm, priv->qemuCaps, -1) < 0)
43fe83
-        goto cleanup;
43fe83
+        goto error;
43fe83
 
43fe83
     /* Failure to connect to agent shouldn't be fatal */
43fe83
     if (qemuConnectAgent(driver, vm) < 0) {
43fe83
@@ -4458,34 +4458,34 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
43fe83
 
43fe83
     VIR_DEBUG("Detecting VCPU PIDs");
43fe83
     if (qemuProcessDetectVcpuPIDs(driver, vm) < 0)
43fe83
-        goto cleanup;
43fe83
+        goto error;
43fe83
 
43fe83
     /* If we have -device, then addresses are assigned explicitly.
43fe83
      * If not, then we have to detect dynamic ones here */
43fe83
     if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
43fe83
         VIR_DEBUG("Determining domain device PCI addresses");
43fe83
         if (qemuProcessInitPCIAddresses(driver, vm) < 0)
43fe83
-            goto cleanup;
43fe83
+            goto error;
43fe83
     }
43fe83
 
43fe83
     VIR_DEBUG("Getting initial memory amount");
43fe83
     qemuDomainObjEnterMonitor(driver, vm);
43fe83
     if (qemuMonitorGetBalloonInfo(priv->mon, &vm->def->mem.cur_balloon) < 0) {
43fe83
         qemuDomainObjExitMonitor(driver, vm);
43fe83
-        goto cleanup;
43fe83
+        goto error;
43fe83
     }
43fe83
     if (qemuMonitorGetStatus(priv->mon, &running, &reason) < 0) {
43fe83
         qemuDomainObjExitMonitor(driver, vm);
43fe83
-        goto cleanup;
43fe83
+        goto error;
43fe83
     }
43fe83
     if (qemuMonitorGetVirtType(priv->mon, &vm->def->virtType) < 0) {
43fe83
         qemuDomainObjExitMonitor(driver, vm);
43fe83
-        goto cleanup;
43fe83
+        goto error;
43fe83
     }
43fe83
     qemuDomainObjExitMonitor(driver, vm);
43fe83
 
43fe83
     if (!virDomainObjIsActive(vm))
43fe83
-        goto cleanup;
43fe83
+        goto error;
43fe83
 
43fe83
     if (running) {
43fe83
         virDomainObjSetState(vm, VIR_DOMAIN_RUNNING,
43fe83
@@ -4502,7 +4502,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
43fe83
 
43fe83
     VIR_DEBUG("Writing domain status to disk");
43fe83
     if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
43fe83
-        goto cleanup;
43fe83
+        goto error;
43fe83
 
43fe83
     /* Run an hook to allow admins to do some magic */
43fe83
     if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
43fe83
@@ -4518,7 +4518,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
43fe83
          * If the script raised an error abort the launch
43fe83
          */
43fe83
         if (hookret < 0)
43fe83
-            goto cleanup;
43fe83
+            goto error;
43fe83
     }
43fe83
 
43fe83
     VIR_FORCE_CLOSE(logfile);
43fe83
@@ -4529,10 +4529,13 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
43fe83
 
43fe83
     return 0;
43fe83
 
43fe83
-cleanup:
43fe83
-    /* We jump here if we failed to start the VM for any reason, or
43fe83
-     * if we failed to initialize the now running VM. kill it off and
43fe83
-     * pretend we never started it */
43fe83
+error:
43fe83
+    /* We jump here if we failed to attach to the VM for any reason.
43fe83
+     * Leave the domain running, but pretend we never attempted to
43fe83
+     * attach to it.  */
43fe83
+    if (active && virAtomicIntDecAndTest(&driver->nactive) &&
43fe83
+        driver->inhibitCallback)
43fe83
+        driver->inhibitCallback(false, driver->inhibitOpaque);
43fe83
     VIR_FORCE_CLOSE(logfile);
43fe83
     VIR_FREE(seclabel);
43fe83
     VIR_FREE(sec_managers);
43fe83
-- 
43fe83
1.8.3.2
43fe83