QEMU will likely report the details of it shutting down, particularly
whether the shutdown was initiated by the guest or host. We should
forward that information along, at least for shutdown events. Reset
has that as well, however that is not a lifecycle event and would add
extra constants that might not be used. It can be added later on.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=
1384007
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
case VIR_DOMAIN_EVENT_SHUTDOWN_FINISHED:
return "Finished";
+ case VIR_DOMAIN_EVENT_SHUTDOWN_GUEST:
+ return "Guest request";
+
+ case VIR_DOMAIN_EVENT_SHUTDOWN_HOST:
+ return "Host request";
+
case VIR_DOMAIN_EVENT_SHUTDOWN_LAST:
break;
}
* Details on the cause of a 'shutdown' lifecycle event
*/
typedef enum {
- VIR_DOMAIN_EVENT_SHUTDOWN_FINISHED = 0, /* Guest finished shutdown sequence */
+ /* Guest finished shutdown sequence */
+ VIR_DOMAIN_EVENT_SHUTDOWN_FINISHED = 0,
+
+ /* Domain finished shutting down after request from the guest itself
+ * (e.g. hardware-specific action) */
+ VIR_DOMAIN_EVENT_SHUTDOWN_GUEST = 1,
+
+ /* Domain finished shutting down after request from the host (e.g. killed by
+ * a signal) */
+ VIR_DOMAIN_EVENT_SHUTDOWN_HOST = 2,
# ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_EVENT_SHUTDOWN_LAST
int
-qemuMonitorEmitShutdown(qemuMonitorPtr mon)
+qemuMonitorEmitShutdown(qemuMonitorPtr mon, virTristateBool guest)
{
int ret = -1;
- VIR_DEBUG("mon=%p", mon);
+ VIR_DEBUG("mon=%p guest=%u", mon, guest);
mon->willhangup = 1;
- QEMU_MONITOR_CALLBACK(mon, ret, domainShutdown, mon->vm);
+ QEMU_MONITOR_CALLBACK(mon, ret, domainShutdown, mon->vm, guest);
return ret;
}
void *opaque);
typedef int (*qemuMonitorDomainShutdownCallback)(qemuMonitorPtr mon,
virDomainObjPtr vm,
+ virTristateBool guest,
void *opaque);
typedef int (*qemuMonitorDomainResetCallback)(qemuMonitorPtr mon,
virDomainObjPtr vm,
int qemuMonitorEmitEvent(qemuMonitorPtr mon, const char *event,
long long seconds, unsigned int micros,
const char *details);
-int qemuMonitorEmitShutdown(qemuMonitorPtr mon);
+int qemuMonitorEmitShutdown(qemuMonitorPtr mon, virTristateBool guest);
int qemuMonitorEmitReset(qemuMonitorPtr mon);
int qemuMonitorEmitPowerdown(qemuMonitorPtr mon);
int qemuMonitorEmitStop(qemuMonitorPtr mon);
}
-static void qemuMonitorJSONHandleShutdown(qemuMonitorPtr mon, virJSONValuePtr data ATTRIBUTE_UNUSED)
+static void qemuMonitorJSONHandleShutdown(qemuMonitorPtr mon, virJSONValuePtr data)
{
- qemuMonitorEmitShutdown(mon);
+ bool guest = false;
+ virTristateBool guest_initiated = VIR_TRISTATE_BOOL_ABSENT;
+
+ if (virJSONValueObjectGetBoolean(data, "guest", &guest) == 0)
+ guest_initiated = guest ? VIR_TRISTATE_BOOL_YES : VIR_TRISTATE_BOOL_NO;
+
+ qemuMonitorEmitShutdown(mon, guest_initiated);
}
static void qemuMonitorJSONHandleReset(qemuMonitorPtr mon, virJSONValuePtr data ATTRIBUTE_UNUSED)
static int
qemuProcessHandleShutdown(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
+ virTristateBool guest_initiated,
void *opaque)
{
virQEMUDriverPtr driver = opaque;
qemuDomainObjPrivatePtr priv;
virObjectEventPtr event = NULL;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ int detail = 0;
VIR_DEBUG("vm=%p", vm);
virDomainObjSetState(vm,
VIR_DOMAIN_SHUTDOWN,
VIR_DOMAIN_SHUTDOWN_UNKNOWN);
+
+ switch (guest_initiated) {
+ case VIR_TRISTATE_BOOL_YES:
+ detail = VIR_DOMAIN_EVENT_SHUTDOWN_GUEST;
+ break;
+
+ case VIR_TRISTATE_BOOL_NO:
+ detail = VIR_DOMAIN_EVENT_SHUTDOWN_HOST;
+ break;
+
+ default:
+ detail = VIR_DOMAIN_EVENT_SHUTDOWN_FINISHED;
+ break;
+ }
+
event = virDomainEventLifecycleNewFromObj(vm,
- VIR_DOMAIN_EVENT_SHUTDOWN,
- VIR_DOMAIN_EVENT_SHUTDOWN_FINISHED);
+ VIR_DOMAIN_EVENT_SHUTDOWN,
+ detail);
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) {
VIR_WARN("Unable to save status on vm %s after state change",
VIR_ENUM_DECL(virshDomainEventShutdown)
VIR_ENUM_IMPL(virshDomainEventShutdown,
VIR_DOMAIN_EVENT_SHUTDOWN_LAST,
- N_("Finished"))
+ N_("Finished"),
+ N_("Finished after guest request"),
+ N_("Finished after host request"))
VIR_ENUM_DECL(virshDomainEventPMSuspended)
VIR_ENUM_IMPL(virshDomainEventPMSuspended,