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 | 140 +++++++++++++++++++++++++++++++++++++++++++++++ src/conf/domain_event.h | 22 ++++++++ src/libvirt_private.syms | 2 + 3 files changed, 164 insertions(+) diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c index 9c18922..66fe769 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,49 @@ 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 + * @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, + int *callbackID) +{ + if (virDomainEventsInitialize() < 0) + return -1; + + /* FIXME support event filtering */ + 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..eb5183e 100644 --- a/src/conf/domain_event.h +++ b/src/conf/domain_event.h @@ -219,4 +219,26 @@ 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, + int *callbackID) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(5) + ATTRIBUTE_NONNULL(8); + +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 dead33b..1d981b2 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -454,6 +454,8 @@ virDomainEventTrayChangeNewFromDom; virDomainEventTrayChangeNewFromObj; virDomainEventWatchdogNewFromDom; virDomainEventWatchdogNewFromObj; +virDomainQemuMonitorEventNew; +virDomainQemuMonitorEventStateRegisterID; # conf/domain_nwfilter.h -- 1.8.5.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list