[PATCH 21/22] qemuDomainSetLifecycleAction: Properly update 'onReboot' action in qemu

Peter Krempa pkrempa at redhat.com
Tue Aug 24 14:44:42 UTC 2021


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 <pkrempa at redhat.com>
---
 src/qemu/qemu_driver.c | 69 ++++++++++++++++++++++++++++++++++++++----
 1 file changed, 63 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 3c57d67d1c..961f521f4b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19629,6 +19629,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,
@@ -19671,14 +19723,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);
-- 
2.31.1




More information about the libvir-list mailing list