just as what b8e25c35d7f80a2fadc0e51e95318e39db3d1687 did,
we fall back to the ACPI method when the guest agent is unresponsive in qemuDomainReboot.
Signed-off-by: YueWenyuan <yuewenyuan(a)huawei.com>
Signed-off-by: Zhang Bo <oscar.zhangbo(a)huawei.com>
---
src/qemu/qemu_driver.c | 67 +++++++++++++++++++++++++-------------------------
1 file changed, 34 insertions(+), 33 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 6fc9696..964a9c5 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 (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
goto cleanup;
- if (useAgent && !qemuDomainAgentAvailable(vm, true))
- goto endjob;
+ agentForced = agentRequested && !acpiRequested;
+ if (useAgent && !qemuDomainAgentAvailable(vm, true)) {
+ if (agentForced)
+ goto endjob;
+ useAgent = false;
+ }
if (!virDomainObjIsActive(vm)) {
virReportError(VIR_ERR_OPERATION_INVALID,
@@ -2071,7 +2051,28 @@ qemuDomainReboot(virDomainPtr dom, unsigned int flags)
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)
--
1.7.12.4