From eadf41fe313a804409415841a3df0a494470f057 Mon Sep 17 00:00:00 2001 From: zhang bo Date: Thu, 23 Apr 2015 11:40:15 +0800 Subject: [PATCH] qemu: Don't fail to reboot domains with unresponsive agent just as what b8e25c35d7f80a2fadc0e51e95318e39db3d1687 did, we fall back to the ACPI method when the guest agent is unresponsive in qemuDomainReboot(). Signed-off-by: YueWenyuan Signed-off-by: Zhang Bo Signed-off-by: Michal Privoznik --- src/qemu/qemu_driver.c | 76 +++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index c4a085362d..82f34ecae1 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2002,21 +2002,14 @@ qemuDomainReboot(virDomainPtr dom, unsigned int flags) virDomainObjPtr vm; int ret = -1; qemuDomainObjPrivatePtr priv; - bool useAgent = false; + bool useAgent = false, agentRequested, acpiRequested; bool isReboot = true; + bool agentForced; int agentFlag = QEMU_AGENT_SHUTDOWN_REBOOT; virCheckFlags(VIR_DOMAIN_REBOOT_ACPI_POWER_BTN | VIR_DOMAIN_REBOOT_GUEST_AGENT, -1); - /* At most one of these two flags should be set. */ - if ((flags & VIR_DOMAIN_REBOOT_ACPI_POWER_BTN) && - (flags & VIR_DOMAIN_REBOOT_GUEST_AGENT)) { - virReportInvalidArg(flags, "%s", - _("flags for acpi power button and guest agent are mutually exclusive")); - return -1; - } - if (!(vm = qemuDomObjFromDomain(dom))) goto cleanup; @@ -2028,38 +2021,25 @@ qemuDomainReboot(virDomainPtr dom, unsigned int flags) } priv = vm->privateData; + agentRequested = flags & VIR_DOMAIN_REBOOT_GUEST_AGENT; + acpiRequested = flags & VIR_DOMAIN_REBOOT_ACPI_POWER_BTN; - if (virDomainRebootEnsureACL(dom->conn, vm->def, flags) < 0) - goto cleanup; - - if ((flags & VIR_DOMAIN_REBOOT_GUEST_AGENT) || - (!(flags & VIR_DOMAIN_REBOOT_ACPI_POWER_BTN) && - priv->agent)) + /* Prefer agent unless we were requested to not to. */ + if (agentRequested || (!flags && priv->agent)) useAgent = true; - if (!useAgent) { -#if WITH_YAJL - if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MONITOR_JSON)) { - if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NO_SHUTDOWN)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("Reboot is not supported with this QEMU binary")); - goto cleanup; - } - } else { -#endif - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("Reboot is not supported without the JSON monitor")); - goto cleanup; -#if WITH_YAJL - } -#endif - } + if (virDomainRebootEnsureACL(dom->conn, vm->def, flags) < 0) + goto cleanup; if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) goto cleanup; - if (useAgent && !qemuDomainAgentAvailable(vm, true)) - goto endjob; + agentForced = agentRequested && !acpiRequested; + if (!qemuDomainAgentAvailable(vm, agentForced)) { + if (agentForced) + goto endjob; + useAgent = false; + } if (!virDomainObjIsActive(vm)) { virReportError(VIR_ERR_OPERATION_INVALID, @@ -2067,18 +2047,38 @@ qemuDomainReboot(virDomainPtr dom, unsigned int flags) goto endjob; } + qemuDomainSetFakeReboot(driver, vm, isReboot); + if (useAgent) { qemuDomainObjEnterAgent(vm); ret = qemuAgentShutdown(priv->agent, agentFlag); qemuDomainObjExitAgent(vm); - } else { + } + + /* If we are not enforced to use just an agent, try ACPI + * shutdown as well in case agent did not succeed. + */ + if ((!useAgent) || + (ret < 0 && (acpiRequested || !flags))) { +#if WITH_YAJL + if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MONITOR_JSON)) { + if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NO_SHUTDOWN)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("ACPI reboot is not supported with this QEMU binary")); + goto endjob; + } + } else { +#endif + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("ACPI reboot is not supported without the JSON monitor")); + goto endjob; +#if WITH_YAJL + } +#endif qemuDomainObjEnterMonitor(driver, vm); ret = qemuMonitorSystemPowerdown(priv->mon); if (qemuDomainObjExitMonitor(driver, vm) < 0) ret = -1; - - if (ret == 0) - qemuDomainSetFakeReboot(driver, vm, isReboot); } endjob: -- 2.47.2