diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 87e762bb51..c12e657859 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -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");
}
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 05e8b96aa4..26f65e2d9b 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -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, "\n",
+ virTristateBoolTypeToString(allowReboot));
+
+}
+
+
static int
qemuDomainObjPrivateXMLFormat(virBufferPtr buf,
virDomainObjPtr vm)
@@ -1998,6 +2009,8 @@ qemuDomainObjPrivateXMLFormat(virBufferPtr buf,
if (priv->chardevStdioLogd)
virBufferAddLit(buf, "\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;
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index a29dd76037..afe979d2ed 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -261,6 +261,7 @@ struct _qemuDomainObjPrivate {
char *lockState;
bool fakeReboot;
+ virTristateBool allowReboot;
int jobs_queued;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 7f833e940b..66e81bbe51 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -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 */
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 14f5b58fe9..2185532a6c 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -109,7 +109,8 @@ static const char testStatusXMLPrefixBodyStatic[] =
"\n"
"\n"
"\n"
-"\n";
+"\n"
+"\n";
static const char testStatusXMLSuffix[] =
"\n";