return result;
}
+
+static int
+qemuConnectDomainQemuMonitorEventRegister(virConnectPtr conn,
+ virDomainPtr dom,
+ const char *event,
+ virConnectDomainQemuMonitorEventCallback callback,
+ void *opaque,
+ virFreeCallback freecb,
+ unsigned int flags)
+{
+ virQEMUDriverPtr driver = conn->privateData;
+ int ret = -1;
+
+ if (virConnectDomainQemuMonitorEventRegisterEnsureACL(conn) < 0)
+ goto cleanup;
+
+ if (virDomainQemuMonitorEventStateRegisterID(conn,
+ driver->domainEventState,
+ dom, event, callback,
+ opaque, freecb, flags,
+ &ret) < 0)
+ ret = -1;
+
+cleanup:
+ return ret;
+}
+
+
+static int
+qemuConnectDomainQemuMonitorEventDeregister(virConnectPtr conn,
+ int callbackID)
+{
+ virQEMUDriverPtr driver = conn->privateData;
+ int ret = -1;
+
+ if (virConnectDomainQemuMonitorEventDeregisterEnsureACL(conn) < 0)
+ goto cleanup;
+
+ if (virObjectEventStateDeregisterID(conn, driver->domainEventState,
+ callbackID) < 0)
+ goto cleanup;
+
+ ret = 0;
+
+cleanup:
+ return ret;
+}
+
+
static int
qemuDomainFSTrim(virDomainPtr dom,
const char *mountPoint,
.domainQemuMonitorCommand = qemuDomainQemuMonitorCommand, /* 0.8.3 */
.domainQemuAttach = qemuDomainQemuAttach, /* 0.9.4 */
.domainQemuAgentCommand = qemuDomainQemuAgentCommand, /* 0.10.0 */
+ .connectDomainQemuMonitorEventRegister = qemuConnectDomainQemuMonitorEventRegister, /* 1.2.3 */
+ .connectDomainQemuMonitorEventDeregister = qemuConnectDomainQemuMonitorEventDeregister, /* 1.2.3 */
.domainOpenConsole = qemuDomainOpenConsole, /* 0.8.6 */
.domainOpenGraphics = qemuDomainOpenGraphics, /* 0.9.7 */
.domainInjectNMI = qemuDomainInjectNMI, /* 0.9.2 */
}
+int
+qemuMonitorEmitEvent(qemuMonitorPtr mon, const char *event,
+ long long seconds, unsigned int micros,
+ const char *details)
+{
+ int ret = -1;
+ VIR_DEBUG("mon=%p event=%s", mon, event);
+
+ QEMU_MONITOR_CALLBACK(mon, ret, domainEvent, mon->vm, event, seconds,
+ micros, details);
+ return ret;
+}
+
+
int qemuMonitorEmitShutdown(qemuMonitorPtr mon)
{
int ret = -1;
/*
* qemu_monitor.h: interaction with QEMU monitor console
*
- * Copyright (C) 2006-2013 Red Hat, Inc.
+ * Copyright (C) 2006-2014 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
char **secret,
size_t *secretLen,
void *opaque);
+typedef int (*qemuMonitorDomainEventCallback)(qemuMonitorPtr mon,
+ virDomainObjPtr vm,
+ const char *event,
+ long long seconds,
+ unsigned int micros,
+ const char *details,
+ void *opaque);
typedef int (*qemuMonitorDomainShutdownCallback)(qemuMonitorPtr mon,
virDomainObjPtr vm,
void *opaque);
qemuMonitorEofNotifyCallback eofNotify;
qemuMonitorErrorNotifyCallback errorNotify;
qemuMonitorDiskSecretLookupCallback diskSecretLookup;
+ qemuMonitorDomainEventCallback domainEvent;
qemuMonitorDomainShutdownCallback domainShutdown;
qemuMonitorDomainResetCallback domainReset;
qemuMonitorDomainPowerdownCallback domainPowerdown;
char **secret,
size_t *secretLen);
+int qemuMonitorEmitEvent(qemuMonitorPtr mon, const char *event,
+ long long seconds, unsigned int micros,
+ const char *details);
int qemuMonitorEmitShutdown(qemuMonitorPtr mon);
int qemuMonitorEmitReset(qemuMonitorPtr mon);
int qemuMonitorEmitPowerdown(qemuMonitorPtr mon);
{
const char *type;
qemuEventHandler *handler;
+ virJSONValuePtr data;
+ char *details = NULL;
+ virJSONValuePtr timestamp;
+ long long seconds = -1;
+ unsigned int micros = 0;
+
VIR_DEBUG("mon=%p obj=%p", mon, obj);
type = virJSONValueObjectGetString(obj, "event");
return -1;
}
+ /* Not all events have data; and event reporting is best-effort only */
+ if ((data = virJSONValueObjectGet(obj, "data")))
+ details = virJSONValueToString(data, false);
+ if ((timestamp = virJSONValueObjectGet(obj, "timestamp"))) {
+ virJSONValuePtr elt;
+
+ if ((elt = virJSONValueObjectGet(timestamp, "seconds")))
+ ignore_value(virJSONValueGetNumberLong(elt, &seconds));
+ if ((elt = virJSONValueObjectGet(timestamp, "microseconds")))
+ ignore_value(virJSONValueGetNumberUint(elt, µs));
+ }
+ qemuMonitorEmitEvent(mon, type, seconds, micros, details);
+ VIR_FREE(details);
+
handler = bsearch(type, eventHandlers, ARRAY_CARDINALITY(eventHandlers),
sizeof(eventHandlers[0]), qemuMonitorEventCompare);
if (handler) {
- virJSONValuePtr data = virJSONValueObjectGet(obj, "data");
VIR_DEBUG("handle %s handler=%p data=%p", type,
handler->handler, data);
(handler->handler)(mon, data);
}
}
+
+static int
+qemuProcessHandleEvent(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm,
+ const char *eventName,
+ long long seconds,
+ unsigned int micros,
+ const char *details,
+ void *opaque)
+{
+ virQEMUDriverPtr driver = opaque;
+ virObjectEventPtr event = NULL;
+
+ VIR_DEBUG("vm=%p", vm);
+
+ virObjectLock(vm);
+ event = virDomainQemuMonitorEventNew(vm->def->id, vm->def->name,
+ vm->def->uuid, eventName,
+ seconds, micros, details);
+
+ virObjectUnlock(vm);
+ if (event)
+ qemuDomainEventQueue(driver, event);
+
+ return 0;
+}
+
+
static int
qemuProcessHandleShutdown(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
.eofNotify = qemuProcessHandleMonitorEOF,
.errorNotify = qemuProcessHandleMonitorError,
.diskSecretLookup = qemuProcessFindVolumeQcowPassphrase,
+ .domainEvent = qemuProcessHandleEvent,
.domainShutdown = qemuProcessHandleShutdown,
.domainStop = qemuProcessHandleStop,
.domainResume = qemuProcessHandleResume,