With hard reboot, we can reboot a TDX guest with 'virsh reboot' or
'virsh shutdown' if action for onPoweroff is 'restart'. But running
reboot cmd in guest shell will always lead to shutdown.
This behavior is not consistent with legacy guest, this patch extend
hard reboot support and make TDX guest behavior same as legacy guest.
Signed-off-by: Zhenzhong Duan <zhenzhong.duan(a)intel.com>
---
src/qemu/qemu_monitor.c | 19 ++++++++++++++++++-
src/qemu/qemu_monitor.h | 2 +-
src/qemu/qemu_monitor_json.c | 6 +++++-
src/qemu/qemu_process.c | 1 +
4 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 320729f067..c250edf8be 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1084,10 +1084,27 @@ qemuMonitorEmitEvent(qemuMonitor *mon, const char *event,
void
-qemuMonitorEmitShutdown(qemuMonitor *mon, virTristateBool guest)
+qemuMonitorEmitShutdown(qemuMonitor *mon, virTristateBool guest,
+ const char *reason)
{
+ virDomainObj *vm = mon->vm;
+ qemuDomainObjPrivate *priv = vm->privateData;
+
VIR_DEBUG("mon=%p guest=%u", mon, guest);
+ /* This isn't a proper place to set hardReboot but we need to access
+ * mon->vm which is defined in this file. Reboot in guest kernel will
+ * trigger SHUTDOWN event for td-guest, so we has to deal with it
+ * here. */
+ if (vm->def->sec &&
+ vm->def->sec->sectype == VIR_DOMAIN_LAUNCH_SECURITY_TDX &&
+ ((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))) {
+ priv->hardReboot = true;
+ }
+
QEMU_MONITOR_CALLBACK(mon, domainShutdown, mon->vm, guest);
}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 6c590933aa..6aae635411 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -443,7 +443,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);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 105d729d7c..794c22eb9c 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -546,12 +546,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)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 9fa679e408..a9bba19852 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -591,6 +591,7 @@ qemuProcessShutdownOrReboot(virDomainObj *vm)
vm) < 0) {
VIR_ERROR(_("Failed to create hard reboot thread, killing
domain"));
ignore_value(qemuProcessKill(vm, VIR_QEMU_PROCESS_KILL_NOWAIT));
+ qemuDomainSetHardReboot(vm, false);
virObjectUnref(vm);
}
} else if (priv->fakeReboot ||
--
2.34.1