提交 a9d637e7 编写于 作者: P Pavel Hrdina

qemu: move detection whether to use -no-reboot to qemu_domain

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: NJohn Ferlan <jferlan@redhat.com>
Signed-off-by: NPavel Hrdina <phrdina@redhat.com>
上级 dd97c148
......@@ -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");
}
......
......@@ -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;
......
......@@ -261,6 +261,7 @@ struct _qemuDomainObjPrivate {
char *lockState;
bool fakeReboot;
virTristateBool allowReboot;
int jobs_queued;
......
......@@ -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 */
......
......@@ -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";
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册