mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
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: John Ferlan <jferlan@redhat.com> Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
This commit is contained in:
parent
dd97c1480e
commit
a9d637e71e
@ -6509,23 +6509,17 @@ qemuBuildPMCommandLine(virCommandPtr cmd,
|
|||||||
const virDomainDef *def,
|
const virDomainDef *def,
|
||||||
qemuDomainObjPrivatePtr priv)
|
qemuDomainObjPrivatePtr priv)
|
||||||
{
|
{
|
||||||
bool allowReboot = true;
|
|
||||||
virQEMUCapsPtr qemuCaps = priv->qemuCaps;
|
virQEMUCapsPtr qemuCaps = priv->qemuCaps;
|
||||||
|
|
||||||
/* Only add -no-reboot option if each event destroys domain */
|
/* Only add -no-reboot option if each event destroys domain */
|
||||||
if (def->onReboot == VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY &&
|
if (priv->allowReboot == VIR_TRISTATE_BOOL_NO)
|
||||||
def->onPoweroff == VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY &&
|
|
||||||
(def->onCrash == VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY ||
|
|
||||||
def->onCrash == VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_DESTROY)) {
|
|
||||||
allowReboot = false;
|
|
||||||
virCommandAddArg(cmd, "-no-reboot");
|
virCommandAddArg(cmd, "-no-reboot");
|
||||||
}
|
|
||||||
|
|
||||||
/* If JSON monitor is enabled, we can receive an event
|
/* If JSON monitor is enabled, we can receive an event
|
||||||
* when QEMU stops. If we use no-shutdown, then we can
|
* when QEMU stops. If we use no-shutdown, then we can
|
||||||
* watch for this event and do a soft/warm reboot.
|
* 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)) {
|
virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_SHUTDOWN)) {
|
||||||
virCommandAddArg(cmd, "-no-shutdown");
|
virCommandAddArg(cmd, "-no-shutdown");
|
||||||
}
|
}
|
||||||
|
@ -1767,6 +1767,7 @@ qemuDomainObjPrivateDataClear(qemuDomainObjPrivatePtr priv)
|
|||||||
priv->namespaces = NULL;
|
priv->namespaces = NULL;
|
||||||
|
|
||||||
priv->reconnectBlockjobs = VIR_TRISTATE_BOOL_ABSENT;
|
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
|
static int
|
||||||
qemuDomainObjPrivateXMLFormat(virBufferPtr buf,
|
qemuDomainObjPrivateXMLFormat(virBufferPtr buf,
|
||||||
virDomainObjPtr vm)
|
virDomainObjPtr vm)
|
||||||
@ -1998,6 +2009,8 @@ qemuDomainObjPrivateXMLFormat(virBufferPtr buf,
|
|||||||
if (priv->chardevStdioLogd)
|
if (priv->chardevStdioLogd)
|
||||||
virBufferAddLit(buf, "<chardevStdioLogd/>\n");
|
virBufferAddLit(buf, "<chardevStdioLogd/>\n");
|
||||||
|
|
||||||
|
qemuDomainObjPrivateXMLFormatAllowReboot(buf, priv->allowReboot);
|
||||||
|
|
||||||
if (qemuDomainObjPrivateXMLFormatBlockjobs(buf, vm) < 0)
|
if (qemuDomainObjPrivateXMLFormatBlockjobs(buf, vm) < 0)
|
||||||
return -1;
|
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
|
static int
|
||||||
qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt,
|
qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
@ -2323,6 +2361,8 @@ qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt,
|
|||||||
priv->chardevStdioLogd = virXPathBoolean("boolean(./chardevStdioLogd)",
|
priv->chardevStdioLogd = virXPathBoolean("boolean(./chardevStdioLogd)",
|
||||||
ctxt) == 1;
|
ctxt) == 1;
|
||||||
|
|
||||||
|
qemuDomainObjPrivateXMLParseAllowReboot(ctxt, &priv->allowReboot);
|
||||||
|
|
||||||
if (qemuDomainObjPrivateXMLParseBlockjobs(priv, ctxt) < 0)
|
if (qemuDomainObjPrivateXMLParseBlockjobs(priv, ctxt) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
@ -261,6 +261,7 @@ struct _qemuDomainObjPrivate {
|
|||||||
char *lockState;
|
char *lockState;
|
||||||
|
|
||||||
bool fakeReboot;
|
bool fakeReboot;
|
||||||
|
virTristateBool allowReboot;
|
||||||
|
|
||||||
int jobs_queued;
|
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:
|
* qemuProcessPrepareDomain:
|
||||||
* @conn: connection object (for looking up storage volumes)
|
* @conn: connection object (for looking up storage volumes)
|
||||||
@ -5365,6 +5385,8 @@ qemuProcessPrepareDomain(virConnectPtr conn,
|
|||||||
priv->chardevStdioLogd = true;
|
priv->chardevStdioLogd = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qemuProcessPrepareAllowReboot(vm);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Normally PCI addresses are assigned in the virDomainCreate
|
* Normally PCI addresses are assigned in the virDomainCreate
|
||||||
* or virDomainDefine methods. We might still need to assign
|
* or virDomainDefine methods. We might still need to assign
|
||||||
@ -6618,6 +6640,10 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
priv->gotShutdown = false;
|
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
|
* Normally PCI addresses are assigned in the virDomainCreate
|
||||||
* or virDomainDefine methods. We might still need to assign
|
* or virDomainDefine methods. We might still need to assign
|
||||||
@ -6994,6 +7020,10 @@ qemuProcessReconnect(void *opaque)
|
|||||||
if (qemuDomainMasterKeyReadFile(priv) < 0)
|
if (qemuDomainMasterKeyReadFile(priv) < 0)
|
||||||
goto error;
|
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);
|
VIR_DEBUG("Reconnect monitor to %p '%s'", obj, obj->def->name);
|
||||||
|
|
||||||
/* XXX check PID liveliness & EXE path */
|
/* XXX check PID liveliness & EXE path */
|
||||||
|
@ -109,7 +109,8 @@ static const char testStatusXMLPrefixBodyStatic[] =
|
|||||||
"</devices>\n"
|
"</devices>\n"
|
||||||
"<numad nodeset='0-2' cpuset='1,3'/>\n"
|
"<numad nodeset='0-2' cpuset='1,3'/>\n"
|
||||||
"<libDir path='/tmp'/>\n"
|
"<libDir path='/tmp'/>\n"
|
||||||
"<channelTargetDir path='/tmp/channel'/>\n";
|
"<channelTargetDir path='/tmp/channel'/>\n"
|
||||||
|
"<allowReboot value='yes'/>\n";
|
||||||
|
|
||||||
static const char testStatusXMLSuffix[] =
|
static const char testStatusXMLSuffix[] =
|
||||||
"</domstatus>\n";
|
"</domstatus>\n";
|
||||||
|
Loading…
Reference in New Issue
Block a user