Signed-off-by: Prerna Saxena <saxenap.ltc(a)gmail.com>
---
src/qemu/qemu_event.c | 11 +
src/qemu/qemu_event.h | 8 +
src/qemu/qemu_monitor.c | 592 +++++++++++++++++++++++++++-----
src/qemu/qemu_monitor.h | 80 +++--
src/qemu/qemu_monitor_json.c | 291 ++++++++++------
src/qemu/qemu_process.c | 789 +++++++++++++++++++++++++++----------------
src/qemu/qemu_process.h | 2 +
tests/qemumonitortestutils.c | 2 +-
8 files changed, 1273 insertions(+), 502 deletions(-)
diff --git a/src/qemu/qemu_event.c b/src/qemu/qemu_event.c
index d52fad2..beb309f 100644
--- a/src/qemu/qemu_event.c
+++ b/src/qemu/qemu_event.c
@@ -50,6 +50,7 @@ VIR_ENUM_IMPL(qemuMonitorEvent,
"RTC Change", "Shutdown", "Stop",
"Suspend", "Suspend To Disk",
"Virtual Serial Port Change",
+ "Spice migrated",
"Wakeup", "Watchdog");
virQemuEventList* virQemuEventListInit(void)
@@ -302,3 +303,13 @@ void virDomainConsumeVMEvents(virDomainObjPtr vm, void *opaque)
}
return;
}
+
+extern void qemuProcessEmitMonitorEvent(qemuEventPtr ev, void *opaque);
+
+void virEventRunHandler(qemuEventPtr ev, void *opaque)
+{
+ if (!ev)
+ return;
+
+ return qemuProcessEmitMonitorEvent(ev, opaque);
+}
diff --git a/src/qemu/qemu_event.h b/src/qemu/qemu_event.h
index 4173834..8552fd1 100644
--- a/src/qemu/qemu_event.h
+++ b/src/qemu/qemu_event.h
@@ -51,6 +51,7 @@ typedef enum {
QEMU_EVENT_SUSPEND,
QEMU_EVENT_SUSPEND_DISK,
QEMU_EVENT_SERIAL_CHANGE,
+ QEMU_EVENT_SPICE_MIGRATED,
QEMU_EVENT_WAKEUP,
QEMU_EVENT_WATCHDOG,
@@ -102,7 +103,12 @@ struct qemuEventTrayChangeData {
int reason;
};
+struct qemuEventShutdownData {
+ virTristateBool guest_initiated;
+};
+
struct qemuEventGuestPanicData {
+ void *info;
};
struct qemuEventMigrationStatusData {
@@ -159,6 +165,7 @@ struct _qemuEvent {
struct qemuEventBlockThresholdData ev_threshold;
struct qemuEventDeviceDeletedData ev_deviceDel;
struct qemuEventTrayChangeData ev_tray;
+ struct qemuEventShutdownData ev_shutdown;
struct qemuEventGuestPanicData ev_panic;
struct qemuEventMigrationStatusData ev_migStatus;
struct qemuEventMigrationPassData ev_migPass;
@@ -219,5 +226,6 @@ int virQemuVmEventListInit(virDomainObjPtr vm);
int virEnqueueVMEvent(virQemuEventList *qlist, qemuEventPtr ev);
qemuEventPtr virDequeueVMEvent(virQemuEventList *qlist, virDomainObjPtr vm);
void virEventWorkerScanQueue(void *dummy, void *opaque);
+void virEventRunHandler(qemuEventPtr ev, void *opaque);
void virDomainConsumeVMEvents(virDomainObjPtr vm, void *opaque);
#endif
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 7a26785..4e45cf9 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -34,6 +34,7 @@
#include "qemu_monitor_json.h"
#include "qemu_domain.h"
#include "qemu_process.h"
+#include "qemu_event.h"
#include "virerror.h"
#include "viralloc.h"
#include "virlog.h"
@@ -1316,6 +1317,14 @@ qemuMonitorGetDiskSecret(qemuMonitorPtr mon,
return ret;
}
+static int
+qemuMonitorEnqueueEvent(qemuMonitorPtr mon, qemuEventPtr ev)
+{
+ int ret = -1;
+ QEMU_MONITOR_CALLBACK(mon, ret, domainEnqueueEvent, ev->vm, ev);
+
+ return ret;
+}
int
qemuMonitorEmitEvent(qemuMonitorPtr mon, const char *event,
@@ -1332,90 +1341,189 @@ qemuMonitorEmitEvent(qemuMonitorPtr mon, const char *event,
int
-qemuMonitorEmitShutdown(qemuMonitorPtr mon, virTristateBool guest)
+qemuMonitorEmitShutdown(qemuMonitorPtr mon, virTristateBool guest,
+ long long seconds, unsigned int micros)
{
int ret = -1;
- VIR_DEBUG("mon=%p guest=%u", mon, guest);
mon->willhangup = 1;
+ qemuEventPtr ev;
+
+ if (VIR_ALLOC(ev) < 0){
+ return ret;
+ }
+
+ ev->ev_type = QEMU_EVENT_SHUTDOWN;
+ ev->vm = mon->vm;
+ ev->seconds = seconds;
+ ev->micros = micros;
+ ev->evData.ev_shutdown.guest_initiated = guest;
- QEMU_MONITOR_CALLBACK(mon, ret, domainShutdown, mon->vm, guest);
+ VIR_DEBUG("Vm %s received shutdown event initiated by %u",
+ mon->vm->def->name, guest);
+ virObjectRef(ev->vm);
+ ret = qemuMonitorEnqueueEvent(mon, ev);
return ret;
}
int
-qemuMonitorEmitReset(qemuMonitorPtr mon)
+qemuMonitorEmitReset(qemuMonitorPtr mon, long long seconds, unsigned int micros)
{
int ret = -1;
- VIR_DEBUG("mon=%p", mon);
+ qemuEventPtr ev;
+
+ if (VIR_ALLOC(ev) < 0){
+ return ret;
+ }
+
+ ev->ev_type = QEMU_EVENT_RESET;
+ ev->vm = mon->vm;
+ ev->seconds = seconds;
+ ev->micros = micros;
- QEMU_MONITOR_CALLBACK(mon, ret, domainReset, mon->vm);
+ VIR_DEBUG("Vm %s received reset event", mon->vm->def->name);
+ virObjectRef(ev->vm);
+ ret = qemuMonitorEnqueueEvent(mon, ev);
return ret;
}
int
-qemuMonitorEmitPowerdown(qemuMonitorPtr mon)
+qemuMonitorEmitPowerdown(qemuMonitorPtr mon, long long seconds, unsigned int micros)
{
int ret = -1;
- VIR_DEBUG("mon=%p", mon);
+ qemuEventPtr ev;
+
+ if (VIR_ALLOC(ev) < 0){
+ return ret;
+ }
+
+ ev->ev_type = QEMU_EVENT_POWERDOWN;
+ ev->vm = mon->vm;
+ ev->seconds = seconds;
+ ev->micros = micros;
- QEMU_MONITOR_CALLBACK(mon, ret, domainPowerdown, mon->vm);
+ VIR_DEBUG("Vm %s received powerdown event", mon->vm->def->name);
+ virObjectRef(ev->vm);
+ ret = qemuMonitorEnqueueEvent(mon, ev);
return ret;
}
int
-qemuMonitorEmitStop(qemuMonitorPtr mon)
+qemuMonitorEmitStop(qemuMonitorPtr mon, long long seconds, unsigned int micros)
{
int ret = -1;
- VIR_DEBUG("mon=%p", mon);
+ qemuEventPtr ev;
+
+ if (VIR_ALLOC(ev) < 0){
+ return ret;
+ }
+
+ ev->ev_type = QEMU_EVENT_STOP;
+ ev->vm = mon->vm;
+ ev->seconds = seconds;
+ ev->micros = micros;
- QEMU_MONITOR_CALLBACK(mon, ret, domainStop, mon->vm);
+ VIR_DEBUG("Vm %s received stop event", mon->vm->def->name);
+ virObjectRef(ev->vm);
+ ret = qemuMonitorEnqueueEvent(mon, ev);
return ret;
}
int
-qemuMonitorEmitResume(qemuMonitorPtr mon)
+qemuMonitorEmitResume(qemuMonitorPtr mon, long long seconds, unsigned int micros)
{
int ret = -1;
- VIR_DEBUG("mon=%p", mon);
+ qemuEventPtr ev;
+
+ if (VIR_ALLOC(ev) < 0){
+ return ret;
+ }
+
+ ev->ev_type = QEMU_EVENT_RESUME;
+ ev->vm = mon->vm;
+ ev->seconds = seconds;
+ ev->micros = micros;
- QEMU_MONITOR_CALLBACK(mon, ret, domainResume, mon->vm);
+ VIR_DEBUG("Vm %s received resume event", mon->vm->def->name);
+ virObjectRef(ev->vm);
+ ret = qemuMonitorEnqueueEvent(mon, ev);
return ret;
}
int
qemuMonitorEmitGuestPanic(qemuMonitorPtr mon,
- qemuMonitorEventPanicInfoPtr info)
+ qemuMonitorEventPanicInfoPtr info,
+ long long seconds, unsigned int micros)
{
int ret = -1;
- VIR_DEBUG("mon=%p", mon);
- QEMU_MONITOR_CALLBACK(mon, ret, domainGuestPanic, mon->vm, info);
+ qemuEventPtr ev;
+
+ if (VIR_ALLOC(ev) < 0){
+ return ret;
+ }
+
+ ev->ev_type = QEMU_EVENT_GUEST_PANICKED;
+ ev->vm = mon->vm;
+ ev->seconds = seconds;
+ ev->micros = micros;
+ ev->evData.ev_panic.info = info;
+
+ VIR_DEBUG("Vm %s received guest panic event",
mon->vm->def->name);
+ virObjectRef(ev->vm);
+ ret = qemuMonitorEnqueueEvent(mon, ev);
return ret;
}
int
-qemuMonitorEmitRTCChange(qemuMonitorPtr mon, long long offset)
+qemuMonitorEmitRTCChange(qemuMonitorPtr mon, long long offset,
+ long long seconds, unsigned int micros)
{
int ret = -1;
- VIR_DEBUG("mon=%p", mon);
+ qemuEventPtr ev;
+
+ if (VIR_ALLOC(ev) < 0){
+ return ret;
+ }
- QEMU_MONITOR_CALLBACK(mon, ret, domainRTCChange, mon->vm, offset);
+ ev->ev_type = QEMU_EVENT_RTC_CHANGE;
+ ev->vm = mon->vm;
+ ev->seconds = seconds;
+ ev->micros = micros;
+ ev->evData.ev_rtc.offset = offset;
+
+ VIR_DEBUG("Vm %s received RTC change event", mon->vm->def->name);
+
+ virObjectRef(ev->vm);
+ ret = qemuMonitorEnqueueEvent(mon, ev);
return ret;
}
int
-qemuMonitorEmitWatchdog(qemuMonitorPtr mon, int action)
+qemuMonitorEmitWatchdog(qemuMonitorPtr mon, int action,
+ long long seconds, unsigned int micros)
{
int ret = -1;
- VIR_DEBUG("mon=%p", mon);
+ qemuEventPtr ev;
+
+ if (VIR_ALLOC(ev) < 0){
+ return ret;
+ }
+
+ ev->ev_type = QEMU_EVENT_WATCHDOG;
+ ev->vm = mon->vm;
+ ev->seconds = seconds;
+ ev->micros = micros;
+ ev->evData.ev_watchdog.action = action;
- QEMU_MONITOR_CALLBACK(mon, ret, domainWatchdog, mon->vm, action);
+ VIR_DEBUG("Vm %s received watchdog event", mon->vm->def->name);
+ virObjectRef(ev->vm);
+ ret = qemuMonitorEnqueueEvent(mon, ev);
return ret;
}
@@ -1424,13 +1532,39 @@ int
qemuMonitorEmitIOError(qemuMonitorPtr mon,
const char *diskAlias,
int action,
- const char *reason)
+ const char *reason,
+ long long seconds, unsigned int micros)
{
int ret = -1;
- VIR_DEBUG("mon=%p", mon);
+ qemuEventPtr ev;
+ struct qemuEventIOErrorData *d = NULL;
+
+ if (VIR_ALLOC(ev) < 0){
+ return ret;
+ }
+
+ ev->ev_type = QEMU_EVENT_BLOCK_IO_ERROR;
+ ev->vm = mon->vm;
+ ev->seconds = seconds;
+ ev->micros = micros;
+ d = &(ev->evData.ev_IOErr);
+ d->action = action;
- QEMU_MONITOR_CALLBACK(mon, ret, domainIOError, mon->vm,
- diskAlias, action, reason);
+ if (VIR_STRDUP(d->device, diskAlias) < 0) {
+ goto cleanup;
+ }
+ if (VIR_STRDUP(d->reason, reason) < 0) {
+ goto cleanup;
+ }
+ VIR_DEBUG("Vm %s received block IO error event",
mon->vm->def->name);
+ virObjectRef(ev->vm);
+ ret = qemuMonitorEnqueueEvent(mon, ev);
+ return ret
+;
+cleanup:
+ if (d->device)
+ VIR_FREE(d->device);
+ VIR_FREE(ev);
return ret;
}
@@ -1446,15 +1580,73 @@ qemuMonitorEmitGraphics(qemuMonitorPtr mon,
const char *remoteService,
const char *authScheme,
const char *x509dname,
- const char *saslUsername)
+ const char *saslUsername,
+ long long seconds, unsigned int micros)
{
int ret = -1;
- VIR_DEBUG("mon=%p", mon);
+ qemuEventPtr ev;
+ struct qemuEventGraphicsData *d;
+
+ if (VIR_ALLOC(ev) < 0){
+ return ret;
+ }
+
+ ev->ev_type = QEMU_EVENT_GRAPHICS;
+ ev->vm = mon->vm;
+ ev->seconds = seconds;
+ ev->micros = micros;
+ d = &(ev->evData.ev_graphics);
+
+ d->phase = phase;
+ d->localFamilyID = localFamily;
+ d->remoteFamilyID = remoteFamily;
+
+ if (VIR_STRDUP((d->localNode), localNode) < 0) {
+ goto cleanup;
+ }
+
+ if (VIR_STRDUP((d->localService), localService) < 0) {
+ goto cleanup;
+ }
+
+ if (VIR_STRDUP((d->remoteNode), remoteNode) < 0) {
+ goto cleanup;
+ }
+
+ if (VIR_STRDUP((d->remoteService), remoteService) < 0) {
+ goto cleanup;
+ }
+
+ if (VIR_STRDUP((d->authScheme), authScheme) < 0) {
+ goto cleanup;
+ }
+
+ if (VIR_STRDUP((d->x509dname), x509dname) < 0) {
+ goto cleanup;
+ }
- QEMU_MONITOR_CALLBACK(mon, ret, domainGraphics, mon->vm, phase,
- localFamily, localNode, localService,
- remoteFamily, remoteNode, remoteService,
- authScheme, x509dname, saslUsername);
+ if (VIR_STRDUP((d->saslUsername), saslUsername) < 0) {
+ goto cleanup;
+ }
+
+ VIR_DEBUG("Vm %s received Graphics event", mon->vm->def->name);
+ virObjectRef(ev->vm);
+ return ret;
+
+cleanup:
+ if (d->localNode)
+ VIR_FREE(d->localNode);
+ if (d->localService)
+ VIR_FREE(d->localService);
+ if (d->remoteNode)
+ VIR_FREE(d->remoteNode);
+ if (d->remoteService)
+ VIR_FREE(d->remoteService);
+ if (d->authScheme)
+ VIR_FREE(d->authScheme);
+ if (d->x509dname)
+ VIR_FREE(d->x509dname);
+ VIR_FREE(ev);
return ret;
}
@@ -1462,50 +1654,101 @@ qemuMonitorEmitGraphics(qemuMonitorPtr mon,
int
qemuMonitorEmitTrayChange(qemuMonitorPtr mon,
const char *devAlias,
- int reason)
+ int reason,
+ long long seconds,
+ unsigned int micros)
{
int ret = -1;
- VIR_DEBUG("mon=%p", mon);
+ qemuEventPtr ev;
+ struct qemuEventTrayChangeData *d;
- QEMU_MONITOR_CALLBACK(mon, ret, domainTrayChange, mon->vm,
- devAlias, reason);
+ if (VIR_ALLOC(ev) < 0){
+ return ret;
+ }
+ ev->ev_type = QEMU_EVENT_DEVICE_TRAY_MOVED;
+ ev->vm = mon->vm;
+ ev->seconds = seconds;
+ ev->micros = micros;
+ d = &(ev->evData.ev_tray);
+
+ if (VIR_STRDUP((d->devAlias), devAlias) < 0) {
+ VIR_FREE(ev);
+ return ret;
+ }
+ d->reason = reason;
+ VIR_DEBUG("Vm %s received tray change event",
mon->vm->def->name);
+ virObjectRef(ev->vm);
+ ret = qemuMonitorEnqueueEvent(mon, ev);
return ret;
}
int
-qemuMonitorEmitPMWakeup(qemuMonitorPtr mon)
+qemuMonitorEmitPMWakeup(qemuMonitorPtr mon, long long seconds,
+ unsigned int micros)
{
int ret = -1;
- VIR_DEBUG("mon=%p", mon);
+ qemuEventPtr ev;
+
+ if (VIR_ALLOC(ev) < 0){
+ return ret;
+ }
- QEMU_MONITOR_CALLBACK(mon, ret, domainPMWakeup, mon->vm);
+ ev->ev_type = QEMU_EVENT_WAKEUP;
+ ev->vm = mon->vm;
+ ev->seconds = seconds;
+ ev->micros = micros;
+ VIR_DEBUG("Vm %s received PM Wakeup event", mon->vm->def->name);
+ virObjectRef(ev->vm);
+ ret = qemuMonitorEnqueueEvent(mon, ev);
return ret;
}
int
-qemuMonitorEmitPMSuspend(qemuMonitorPtr mon)
+qemuMonitorEmitPMSuspend(qemuMonitorPtr mon, long long seconds,
+ unsigned int micros)
{
int ret = -1;
- VIR_DEBUG("mon=%p", mon);
+ qemuEventPtr ev;
- QEMU_MONITOR_CALLBACK(mon, ret, domainPMSuspend, mon->vm);
+ if (VIR_ALLOC(ev) < 0){
+ return ret;
+ }
+ ev->ev_type = QEMU_EVENT_SUSPEND;
+ ev->vm = mon->vm;
+ ev->seconds = seconds;
+ ev->micros = micros;
+
+ VIR_DEBUG("Vm %s received PM Suspend event", mon->vm->def->name);
+ virObjectRef(ev->vm);
+ ret = qemuMonitorEnqueueEvent(mon, ev);
return ret;
}
int
-qemuMonitorEmitPMSuspendDisk(qemuMonitorPtr mon)
+qemuMonitorEmitPMSuspendDisk(qemuMonitorPtr mon, long long seconds,
+ unsigned int micros)
{
int ret = -1;
- VIR_DEBUG("mon=%p", mon);
+ qemuEventPtr ev;
- QEMU_MONITOR_CALLBACK(mon, ret, domainPMSuspendDisk, mon->vm);
+ if (VIR_ALLOC(ev) < 0){
+ return ret;
+ }
+
+ ev->ev_type = QEMU_EVENT_SUSPEND_DISK;
+ ev->vm = mon->vm;
+ ev->seconds = seconds;
+ ev->micros = micros;
+ VIR_DEBUG("Vm %s received PM Suspend Disk event",
mon->vm->def->name);
+ virObjectRef(ev->vm);
+ ret = qemuMonitorEnqueueEvent(mon, ev);
return ret;
}
@@ -1514,51 +1757,122 @@ int
qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
const char *diskAlias,
int type,
- int status)
+ int status, long long seconds,
+ unsigned int micros)
{
int ret = -1;
- VIR_DEBUG("mon=%p", mon);
+ qemuEventPtr ev;
+ struct qemuEventBlockJobData *d = NULL;
+ if (VIR_ALLOC(ev) < 0){
+ return ret;
+ }
+
+ ev->ev_type = QEMU_EVENT_BLOCK_JOB;
+ ev->vm = mon->vm;
+ ev->seconds = seconds;
+ ev->micros = micros;
+ d = &(ev->evData.ev_blockJob);
+
+ if (VIR_STRDUP(d->device, diskAlias) < 0) {
+ VIR_FREE(ev);
+ return ret;
+ }
- QEMU_MONITOR_CALLBACK(mon, ret, domainBlockJob, mon->vm,
- diskAlias, type, status);
+ d->type = type;
+ d->status = status;
+ VIR_DEBUG("Vm %s received Block Job event", mon->vm->def->name);
+ virObjectRef(ev->vm);
+ ret = qemuMonitorEnqueueEvent(mon, ev);
return ret;
}
int
qemuMonitorEmitBalloonChange(qemuMonitorPtr mon,
- unsigned long long actual)
+ unsigned long long actual,
+ long long seconds,
+ unsigned int micros)
{
int ret = -1;
- VIR_DEBUG("mon=%p", mon);
+ qemuEventPtr ev;
+
+ if (VIR_ALLOC(ev) < 0){
+ return ret;
+ }
+
+ ev->ev_type = QEMU_EVENT_BALLOON_CHANGE;
+ ev->vm = mon->vm;
+ ev->seconds = seconds;
+ ev->micros = micros;
+ ev->evData.ev_balloon.actual = actual;
- QEMU_MONITOR_CALLBACK(mon, ret, domainBalloonChange, mon->vm, actual);
+ VIR_DEBUG("Vm %s received balloon change event",
mon->vm->def->name);
+ virObjectRef(ev->vm);
+ ret = qemuMonitorEnqueueEvent(mon, ev);
return ret;
}
int
qemuMonitorEmitDeviceDeleted(qemuMonitorPtr mon,
- const char *devAlias)
+ const char *devAlias,
+ long long seconds,
+ unsigned int micros)
{
int ret = -1;
- VIR_DEBUG("mon=%p", mon);
+ qemuEventPtr ev;
+ struct qemuEventDeviceDeletedData *d = NULL;
- QEMU_MONITOR_CALLBACK(mon, ret, domainDeviceDeleted, mon->vm, devAlias);
+ if (VIR_ALLOC(ev) < 0){
+ return ret;
+ }
+ ev->ev_type = QEMU_EVENT_DEVICE_DELETED;
+ ev->vm = mon->vm;
+ ev->seconds = seconds;
+ ev->micros = micros;
+ d = &(ev->evData.ev_deviceDel);
+
+ if (VIR_STRDUP(d->device, devAlias) < 0) {
+ VIR_FREE(ev);
+ return ret;
+ }
+ VIR_DEBUG("Vm %s received device deleted event for %s",
mon->vm->def->name,
+ devAlias);
+ virObjectRef(ev->vm);
+ ret = qemuMonitorEnqueueEvent(mon, ev);
return ret;
}
int
qemuMonitorEmitNicRxFilterChanged(qemuMonitorPtr mon,
- const char *devAlias)
+ const char *devAlias,
+ long long seconds,
+ unsigned int micros)
{
int ret = -1;
- VIR_DEBUG("mon=%p", mon);
+ qemuEventPtr ev;
+ struct qemuEventNicRxFilterChangeData *d = NULL;
+
+ if (VIR_ALLOC(ev) < 0){
+ return ret;
+ }
- QEMU_MONITOR_CALLBACK(mon, ret, domainNicRxFilterChanged, mon->vm, devAlias);
+ ev->ev_type = QEMU_EVENT_NIC_RX_FILTER_CHANGED;
+ ev->vm = mon->vm;
+ ev->seconds = seconds;
+ ev->micros = micros;
+ d = &(ev->evData.ev_nic);
+ if (VIR_STRDUP(d->devAlias, devAlias) < 0) {
+ VIR_FREE(ev);
+ return ret;
+ }
+ VIR_DEBUG("Vm %s received nic RX filter change event for %s",
mon->vm->def->name,
+ devAlias);
+ virObjectRef(ev->vm);
+ ret = qemuMonitorEnqueueEvent(mon, ev);
return ret;
}
@@ -1566,52 +1880,110 @@ qemuMonitorEmitNicRxFilterChanged(qemuMonitorPtr mon,
int
qemuMonitorEmitSerialChange(qemuMonitorPtr mon,
const char *devAlias,
- bool connected)
+ bool connected,
+ long long seconds,
+ unsigned int micros)
{
int ret = -1;
- VIR_DEBUG("mon=%p, devAlias='%s', connected=%d", mon, devAlias,
connected);
+ qemuEventPtr ev;
+ struct qemuEventSerialChangeData *d = NULL;
+
+ if (VIR_ALLOC(ev) < 0){
+ return ret;
+ }
- QEMU_MONITOR_CALLBACK(mon, ret, domainSerialChange, mon->vm, devAlias,
connected);
+ ev->ev_type = QEMU_EVENT_SERIAL_CHANGE;
+ ev->vm = mon->vm;
+ ev->seconds = seconds;
+ ev->micros = micros;
+ d = &(ev->evData.ev_serial);
+ d->connected = connected;
+ if (VIR_STRDUP(d->devAlias, devAlias) < 0) {
+ VIR_FREE(ev);
+ return ret;
+ }
+ VIR_DEBUG("Vm %s received Serial change event for %s",
mon->vm->def->name,
+ devAlias);
+ virObjectRef(ev->vm);
+ ret = qemuMonitorEnqueueEvent(mon, ev);
return ret;
}
int
-qemuMonitorEmitSpiceMigrated(qemuMonitorPtr mon)
+qemuMonitorEmitSpiceMigrated(qemuMonitorPtr mon, long long seconds,
+ unsigned int micros)
{
int ret = -1;
- VIR_DEBUG("mon=%p", mon);
+ qemuEventPtr ev;
+
+ if (VIR_ALLOC(ev) < 0){
+ return ret;
+ }
- QEMU_MONITOR_CALLBACK(mon, ret, domainSpiceMigrated, mon->vm);
+ ev->ev_type = QEMU_EVENT_SPICE_MIGRATED;
+ ev->vm = mon->vm;
+ ev->seconds = seconds;
+ ev->micros = micros;
+ VIR_DEBUG("Vm %s received spice migrated event",
mon->vm->def->name);
+ virObjectRef(ev->vm);
+ ret = qemuMonitorEnqueueEvent(mon, ev);
return ret;
}
int
qemuMonitorEmitMigrationStatus(qemuMonitorPtr mon,
- int status)
+ int status,
+ long long seconds,
+ unsigned int micros)
{
int ret = -1;
- VIR_DEBUG("mon=%p, status=%s",
- mon, NULLSTR(qemuMonitorMigrationStatusTypeToString(status)));
+ qemuEventPtr ev;
- QEMU_MONITOR_CALLBACK(mon, ret, domainMigrationStatus, mon->vm, status);
+ if (VIR_ALLOC(ev) < 0){
+ return ret;
+ }
+ ev->ev_type = QEMU_EVENT_MIGRATION;
+ ev->vm = mon->vm;
+ ev->seconds = seconds;
+ ev->micros = micros;
+ ev->evData.ev_migStatus.status = status;
+
+ VIR_DEBUG("Vm %s received migration status %s",
mon->vm->def->name,
+ NULLSTR(qemuMonitorMigrationStatusTypeToString(status)));
+ virObjectRef(ev->vm);
+ ret = qemuMonitorEnqueueEvent(mon, ev);
return ret;
}
int
qemuMonitorEmitMigrationPass(qemuMonitorPtr mon,
- int pass)
+ int pass,
+ long long seconds,
+ unsigned int micros)
{
int ret = -1;
- VIR_DEBUG("mon=%p, pass=%d", mon, pass);
+ qemuEventPtr ev;
+
+ if (VIR_ALLOC(ev) < 0){
+ return ret;
+ }
- QEMU_MONITOR_CALLBACK(mon, ret, domainMigrationPass, mon->vm, pass);
+ ev->ev_type = QEMU_EVENT_MIGRATION_PASS;
+ ev->vm = mon->vm;
+ ev->seconds = seconds;
+ ev->micros = micros;
+ ev->evData.ev_migPass.pass = pass;
+ VIR_DEBUG("Vm %s received migration pass %d", mon->vm->def->name,
+ pass);
+ virObjectRef(ev->vm);
+ ret = qemuMonitorEnqueueEvent(mon, ev);
return ret;
}
@@ -1622,15 +1994,49 @@ qemuMonitorEmitAcpiOstInfo(qemuMonitorPtr mon,
const char *slotType,
const char *slot,
unsigned int source,
- unsigned int status)
+ unsigned int status,
+ long long seconds,
+ unsigned int micros)
{
int ret = -1;
- VIR_DEBUG("mon=%p, alias='%s', slotType='%s', slot='%s',
source='%u' status=%u",
- mon, NULLSTR(alias), slotType, slot, source, status);
+ qemuEventPtr ev;
+ struct qemuEventAcpiOstInfoData *d = NULL;
+
+ if (VIR_ALLOC(ev) < 0){
+ return ret;
+ }
+
+ ev->ev_type = QEMU_EVENT_ACPI_OST;
+ ev->vm = mon->vm;
+ ev->seconds = seconds;
+ ev->micros = micros;
+ ev->evData.ev_acpi.source = source;
+ ev->evData.ev_acpi.status = status;
+
+ d = &(ev->evData.ev_acpi);
+
+ if (VIR_STRDUP(d->alias, alias) < 0) {
+ goto cleanup;
+ }
+ if (VIR_STRDUP(d->slotType, slotType) < 0) {
+ goto cleanup;
+ }
+ if (VIR_STRDUP(d->slot, slot) < 0) {
+ goto cleanup;
+ }
- QEMU_MONITOR_CALLBACK(mon, ret, domainAcpiOstInfo, mon->vm,
- alias, slotType, slot, source, status);
+ VIR_DEBUG("Vm %s received ACPI OST event: alias[%s] slotType [%s]
slot[%s]"
+ " status[%d]", mon->vm->def->name, alias, slotType,
slot, status);
+ virObjectRef(ev->vm);
+ ret = qemuMonitorEnqueueEvent(mon, ev);
+ return ret;
+cleanup:
+ if (d->alias)
+ VIR_FREE(d->alias);
+ if (d->slotType)
+ VIR_FREE(d->slotType);
+ VIR_FREE(ev);
return ret;
}
@@ -1639,16 +2045,36 @@ int
qemuMonitorEmitBlockThreshold(qemuMonitorPtr mon,
const char *nodename,
unsigned long long threshold,
- unsigned long long excess)
+ unsigned long long excess,
+ long long seconds,
+ unsigned int micros)
{
int ret = -1;
+ qemuEventPtr ev;
+ struct qemuEventBlockThresholdData *d = NULL;
- VIR_DEBUG("mon=%p, node-name='%s', threshold='%llu',
excess='%llu'",
- mon, nodename, threshold, excess);
+ if (VIR_ALLOC(ev) < 0){
+ return ret;
+ }
+
+ ev->ev_type = QEMU_EVENT_BLOCK_WRITE_THRESHOLD;
+ ev->vm = mon->vm;
+ ev->seconds = seconds;
+ ev->micros = micros;
+ ev->evData.ev_threshold.threshold = threshold;
+ ev->evData.ev_threshold.excess = excess;
- QEMU_MONITOR_CALLBACK(mon, ret, domainBlockThreshold, mon->vm,
- nodename, threshold, excess);
+ d = &(ev->evData.ev_threshold);
+ if (VIR_STRDUP(d->nodename, nodename) < 0) {
+ VIR_FREE(ev);
+ return ret;
+ }
+ VIR_DEBUG("Vm %s received Block Threshold event:"
+ "node-name='%s', threshold='%llu',
excess='%llu'",
+ mon->vm->def->name, nodename, threshold, excess);
+ virObjectRef(ev->vm);
+ ret = qemuMonitorEnqueueEvent(mon, ev);
return ret;
}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index d9c27ac..7b5a984 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -35,6 +35,7 @@
# include "device_conf.h"
# include "cpu/cpu.h"
# include "util/virgic.h"
+# include "qemu_event.h"
typedef struct _qemuMonitor qemuMonitor;
typedef qemuMonitor *qemuMonitorPtr;
@@ -89,7 +90,7 @@ struct _qemuMonitorEventPanicInfoHyperv {
};
typedef struct _qemuMonitorEventPanicInfo qemuMonitorEventPanicInfo;
-typedef qemuMonitorEventPanicInfo *qemuMonitorEventPanicInfoPtr;
+typedef qemuMonitorEventPanicInfo * qemuMonitorEventPanicInfoPtr;
struct _qemuMonitorEventPanicInfo {
qemuMonitorEventPanicInfoType type;
union {
@@ -128,6 +129,10 @@ typedef int (*qemuMonitorDomainEventCallback)(qemuMonitorPtr mon,
unsigned int micros,
const char *details,
void *opaque);
+typedef int (*qemuMonitorDomainEnqueueEventCallback)(qemuMonitorPtr mon,
+ virDomainObjPtr vm,
+ qemuEventPtr ev,
+ void *opaque);
typedef int (*qemuMonitorDomainShutdownCallback)(qemuMonitorPtr mon,
virDomainObjPtr vm,
virTristateBool guest,
@@ -254,6 +259,7 @@ struct _qemuMonitorCallbacks {
qemuMonitorErrorNotifyCallback errorNotify;
qemuMonitorDiskSecretLookupCallback diskSecretLookup;
qemuMonitorDomainEventCallback domainEvent;
+ qemuMonitorDomainEnqueueEventCallback domainEnqueueEvent;
qemuMonitorDomainShutdownCallback domainShutdown;
qemuMonitorDomainResetCallback domainReset;
qemuMonitorDomainPowerdownCallback domainPowerdown;
@@ -345,17 +351,25 @@ int qemuMonitorGetDiskSecret(qemuMonitorPtr mon,
int qemuMonitorEmitEvent(qemuMonitorPtr mon, const char *event,
long long seconds, unsigned int micros,
const char *details);
-int qemuMonitorEmitShutdown(qemuMonitorPtr mon, virTristateBool guest);
-int qemuMonitorEmitReset(qemuMonitorPtr mon);
-int qemuMonitorEmitPowerdown(qemuMonitorPtr mon);
-int qemuMonitorEmitStop(qemuMonitorPtr mon);
-int qemuMonitorEmitResume(qemuMonitorPtr mon);
-int qemuMonitorEmitRTCChange(qemuMonitorPtr mon, long long offset);
-int qemuMonitorEmitWatchdog(qemuMonitorPtr mon, int action);
+int qemuMonitorEmitShutdown(qemuMonitorPtr mon, virTristateBool guest,
+ long long seconds, unsigned int micros);
+int qemuMonitorEmitReset(qemuMonitorPtr mon,
+ long long seconds, unsigned int micros);
+int qemuMonitorEmitPowerdown(qemuMonitorPtr mon,
+ long long seconds, unsigned int micros);
+int qemuMonitorEmitStop(qemuMonitorPtr mon,
+ long long seconds, unsigned int micros);
+int qemuMonitorEmitResume(qemuMonitorPtr mon,
+ long long seconds, unsigned int micros);
+int qemuMonitorEmitRTCChange(qemuMonitorPtr mon, long long offset,
+ long long seconds, unsigned int micros);
+int qemuMonitorEmitWatchdog(qemuMonitorPtr mon, int action,
+ long long seconds, unsigned int micros);
int qemuMonitorEmitIOError(qemuMonitorPtr mon,
const char *diskAlias,
int action,
- const char *reason);
+ const char *reason,
+ long long seconds, unsigned int micros);
int qemuMonitorEmitGraphics(qemuMonitorPtr mon,
int phase,
int localFamily,
@@ -366,45 +380,61 @@ int qemuMonitorEmitGraphics(qemuMonitorPtr mon,
const char *remoteService,
const char *authScheme,
const char *x509dname,
- const char *saslUsername);
+ const char *saslUsername,
+ long long seconds, unsigned int micros);
int qemuMonitorEmitTrayChange(qemuMonitorPtr mon,
const char *devAlias,
- int reason);
-int qemuMonitorEmitPMWakeup(qemuMonitorPtr mon);
-int qemuMonitorEmitPMSuspend(qemuMonitorPtr mon);
+ int reason,
+ long long seconds, unsigned int micros);
+int qemuMonitorEmitPMWakeup(qemuMonitorPtr mon,
+ long long seconds, unsigned int micros);
+int qemuMonitorEmitPMSuspend(qemuMonitorPtr mon,
+ long long seconds, unsigned int micros);
int qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
const char *diskAlias,
int type,
- int status);
+ int status,
+ long long seconds, unsigned int micros);
int qemuMonitorEmitBalloonChange(qemuMonitorPtr mon,
- unsigned long long actual);
-int qemuMonitorEmitPMSuspendDisk(qemuMonitorPtr mon);
+ unsigned long long actual,
+ long long seconds, unsigned int micros);
+int qemuMonitorEmitPMSuspendDisk(qemuMonitorPtr mon,
+ long long seconds, unsigned int micros);
int qemuMonitorEmitGuestPanic(qemuMonitorPtr mon,
- qemuMonitorEventPanicInfoPtr info);
+ qemuMonitorEventPanicInfoPtr info,
+ long long seconds, unsigned int micros);
int qemuMonitorEmitDeviceDeleted(qemuMonitorPtr mon,
- const char *devAlias);
+ const char *devAlias,
+ long long seconds, unsigned int micros);
int qemuMonitorEmitNicRxFilterChanged(qemuMonitorPtr mon,
- const char *devAlias);
+ const char *devAlias,
+ long long seconds, unsigned int micros);
int qemuMonitorEmitSerialChange(qemuMonitorPtr mon,
const char *devAlias,
- bool connected);
-int qemuMonitorEmitSpiceMigrated(qemuMonitorPtr mon);
+ bool connected,
+ long long seconds, unsigned int micros);
+int qemuMonitorEmitSpiceMigrated(qemuMonitorPtr mon,
+ long long seconds, unsigned int micros);
int qemuMonitorEmitMigrationStatus(qemuMonitorPtr mon,
- int status);
+ int status,
+ long long seconds, unsigned int micros);
int qemuMonitorEmitMigrationPass(qemuMonitorPtr mon,
- int pass);
+ int pass,
+ long long seconds, unsigned int micros);
int qemuMonitorEmitAcpiOstInfo(qemuMonitorPtr mon,
const char *alias,
const char *slotType,
const char *slot,
unsigned int source,
- unsigned int status);
+ unsigned int status,
+ long long seconds, unsigned int micros);
int qemuMonitorEmitBlockThreshold(qemuMonitorPtr mon,
const char *nodename,
unsigned long long threshold,
- unsigned long long excess);
+ unsigned long long excess,
+ long long seconds, unsigned int micros);
int qemuMonitorStartCPUs(qemuMonitorPtr mon,
virConnectPtr conn);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index a9070fe..b4c7118 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -59,41 +59,73 @@ VIR_LOG_INIT("qemu.qemu_monitor_json");
#define LINE_ENDING "\r\n"
-static void qemuMonitorJSONHandleShutdown(qemuMonitorPtr mon, virJSONValuePtr data);
-static void qemuMonitorJSONHandleReset(qemuMonitorPtr mon, virJSONValuePtr data);
-static void qemuMonitorJSONHandlePowerdown(qemuMonitorPtr mon, virJSONValuePtr data);
-static void qemuMonitorJSONHandleStop(qemuMonitorPtr mon, virJSONValuePtr data);
-static void qemuMonitorJSONHandleResume(qemuMonitorPtr mon, virJSONValuePtr data);
-static void qemuMonitorJSONHandleRTCChange(qemuMonitorPtr mon, virJSONValuePtr data);
-static void qemuMonitorJSONHandleWatchdog(qemuMonitorPtr mon, virJSONValuePtr data);
-static void qemuMonitorJSONHandleIOError(qemuMonitorPtr mon, virJSONValuePtr data);
-static void qemuMonitorJSONHandleVNCConnect(qemuMonitorPtr mon, virJSONValuePtr data);
-static void qemuMonitorJSONHandleVNCInitialize(qemuMonitorPtr mon, virJSONValuePtr
data);
-static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitorPtr mon, virJSONValuePtr
data);
-static void qemuMonitorJSONHandleSPICEConnect(qemuMonitorPtr mon, virJSONValuePtr data);
-static void qemuMonitorJSONHandleSPICEInitialize(qemuMonitorPtr mon, virJSONValuePtr
data);
-static void qemuMonitorJSONHandleSPICEDisconnect(qemuMonitorPtr mon, virJSONValuePtr
data);
-static void qemuMonitorJSONHandleTrayChange(qemuMonitorPtr mon, virJSONValuePtr data);
-static void qemuMonitorJSONHandlePMWakeup(qemuMonitorPtr mon, virJSONValuePtr data);
-static void qemuMonitorJSONHandlePMSuspend(qemuMonitorPtr mon, virJSONValuePtr data);
-static void qemuMonitorJSONHandleBlockJobCompleted(qemuMonitorPtr mon, virJSONValuePtr
data);
-static void qemuMonitorJSONHandleBlockJobCanceled(qemuMonitorPtr mon, virJSONValuePtr
data);
-static void qemuMonitorJSONHandleBlockJobReady(qemuMonitorPtr mon, virJSONValuePtr
data);
-static void qemuMonitorJSONHandleBalloonChange(qemuMonitorPtr mon, virJSONValuePtr
data);
-static void qemuMonitorJSONHandlePMSuspendDisk(qemuMonitorPtr mon, virJSONValuePtr
data);
-static void qemuMonitorJSONHandleGuestPanic(qemuMonitorPtr mon, virJSONValuePtr data);
-static void qemuMonitorJSONHandleDeviceDeleted(qemuMonitorPtr mon, virJSONValuePtr
data);
-static void qemuMonitorJSONHandleNicRxFilterChanged(qemuMonitorPtr mon, virJSONValuePtr
data);
-static void qemuMonitorJSONHandleSerialChange(qemuMonitorPtr mon, virJSONValuePtr data);
-static void qemuMonitorJSONHandleSpiceMigrated(qemuMonitorPtr mon, virJSONValuePtr
data);
-static void qemuMonitorJSONHandleMigrationStatus(qemuMonitorPtr mon, virJSONValuePtr
data);
-static void qemuMonitorJSONHandleMigrationPass(qemuMonitorPtr mon, virJSONValuePtr
data);
-static void qemuMonitorJSONHandleAcpiOstInfo(qemuMonitorPtr mon, virJSONValuePtr data);
-static void qemuMonitorJSONHandleBlockThreshold(qemuMonitorPtr mon, virJSONValuePtr
data);
+static void qemuMonitorJSONHandleShutdown(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
+static void qemuMonitorJSONHandleReset(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
+static void qemuMonitorJSONHandlePowerdown(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
+static void qemuMonitorJSONHandleStop(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
+static void qemuMonitorJSONHandleResume(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
+static void qemuMonitorJSONHandleRTCChange(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
+static void qemuMonitorJSONHandleWatchdog(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
+static void qemuMonitorJSONHandleIOError(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
+static void qemuMonitorJSONHandleVNCConnect(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
+static void qemuMonitorJSONHandleVNCInitialize(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
+static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
+static void qemuMonitorJSONHandleSPICEConnect(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
+static void qemuMonitorJSONHandleSPICEInitialize(qemuMonitorPtr mon, virJSONValuePtr
data,
+ long long seconds, unsigned int
micros);
+static void qemuMonitorJSONHandleSPICEDisconnect(qemuMonitorPtr mon, virJSONValuePtr
data,
+ long long seconds, unsigned int
micros);
+static void qemuMonitorJSONHandleTrayChange(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
+static void qemuMonitorJSONHandlePMWakeup(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
+static void qemuMonitorJSONHandlePMSuspend(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
+static void qemuMonitorJSONHandleBlockJobCompleted(qemuMonitorPtr mon, virJSONValuePtr
data,
+ long long seconds, unsigned int
micros);
+static void qemuMonitorJSONHandleBlockJobCanceled(qemuMonitorPtr mon, virJSONValuePtr
data,
+ long long seconds, unsigned int
micros);
+static void qemuMonitorJSONHandleBlockJobReady(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
+static void qemuMonitorJSONHandleBalloonChange(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
+static void qemuMonitorJSONHandlePMSuspendDisk(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
+static void qemuMonitorJSONHandleGuestPanic(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
+static void qemuMonitorJSONHandleDeviceDeleted(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
+static void qemuMonitorJSONHandleNicRxFilterChanged(qemuMonitorPtr mon, virJSONValuePtr
data,
+ long long seconds, unsigned int
micros);
+static void qemuMonitorJSONHandleSerialChange(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
+static void qemuMonitorJSONHandleSpiceMigrated(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
+static void qemuMonitorJSONHandleMigrationStatus(qemuMonitorPtr mon, virJSONValuePtr
data,
+ long long seconds, unsigned int
micros);
+static void qemuMonitorJSONHandleMigrationPass(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
+static void qemuMonitorJSONHandleAcpiOstInfo(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
+static void qemuMonitorJSONHandleBlockThreshold(qemuMonitorPtr mon, virJSONValuePtr
data,
+ long long seconds, unsigned int micros);
typedef struct {
const char *type;
- void (*handler)(qemuMonitorPtr mon, virJSONValuePtr data);
+ void (*handler)(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros);
} qemuEventHandler;
static qemuEventHandler eventHandlers[] = {
@@ -146,7 +178,6 @@ qemuMonitorJSONIOProcessEvent(qemuMonitorPtr mon,
const char *type;
qemuEventHandler *handler;
virJSONValuePtr data;
- char *details = NULL;
virJSONValuePtr timestamp;
long long seconds = -1;
unsigned int micros = 0;
@@ -161,23 +192,20 @@ qemuMonitorJSONIOProcessEvent(qemuMonitorPtr mon,
}
/* Not all events have data; and event reporting is best-effort only */
- if ((data = virJSONValueObjectGet(obj, "data")))
- details = virJSONValueToString(data, false);
+ ignore_value(data = virJSONValueObjectGet(obj, "data"));
if ((timestamp = virJSONValueObjectGet(obj, "timestamp"))) {
ignore_value(virJSONValueObjectGetNumberLong(timestamp, "seconds",
&seconds));
ignore_value(virJSONValueObjectGetNumberUint(timestamp,
"microseconds",
µs));
}
- qemuMonitorEmitEvent(mon, type, seconds, micros, details);
- VIR_FREE(details);
handler = bsearch(type, eventHandlers, ARRAY_CARDINALITY(eventHandlers),
sizeof(eventHandlers[0]), qemuMonitorEventCompare);
if (handler) {
VIR_DEBUG("handle %s handler=%p data=%p", type,
handler->handler, data);
- (handler->handler)(mon, data);
+ (handler->handler)(mon, data, seconds, micros);
}
return 0;
}
@@ -523,7 +551,8 @@ qemuMonitorJSONKeywordStringToJSON(const char *str, const char
*firstkeyword)
}
-static void qemuMonitorJSONHandleShutdown(qemuMonitorPtr mon, virJSONValuePtr data)
+static void qemuMonitorJSONHandleShutdown(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros)
{
bool guest = false;
virTristateBool guest_initiated = VIR_TRISTATE_BOOL_ABSENT;
@@ -531,27 +560,35 @@ static void qemuMonitorJSONHandleShutdown(qemuMonitorPtr mon,
virJSONValuePtr da
if (data && virJSONValueObjectGetBoolean(data, "guest", &guest)
== 0)
guest_initiated = guest ? VIR_TRISTATE_BOOL_YES : VIR_TRISTATE_BOOL_NO;
- qemuMonitorEmitShutdown(mon, guest_initiated);
+ qemuMonitorEmitShutdown(mon, guest_initiated, seconds, micros);
}
-static void qemuMonitorJSONHandleReset(qemuMonitorPtr mon, virJSONValuePtr data
ATTRIBUTE_UNUSED)
+static void qemuMonitorJSONHandleReset(qemuMonitorPtr mon,
+ virJSONValuePtr data ATTRIBUTE_UNUSED,
+ long long seconds, unsigned int micros)
{
- qemuMonitorEmitReset(mon);
+ qemuMonitorEmitReset(mon, seconds, micros);
}
-static void qemuMonitorJSONHandlePowerdown(qemuMonitorPtr mon, virJSONValuePtr data
ATTRIBUTE_UNUSED)
+static void qemuMonitorJSONHandlePowerdown(qemuMonitorPtr mon,
+ virJSONValuePtr data ATTRIBUTE_UNUSED,
+ long long seconds, unsigned int micros)
{
- qemuMonitorEmitPowerdown(mon);
+ qemuMonitorEmitPowerdown(mon, seconds, micros);
}
-static void qemuMonitorJSONHandleStop(qemuMonitorPtr mon, virJSONValuePtr data
ATTRIBUTE_UNUSED)
+static void qemuMonitorJSONHandleStop(qemuMonitorPtr mon,
+ virJSONValuePtr data ATTRIBUTE_UNUSED,
+ long long seconds, unsigned int micros)
{
- qemuMonitorEmitStop(mon);
+ qemuMonitorEmitStop(mon, seconds, micros);
}
-static void qemuMonitorJSONHandleResume(qemuMonitorPtr mon, virJSONValuePtr data
ATTRIBUTE_UNUSED)
+static void qemuMonitorJSONHandleResume(qemuMonitorPtr mon,
+ virJSONValuePtr data ATTRIBUTE_UNUSED,
+ long long seconds, unsigned int micros)
{
- qemuMonitorEmitResume(mon);
+ qemuMonitorEmitResume(mon, seconds, micros);
}
@@ -599,7 +636,9 @@ qemuMonitorJSONGuestPanicExtractInfo(virJSONValuePtr data)
static void
qemuMonitorJSONHandleGuestPanic(qemuMonitorPtr mon,
- virJSONValuePtr data)
+ virJSONValuePtr data,
+ long long seconds,
+ unsigned int micros)
{
virJSONValuePtr infojson = virJSONValueObjectGetObject(data, "info");
qemuMonitorEventPanicInfoPtr info = NULL;
@@ -607,25 +646,27 @@ qemuMonitorJSONHandleGuestPanic(qemuMonitorPtr mon,
if (infojson)
info = qemuMonitorJSONGuestPanicExtractInfo(infojson);
- qemuMonitorEmitGuestPanic(mon, info);
+ qemuMonitorEmitGuestPanic(mon, info, seconds, micros);
}
-static void qemuMonitorJSONHandleRTCChange(qemuMonitorPtr mon, virJSONValuePtr data)
+static void qemuMonitorJSONHandleRTCChange(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros)
{
long long offset = 0;
if (virJSONValueObjectGetNumberLong(data, "offset", &offset) < 0) {
VIR_WARN("missing offset in RTC change event");
offset = 0;
}
- qemuMonitorEmitRTCChange(mon, offset);
+ qemuMonitorEmitRTCChange(mon, offset, seconds, micros);
}
VIR_ENUM_DECL(qemuMonitorWatchdogAction)
VIR_ENUM_IMPL(qemuMonitorWatchdogAction, VIR_DOMAIN_EVENT_WATCHDOG_LAST,
"none", "pause", "reset",
"poweroff", "shutdown", "debug", "inject-nmi");
-static void qemuMonitorJSONHandleWatchdog(qemuMonitorPtr mon, virJSONValuePtr data)
+static void qemuMonitorJSONHandleWatchdog(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros)
{
const char *action;
int actionID;
@@ -639,7 +680,7 @@ static void qemuMonitorJSONHandleWatchdog(qemuMonitorPtr mon,
virJSONValuePtr da
} else {
actionID = VIR_DOMAIN_EVENT_WATCHDOG_NONE;
}
- qemuMonitorEmitWatchdog(mon, actionID);
+ qemuMonitorEmitWatchdog(mon, actionID, seconds, micros);
}
VIR_ENUM_DECL(qemuMonitorIOErrorAction)
@@ -648,7 +689,8 @@ VIR_ENUM_IMPL(qemuMonitorIOErrorAction,
VIR_DOMAIN_EVENT_IO_ERROR_LAST,
static void
-qemuMonitorJSONHandleIOError(qemuMonitorPtr mon, virJSONValuePtr data)
+qemuMonitorJSONHandleIOError(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros)
{
const char *device;
const char *action;
@@ -676,7 +718,7 @@ qemuMonitorJSONHandleIOError(qemuMonitorPtr mon, virJSONValuePtr
data)
actionID = VIR_DOMAIN_EVENT_IO_ERROR_NONE;
}
- qemuMonitorEmitIOError(mon, device, actionID, reason);
+ qemuMonitorEmitIOError(mon, device, actionID, reason, seconds, micros);
}
@@ -688,7 +730,8 @@ VIR_ENUM_IMPL(qemuMonitorGraphicsAddressFamily,
static void
qemuMonitorJSONHandleGraphicsVNC(qemuMonitorPtr mon,
virJSONValuePtr data,
- int phase)
+ int phase,
+ long long seconds, unsigned int micros)
{
const char *localNode, *localService, *localFamily;
const char *remoteNode, *remoteService, *remoteFamily;
@@ -753,31 +796,39 @@ qemuMonitorJSONHandleGraphicsVNC(qemuMonitorPtr mon,
qemuMonitorEmitGraphics(mon, phase,
localFamilyID, localNode, localService,
remoteFamilyID, remoteNode, remoteService,
- authScheme, x509dname, saslUsername);
+ authScheme, x509dname, saslUsername,
+ seconds, micros);
}
-static void qemuMonitorJSONHandleVNCConnect(qemuMonitorPtr mon, virJSONValuePtr data)
+static void qemuMonitorJSONHandleVNCConnect(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros)
{
- qemuMonitorJSONHandleGraphicsVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_CONNECT);
+ qemuMonitorJSONHandleGraphicsVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_CONNECT,
+ seconds, micros);
}
-static void qemuMonitorJSONHandleVNCInitialize(qemuMonitorPtr mon, virJSONValuePtr data)
+static void qemuMonitorJSONHandleVNCInitialize(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros)
{
- qemuMonitorJSONHandleGraphicsVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE);
+ qemuMonitorJSONHandleGraphicsVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE,
+ seconds, micros);
}
-static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitorPtr mon, virJSONValuePtr data)
+static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros)
{
- qemuMonitorJSONHandleGraphicsVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT);
+ qemuMonitorJSONHandleGraphicsVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT,
+ seconds, micros);
}
static void
qemuMonitorJSONHandleGraphicsSPICE(qemuMonitorPtr mon,
virJSONValuePtr data,
- int phase)
+ int phase,
+ long long seconds, unsigned int micros)
{
const char *lhost, *lport, *lfamily;
const char *rhost, *rport, *rfamily;
@@ -834,31 +885,39 @@ qemuMonitorJSONHandleGraphicsSPICE(qemuMonitorPtr mon,
}
qemuMonitorEmitGraphics(mon, phase, lfamilyID, lhost, lport, rfamilyID,
- rhost, rport, auth, NULL, NULL);
+ rhost, rport, auth, NULL, NULL,
+ seconds, micros);
}
-static void qemuMonitorJSONHandleSPICEConnect(qemuMonitorPtr mon, virJSONValuePtr data)
+static void qemuMonitorJSONHandleSPICEConnect(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros)
{
- qemuMonitorJSONHandleGraphicsSPICE(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_CONNECT);
+ qemuMonitorJSONHandleGraphicsSPICE(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_CONNECT,
+ seconds, micros);
}
-static void qemuMonitorJSONHandleSPICEInitialize(qemuMonitorPtr mon, virJSONValuePtr
data)
+static void qemuMonitorJSONHandleSPICEInitialize(qemuMonitorPtr mon, virJSONValuePtr
data,
+ long long seconds, unsigned int micros)
{
- qemuMonitorJSONHandleGraphicsSPICE(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE);
+ qemuMonitorJSONHandleGraphicsSPICE(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE,
+ seconds, micros);
}
-static void qemuMonitorJSONHandleSPICEDisconnect(qemuMonitorPtr mon, virJSONValuePtr
data)
+static void qemuMonitorJSONHandleSPICEDisconnect(qemuMonitorPtr mon, virJSONValuePtr
data,
+ long long seconds, unsigned int micros)
{
- qemuMonitorJSONHandleGraphicsSPICE(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT);
+ qemuMonitorJSONHandleGraphicsSPICE(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT,
+ seconds, micros);
}
static void
qemuMonitorJSONHandleBlockJobImpl(qemuMonitorPtr mon,
virJSONValuePtr data,
- int event)
+ int event,
+ long long seconds, unsigned int micros)
{
const char *device;
const char *type_str;
@@ -908,12 +967,13 @@ qemuMonitorJSONHandleBlockJobImpl(qemuMonitorPtr mon,
}
out:
- qemuMonitorEmitBlockJob(mon, device, type, event);
+ qemuMonitorEmitBlockJob(mon, device, type, event, seconds, micros);
}
static void
qemuMonitorJSONHandleTrayChange(qemuMonitorPtr mon,
- virJSONValuePtr data)
+ virJSONValuePtr data,
+ long long seconds, unsigned int micros)
{
const char *devAlias = NULL;
bool trayOpened;
@@ -934,50 +994,58 @@ qemuMonitorJSONHandleTrayChange(qemuMonitorPtr mon,
else
reason = VIR_DOMAIN_EVENT_TRAY_CHANGE_CLOSE;
- qemuMonitorEmitTrayChange(mon, devAlias, reason);
+ qemuMonitorEmitTrayChange(mon, devAlias, reason, seconds, micros);
}
static void
qemuMonitorJSONHandlePMWakeup(qemuMonitorPtr mon,
- virJSONValuePtr data ATTRIBUTE_UNUSED)
+ virJSONValuePtr data ATTRIBUTE_UNUSED,
+ long long seconds, unsigned int micros)
{
- qemuMonitorEmitPMWakeup(mon);
+ qemuMonitorEmitPMWakeup(mon, micros, seconds);
}
static void
qemuMonitorJSONHandlePMSuspend(qemuMonitorPtr mon,
- virJSONValuePtr data ATTRIBUTE_UNUSED)
+ virJSONValuePtr data ATTRIBUTE_UNUSED,
+ long long seconds, unsigned int micros)
{
- qemuMonitorEmitPMSuspend(mon);
+ qemuMonitorEmitPMSuspend(mon, seconds, micros);
}
static void
qemuMonitorJSONHandleBlockJobCompleted(qemuMonitorPtr mon,
- virJSONValuePtr data)
+ virJSONValuePtr data,
+ long long seconds, unsigned int micros)
{
qemuMonitorJSONHandleBlockJobImpl(mon, data,
- VIR_DOMAIN_BLOCK_JOB_COMPLETED);
+ VIR_DOMAIN_BLOCK_JOB_COMPLETED,
+ seconds, micros);
}
static void
qemuMonitorJSONHandleBlockJobCanceled(qemuMonitorPtr mon,
- virJSONValuePtr data)
+ virJSONValuePtr data,
+ long long seconds, unsigned int micros)
{
qemuMonitorJSONHandleBlockJobImpl(mon, data,
- VIR_DOMAIN_BLOCK_JOB_CANCELED);
+ VIR_DOMAIN_BLOCK_JOB_CANCELED,
+ seconds, micros);
}
static void
qemuMonitorJSONHandleBlockJobReady(qemuMonitorPtr mon,
- virJSONValuePtr data)
+ virJSONValuePtr data,
+ long long seconds, unsigned int micros)
{
qemuMonitorJSONHandleBlockJobImpl(mon, data,
- VIR_DOMAIN_BLOCK_JOB_READY);
+ VIR_DOMAIN_BLOCK_JOB_READY, seconds, micros);
}
static void
qemuMonitorJSONHandleBalloonChange(qemuMonitorPtr mon,
- virJSONValuePtr data)
+ virJSONValuePtr data,
+ long long seconds, unsigned int micros)
{
unsigned long long actual = 0;
if (virJSONValueObjectGetNumberUlong(data, "actual", &actual) < 0)
{
@@ -985,18 +1053,20 @@ qemuMonitorJSONHandleBalloonChange(qemuMonitorPtr mon,
return;
}
actual = VIR_DIV_UP(actual, 1024);
- qemuMonitorEmitBalloonChange(mon, actual);
+ qemuMonitorEmitBalloonChange(mon, actual, seconds, micros);
}
static void
qemuMonitorJSONHandlePMSuspendDisk(qemuMonitorPtr mon,
- virJSONValuePtr data ATTRIBUTE_UNUSED)
+ virJSONValuePtr data ATTRIBUTE_UNUSED,
+ long long seconds, unsigned int micros)
{
- qemuMonitorEmitPMSuspendDisk(mon);
+ qemuMonitorEmitPMSuspendDisk(mon, seconds, micros);
}
static void
-qemuMonitorJSONHandleDeviceDeleted(qemuMonitorPtr mon, virJSONValuePtr data)
+qemuMonitorJSONHandleDeviceDeleted(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros)
{
const char *device;
@@ -1005,12 +1075,13 @@ qemuMonitorJSONHandleDeviceDeleted(qemuMonitorPtr mon,
virJSONValuePtr data)
return;
}
- qemuMonitorEmitDeviceDeleted(mon, device);
+ qemuMonitorEmitDeviceDeleted(mon, device, seconds, micros);
}
static void
-qemuMonitorJSONHandleNicRxFilterChanged(qemuMonitorPtr mon, virJSONValuePtr data)
+qemuMonitorJSONHandleNicRxFilterChanged(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros)
{
const char *name;
@@ -1019,13 +1090,14 @@ qemuMonitorJSONHandleNicRxFilterChanged(qemuMonitorPtr mon,
virJSONValuePtr data
return;
}
- qemuMonitorEmitNicRxFilterChanged(mon, name);
+ qemuMonitorEmitNicRxFilterChanged(mon, name, seconds, micros);
}
static void
qemuMonitorJSONHandleSerialChange(qemuMonitorPtr mon,
- virJSONValuePtr data)
+ virJSONValuePtr data,
+ long long seconds, unsigned int micros)
{
const char *name;
bool connected;
@@ -1040,21 +1112,23 @@ qemuMonitorJSONHandleSerialChange(qemuMonitorPtr mon,
return;
}
- qemuMonitorEmitSerialChange(mon, name, connected);
+ qemuMonitorEmitSerialChange(mon, name, connected, seconds, micros);
}
static void
qemuMonitorJSONHandleSpiceMigrated(qemuMonitorPtr mon,
- virJSONValuePtr data ATTRIBUTE_UNUSED)
+ virJSONValuePtr data ATTRIBUTE_UNUSED,
+ long long seconds, unsigned int micros)
{
- qemuMonitorEmitSpiceMigrated(mon);
+ qemuMonitorEmitSpiceMigrated(mon, seconds, micros);
}
static void
qemuMonitorJSONHandleMigrationStatus(qemuMonitorPtr mon,
- virJSONValuePtr data)
+ virJSONValuePtr data,
+ long long seconds, unsigned int micros)
{
const char *str;
int status;
@@ -1069,13 +1143,14 @@ qemuMonitorJSONHandleMigrationStatus(qemuMonitorPtr mon,
return;
}
- qemuMonitorEmitMigrationStatus(mon, status);
+ qemuMonitorEmitMigrationStatus(mon, status, seconds, micros);
}
static void
qemuMonitorJSONHandleMigrationPass(qemuMonitorPtr mon,
- virJSONValuePtr data)
+ virJSONValuePtr data,
+ long long seconds, unsigned int micros)
{
int pass;
@@ -1084,12 +1159,13 @@ qemuMonitorJSONHandleMigrationPass(qemuMonitorPtr mon,
return;
}
- qemuMonitorEmitMigrationPass(mon, pass);
+ qemuMonitorEmitMigrationPass(mon, pass, seconds, micros);
}
static void
-qemuMonitorJSONHandleAcpiOstInfo(qemuMonitorPtr mon, virJSONValuePtr data)
+qemuMonitorJSONHandleAcpiOstInfo(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros)
{
virJSONValuePtr info;
const char *alias;
@@ -1116,7 +1192,8 @@ qemuMonitorJSONHandleAcpiOstInfo(qemuMonitorPtr mon, virJSONValuePtr
data)
if (virJSONValueObjectGetNumberUint(info, "status", &status) < 0)
goto error;
- qemuMonitorEmitAcpiOstInfo(mon, alias, slotType, slot, source, status);
+ qemuMonitorEmitAcpiOstInfo(mon, alias, slotType, slot, source, status,
+ seconds, micros);
return;
error:
@@ -1126,7 +1203,8 @@ qemuMonitorJSONHandleAcpiOstInfo(qemuMonitorPtr mon, virJSONValuePtr
data)
static void
-qemuMonitorJSONHandleBlockThreshold(qemuMonitorPtr mon, virJSONValuePtr data)
+qemuMonitorJSONHandleBlockThreshold(qemuMonitorPtr mon, virJSONValuePtr data,
+ long long seconds, unsigned int micros)
{
const char *nodename;
unsigned long long threshold;
@@ -1141,7 +1219,8 @@ qemuMonitorJSONHandleBlockThreshold(qemuMonitorPtr mon,
virJSONValuePtr data)
if (virJSONValueObjectGetNumberUlong(data, "amount-exceeded", &excess)
< 0)
goto error;
- qemuMonitorEmitBlockThreshold(mon, nodename, threshold, excess);
+ qemuMonitorEmitBlockThreshold(mon, nodename, threshold, excess,
+ seconds, micros);
return;
error:
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 8e6498e..ee8bae5 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -82,6 +82,12 @@
VIR_LOG_INIT("qemu.qemu_process");
+typedef struct {
+ qemuMonitorEventType type;
+ void (*handler_func)(qemuEventPtr ev, void *opaque);
+} qemuEventFuncTable;
+
+
/**
* qemuProcessRemoveDomainStatus
*
@@ -474,20 +480,24 @@ qemuProcessFindVolumeQcowPassphrase(qemuMonitorPtr mon
ATTRIBUTE_UNUSED,
return ret;
}
-
-static int
-qemuProcessHandleReset(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- void *opaque)
+static void
+qemuProcessEventHandleReset(qemuEventPtr ev,
+ void *opaque)
{
virQEMUDriverPtr driver = opaque;
virObjectEventPtr event;
qemuDomainObjPrivatePtr priv;
+ virDomainObjPtr vm;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
- int ret = -1;
- virObjectLock(vm);
+ if (!ev)
+ return;
+ if (!ev->vm) {
+ VIR_INFO("Dropping reset event for unknown VM");
+ return;
+ }
+ vm = ev->vm;
event = virDomainEventRebootNewFromObj(vm);
priv = vm->privateData;
if (priv->agent)
@@ -516,12 +526,10 @@ qemuProcessHandleReset(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
qemuDomainObjEndJob(driver, vm);
}
- ret = 0;
cleanup:
- virObjectUnlock(vm);
qemuDomainEventQueue(driver, event);
virObjectUnref(cfg);
- return ret;
+ return;
}
@@ -623,60 +631,69 @@ qemuProcessShutdownOrReboot(virQEMUDriverPtr driver,
}
-static int
-qemuProcessHandleEvent(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- const char *eventName,
- long long seconds,
- unsigned int micros,
- const char *details,
- void *opaque)
+
+void
+qemuProcessEmitMonitorEvent(qemuEventPtr ev,
+ void *opaque)
{
virQEMUDriverPtr driver = opaque;
virObjectEventPtr event = NULL;
+ virDomainObjPtr vm;
+ const char * eventName;
- VIR_DEBUG("vm=%p", vm);
+ if (!ev)
+ return;
+
+ vm = ev->vm;
+
+ eventName = qemuMonitorEventTypeToString(ev->ev_type);
+ VIR_DEBUG("vm=%s monitor event %s", vm->def->name, eventName);
- virObjectLock(vm);
event = virDomainQemuMonitorEventNew(vm->def->id, vm->def->name,
vm->def->uuid, eventName,
- seconds, micros, details);
-
- virObjectUnlock(vm);
- qemuDomainEventQueue(driver, event);
+ ev->seconds, ev->micros, NULL);
+ if (event)
+ qemuDomainEventQueue(driver, event);
- return 0;
+ return;
}
-static int
-qemuProcessHandleShutdown(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- virTristateBool guest_initiated,
- void *opaque)
+static void
+qemuProcessEventHandleShutdown(qemuEventPtr ev,
+
+ void *opaque)
{
virQEMUDriverPtr driver = opaque;
qemuDomainObjPrivatePtr priv;
+ virDomainObjPtr vm;
+ virTristateBool guest_initiated;
virObjectEventPtr event = NULL;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
int detail = 0;
- VIR_DEBUG("vm=%p", vm);
+ if (!ev)
+ return;
+ vm = ev->vm;
- virObjectLock(vm);
+ if (!ev->vm) {
+ VIR_WARN("Unable to locate VM, dropping SHUTDOWN event");
+ goto exit;
+ }
+ VIR_DEBUG("Processing SHUTDOWN event for VM %s", vm->def->name);
priv = vm->privateData;
if (priv->gotShutdown) {
VIR_DEBUG("Ignoring repeated SHUTDOWN event from domain %s",
vm->def->name);
- goto unlock;
+ goto exit;
} else if (!virDomainObjIsActive(vm)) {
VIR_DEBUG("Ignoring SHUTDOWN event from inactive domain %s",
vm->def->name);
- goto unlock;
+ goto exit;
}
priv->gotShutdown = true;
-
+ guest_initiated = ev->evData.ev_shutdown.guest_initiated;
VIR_DEBUG("Transitioned guest %s to shutdown state",
vm->def->name);
virDomainObjSetState(vm,
@@ -710,34 +727,39 @@ qemuProcessHandleShutdown(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
qemuAgentNotifyEvent(priv->agent, QEMU_AGENT_EVENT_SHUTDOWN);
qemuProcessShutdownOrReboot(driver, vm);
-
- unlock:
- virObjectUnlock(vm);
qemuDomainEventQueue(driver, event);
- virObjectUnref(cfg);
- return 0;
+ virObjectUnref(cfg);
+exit:
+ return;
}
-
-static int
-qemuProcessHandleStop(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- void *opaque)
+static void
+qemuProcessEventHandleStop(qemuEventPtr ev,
+ void *opaque)
{
virQEMUDriverPtr driver = opaque;
virObjectEventPtr event = NULL;
virDomainPausedReason reason = VIR_DOMAIN_PAUSED_UNKNOWN;
virDomainEventSuspendedDetailType detail = VIR_DOMAIN_EVENT_SUSPENDED_PAUSED;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ virDomainObjPtr vm;
+
+ if (!ev)
+ return;
+ vm = ev->vm;
+
+ if (!ev->vm) {
+ VIR_WARN("Unable to locate VM, dropping STOP event");
+ goto exit;
+ }
- virObjectLock(vm);
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
qemuDomainObjPrivatePtr priv = vm->privateData;
if (priv->gotShutdown) {
VIR_DEBUG("Ignoring STOP event after SHUTDOWN");
- goto unlock;
+ goto exit;
}
if (priv->job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_OUT) {
@@ -776,31 +798,38 @@ qemuProcessHandleStop(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
}
}
- unlock:
- virObjectUnlock(vm);
+exit:
qemuDomainEventQueue(driver, event);
virObjectUnref(cfg);
- return 0;
+ return;
}
-static int
-qemuProcessHandleResume(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
+static void
+qemuProcessEventHandleResume(qemuEventPtr ev,
void *opaque)
{
virQEMUDriverPtr driver = opaque;
virObjectEventPtr event = NULL;
+ virDomainObjPtr vm;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
- virObjectLock(vm);
+ if (!ev)
+ return;
+ vm = ev->vm;
+
+ if (!ev->vm) {
+ VIR_WARN("Unable to locate VM, dropping RESUME event");
+ goto exit;
+ }
+
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) {
qemuDomainObjPrivatePtr priv = vm->privateData;
if (priv->gotShutdown) {
VIR_DEBUG("Ignoring RESUME event after SHUTDOWN");
- goto unlock;
+ goto exit;
}
VIR_DEBUG("Transitioned guest %s out of paused into resumed state",
@@ -818,25 +847,32 @@ qemuProcessHandleResume(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
}
}
- unlock:
- virObjectUnlock(vm);
+exit:
qemuDomainEventQueue(driver, event);
virObjectUnref(cfg);
- return 0;
+ return;
}
-static int
-qemuProcessHandleRTCChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- long long offset,
- void *opaque)
+static void
+qemuProcessEventHandleRTCChange(qemuEventPtr ev,
+ void *opaque)
{
virQEMUDriverPtr driver = opaque;
virObjectEventPtr event = NULL;
+ virDomainObjPtr vm;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ unsigned long long offset;
- virObjectLock(vm);
+ if (!ev)
+ return;
+ vm = ev->vm;
+
+ if (!ev->vm) {
+ VIR_WARN("Unable to locate VM, dropping RTC event");
+ goto exit;
+ }
+ offset = ev->evData.ev_rtc.offset;
if (vm->def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_VARIABLE) {
/* when a basedate is manually given on the qemu commandline
* rather than simply "-rtc base=utc", the offset sent by qemu
@@ -862,26 +898,33 @@ qemuProcessHandleRTCChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
event = virDomainEventRTCChangeNewFromObj(vm, offset);
- virObjectUnlock(vm);
-
- qemuDomainEventQueue(driver, event);
+ if (event)
+ qemuDomainEventQueue(driver, event);
virObjectUnref(cfg);
- return 0;
+exit:
+ return;
}
-
-static int
-qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- int action,
- void *opaque)
+static void
+qemuProcessEventHandleWatchdog1(qemuEventPtr ev,
+ void *opaque)
{
virQEMUDriverPtr driver = opaque;
virObjectEventPtr watchdogEvent = NULL;
virObjectEventPtr lifecycleEvent = NULL;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ virDomainObjPtr vm;
+ int action;
- virObjectLock(vm);
+ if (!ev)
+ return;
+ vm = ev->vm;
+
+ if (!ev->vm) {
+ VIR_WARN("Unable to locate VM, dropping Watchdog event");
+ goto exit;
+ }
+ action = ev->evData.ev_watchdog.action;
watchdogEvent = virDomainEventWatchdogNewFromObj(vm, action);
if (action == VIR_DOMAIN_EVENT_WATCHDOG_PAUSE &&
@@ -923,22 +966,16 @@ qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
}
}
- if (vm)
- virObjectUnlock(vm);
qemuDomainEventQueue(driver, watchdogEvent);
qemuDomainEventQueue(driver, lifecycleEvent);
virObjectUnref(cfg);
- return 0;
+exit:
+ return;
}
-
-static int
-qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- const char *diskAlias,
- int action,
- const char *reason,
+static void
+qemuProcessEventHandleIOError(qemuEventPtr ev,
void *opaque)
{
virQEMUDriverPtr driver = opaque;
@@ -949,8 +986,24 @@ qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
const char *devAlias;
virDomainDiskDefPtr disk;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ virDomainObjPtr vm;
+ const char *diskAlias;
+ int action;
+ const char *reason;
+
+ if (!ev)
+ return;
+ vm = ev->vm;
+
+ if (!ev->vm) {
+ VIR_WARN("Unable to locate VM, dropping IO Error event");
+ goto exit;
+ }
+
+ diskAlias = ev->evData.ev_IOErr.device;
+ action = ev->evData.ev_IOErr.action;
+ reason = ev->evData.ev_IOErr.reason;
- virObjectLock(vm);
disk = qemuProcessFindDomainDiskByAlias(vm, diskAlias);
if (disk) {
@@ -975,7 +1028,7 @@ qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_IOERROR);
lifecycleEvent = virDomainEventLifecycleNewFromObj(vm,
VIR_DOMAIN_EVENT_SUSPENDED,
- VIR_DOMAIN_EVENT_SUSPENDED_IOERROR);
+ VIR_DOMAIN_PAUSED_IOERROR);
VIR_FREE(priv->lockState);
if (virDomainLockProcessPause(driver->lockManager, vm,
&priv->lockState) < 0)
@@ -985,32 +1038,45 @@ qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps)
< 0)
VIR_WARN("Unable to save status on vm %s after IO error",
vm->def->name);
}
- virObjectUnlock(vm);
qemuDomainEventQueue(driver, ioErrorEvent);
qemuDomainEventQueue(driver, ioErrorEvent2);
qemuDomainEventQueue(driver, lifecycleEvent);
+
+exit:
virObjectUnref(cfg);
- return 0;
+ VIR_FREE(ev->evData.ev_IOErr.device);
+ VIR_FREE(ev->evData.ev_IOErr.reason);
+ return;
}
-static int
-qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- const char *diskAlias,
- int type,
- int status,
- void *opaque)
+static void
+qemuProcessEventHandleBlockJob(qemuEventPtr ev,
+ void *opaque)
{
virQEMUDriverPtr driver = opaque;
struct qemuProcessEvent *processEvent = NULL;
virDomainDiskDefPtr disk;
qemuDomainDiskPrivatePtr diskPriv;
char *data = NULL;
+ virDomainObjPtr vm;
+ const char *diskAlias;
+ int type, status;
- virObjectLock(vm);
+ if (!ev)
+ return;
+ vm = ev->vm;
- VIR_DEBUG("Block job for device %s (domain: %p,%s) type %d status %d",
+ if (!ev->vm) {
+ VIR_WARN("Unable to locate VM, dropping Block Job event");
+ goto cleanup;
+ }
+
+ diskAlias = ev->evData.ev_blockJob.device;
+ type = ev->evData.ev_blockJob.type;
+ status = ev->evData.ev_blockJob.status;
+
+ VIR_INFO("Block job for device %s (domain: %p,%s) type %d status %d",
diskAlias, vm, vm->def->name, type, status);
if (!(disk = qemuProcessFindDomainDiskByAlias(vm, diskAlias)))
@@ -1043,8 +1109,7 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
}
cleanup:
- virObjectUnlock(vm);
- return 0;
+ return;
error:
if (processEvent)
VIR_FREE(processEvent->data);
@@ -1052,21 +1117,9 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
goto cleanup;
}
-
-static int
-qemuProcessHandleGraphics(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- int phase,
- int localFamily,
- const char *localNode,
- const char *localService,
- int remoteFamily,
- const char *remoteNode,
- const char *remoteService,
- const char *authScheme,
- const char *x509dname,
- const char *saslUsername,
- void *opaque)
+static void
+qemuProcessEventHandleGraphics(qemuEventPtr ev,
+ void *opaque)
{
virQEMUDriverPtr driver = opaque;
virObjectEventPtr event;
@@ -1074,49 +1127,65 @@ qemuProcessHandleGraphics(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virDomainEventGraphicsAddressPtr remoteAddr = NULL;
virDomainEventGraphicsSubjectPtr subject = NULL;
size_t i;
+ virDomainObjPtr vm;
+ struct qemuEventGraphicsData *data;
+
+ if (!ev)
+ return;
+ vm = ev->vm;
+
+ if (!ev->vm) {
+ VIR_WARN("Unable to locate VM, dropping Graphics event");
+ goto exit;
+ }
+ data = &(ev->evData.ev_graphics);
if (VIR_ALLOC(localAddr) < 0)
goto error;
- localAddr->family = localFamily;
- if (VIR_STRDUP(localAddr->service, localService) < 0 ||
- VIR_STRDUP(localAddr->node, localNode) < 0)
+
+ localAddr->family = data->localFamilyID;
+ if (VIR_STRDUP(localAddr->service, data->localService) < 0 ||
+ VIR_STRDUP(localAddr->node, data->localNode) < 0)
goto error;
if (VIR_ALLOC(remoteAddr) < 0)
goto error;
- remoteAddr->family = remoteFamily;
- if (VIR_STRDUP(remoteAddr->service, remoteService) < 0 ||
- VIR_STRDUP(remoteAddr->node, remoteNode) < 0)
+ remoteAddr->family = data->remoteFamilyID;
+ if (VIR_STRDUP(remoteAddr->service, data->remoteService) < 0 ||
+ VIR_STRDUP(remoteAddr->node, data->remoteNode) < 0)
goto error;
if (VIR_ALLOC(subject) < 0)
goto error;
- if (x509dname) {
+ if (data->x509dname) {
if (VIR_REALLOC_N(subject->identities, subject->nidentity+1) < 0)
goto error;
subject->nidentity++;
if (VIR_STRDUP(subject->identities[subject->nidentity-1].type,
"x509dname") < 0 ||
- VIR_STRDUP(subject->identities[subject->nidentity-1].name, x509dname)
< 0)
+ VIR_STRDUP(subject->identities[subject->nidentity-1].name,
+ data->x509dname) < 0)
goto error;
}
- if (saslUsername) {
+ if (data->saslUsername) {
if (VIR_REALLOC_N(subject->identities, subject->nidentity+1) < 0)
goto error;
subject->nidentity++;
if (VIR_STRDUP(subject->identities[subject->nidentity-1].type,
"saslUsername") < 0 ||
- VIR_STRDUP(subject->identities[subject->nidentity-1].name,
saslUsername) < 0)
+ VIR_STRDUP(subject->identities[subject->nidentity-1].name,
+ data->saslUsername) < 0)
goto error;
}
- virObjectLock(vm);
- event = virDomainEventGraphicsNewFromObj(vm, phase, localAddr, remoteAddr,
authScheme, subject);
- virObjectUnlock(vm);
+ event = virDomainEventGraphicsNewFromObj(vm, data->phase,
+ localAddr, remoteAddr,
+ data->authScheme,
+ subject);
qemuDomainEventQueue(driver, event);
- return 0;
+ goto exit;
- error:
+error:
if (localAddr) {
VIR_FREE(localAddr->service);
VIR_FREE(localAddr->node);
@@ -1136,22 +1205,41 @@ qemuProcessHandleGraphics(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
VIR_FREE(subject);
}
- return -1;
+exit:
+ VIR_FREE(ev->evData.ev_graphics.localNode);
+ VIR_FREE(ev->evData.ev_graphics.localService);
+ VIR_FREE(ev->evData.ev_graphics.remoteNode);
+ VIR_FREE(ev->evData.ev_graphics.remoteService);
+ VIR_FREE(ev->evData.ev_graphics.x509dname);
+ VIR_FREE(ev->evData.ev_graphics.saslUsername);
+ VIR_FREE(ev->evData.ev_graphics.authScheme);
+ return;
}
-static int
-qemuProcessHandleTrayChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- const char *devAlias,
- int reason,
- void *opaque)
+static void
+qemuProcessEventHandleTrayChange(qemuEventPtr ev,
+ void *opaque)
{
virQEMUDriverPtr driver = opaque;
virObjectEventPtr event = NULL;
virDomainDiskDefPtr disk;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ virDomainObjPtr vm;
+ const char *devAlias;
+ int reason;
+
+ if (!ev)
+ return;
+ vm = ev->vm;
+
+ if (!ev->vm) {
+ VIR_WARN("Unable to locate VM, dropping Graphics event");
+ goto exit;
+ }
+
+ devAlias = ev->evData.ev_tray.devAlias;
+ reason = ev->evData.ev_tray.reason;
- virObjectLock(vm);
disk = qemuProcessFindDomainDiskByAlias(vm, devAlias);
if (disk) {
@@ -1168,27 +1256,36 @@ qemuProcessHandleTrayChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
VIR_WARN("Unable to save status on vm %s after tray moved event",
vm->def->name);
}
-
- virDomainObjBroadcast(vm);
+// Why the broadcast here?
+// virDomainObjBroadcast(vm);
}
- virObjectUnlock(vm);
qemuDomainEventQueue(driver, event);
virObjectUnref(cfg);
- return 0;
+exit:
+ VIR_FREE(ev->evData.ev_tray.devAlias);
+ return;
}
-static int
-qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- void *opaque)
+static void
+qemuProcessEventHandlePMWakeup(qemuEventPtr ev,
+ void *opaque)
{
virQEMUDriverPtr driver = opaque;
virObjectEventPtr event = NULL;
virObjectEventPtr lifecycleEvent = NULL;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ virDomainObjPtr vm;
+
+ if (!ev)
+ return;
+ vm = ev->vm;
+
+ if (!ev->vm) {
+ VIR_WARN("Unable to locate VM, dropping PM Wakeup event");
+ goto exit;
+ }
- virObjectLock(vm);
event = virDomainEventPMWakeupNewFromObj(vm);
/* Don't set domain status back to running if it wasn't paused
@@ -1210,24 +1307,32 @@ qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
}
}
- virObjectUnlock(vm);
qemuDomainEventQueue(driver, event);
qemuDomainEventQueue(driver, lifecycleEvent);
virObjectUnref(cfg);
- return 0;
+exit:
+ return;
}
-static int
-qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- void *opaque)
+static void
+qemuProcessEventHandlePMSuspend(qemuEventPtr ev,
+ void *opaque)
{
virQEMUDriverPtr driver = opaque;
virObjectEventPtr event = NULL;
virObjectEventPtr lifecycleEvent = NULL;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ virDomainObjPtr vm;
+
+ if (!ev)
+ return;
+ vm = ev->vm;
+
+ if (!ev->vm) {
+ VIR_WARN("Unable to locate VM, dropping PM Suspend event");
+ goto exit;
+ }
- virObjectLock(vm);
event = virDomainEventPMSuspendNewFromObj(vm);
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
@@ -1251,25 +1356,33 @@ qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
qemuAgentNotifyEvent(priv->agent, QEMU_AGENT_EVENT_SUSPEND);
}
- virObjectUnlock(vm);
-
qemuDomainEventQueue(driver, event);
qemuDomainEventQueue(driver, lifecycleEvent);
virObjectUnref(cfg);
- return 0;
+exit:
+ return;
}
-static int
-qemuProcessHandleBalloonChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- unsigned long long actual,
- void *opaque)
+static void
+qemuProcessEventHandleBalloonChange(qemuEventPtr ev,
+ void *opaque)
{
virQEMUDriverPtr driver = opaque;
virObjectEventPtr event = NULL;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ virDomainObjPtr vm;
+ unsigned long long actual;
- virObjectLock(vm);
+ if (!ev)
+ return;
+ vm = ev->vm;
+
+ if (!ev->vm) {
+ VIR_WARN("Unable to locate VM, dropping Balloon event");
+ goto exit;
+ }
+
+ actual = ev->evData.ev_balloon.actual;
event = virDomainEventBalloonChangeNewFromObj(vm, actual);
VIR_DEBUG("Updating balloon from %lld to %lld kb",
@@ -1279,24 +1392,30 @@ qemuProcessHandleBalloonChange(qemuMonitorPtr mon
ATTRIBUTE_UNUSED,
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps)
< 0)
VIR_WARN("unable to save domain status with balloon change");
- virObjectUnlock(vm);
-
qemuDomainEventQueue(driver, event);
virObjectUnref(cfg);
- return 0;
+exit:
+ return;
}
-static int
-qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- void *opaque)
+static void
+qemuProcessEventHandlePMSuspendDisk(qemuEventPtr ev,
+ void *opaque)
{
virQEMUDriverPtr driver = opaque;
virObjectEventPtr event = NULL;
virObjectEventPtr lifecycleEvent = NULL;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ virDomainObjPtr vm;
- virObjectLock(vm);
+ if (!ev)
+ return;
+ vm = ev->vm;
+
+ if (!ev->vm) {
+ VIR_WARN("Unable to locate VM, dropping PM Suspend disk event");
+ goto exit;
+ }
event = virDomainEventPMSuspendDiskNewFromObj(vm);
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
@@ -1320,28 +1439,35 @@ qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon
ATTRIBUTE_UNUSED,
qemuAgentNotifyEvent(priv->agent, QEMU_AGENT_EVENT_SUSPEND);
}
- virObjectUnlock(vm);
-
qemuDomainEventQueue(driver, event);
qemuDomainEventQueue(driver, lifecycleEvent);
virObjectUnref(cfg);
-
- return 0;
+exit:
+ return;
}
-static int
-qemuProcessHandleGuestPanic(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- qemuMonitorEventPanicInfoPtr info,
- void *opaque)
+static void
+qemuProcessEventHandleGuestPanic(qemuEventPtr ev,
+ void *opaque)
{
virQEMUDriverPtr driver = opaque;
struct qemuProcessEvent *processEvent;
+ virDomainObjPtr vm;
+ qemuMonitorEventPanicInfoPtr info;
- virObjectLock(vm);
+ if (!ev)
+ return;
+ vm = ev->vm;
+
+ if (!ev->vm) {
+ VIR_WARN("Unable to locate VM, dropping Guest Panic event");
+ goto exit;
+ }
+
+ info = ev->evData.ev_panic.info;
if (VIR_ALLOC(processEvent) < 0)
- goto cleanup;
+ goto exit;
processEvent->eventType = QEMU_PROCESS_EVENT_GUESTPANIC;
processEvent->action = vm->def->onCrash;
@@ -1357,26 +1483,31 @@ qemuProcessHandleGuestPanic(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
VIR_FREE(processEvent);
}
- cleanup:
- if (vm)
- virObjectUnlock(vm);
-
- return 0;
+exit:
+ return;
}
-int
-qemuProcessHandleDeviceDeleted(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- const char *devAlias,
- void *opaque)
+static void
+qemuProcessEventHandleDeviceDeleted(qemuEventPtr ev,
+ void *opaque)
{
virQEMUDriverPtr driver = opaque;
struct qemuProcessEvent *processEvent = NULL;
char *data;
+ virDomainObjPtr vm;
+ const char *devAlias;
- virObjectLock(vm);
+ if (!ev)
+ return;
+ vm = ev->vm;
+
+ if (!ev->vm) {
+ VIR_WARN("Unable to locate VM, dropping Device deleted event");
+ goto cleanup;
+ }
+ devAlias = ev->evData.ev_deviceDel.device;
VIR_DEBUG("Device %s removed from domain %p %s",
devAlias, vm, vm->def->name);
@@ -1400,8 +1531,8 @@ qemuProcessHandleDeviceDeleted(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
}
cleanup:
- virObjectUnlock(vm);
- return 0;
+ VIR_FREE(ev->evData.ev_deviceDel.device);
+ return;
error:
if (processEvent)
VIR_FREE(processEvent->data);
@@ -1444,20 +1575,34 @@ qemuProcessHandleDeviceDeleted(qemuMonitorPtr mon
ATTRIBUTE_UNUSED,
* Note that qemu does not emit the event for all the documented sources or
* devices.
*/
-static int
-qemuProcessHandleAcpiOstInfo(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- const char *alias,
- const char *slotType,
- const char *slot,
- unsigned int source,
- unsigned int status,
- void *opaque)
+
+static void
+qemuProcessEventHandleAcpiOstInfo(qemuEventPtr ev,
+ void *opaque)
{
virQEMUDriverPtr driver = opaque;
virObjectEventPtr event = NULL;
+ virDomainObjPtr vm;
+ const char *alias;
+ const char *slotType;
+ const char *slot;
+ unsigned int source;
+ unsigned int status;
- virObjectLock(vm);
+ if (!ev)
+ return;
+ vm = ev->vm;
+
+ if (!ev->vm) {
+ VIR_WARN("Unable to locate VM, dropping ACPI event");
+ goto exit;
+ }
+
+ alias = ev->evData.ev_acpi.alias;
+ slotType = ev->evData.ev_acpi.slotType;
+ slot = ev->evData.ev_acpi.slot;
+ source = ev->evData.ev_acpi.source;
+ status = ev->evData.ev_acpi.status;
VIR_DEBUG("ACPI OST info for device %s domain %p %s. "
"slotType='%s' slot='%s' source=%u status=%u",
@@ -1471,20 +1616,19 @@ qemuProcessHandleAcpiOstInfo(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
event = virDomainEventDeviceRemovalFailedNewFromObj(vm, alias);
}
- virObjectUnlock(vm);
qemuDomainEventQueue(driver, event);
- return 0;
+exit:
+ VIR_FREE(ev->evData.ev_acpi.alias);
+ VIR_FREE(ev->evData.ev_acpi.slotType);
+ VIR_FREE(ev->evData.ev_acpi.slot);
+ return;
}
-static int
-qemuProcessHandleBlockThreshold(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- const char *nodename,
- unsigned long long threshold,
- unsigned long long excess,
- void *opaque)
+static void
+qemuProcessEventHandleBlockThreshold(qemuEventPtr ev,
+ void *opaque)
{
virQEMUDriverPtr driver = opaque;
virObjectEventPtr event = NULL;
@@ -1493,8 +1637,23 @@ qemuProcessHandleBlockThreshold(qemuMonitorPtr mon
ATTRIBUTE_UNUSED,
unsigned int idx;
char *dev = NULL;
const char *path = NULL;
+ virDomainObjPtr vm;
+ const char *nodename;
+ unsigned long long threshold;
+ unsigned long long excess;
- virObjectLock(vm);
+ if (!ev)
+ return;
+ vm = ev->vm;
+
+ if (!ev->vm) {
+ VIR_WARN("Unable to locate VM, dropping Block Threshold event");
+ goto exit;
+ }
+
+ nodename = ev->evData.ev_threshold.nodename;
+ threshold = ev->evData.ev_threshold.threshold;
+ excess = ev->evData.ev_threshold.excess;
VIR_DEBUG("BLOCK_WRITE_THRESHOLD event for block node '%s' in domain %p
%s:"
"threshold '%llu' exceeded by '%llu'",
@@ -1511,25 +1670,33 @@ qemuProcessHandleBlockThreshold(qemuMonitorPtr mon
ATTRIBUTE_UNUSED,
}
}
- virObjectUnlock(vm);
qemuDomainEventQueue(driver, event);
-
- return 0;
+exit:
+ VIR_FREE(ev->evData.ev_threshold.nodename);
+ return;
}
-static int
-qemuProcessHandleNicRxFilterChanged(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- const char *devAlias,
- void *opaque)
+static void
+qemuProcessEventHandleNicRxFilterChanged(qemuEventPtr ev,
+ void *opaque)
{
virQEMUDriverPtr driver = opaque;
struct qemuProcessEvent *processEvent = NULL;
char *data;
+ virDomainObjPtr vm;
+ char *devAlias;
- virObjectLock(vm);
+ if (!ev)
+ return;
+ vm = ev->vm;
+
+ if (!ev->vm) {
+ VIR_WARN("Unable to locate VM, dropping Nic Filter Change event");
+ goto exit;
+ }
+ devAlias = ev->evData.ev_nic.devAlias;
VIR_DEBUG("Device %s RX Filter changed in domain %p %s",
devAlias, vm, vm->def->name);
@@ -1548,30 +1715,39 @@ qemuProcessHandleNicRxFilterChanged(qemuMonitorPtr mon
ATTRIBUTE_UNUSED,
goto error;
}
- cleanup:
- virObjectUnlock(vm);
- return 0;
+exit:
+ VIR_FREE(ev->evData.ev_nic.devAlias);
+ return;
error:
if (processEvent)
VIR_FREE(processEvent->data);
VIR_FREE(processEvent);
- goto cleanup;
+ goto exit;
}
-static int
-qemuProcessHandleSerialChanged(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- const char *devAlias,
- bool connected,
- void *opaque)
+static void
+qemuProcessEventHandleSerialChanged(qemuEventPtr ev,
+ void *opaque)
{
virQEMUDriverPtr driver = opaque;
struct qemuProcessEvent *processEvent = NULL;
char *data;
+ virDomainObjPtr vm;
+ char *devAlias;
+ bool connected;
- virObjectLock(vm);
+ if (!ev)
+ return;
+ vm = ev->vm;
+ if (!ev->vm) {
+ VIR_WARN("Unable to locate VM, dropping Serial Change event");
+ goto cleanup;
+ }
+
+ devAlias = ev->evData.ev_serial.devAlias;
+ connected = ev->evData.ev_serial.connected;
VIR_DEBUG("Serial port %s state changed to '%d' in domain %p %s",
devAlias, connected, vm, vm->def->name);
@@ -1592,8 +1768,8 @@ qemuProcessHandleSerialChanged(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
}
cleanup:
- virObjectUnlock(vm);
- return 0;
+ VIR_FREE(ev->evData.ev_serial.devAlias);
+ return;
error:
if (processEvent)
VIR_FREE(processEvent->data);
@@ -1602,14 +1778,21 @@ qemuProcessHandleSerialChanged(qemuMonitorPtr mon
ATTRIBUTE_UNUSED,
}
-static int
-qemuProcessHandleSpiceMigrated(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- void *opaque ATTRIBUTE_UNUSED)
+static void
+qemuProcessEventHandleSpiceMigrated(qemuEventPtr ev,
+ void *opaque ATTRIBUTE_UNUSED)
{
qemuDomainObjPrivatePtr priv;
+ virDomainObjPtr vm;
- virObjectLock(vm);
+ if (!ev)
+ return;
+ vm = ev->vm;
+
+ if (!ev->vm) {
+ VIR_WARN("Unable to locate VM, dropping Spice Migrated event");
+ goto cleanup;
+ }
VIR_DEBUG("Spice migration completed for domain %p %s",
vm, vm->def->name);
@@ -1621,28 +1804,37 @@ qemuProcessHandleSpiceMigrated(qemuMonitorPtr mon
ATTRIBUTE_UNUSED,
}
priv->job.spiceMigrated = true;
- virDomainObjBroadcast(vm);
+// virDomainObjBroadcast(vm);
cleanup:
- virObjectUnlock(vm);
- return 0;
+ return;
}
-static int
-qemuProcessHandleMigrationStatus(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- int status,
- void *opaque ATTRIBUTE_UNUSED)
+static void
+qemuProcessEventHandleMigrationStatus(qemuEventPtr ev,
+ void *opaque ATTRIBUTE_UNUSED)
{
qemuDomainObjPrivatePtr priv;
+ virDomainObjPtr vm;
+ int status;
- virObjectLock(vm);
+ if (!ev)
+ return;
+ vm = ev->vm;
+
+ if (!ev->vm) {
+ VIR_WARN("Unable to locate VM, dropping Migration Status event");
+ goto cleanup;
+ }
+
+ status = ev->evData.ev_migStatus.status;
VIR_DEBUG("Migration of domain %p %s changed state to %s",
vm, vm->def->name,
qemuMonitorMigrationStatusTypeToString(status));
+
priv = vm->privateData;
if (priv->job.asyncJob == QEMU_ASYNC_JOB_NONE) {
VIR_DEBUG("got MIGRATION event without a migration job");
@@ -1650,25 +1842,32 @@ qemuProcessHandleMigrationStatus(qemuMonitorPtr mon
ATTRIBUTE_UNUSED,
}
priv->job.current->stats.status = status;
- virDomainObjBroadcast(vm);
+// virDomainObjBroadcast(vm);
cleanup:
- virObjectUnlock(vm);
- return 0;
+ return;
}
-static int
-qemuProcessHandleMigrationPass(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- int pass,
- void *opaque)
+static void
+qemuProcessEventHandleMigrationPass(qemuEventPtr ev,
+ void *opaque)
{
virQEMUDriverPtr driver = opaque;
qemuDomainObjPrivatePtr priv;
+ virDomainObjPtr vm;
+ int pass;
- virObjectLock(vm);
+ if (!ev)
+ return;
+ vm = ev->vm;
+ if (!ev->vm) {
+ VIR_WARN("Unable to locate VM, dropping Migration Pass event");
+ goto cleanup;
+ }
+
+ pass = ev->evData.ev_migPass.pass;
VIR_DEBUG("Migrating domain %p %s, iteration %d",
vm, vm->def->name, pass);
@@ -1681,42 +1880,58 @@ qemuProcessHandleMigrationPass(qemuMonitorPtr mon
ATTRIBUTE_UNUSED,
qemuDomainEventQueue(driver,
virDomainEventMigrationIterationNewFromObj(vm, pass));
- cleanup:
- virObjectUnlock(vm);
- return 0;
+cleanup:
+ return;
}
+static qemuEventFuncTable qemuEventFunctions[] = {
+ { QEMU_EVENT_ACPI_OST, qemuProcessEventHandleAcpiOstInfo, },
+ { QEMU_EVENT_BALLOON_CHANGE, qemuProcessEventHandleBalloonChange, },
+ { QEMU_EVENT_BLOCK_IO_ERROR, qemuProcessEventHandleIOError, },
+ { QEMU_EVENT_BLOCK_JOB, qemuProcessEventHandleBlockJob, },
+ { QEMU_EVENT_BLOCK_WRITE_THRESHOLD, qemuProcessEventHandleBlockThreshold, },
+ { QEMU_EVENT_DEVICE_DELETED, qemuProcessEventHandleDeviceDeleted, },
+ { QEMU_EVENT_DEVICE_TRAY_MOVED, qemuProcessEventHandleTrayChange, },
+ { QEMU_EVENT_GRAPHICS, qemuProcessEventHandleGraphics,},
+ { QEMU_EVENT_GUEST_PANICKED, qemuProcessEventHandleGuestPanic,},
+ { QEMU_EVENT_MIGRATION, qemuProcessEventHandleMigrationStatus,},
+ { QEMU_EVENT_MIGRATION_PASS, qemuProcessEventHandleMigrationPass,},
+ { QEMU_EVENT_NIC_RX_FILTER_CHANGED, qemuProcessEventHandleNicRxFilterChanged, },
+ { QEMU_EVENT_POWERDOWN, NULL, },
+ { QEMU_EVENT_RESET, qemuProcessEventHandleReset, },
+ { QEMU_EVENT_RESUME, qemuProcessEventHandleResume, },
+ { QEMU_EVENT_RTC_CHANGE, qemuProcessEventHandleRTCChange, },
+ { QEMU_EVENT_SHUTDOWN, qemuProcessEventHandleShutdown,},
+ { QEMU_EVENT_SPICE_MIGRATED, qemuProcessEventHandleSpiceMigrated, },
+ { QEMU_EVENT_STOP, qemuProcessEventHandleStop, },
+ { QEMU_EVENT_SUSPEND, qemuProcessEventHandlePMSuspend,},
+ { QEMU_EVENT_SUSPEND_DISK, qemuProcessEventHandlePMSuspendDisk,},
+ { QEMU_EVENT_SERIAL_CHANGE, qemuProcessEventHandleSerialChanged,},
+ { QEMU_EVENT_WAKEUP, qemuProcessEventHandlePMWakeup,},
+ { QEMU_EVENT_WATCHDOG, qemuProcessEventHandleWatchdog1,},
+};
+
+static int
+qemuProcessEnqueueEvent(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ qemuEventPtr ev,
+ void *opaque)
+{
+ virQEMUDriverPtr driver = opaque;
+ /* Bad code alert: Fix this lookup to scan table for correct index.
+ * Works for now since event table is sorted */
+ ev->handler = qemuEventFunctions[ev->ev_type].handler_func;
+ return virEnqueueVMEvent(driver->ev_list, ev);
+}
static qemuMonitorCallbacks monitorCallbacks = {
.eofNotify = qemuProcessHandleMonitorEOF,
.errorNotify = qemuProcessHandleMonitorError,
.diskSecretLookup = qemuProcessFindVolumeQcowPassphrase,
- .domainEvent = qemuProcessHandleEvent,
- .domainShutdown = qemuProcessHandleShutdown,
- .domainStop = qemuProcessHandleStop,
- .domainResume = qemuProcessHandleResume,
- .domainReset = qemuProcessHandleReset,
- .domainRTCChange = qemuProcessHandleRTCChange,
- .domainWatchdog = qemuProcessHandleWatchdog,
- .domainIOError = qemuProcessHandleIOError,
- .domainGraphics = qemuProcessHandleGraphics,
- .domainBlockJob = qemuProcessHandleBlockJob,
- .domainTrayChange = qemuProcessHandleTrayChange,
- .domainPMWakeup = qemuProcessHandlePMWakeup,
- .domainPMSuspend = qemuProcessHandlePMSuspend,
- .domainBalloonChange = qemuProcessHandleBalloonChange,
- .domainPMSuspendDisk = qemuProcessHandlePMSuspendDisk,
- .domainGuestPanic = qemuProcessHandleGuestPanic,
- .domainDeviceDeleted = qemuProcessHandleDeviceDeleted,
- .domainNicRxFilterChanged = qemuProcessHandleNicRxFilterChanged,
- .domainSerialChange = qemuProcessHandleSerialChanged,
- .domainSpiceMigrated = qemuProcessHandleSpiceMigrated,
- .domainMigrationStatus = qemuProcessHandleMigrationStatus,
- .domainMigrationPass = qemuProcessHandleMigrationPass,
- .domainAcpiOstInfo = qemuProcessHandleAcpiOstInfo,
- .domainBlockThreshold = qemuProcessHandleBlockThreshold,
+ .domainEnqueueEvent = qemuProcessEnqueueEvent,
};
+
static void
qemuProcessMonitorReportLogError(qemuMonitorPtr mon,
const char *msg,
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 814b86d..a2bbc4f 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -129,6 +129,8 @@ int qemuProcessFinishStartup(virConnectPtr conn,
bool startCPUs,
virDomainPausedReason pausedReason);
+void qemuProcessEmitMonitorEvent(qemuEventPtr ev,
+ void *opaque);
typedef enum {
VIR_QEMU_PROCESS_STOP_MIGRATED = 1 << 0,
VIR_QEMU_PROCESS_STOP_NO_RELABEL = 1 << 1,
diff --git a/tests/qemumonitortestutils.c b/tests/qemumonitortestutils.c
index 5e30fb0..94375a3 100644
--- a/tests/qemumonitortestutils.c
+++ b/tests/qemumonitortestutils.c
@@ -1013,7 +1013,7 @@ qemuMonitorTestErrorNotify(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
static qemuMonitorCallbacks qemuMonitorTestCallbacks = {
.eofNotify = qemuMonitorTestEOFNotify,
.errorNotify = qemuMonitorTestErrorNotify,
- .domainDeviceDeleted = qemuProcessHandleDeviceDeleted,
+ .domainDeviceDeleted = NULL, //qemuProcessHandleDeviceDeleted,
};
--
2.9.5