Create qemu monitor events as a distinct class to normal domain
events, because they will be filtered differently. For ease of
review, the logic for filtering by event name is saved for a later
patch.
* src/conf/domain_event.c (virDomainQemuMonitorEventClass): New
class.
(virDomainEventsOnceInit): Register it.
(virDomainQemuMonitorEventDispose, virDomainQemuMonitorEventNew)
(virDomainQemuMonitorEventDispatchFunc)
(virDomainQemuMonitorEventStateRegisterID): New functions.
* src/conf/domain_event.h (virDomainQemuMonitorEventNew)
(virDomainQemuMonitorEventStateRegisterID): New prototypes.
* src/libvirt_private.syms (conf/domain_conf.h): Export them.
---
src/conf/domain_event.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++
src/conf/domain_event.h | 23 ++++++++
src/libvirt_private.syms | 2 +
3 files changed, 169 insertions(+)
diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
index 9c18922..01c0ae6 100644
--- a/src/conf/domain_event.c
+++ b/src/conf/domain_event.c
@@ -48,6 +48,7 @@ static virClassPtr virDomainEventTrayChangeClass;
static virClassPtr virDomainEventBalloonChangeClass;
static virClassPtr virDomainEventDeviceRemovedClass;
static virClassPtr virDomainEventPMClass;
+static virClassPtr virDomainQemuMonitorEventClass;
static void virDomainEventDispose(void *obj);
@@ -62,6 +63,7 @@ static void virDomainEventTrayChangeDispose(void *obj);
static void virDomainEventBalloonChangeDispose(void *obj);
static void virDomainEventDeviceRemovedDispose(void *obj);
static void virDomainEventPMDispose(void *obj);
+static void virDomainQemuMonitorEventDispose(void *obj);
static void
virDomainEventDispatchDefaultFunc(virConnectPtr conn,
@@ -69,6 +71,12 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn,
virConnectObjectEventGenericCallback cb,
void *cbopaque);
+static void
+virDomainQemuMonitorEventDispatchFunc(virConnectPtr conn,
+ virObjectEventPtr event,
+ virConnectObjectEventGenericCallback cb,
+ void *cbopaque);
+
struct _virDomainEvent {
virObjectEvent parent;
@@ -181,6 +189,17 @@ struct _virDomainEventPM {
typedef struct _virDomainEventPM virDomainEventPM;
typedef virDomainEventPM *virDomainEventPMPtr;
+struct _virDomainQemuMonitorEvent {
+ virObjectEvent parent;
+
+ char *event;
+ long long seconds;
+ unsigned int micros;
+ char *details;
+};
+typedef struct _virDomainQemuMonitorEvent virDomainQemuMonitorEvent;
+typedef virDomainQemuMonitorEvent *virDomainQemuMonitorEventPtr;
+
static int
virDomainEventsOnceInit(void)
@@ -257,6 +276,12 @@ virDomainEventsOnceInit(void)
sizeof(virDomainEventPM),
virDomainEventPMDispose)))
return -1;
+ if (!(virDomainQemuMonitorEventClass =
+ virClassNew(virClassForObjectEvent(),
+ "virDomainQemuMonitorEvent",
+ sizeof(virDomainQemuMonitorEvent),
+ virDomainQemuMonitorEventDispose)))
+ return -1;
return 0;
}
@@ -382,6 +407,16 @@ virDomainEventPMDispose(void *obj)
VIR_DEBUG("obj=%p", event);
}
+static void
+virDomainQemuMonitorEventDispose(void *obj)
+{
+ virDomainQemuMonitorEventPtr event = obj;
+ VIR_DEBUG("obj=%p", event);
+
+ VIR_FREE(event->event);
+ VIR_FREE(event->details);
+}
+
static void *
virDomainEventNew(virClassPtr klass,
@@ -1313,6 +1348,65 @@ cleanup:
}
+virObjectEventPtr
+virDomainQemuMonitorEventNew(int id,
+ const char *name,
+ const unsigned char *uuid,
+ const char *event,
+ long long seconds,
+ unsigned int micros,
+ const char *details)
+{
+ virDomainQemuMonitorEventPtr ev;
+
+ if (virDomainEventsInitialize() < 0)
+ return NULL;
+
+ if (!(ev = virObjectEventNew(virDomainQemuMonitorEventClass,
+ virDomainQemuMonitorEventDispatchFunc,
+ 0, id, name, uuid)))
+ return NULL;
+
+ /* event is mandatory, details are optional */
+ if (VIR_STRDUP(ev->event, event) <= 0)
+ goto error;
+ ev->seconds = seconds;
+ ev->micros = micros;
+ if (VIR_STRDUP(ev->details, details) < 0)
+ goto error;
+
+ return (virObjectEventPtr)ev;
+
+error:
+ virObjectUnref(ev);
+ return NULL;
+}
+
+
+static void
+virDomainQemuMonitorEventDispatchFunc(virConnectPtr conn,
+ virObjectEventPtr event,
+ virConnectObjectEventGenericCallback cb,
+ void *cbopaque)
+{
+ virDomainPtr dom = virGetDomain(conn, event->meta.name, event->meta.uuid);
+ virDomainQemuMonitorEventPtr qemuMonitorEvent;
+
+ if (!dom)
+ return;
+ dom->id = event->meta.id;
+
+ qemuMonitorEvent = (virDomainQemuMonitorEventPtr)event;
+ ((virConnectDomainQemuMonitorEventCallback)cb)(conn, dom,
+ qemuMonitorEvent->event,
+ qemuMonitorEvent->seconds,
+ qemuMonitorEvent->micros,
+ qemuMonitorEvent->details,
+ cbopaque);
+ virDomainFree(dom);
+}
+
+
/**
* virDomainEventStateRegister:
* @conn: connection to associate with callback
@@ -1480,3 +1574,53 @@ virDomainEventStateDeregister(virConnectPtr conn,
return -1;
return virObjectEventStateDeregisterID(conn, state, callbackID);
}
+
+
+/**
+ * virDomainQemuMonitorEventStateRegisterID:
+ * @conn: connection to associate with callback
+ * @state: object event state
+ * @dom: optional domain where event must occur
+ * @event: optional name of event to register for
+ * @cb: function to invoke when event occurs
+ * @opaque: data blob to pass to callback
+ * @freecb: callback to free @opaque
+ * @flags: -1 for client, or set of registration flags on server
+ * @callbackID: filled with callback ID
+ *
+ * Register the function @cb with connection @conn, from @state, for
+ * events of type @eventID.
+ *
+ * Returns: the number of callbacks now registered, or -1 on error
+ */
+int
+virDomainQemuMonitorEventStateRegisterID(virConnectPtr conn,
+ virObjectEventStatePtr state,
+ virDomainPtr dom,
+ const char *event,
+ virConnectDomainQemuMonitorEventCallback cb,
+ void *opaque,
+ virFreeCallback freecb,
+ unsigned int flags,
+ int *callbackID)
+{
+ if (virDomainEventsInitialize() < 0)
+ return -1;
+
+ /* FIXME support event filtering */
+ if (flags != -1)
+ virCheckFlags(0, -1);
+ if (event) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("event filtering on '%s' not implemented
yet"),
+ event);
+ return -1;
+ }
+
+ return virObjectEventStateRegisterID(conn, state, dom ? dom->uuid : NULL,
+ NULL, NULL,
+ virDomainQemuMonitorEventClass, 0,
+ VIR_OBJECT_EVENT_CALLBACK(cb),
+ opaque, freecb,
+ false, callbackID, false);
+}
diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h
index 300c41b..9c41090 100644
--- a/src/conf/domain_event.h
+++ b/src/conf/domain_event.h
@@ -219,4 +219,27 @@ virDomainEventStateDeregister(virConnectPtr conn,
virConnectDomainEventCallback callback)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
+int
+virDomainQemuMonitorEventStateRegisterID(virConnectPtr conn,
+ virObjectEventStatePtr state,
+ virDomainPtr dom,
+ const char *event,
+ virConnectDomainQemuMonitorEventCallback cb,
+ void *opaque,
+ virFreeCallback freecb,
+ unsigned int flags,
+ int *callbackID)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(5)
+ ATTRIBUTE_NONNULL(9);
+
+virObjectEventPtr
+virDomainQemuMonitorEventNew(int id,
+ const char *name,
+ const unsigned char *uuid,
+ const char *event,
+ long long seconds,
+ unsigned int micros,
+ const char *details)
+ ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
+
#endif
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index f1607cd..a3eca41 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -459,6 +459,8 @@ virDomainEventTrayChangeNewFromDom;
virDomainEventTrayChangeNewFromObj;
virDomainEventWatchdogNewFromDom;
virDomainEventWatchdogNewFromObj;
+virDomainQemuMonitorEventNew;
+virDomainQemuMonitorEventStateRegisterID;
# conf/domain_nwfilter.h
--
1.8.5.3