]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: Support reboot command in guest
authorZhenzhong Duan <zhenzhong.duan@intel.com>
Thu, 10 Jul 2025 07:21:19 +0000 (03:21 -0400)
committerDaniel P. Berrangé <berrange@redhat.com>
Fri, 25 Jul 2025 10:36:11 +0000 (11:36 +0100)
We can reboot a TDX guest with 'virsh reboot' or 'virsh shutdown' if action
for onPoweroff is 'restart'. But running reboot command in guest shell will
always lead to shutdown.

This behavior is not consistent with normal guest, fix it by checking
shutdown reason and action configuration to trigger FakeReboot.

Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
src/qemu/qemu_monitor.c
src/qemu/qemu_monitor.h
src/qemu/qemu_monitor_json.c

index b06949ab6634966b544cb47b6c36ab15d4fde805..6d984df412e8392b815ae1fdb756e183810d94dd 100644 (file)
@@ -1060,10 +1060,26 @@ qemuMonitorEmitEvent(qemuMonitor *mon, const char *event,
 
 
 void
-qemuMonitorEmitShutdown(qemuMonitor *mon, virTristateBool guest)
+qemuMonitorEmitShutdown(qemuMonitor *mon, virTristateBool guest,
+                        const char *reason)
 {
+    virDomainObj *vm = mon->vm;
+
     VIR_DEBUG("mon=%p guest=%u", mon, guest);
 
+    /* This isn't best place to set FakeReboot but we need to access
+     * mon->vm which is defined in this file. Reboot command in guest
+     * will trigger SHUTDOWN event for TDX guest, so we has to deal
+     * with it here. */
+    if (vm->def->sec &&
+        vm->def->sec->sectype == VIR_DOMAIN_LAUNCH_SECURITY_TDX) {
+        if ((STREQ_NULLABLE(reason, "guest-shutdown") &&
+             vm->def->onPoweroff == VIR_DOMAIN_LIFECYCLE_ACTION_RESTART) ||
+            (STREQ_NULLABLE(reason, "guest-reset") &&
+             vm->def->onReboot == VIR_DOMAIN_LIFECYCLE_ACTION_RESTART))
+            qemuDomainSetFakeReboot(vm, true);
+    }
+
     QEMU_MONITOR_CALLBACK(mon, domainShutdown, mon->vm, guest);
 }
 
index 98eabbb89f689a303ddbbcced4bcbb53b0c679bc..755f347e17f1c83564673984ea73d2e27b36126b 100644 (file)
@@ -460,7 +460,7 @@ int qemuMonitorUpdateVideoVram64Size(qemuMonitor *mon,
 void qemuMonitorEmitEvent(qemuMonitor *mon, const char *event,
                           long long seconds, unsigned int micros,
                           const char *details);
-void qemuMonitorEmitShutdown(qemuMonitor *mon, virTristateBool guest);
+void qemuMonitorEmitShutdown(qemuMonitor *mon, virTristateBool guest, const char *reason);
 void qemuMonitorEmitReset(qemuMonitor *mon);
 void qemuMonitorEmitStop(qemuMonitor *mon);
 void qemuMonitorEmitResume(qemuMonitor *mon);
index 6697b747b0f8b34c0ac6d4d527707d4cef05deea..9f51421478bd46af2da46653750a9eb276dc51f4 100644 (file)
@@ -548,12 +548,16 @@ qemuMonitorJSONMakeCommand(const char *cmdname,
 static void qemuMonitorJSONHandleShutdown(qemuMonitor *mon, virJSONValue *data)
 {
     bool guest = false;
+    const char *reason = NULL;
     virTristateBool guest_initiated = VIR_TRISTATE_BOOL_ABSENT;
 
     if (data && virJSONValueObjectGetBoolean(data, "guest", &guest) == 0)
         guest_initiated = virTristateBoolFromBool(guest);
 
-    qemuMonitorEmitShutdown(mon, guest_initiated);
+    if (data)
+        reason = virJSONValueObjectGetString(data, "reason");
+
+    qemuMonitorEmitShutdown(mon, guest_initiated, reason);
 }
 
 static void qemuMonitorJSONHandleReset(qemuMonitor *mon, virJSONValue *data G_GNUC_UNUSED)