qemu: Report shutdown event details

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>
This commit is contained in:
Martin Kletzander 2017-04-12 12:00:37 +02:00
parent 4c70a6f874
commit a8eba5036c
7 changed files with 51 additions and 10 deletions

View File

@ -240,6 +240,12 @@ eventDetailToString(int event,
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;
}

View File

@ -2983,7 +2983,16 @@ typedef enum {
* 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

View File

@ -1326,13 +1326,13 @@ qemuMonitorEmitEvent(qemuMonitorPtr mon, const char *event,
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;
}

View File

@ -130,6 +130,7 @@ typedef int (*qemuMonitorDomainEventCallback)(qemuMonitorPtr mon,
void *opaque);
typedef int (*qemuMonitorDomainShutdownCallback)(qemuMonitorPtr mon,
virDomainObjPtr vm,
virTristateBool guest,
void *opaque);
typedef int (*qemuMonitorDomainResetCallback)(qemuMonitorPtr mon,
virDomainObjPtr vm,
@ -344,7 +345,7 @@ int qemuMonitorGetDiskSecret(qemuMonitorPtr mon,
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);

View File

@ -523,9 +523,15 @@ qemuMonitorJSONKeywordStringToJSON(const char *str, const char *firstkeyword)
}
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)

View File

@ -634,12 +634,14 @@ qemuProcessHandleEvent(qemuMonitorPtr mon 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);
@ -662,9 +664,24 @@ qemuProcessHandleShutdown(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
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",

View File

@ -12257,7 +12257,9 @@ VIR_ENUM_IMPL(virshDomainEventStopped,
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,