From: Peter Krempa Date: Fri, 20 Aug 2021 13:40:18 +0000 (+0200) Subject: qemuDomainSetLifecycleAction: Properly update 'onReboot' action in qemu X-Git-Tag: v7.7.0-rc1~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=526cff4f03049bcbbad857b9e79f15d3dd30198b;p=thirdparty%2Flibvirt.git qemuDomainSetLifecycleAction: Properly update 'onReboot' action in qemu When qemu supports 'set-action' command we can update what happens on reboot. Additionally we can fully relax the checks as we now properly update the lifecycle actions. Signed-off-by: Peter Krempa Reviewed-by: Michal Privoznik --- diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 1178ebc795..f1f961c51c 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -19627,6 +19627,58 @@ qemuDomainModifyLifecycleAction(virDomainDef *def, } +static int +qemuDomainModifyLifecycleActionLive(virDomainObj *vm, + virDomainLifecycle type, + virDomainLifecycleAction action) +{ + qemuMonitorActionReboot monReboot = QEMU_MONITOR_ACTION_REBOOT_KEEP; + qemuDomainObjPrivate *priv = vm->privateData; + virQEMUDriver *driver = priv->driver; + int rc; + + if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_SET_ACTION)) + return 0; + + /* For now we only update 'reboot' action here as we want to keep the + * shutdown action as is (we're emulating the outcome anyways)) */ + if (type != VIR_DOMAIN_LIFECYCLE_REBOOT || + vm->def->onReboot == action) + return 0; + + + switch (action) { + case VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY: + monReboot = QEMU_MONITOR_ACTION_REBOOT_SHUTDOWN; + break; + + case VIR_DOMAIN_LIFECYCLE_ACTION_RESTART: + monReboot = QEMU_MONITOR_ACTION_REBOOT_RESET; + break; + + case VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE: + case VIR_DOMAIN_LIFECYCLE_ACTION_RESTART_RENAME: + case VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_DESTROY: + case VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_RESTART: + case VIR_DOMAIN_LIFECYCLE_ACTION_LAST: + return 0; + } + + + qemuDomainObjEnterMonitor(driver, vm); + + rc = qemuMonitorSetAction(priv->mon, + QEMU_MONITOR_ACTION_SHUTDOWN_KEEP, + monReboot, + QEMU_MONITOR_ACTION_WATCHDOG_KEEP, + QEMU_MONITOR_ACTION_PANIC_KEEP); + + if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0) + return -1; + + return 0; +} + static int qemuDomainSetLifecycleAction(virDomainPtr dom, @@ -19669,14 +19721,19 @@ qemuDomainSetLifecycleAction(virDomainPtr dom, goto endjob; if (def) { - if (priv->allowReboot == VIR_TRISTATE_BOOL_NO || - (type == VIR_DOMAIN_LIFECYCLE_REBOOT && - def->onReboot != action)) { - virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", - _("cannot update lifecycle action because QEMU was started with incompatible -no-reboot setting")); - goto endjob; + if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_SET_ACTION)) { + if (priv->allowReboot == VIR_TRISTATE_BOOL_NO || + (type == VIR_DOMAIN_LIFECYCLE_REBOOT && + def->onReboot != action)) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("cannot update lifecycle action because QEMU was started with incompatible -no-reboot setting")); + goto endjob; + } } + if (qemuDomainModifyLifecycleActionLive(vm, type, action) < 0) + goto endjob; + qemuDomainModifyLifecycleAction(def, type, action); qemuDomainSaveStatus(vm);