]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: move detection whether to use -no-reboot to qemu_domain
authorPavel Hrdina <phrdina@redhat.com>
Wed, 11 Oct 2017 13:57:16 +0000 (15:57 +0200)
committerPavel Hrdina <phrdina@redhat.com>
Thu, 19 Oct 2017 09:52:30 +0000 (11:52 +0200)
This will be used later on in implementation of new API
virDomainSetLifecycleAction().  In order to use it, we need to store
the value in status XML to not lose the information if libvirtd is
restarted.

If some guest was started by old libvirt where it was not possible
to change the lifecycle action for running guest, we can safely
detect it based on the current actions from the status XML.

Reviewed-by: John Ferlan <jferlan@redhat.com>
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
src/qemu/qemu_command.c
src/qemu/qemu_domain.c
src/qemu/qemu_domain.h
src/qemu/qemu_process.c
tests/qemuxml2xmltest.c

index 87e762bb516fe5f106eaf643891cf85ecf4ddc51..c12e65785939919326b0fe284cb637f572afc2b1 100644 (file)
@@ -6509,23 +6509,17 @@ qemuBuildPMCommandLine(virCommandPtr cmd,
                        const virDomainDef *def,
                        qemuDomainObjPrivatePtr priv)
 {
-    bool allowReboot = true;
     virQEMUCapsPtr qemuCaps = priv->qemuCaps;
 
     /* Only add -no-reboot option if each event destroys domain */
-    if (def->onReboot == VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY &&
-        def->onPoweroff == VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY &&
-        (def->onCrash == VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY ||
-         def->onCrash == VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_DESTROY)) {
-        allowReboot = false;
+    if (priv->allowReboot == VIR_TRISTATE_BOOL_NO)
         virCommandAddArg(cmd, "-no-reboot");
-    }
 
     /* If JSON monitor is enabled, we can receive an event
      * when QEMU stops. If we use no-shutdown, then we can
      * watch for this event and do a soft/warm reboot.
      */
-    if (priv->monJSON && allowReboot &&
+    if (priv->monJSON && priv->allowReboot == VIR_TRISTATE_BOOL_YES &&
         virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_SHUTDOWN)) {
         virCommandAddArg(cmd, "-no-shutdown");
     }
index 05e8b96aa459fa9fd8d644b26d0e96dbfa8cb67c..26f65e2d9bcd2877a46dbaab1d75fce428442d88 100644 (file)
@@ -1767,6 +1767,7 @@ qemuDomainObjPrivateDataClear(qemuDomainObjPrivatePtr priv)
     priv->namespaces = NULL;
 
     priv->reconnectBlockjobs = VIR_TRISTATE_BOOL_ABSENT;
+    priv->allowReboot = VIR_TRISTATE_BOOL_ABSENT;
 }
 
 
@@ -1876,6 +1877,16 @@ qemuDomainObjPrivateXMLFormatBlockjobs(virBufferPtr buf,
 }
 
 
+static void
+qemuDomainObjPrivateXMLFormatAllowReboot(virBufferPtr buf,
+                                         virTristateBool allowReboot)
+{
+    virBufferAsprintf(buf, "<allowReboot value='%s'/>\n",
+                      virTristateBoolTypeToString(allowReboot));
+
+}
+
+
 static int
 qemuDomainObjPrivateXMLFormat(virBufferPtr buf,
                               virDomainObjPtr vm)
@@ -1998,6 +2009,8 @@ qemuDomainObjPrivateXMLFormat(virBufferPtr buf,
     if (priv->chardevStdioLogd)
         virBufferAddLit(buf, "<chardevStdioLogd/>\n");
 
+    qemuDomainObjPrivateXMLFormatAllowReboot(buf, priv->allowReboot);
+
     if (qemuDomainObjPrivateXMLFormatBlockjobs(buf, vm) < 0)
         return -1;
 
@@ -2108,6 +2121,31 @@ qemuDomainObjPrivateXMLParseBlockjobs(qemuDomainObjPrivatePtr priv,
 }
 
 
+static int
+qemuDomainObjPrivateXMLParseAllowReboot(xmlXPathContextPtr ctxt,
+                                        virTristateBool *allowReboot)
+{
+    int ret = -1;
+    int val;
+    char *valStr;
+
+    if ((valStr = virXPathString("string(./allowReboot/@value)", ctxt))) {
+        if ((val = virTristateBoolTypeFromString(valStr)) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("invalid allowReboot value '%s'"), valStr);
+            goto cleanup;
+        }
+        *allowReboot = val;
+    }
+
+    ret = 0;
+
+ cleanup:
+    VIR_FREE(valStr);
+    return ret;
+}
+
+
 static int
 qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt,
                              virDomainObjPtr vm,
@@ -2323,6 +2361,8 @@ qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt,
     priv->chardevStdioLogd = virXPathBoolean("boolean(./chardevStdioLogd)",
                                              ctxt) == 1;
 
+    qemuDomainObjPrivateXMLParseAllowReboot(ctxt, &priv->allowReboot);
+
     if (qemuDomainObjPrivateXMLParseBlockjobs(priv, ctxt) < 0)
         goto error;
 
index a29dd760372602d377dd905b0a70989bb79522ea..afe979d2ed5748bddc9b240d6c0266bcf50946f2 100644 (file)
@@ -261,6 +261,7 @@ struct _qemuDomainObjPrivate {
     char *lockState;
 
     bool fakeReboot;
+    virTristateBool allowReboot;
 
     int jobs_queued;
 
index 7f833e940b2afba729cf341b36a620859e93401b..66e81bbe51d954377178060781ed422dffc1922a 100644 (file)
@@ -5309,6 +5309,26 @@ qemuProcessPrepareDomainStorage(virConnectPtr conn,
 }
 
 
+static void
+qemuProcessPrepareAllowReboot(virDomainObjPtr vm)
+{
+    virDomainDefPtr def = vm->def;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+
+    if (priv->allowReboot != VIR_TRISTATE_BOOL_ABSENT)
+        return;
+
+    if (def->onReboot == VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY &&
+        def->onPoweroff == VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY &&
+        (def->onCrash == VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY ||
+         def->onCrash == VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_DESTROY)) {
+        priv->allowReboot = VIR_TRISTATE_BOOL_NO;
+    } else {
+        priv->allowReboot = VIR_TRISTATE_BOOL_YES;
+    }
+}
+
+
 /**
  * qemuProcessPrepareDomain:
  * @conn: connection object (for looking up storage volumes)
@@ -5365,6 +5385,8 @@ qemuProcessPrepareDomain(virConnectPtr conn,
         priv->chardevStdioLogd = true;
     }
 
+    qemuProcessPrepareAllowReboot(vm);
+
     /*
      * Normally PCI addresses are assigned in the virDomainCreate
      * or virDomainDefine methods. We might still need to assign
@@ -6618,6 +6640,10 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
 
     priv->gotShutdown = false;
 
+    /* Attaching to running QEMU so we need to detect whether it was started
+     * with -no-reboot. */
+    qemuProcessPrepareAllowReboot(vm);
+
     /*
      * Normally PCI addresses are assigned in the virDomainCreate
      * or virDomainDefine methods. We might still need to assign
@@ -6994,6 +7020,10 @@ qemuProcessReconnect(void *opaque)
     if (qemuDomainMasterKeyReadFile(priv) < 0)
         goto error;
 
+    /* If we are connecting to a guest started by old libvirt there is no
+     * allowReboot in status XML and we need to initialize it. */
+    qemuProcessPrepareAllowReboot(obj);
+
     VIR_DEBUG("Reconnect monitor to %p '%s'", obj, obj->def->name);
 
     /* XXX check PID liveliness & EXE path */
index 14f5b58fe913361db856b992f6a0f89525aae34b..2185532a6cc0e89e0b424ff2cf4a342c131b2206 100644 (file)
@@ -109,7 +109,8 @@ static const char testStatusXMLPrefixBodyStatic[] =
 "</devices>\n"
 "<numad nodeset='0-2' cpuset='1,3'/>\n"
 "<libDir path='/tmp'/>\n"
-"<channelTargetDir path='/tmp/channel'/>\n";
+"<channelTargetDir path='/tmp/channel'/>\n"
+"<allowReboot value='yes'/>\n";
 
 static const char testStatusXMLSuffix[] =
 "</domstatus>\n";