提交 a59097e5 编写于 作者: E Eric Blake

event: add notion of remoteID for filtering client network events

In order to mirror a server with per-object filtering, the client
needs to track which server callbackID is servicing the client
callback.  This patch introduces the notion of a serverID, as
well as the plumbing to use it for network events, although the
actual complexity of using per-object filtering in the remote
driver is deferred to a later patch.

* src/conf/object_event.h (virObjectEventStateEventID): Add parameter.
(virObjectEventStateQueueRemote, virObjectEventStateSetRemote):
New prototypes.
(virObjectEventStateRegisterID): Move...
* src/conf/object_event_private.h: ...here, and add parameter.
(_virObjectEvent): Add field.
* src/conf/network_event.h (virNetworkEventStateRegisterClient): New
prototype.
* src/conf/object_event.c (_virObjectEventCallback): Add field.
(virObjectEventStateSetRemote): New function.
(virObjectEventStateQueue): Make wrapper around...
(virObjectEventStateQueueRemote): New function.
(virObjectEventCallbackListCount): Tweak return count when remote
id matching is used.
(virObjectEventCallbackLookup, virObjectEventStateRegisterID):
Tweak registration when remote id matching will be used.
(virObjectEventNew): Default to no remote id.
(virObjectEventCallbackListAddID): Likewise, but set remote id
when one is available.
(virObjectEventCallbackListRemoveID)
(virObjectEventCallbackListMarkDeleteID): Adjust return value when
remote id was set.
(virObjectEventStateEventID): Query existing id.
(virObjectEventDispatchMatchCallback): Require matching event id.
(virObjectEventStateCallbackID): Adjust caller.
* src/conf/network_event.c (virNetworkEventStateRegisterClient): New
function.
(virNetworkEventStateRegisterID): Update caller.
* src/conf/domain_event.c (virDomainEventStateRegister)
(virDomainEventStateRegisterID): Update callers.
* src/remote/remote_driver.c
(remoteConnectNetworkEventRegisterAny)
(remoteConnectNetworkEventDeregisterAny)
(remoteConnectDomainEventDeregisterAny): Likewise.
(remoteEventQueue): Hoist earlier to avoid forward declaration,
and add parameter.  Adjust all callers.
* src/libvirt_private.syms (conf/object_event.h): Drop function.
Signed-off-by: NEric Blake <eblake@redhat.com>
上级 b9d14ef0
...@@ -1288,7 +1288,7 @@ virDomainEventStateRegister(virConnectPtr conn, ...@@ -1288,7 +1288,7 @@ virDomainEventStateRegister(virConnectPtr conn,
virDomainEventClass, virDomainEventClass,
VIR_DOMAIN_EVENT_ID_LIFECYCLE, VIR_DOMAIN_EVENT_ID_LIFECYCLE,
VIR_OBJECT_EVENT_CALLBACK(callback), VIR_OBJECT_EVENT_CALLBACK(callback),
opaque, freecb, NULL); opaque, freecb, NULL, false);
} }
...@@ -1325,7 +1325,7 @@ virDomainEventStateRegisterID(virConnectPtr conn, ...@@ -1325,7 +1325,7 @@ virDomainEventStateRegisterID(virConnectPtr conn,
return virObjectEventStateRegisterID(conn, state, dom ? dom->uuid : NULL, return virObjectEventStateRegisterID(conn, state, dom ? dom->uuid : NULL,
virDomainEventClass, eventID, virDomainEventClass, eventID,
VIR_OBJECT_EVENT_CALLBACK(cb), VIR_OBJECT_EVENT_CALLBACK(cb),
opaque, freecb, callbackID); opaque, freecb, callbackID, false);
} }
......
...@@ -154,7 +154,47 @@ virNetworkEventStateRegisterID(virConnectPtr conn, ...@@ -154,7 +154,47 @@ virNetworkEventStateRegisterID(virConnectPtr conn,
return virObjectEventStateRegisterID(conn, state, net ? net->uuid : NULL, return virObjectEventStateRegisterID(conn, state, net ? net->uuid : NULL,
virNetworkEventClass, eventID, virNetworkEventClass, eventID,
VIR_OBJECT_EVENT_CALLBACK(cb), VIR_OBJECT_EVENT_CALLBACK(cb),
opaque, freecb, callbackID); opaque, freecb, callbackID, false);
}
/**
* virNetworkEventStateRegisterClient:
* @conn: connection to associate with callback
* @state: object event state
* @net: network to filter on or NULL for all networks
* @eventID: ID of the event type 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, and return the registration handle in
* @callbackID. This version is intended for use on the client side
* of RPC.
*
* Returns: the number of callbacks now registered, or -1 on error
*/
int
virNetworkEventStateRegisterClient(virConnectPtr conn,
virObjectEventStatePtr state,
virNetworkPtr net,
int eventID,
virConnectNetworkEventGenericCallback cb,
void *opaque,
virFreeCallback freecb,
int *callbackID)
{
if (virNetworkEventsInitialize() < 0)
return -1;
/* FIXME: All servers that support network events should also support
* per-object filtering. */
return virObjectEventStateRegisterID(conn, state, net ? net->uuid : NULL,
virNetworkEventClass, eventID,
VIR_OBJECT_EVENT_CALLBACK(cb),
opaque, freecb, callbackID, false);
} }
......
...@@ -36,7 +36,21 @@ virNetworkEventStateRegisterID(virConnectPtr conn, ...@@ -36,7 +36,21 @@ virNetworkEventStateRegisterID(virConnectPtr conn,
virConnectNetworkEventGenericCallback cb, virConnectNetworkEventGenericCallback cb,
void *opaque, void *opaque,
virFreeCallback freecb, virFreeCallback freecb,
int *callbackID); int *callbackID)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(5)
ATTRIBUTE_NONNULL(8);
int
virNetworkEventStateRegisterClient(virConnectPtr conn,
virObjectEventStatePtr state,
virNetworkPtr net,
int eventID,
virConnectNetworkEventGenericCallback cb,
void *opaque,
virFreeCallback freecb,
int *callbackID)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(5)
ATTRIBUTE_NONNULL(8);
virObjectEventPtr virObjectEventPtr
virNetworkEventLifecycleNew(const char *name, virNetworkEventLifecycleNew(const char *name,
......
...@@ -66,6 +66,7 @@ struct _virObjectEventCallback { ...@@ -66,6 +66,7 @@ struct _virObjectEventCallback {
virClassPtr klass; virClassPtr klass;
int eventID; int eventID;
virConnectPtr conn; virConnectPtr conn;
int remoteID;
bool uuid_filter; bool uuid_filter;
unsigned char uuid[VIR_UUID_BUFLEN]; unsigned char uuid[VIR_UUID_BUFLEN];
virConnectObjectEventGenericCallback cb; virConnectObjectEventGenericCallback cb;
...@@ -148,19 +149,29 @@ virObjectEventCallbackListFree(virObjectEventCallbackListPtr list) ...@@ -148,19 +149,29 @@ virObjectEventCallbackListFree(virObjectEventCallbackListPtr list)
* @cbList: the list * @cbList: the list
* @klass: the base event class * @klass: the base event class
* @eventID: the event ID * @eventID: the event ID
* @uuid: optional uuid of per-object filtering
* @serverFilter: true if server supports object filtering
* *
* Internal function to count how many callbacks remain registered for * Internal function to count how many callbacks remain registered for
* the given @eventID; knowing this allows the client side of the * the given @eventID and @uuid; knowing this allows the client side
* remote driver know when it must send an RPC to adjust the callbacks * of the remote driver know when it must send an RPC to adjust the
* on the server. Note that this function intentionally ignores * callbacks on the server. When @serverFilter is false, this function
* the legacy field, since RPC calls use only a single callback on * returns a count that includes both global and per-object callbacks,
* the server to manage both legacy and modern domain lifecycle events. * since the remote side will use a single global event to feed both.
* When true, the count is limited to the callbacks with the same
* @uuid, and where a remoteID has already been set on the callback
* with virObjectEventStateSetRemote(). Note that this function
* intentionally ignores the legacy field, since RPC calls use only a
* single callback on the server to manage both legacy and modern
* global domain lifecycle events.
*/ */
static int static int
virObjectEventCallbackListCount(virConnectPtr conn, virObjectEventCallbackListCount(virConnectPtr conn,
virObjectEventCallbackListPtr cbList, virObjectEventCallbackListPtr cbList,
virClassPtr klass, virClassPtr klass,
int eventID) int eventID,
unsigned char uuid[VIR_UUID_BUFLEN],
bool serverFilter)
{ {
size_t i; size_t i;
int ret = 0; int ret = 0;
...@@ -171,7 +182,12 @@ virObjectEventCallbackListCount(virConnectPtr conn, ...@@ -171,7 +182,12 @@ virObjectEventCallbackListCount(virConnectPtr conn,
if (cb->klass == klass && if (cb->klass == klass &&
cb->eventID == eventID && cb->eventID == eventID &&
cb->conn == conn && cb->conn == conn &&
!cb->deleted) !cb->deleted &&
(!serverFilter ||
(cb->remoteID >= 0 &&
((uuid && cb->uuid_filter &&
memcmp(cb->uuid, uuid, VIR_UUID_BUFLEN) == 0) ||
(!uuid && !cb->uuid_filter)))))
ret++; ret++;
} }
return ret; return ret;
...@@ -196,17 +212,19 @@ virObjectEventCallbackListRemoveID(virConnectPtr conn, ...@@ -196,17 +212,19 @@ virObjectEventCallbackListRemoveID(virConnectPtr conn,
virObjectEventCallbackPtr cb = cbList->callbacks[i]; virObjectEventCallbackPtr cb = cbList->callbacks[i];
if (cb->callbackID == callbackID && cb->conn == conn) { if (cb->callbackID == callbackID && cb->conn == conn) {
virClassPtr klass = cb->klass; int ret;
int eventID = cb->eventID;
ret = virObjectEventCallbackListCount(conn, cbList, cb->klass,
cb->eventID,
cb->uuid_filter ? cb->uuid : NULL,
cb->remoteID >= 0) - 1;
if (cb->freecb) if (cb->freecb)
(*cb->freecb)(cb->opaque); (*cb->freecb)(cb->opaque);
virObjectUnref(cb->conn); virObjectUnref(cb->conn);
VIR_FREE(cb); VIR_FREE(cb);
VIR_DELETE_ELEMENT(cbList->callbacks, i, cbList->count); VIR_DELETE_ELEMENT(cbList->callbacks, i, cbList->count);
return ret;
return virObjectEventCallbackListCount(conn, cbList, klass,
eventID);
} }
} }
...@@ -230,7 +248,9 @@ virObjectEventCallbackListMarkDeleteID(virConnectPtr conn, ...@@ -230,7 +248,9 @@ virObjectEventCallbackListMarkDeleteID(virConnectPtr conn,
if (cb->callbackID == callbackID && cb->conn == conn) { if (cb->callbackID == callbackID && cb->conn == conn) {
cb->deleted = true; cb->deleted = true;
return virObjectEventCallbackListCount(conn, cbList, cb->klass, return virObjectEventCallbackListCount(conn, cbList, cb->klass,
cb->eventID); cb->eventID,
cb->uuid_filter ? cb->uuid : NULL,
cb->remoteID >= 0);
} }
} }
...@@ -280,9 +300,13 @@ virObjectEventCallbackListPurgeMarked(virObjectEventCallbackListPtr cbList) ...@@ -280,9 +300,13 @@ virObjectEventCallbackListPurgeMarked(virObjectEventCallbackListPtr cbList)
* @eventID: the event ID * @eventID: the event ID
* @callback: the callback to locate * @callback: the callback to locate
* @legacy: true if callback is tracked by function instead of callbackID * @legacy: true if callback is tracked by function instead of callbackID
* @remoteID: optionally return a known remoteID
* *
* Internal function to determine if @callback already has a * Internal function to determine if @callback already has a
* callbackID in @cbList for the given @conn and other filters. * callbackID in @cbList for the given @conn and other filters. If
* @remoteID is non-NULL, and another callback exists that can be
* serviced by the same remote event, then set it to that remote ID.
*
* Return the id if found, or -1 with no error issued if not present. * Return the id if found, or -1 with no error issued if not present.
*/ */
static int ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) static int ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
...@@ -292,29 +316,33 @@ virObjectEventCallbackLookup(virConnectPtr conn, ...@@ -292,29 +316,33 @@ virObjectEventCallbackLookup(virConnectPtr conn,
virClassPtr klass, virClassPtr klass,
int eventID, int eventID,
virConnectObjectEventGenericCallback callback, virConnectObjectEventGenericCallback callback,
bool legacy) bool legacy,
int *remoteID)
{ {
int ret = -1;
size_t i; size_t i;
if (remoteID)
*remoteID = -1;
for (i = 0; i < cbList->count; i++) { for (i = 0; i < cbList->count; i++) {
virObjectEventCallbackPtr cb = cbList->callbacks[i]; virObjectEventCallbackPtr cb = cbList->callbacks[i];
if (cb->deleted) if (cb->deleted)
continue; continue;
if (cb->cb == callback && if (cb->klass == klass &&
cb->klass == klass &&
cb->eventID == eventID && cb->eventID == eventID &&
cb->conn == conn && cb->conn == conn &&
cb->legacy == legacy && cb->legacy == legacy &&
((uuid && cb->uuid_filter && ((uuid && cb->uuid_filter &&
memcmp(cb->uuid, uuid, VIR_UUID_BUFLEN) == 0) || memcmp(cb->uuid, uuid, VIR_UUID_BUFLEN) == 0) ||
(!uuid && !cb->uuid_filter))) { (!uuid && !cb->uuid_filter))) {
ret = cb->callbackID; if (remoteID)
break; *remoteID = cb->remoteID;
if (cb->cb == callback)
return cb->callbackID;
} }
} }
return ret; return -1;
} }
...@@ -329,6 +357,7 @@ virObjectEventCallbackLookup(virConnectPtr conn, ...@@ -329,6 +357,7 @@ virObjectEventCallbackLookup(virConnectPtr conn,
* @opaque: opaque data to pass to @callback * @opaque: opaque data to pass to @callback
* @freecb: callback to free @opaque * @freecb: callback to free @opaque
* @callbackID: filled with callback ID * @callbackID: filled with callback ID
* @serverFilter: true if server supports object filtering
* *
* Internal function to add a callback from a virObjectEventCallbackListPtr * Internal function to add a callback from a virObjectEventCallbackListPtr
*/ */
...@@ -341,10 +370,12 @@ virObjectEventCallbackListAddID(virConnectPtr conn, ...@@ -341,10 +370,12 @@ virObjectEventCallbackListAddID(virConnectPtr conn,
virConnectObjectEventGenericCallback callback, virConnectObjectEventGenericCallback callback,
void *opaque, void *opaque,
virFreeCallback freecb, virFreeCallback freecb,
int *callbackID) int *callbackID,
bool serverFilter)
{ {
virObjectEventCallbackPtr event; virObjectEventCallbackPtr event;
int ret = -1; int ret = -1;
int remoteID = -1;
VIR_DEBUG("conn=%p cblist=%p uuid=%p " VIR_DEBUG("conn=%p cblist=%p uuid=%p "
"klass=%p eventID=%d callback=%p opaque=%p", "klass=%p eventID=%d callback=%p opaque=%p",
...@@ -358,7 +389,8 @@ virObjectEventCallbackListAddID(virConnectPtr conn, ...@@ -358,7 +389,8 @@ virObjectEventCallbackListAddID(virConnectPtr conn,
/* check if we already have this callback on our list */ /* check if we already have this callback on our list */
if (virObjectEventCallbackLookup(conn, cbList, uuid, if (virObjectEventCallbackLookup(conn, cbList, uuid,
klass, eventID, callback, klass, eventID, callback,
!callbackID) != -1) { !callbackID,
serverFilter ? &remoteID : NULL) != -1) {
virReportError(VIR_ERR_INVALID_ARG, "%s", virReportError(VIR_ERR_INVALID_ARG, "%s",
_("event callback already tracked")); _("event callback already tracked"));
return -1; return -1;
...@@ -373,6 +405,7 @@ virObjectEventCallbackListAddID(virConnectPtr conn, ...@@ -373,6 +405,7 @@ virObjectEventCallbackListAddID(virConnectPtr conn,
event->eventID = eventID; event->eventID = eventID;
event->opaque = opaque; event->opaque = opaque;
event->freecb = freecb; event->freecb = freecb;
event->remoteID = remoteID;
/* Only need 'uuid' for matching; 'id' can change as domain /* Only need 'uuid' for matching; 'id' can change as domain
* switches between running and shutoff, and 'name' can change in * switches between running and shutoff, and 'name' can change in
...@@ -390,7 +423,10 @@ virObjectEventCallbackListAddID(virConnectPtr conn, ...@@ -390,7 +423,10 @@ virObjectEventCallbackListAddID(virConnectPtr conn,
if (VIR_APPEND_ELEMENT(cbList->callbacks, cbList->count, event) < 0) if (VIR_APPEND_ELEMENT(cbList->callbacks, cbList->count, event) < 0)
goto cleanup; goto cleanup;
ret = virObjectEventCallbackListCount(conn, cbList, klass, eventID); ret = virObjectEventCallbackListCount(conn, cbList, klass, eventID,
uuid, serverFilter);
if (serverFilter && remoteID < 0)
ret++;
cleanup: cleanup:
if (event) if (event)
...@@ -588,6 +624,7 @@ virObjectEventNew(virClassPtr klass, ...@@ -588,6 +624,7 @@ virObjectEventNew(virClassPtr klass,
event->dispatch = dispatcher; event->dispatch = dispatcher;
event->eventID = eventID; event->eventID = eventID;
event->remoteID = -1;
if (VIR_STRDUP(event->meta.name, name) < 0) { if (VIR_STRDUP(event->meta.name, name) < 0) {
VIR_FREE(event); VIR_FREE(event);
...@@ -635,6 +672,8 @@ virObjectEventDispatchMatchCallback(virObjectEventPtr event, ...@@ -635,6 +672,8 @@ virObjectEventDispatchMatchCallback(virObjectEventPtr event,
return false; return false;
if (cb->eventID != event->eventID) if (cb->eventID != event->eventID)
return false; return false;
if (cb->remoteID != event->remoteID)
return false;
if (cb->uuid_filter) { if (cb->uuid_filter) {
/* Deliberately ignoring 'id' for matching, since that /* Deliberately ignoring 'id' for matching, since that
...@@ -692,17 +731,21 @@ virObjectEventStateQueueDispatch(virObjectEventStatePtr state, ...@@ -692,17 +731,21 @@ virObjectEventStateQueueDispatch(virObjectEventStatePtr state,
/** /**
* virObjectEventStateQueue: * virObjectEventStateQueueRemote:
* @state: the event state object * @state: the event state object
* @event: event to add to the queue * @event: event to add to the queue
* @remoteID: limit dispatch to callbacks with the same remote id
* *
* Adds @event to the queue of events to be dispatched at the next * Adds @event to the queue of events to be dispatched at the next
* safe moment. The caller should no longer use @event after this * safe moment. The caller should no longer use @event after this
* call. * call. If @remoteID is non-negative, the event will only be sent to
* callbacks where virObjectEventStateSetRemote() registered a remote
* id.
*/ */
void void
virObjectEventStateQueue(virObjectEventStatePtr state, virObjectEventStateQueueRemote(virObjectEventStatePtr state,
virObjectEventPtr event) virObjectEventPtr event,
int remoteID)
{ {
if (state->timer < 0) { if (state->timer < 0) {
virObjectUnref(event); virObjectUnref(event);
...@@ -711,6 +754,7 @@ virObjectEventStateQueue(virObjectEventStatePtr state, ...@@ -711,6 +754,7 @@ virObjectEventStateQueue(virObjectEventStatePtr state,
virObjectEventStateLock(state); virObjectEventStateLock(state);
event->remoteID = remoteID;
if (virObjectEventQueuePush(state->queue, event) < 0) { if (virObjectEventQueuePush(state->queue, event) < 0) {
VIR_DEBUG("Error adding event to queue"); VIR_DEBUG("Error adding event to queue");
virObjectUnref(event); virObjectUnref(event);
...@@ -722,6 +766,23 @@ virObjectEventStateQueue(virObjectEventStatePtr state, ...@@ -722,6 +766,23 @@ virObjectEventStateQueue(virObjectEventStatePtr state,
} }
/**
* virObjectEventStateQueue:
* @state: the event state object
* @event: event to add to the queue
*
* Adds @event to the queue of events to be dispatched at the next
* safe moment. The caller should no longer use @event after this
* call.
*/
void
virObjectEventStateQueue(virObjectEventStatePtr state,
virObjectEventPtr event)
{
virObjectEventStateQueueRemote(state, event, -1);
}
static void static void
virObjectEventStateFlush(virObjectEventStatePtr state) virObjectEventStateFlush(virObjectEventStatePtr state)
{ {
...@@ -761,12 +822,27 @@ virObjectEventStateFlush(virObjectEventStatePtr state) ...@@ -761,12 +822,27 @@ virObjectEventStateFlush(virObjectEventStatePtr state)
* @opaque: data blob to pass to @callback * @opaque: data blob to pass to @callback
* @freecb: callback to free @opaque * @freecb: callback to free @opaque
* @callbackID: filled with callback ID * @callbackID: filled with callback ID
* @serverFilter: true if server supports object filtering
* *
* Register the function @cb with connection @conn, from @state, for * Register the function @cb with connection @conn, from @state, for
* events of type @eventID, and return the registration handle in * events of type @eventID, and return the registration handle in
* @callbackID. * @callbackID.
* *
* Returns: the number of callbacks now registered, or -1 on error * The return value is only important when registering client-side
* mirroring of remote events (since the public API is documented to
* return the callbackID rather than a count). A return of 1 means
* that this is the first use of this type of event, so a remote event
* must be enabled; a return larger than 1 means that an existing
* remote event can already feed this callback. If @serverFilter is
* false, the return count assumes that a single global remote feeds
* both generic and per-object callbacks, and that the event queue
* will be fed with virObjectEventStateQueue(). If it is true, then
* the return count assumes that the remote side is capable of per-
* object filtering; the user must call virObjectEventStateSetRemote()
* to record the remote id, and queue events with
* virObjectEventStateQueueRemote().
*
* Returns: the number of callbacks now registered, or -1 on error.
*/ */
int int
virObjectEventStateRegisterID(virConnectPtr conn, virObjectEventStateRegisterID(virConnectPtr conn,
...@@ -777,7 +853,8 @@ virObjectEventStateRegisterID(virConnectPtr conn, ...@@ -777,7 +853,8 @@ virObjectEventStateRegisterID(virConnectPtr conn,
virConnectObjectEventGenericCallback cb, virConnectObjectEventGenericCallback cb,
void *opaque, void *opaque,
virFreeCallback freecb, virFreeCallback freecb,
int *callbackID) int *callbackID,
bool serverFilter)
{ {
int ret = -1; int ret = -1;
...@@ -797,7 +874,7 @@ virObjectEventStateRegisterID(virConnectPtr conn, ...@@ -797,7 +874,7 @@ virObjectEventStateRegisterID(virConnectPtr conn,
ret = virObjectEventCallbackListAddID(conn, state->callbacks, ret = virObjectEventCallbackListAddID(conn, state->callbacks,
uuid, klass, eventID, uuid, klass, eventID,
cb, opaque, freecb, cb, opaque, freecb,
callbackID); callbackID, serverFilter);
if (ret == -1 && if (ret == -1 &&
state->callbacks->count == 0 && state->callbacks->count == 0 &&
...@@ -874,7 +951,7 @@ virObjectEventStateCallbackID(virConnectPtr conn, ...@@ -874,7 +951,7 @@ virObjectEventStateCallbackID(virConnectPtr conn,
virObjectEventStateLock(state); virObjectEventStateLock(state);
ret = virObjectEventCallbackLookup(conn, state->callbacks, NULL, ret = virObjectEventCallbackLookup(conn, state->callbacks, NULL,
klass, eventID, callback, true); klass, eventID, callback, true, NULL);
virObjectEventStateUnlock(state); virObjectEventStateUnlock(state);
if (ret < 0) if (ret < 0)
...@@ -890,16 +967,20 @@ virObjectEventStateCallbackID(virConnectPtr conn, ...@@ -890,16 +967,20 @@ virObjectEventStateCallbackID(virConnectPtr conn,
* @conn: connection associated with the callback * @conn: connection associated with the callback
* @state: object event state * @state: object event state
* @callbackID: the callback to query * @callbackID: the callback to query
* @remoteID: optionally output remote ID of the callback
* *
* Query what event ID type is associated with the * Query what event ID type is associated with the callback
* callback @callbackID for connection @conn * @callbackID for connection @conn. If @remoteID is non-null, it
* will be set to the remote id previously registered with
* virObjectEventStateSetRemote().
* *
* Returns 0 on success, -1 on error * Returns 0 on success, -1 on error
*/ */
int int
virObjectEventStateEventID(virConnectPtr conn, virObjectEventStateEventID(virConnectPtr conn,
virObjectEventStatePtr state, virObjectEventStatePtr state,
int callbackID) int callbackID,
int *remoteID)
{ {
int ret = -1; int ret = -1;
size_t i; size_t i;
...@@ -913,6 +994,8 @@ virObjectEventStateEventID(virConnectPtr conn, ...@@ -913,6 +994,8 @@ virObjectEventStateEventID(virConnectPtr conn,
continue; continue;
if (cb->callbackID == callbackID && cb->conn == conn) { if (cb->callbackID == callbackID && cb->conn == conn) {
if (remoteID)
*remoteID = cb->remoteID;
ret = cb->eventID; ret = cb->eventID;
break; break;
} }
...@@ -925,3 +1008,39 @@ virObjectEventStateEventID(virConnectPtr conn, ...@@ -925,3 +1008,39 @@ virObjectEventStateEventID(virConnectPtr conn,
callbackID); callbackID);
return ret; return ret;
} }
/**
* virObjectEventStateSetRemote:
* @conn: connection associated with the callback
* @state: object event state
* @callbackID: the callback to adjust
* @remoteID: the remote ID to associate with the callback
*
* Update @callbackID for connection @conn to record that it is now
* tied to @remoteID, and will therefore only match events that are
* sent with virObjectEventStateQueueRemote() with the same remote ID.
* Silently does nothing if @callbackID is invalid.
*/
void
virObjectEventStateSetRemote(virConnectPtr conn,
virObjectEventStatePtr state,
int callbackID,
int remoteID)
{
size_t i;
virObjectEventStateLock(state);
for (i = 0; i < state->callbacks->count; i++) {
virObjectEventCallbackPtr cb = state->callbacks->callbacks[i];
if (cb->deleted)
continue;
if (cb->callbackID == callbackID && cb->conn == conn) {
cb->remoteID = remoteID;
break;
}
}
virObjectEventStateUnlock(state);
}
...@@ -67,27 +67,31 @@ void ...@@ -67,27 +67,31 @@ void
virObjectEventStateQueue(virObjectEventStatePtr state, virObjectEventStateQueue(virObjectEventStatePtr state,
virObjectEventPtr event) virObjectEventPtr event)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
int
virObjectEventStateRegisterID(virConnectPtr conn, void
virObjectEventStatePtr state, virObjectEventStateQueueRemote(virObjectEventStatePtr state,
unsigned char *uuid, virObjectEventPtr event,
virClassPtr klass, int remoteID)
int eventID, ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
virConnectObjectEventGenericCallback cb,
void *opaque,
virFreeCallback freecb,
int *callbackID)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4)
ATTRIBUTE_NONNULL(6);
int int
virObjectEventStateDeregisterID(virConnectPtr conn, virObjectEventStateDeregisterID(virConnectPtr conn,
virObjectEventStatePtr state, virObjectEventStatePtr state,
int callbackID) int callbackID)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
int int
virObjectEventStateEventID(virConnectPtr conn, virObjectEventStateEventID(virConnectPtr conn,
virObjectEventStatePtr state, virObjectEventStatePtr state,
int callbackID) int callbackID,
int *remoteID)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
void
virObjectEventStateSetRemote(virConnectPtr conn,
virObjectEventStatePtr state,
int callbackID,
int remoteID)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
#endif #endif
...@@ -48,12 +48,27 @@ struct _virObjectEvent { ...@@ -48,12 +48,27 @@ struct _virObjectEvent {
virObject parent; virObject parent;
int eventID; int eventID;
virObjectMeta meta; virObjectMeta meta;
int remoteID;
virObjectEventDispatchFunc dispatch; virObjectEventDispatchFunc dispatch;
}; };
virClassPtr virClassPtr
virClassForObjectEvent(void); virClassForObjectEvent(void);
int
virObjectEventStateRegisterID(virConnectPtr conn,
virObjectEventStatePtr state,
unsigned char *uuid,
virClassPtr klass,
int eventID,
virConnectObjectEventGenericCallback cb,
void *opaque,
virFreeCallback freecb,
int *callbackID,
bool remoteFilter)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4)
ATTRIBUTE_NONNULL(6);
int int
virObjectEventStateCallbackID(virConnectPtr conn, virObjectEventStateCallbackID(virConnectPtr conn,
virObjectEventStatePtr state, virObjectEventStatePtr state,
......
...@@ -634,7 +634,6 @@ virObjectEventStateEventID; ...@@ -634,7 +634,6 @@ virObjectEventStateEventID;
virObjectEventStateFree; virObjectEventStateFree;
virObjectEventStateNew; virObjectEventStateNew;
virObjectEventStateQueue; virObjectEventStateQueue;
virObjectEventStateRegisterID;
# conf/secret_conf.h # conf/secret_conf.h
......
...@@ -151,7 +151,7 @@ static void make_nonnull_storage_vol(remote_nonnull_storage_vol *vol_dst, virSto ...@@ -151,7 +151,7 @@ static void make_nonnull_storage_vol(remote_nonnull_storage_vol *vol_dst, virSto
static void make_nonnull_secret(remote_nonnull_secret *secret_dst, virSecretPtr secret_src); static void make_nonnull_secret(remote_nonnull_secret *secret_dst, virSecretPtr secret_src);
static void make_nonnull_nwfilter(remote_nonnull_nwfilter *nwfilter_dst, virNWFilterPtr nwfilter_src); static void make_nonnull_nwfilter(remote_nonnull_nwfilter *nwfilter_dst, virNWFilterPtr nwfilter_src);
static void make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *snapshot_dst, virDomainSnapshotPtr snapshot_src); static void make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *snapshot_dst, virDomainSnapshotPtr snapshot_src);
static void remoteEventQueue(struct private_data *priv, virObjectEventPtr event);
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
/* Helper functions for remoteOpen. */ /* Helper functions for remoteOpen. */
...@@ -2928,10 +2928,10 @@ remoteConnectNetworkEventRegisterAny(virConnectPtr conn, ...@@ -2928,10 +2928,10 @@ remoteConnectNetworkEventRegisterAny(virConnectPtr conn,
remoteDriverLock(priv); remoteDriverLock(priv);
if ((count = virNetworkEventStateRegisterID(conn, priv->eventState, if ((count = virNetworkEventStateRegisterClient(conn, priv->eventState,
net, eventID, callback, net, eventID, callback,
opaque, freecb, opaque, freecb,
&callbackID)) < 0) &callbackID)) < 0)
goto done; goto done;
/* If this is the first callback for this eventID, we need to enable /* If this is the first callback for this eventID, we need to enable
...@@ -2964,12 +2964,13 @@ remoteConnectNetworkEventDeregisterAny(virConnectPtr conn, ...@@ -2964,12 +2964,13 @@ remoteConnectNetworkEventDeregisterAny(virConnectPtr conn,
int rv = -1; int rv = -1;
remote_connect_network_event_deregister_any_args args; remote_connect_network_event_deregister_any_args args;
int eventID; int eventID;
int remoteID;
int count; int count;
remoteDriverLock(priv); remoteDriverLock(priv);
if ((eventID = virObjectEventStateEventID(conn, priv->eventState, if ((eventID = virObjectEventStateEventID(conn, priv->eventState,
callbackID)) < 0) callbackID, &remoteID)) < 0)
goto done; goto done;
if ((count = virObjectEventStateDeregisterID(conn, priv->eventState, if ((count = virObjectEventStateDeregisterID(conn, priv->eventState,
...@@ -4466,6 +4467,15 @@ done: ...@@ -4466,6 +4467,15 @@ done:
} }
static void
remoteEventQueue(struct private_data *priv, virObjectEventPtr event,
int remoteID)
{
if (event)
virObjectEventStateQueueRemote(priv->eventState, event, remoteID);
}
static void static void
remoteDomainBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, remoteDomainBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virNetClientPtr client ATTRIBUTE_UNUSED, virNetClientPtr client ATTRIBUTE_UNUSED,
...@@ -4484,7 +4494,7 @@ remoteDomainBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, ...@@ -4484,7 +4494,7 @@ remoteDomainBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
event = virDomainEventLifecycleNewFromDom(dom, msg->event, msg->detail); event = virDomainEventLifecycleNewFromDom(dom, msg->event, msg->detail);
virDomainFree(dom); virDomainFree(dom);
remoteEventQueue(priv, event); remoteEventQueue(priv, event, -1);
} }
...@@ -4506,7 +4516,7 @@ remoteDomainBuildEventReboot(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, ...@@ -4506,7 +4516,7 @@ remoteDomainBuildEventReboot(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
event = virDomainEventRebootNewFromDom(dom); event = virDomainEventRebootNewFromDom(dom);
virDomainFree(dom); virDomainFree(dom);
remoteEventQueue(priv, event); remoteEventQueue(priv, event, -1);
} }
...@@ -4528,7 +4538,7 @@ remoteDomainBuildEventRTCChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, ...@@ -4528,7 +4538,7 @@ remoteDomainBuildEventRTCChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
event = virDomainEventRTCChangeNewFromDom(dom, msg->offset); event = virDomainEventRTCChangeNewFromDom(dom, msg->offset);
virDomainFree(dom); virDomainFree(dom);
remoteEventQueue(priv, event); remoteEventQueue(priv, event, -1);
} }
...@@ -4550,7 +4560,7 @@ remoteDomainBuildEventWatchdog(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, ...@@ -4550,7 +4560,7 @@ remoteDomainBuildEventWatchdog(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
event = virDomainEventWatchdogNewFromDom(dom, msg->action); event = virDomainEventWatchdogNewFromDom(dom, msg->action);
virDomainFree(dom); virDomainFree(dom);
remoteEventQueue(priv, event); remoteEventQueue(priv, event, -1);
} }
...@@ -4575,7 +4585,7 @@ remoteDomainBuildEventIOError(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, ...@@ -4575,7 +4585,7 @@ remoteDomainBuildEventIOError(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
msg->action); msg->action);
virDomainFree(dom); virDomainFree(dom);
remoteEventQueue(priv, event); remoteEventQueue(priv, event, -1);
} }
...@@ -4602,7 +4612,7 @@ remoteDomainBuildEventIOErrorReason(virNetClientProgramPtr prog ATTRIBUTE_UNUSED ...@@ -4602,7 +4612,7 @@ remoteDomainBuildEventIOErrorReason(virNetClientProgramPtr prog ATTRIBUTE_UNUSED
virDomainFree(dom); virDomainFree(dom);
remoteEventQueue(priv, event); remoteEventQueue(priv, event, -1);
} }
static void static void
...@@ -4625,7 +4635,7 @@ remoteDomainBuildEventBlockJob(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, ...@@ -4625,7 +4635,7 @@ remoteDomainBuildEventBlockJob(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virDomainFree(dom); virDomainFree(dom);
remoteEventQueue(priv, event); remoteEventQueue(priv, event, -1);
} }
static void static void
...@@ -4681,7 +4691,7 @@ remoteDomainBuildEventGraphics(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, ...@@ -4681,7 +4691,7 @@ remoteDomainBuildEventGraphics(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virDomainFree(dom); virDomainFree(dom);
remoteEventQueue(priv, event); remoteEventQueue(priv, event, -1);
return; return;
error: error:
...@@ -4727,7 +4737,7 @@ remoteDomainBuildEventControlError(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, ...@@ -4727,7 +4737,7 @@ remoteDomainBuildEventControlError(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virDomainFree(dom); virDomainFree(dom);
remoteEventQueue(priv, event); remoteEventQueue(priv, event, -1);
} }
...@@ -4754,7 +4764,7 @@ remoteDomainBuildEventDiskChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, ...@@ -4754,7 +4764,7 @@ remoteDomainBuildEventDiskChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virDomainFree(dom); virDomainFree(dom);
remoteEventQueue(priv, event); remoteEventQueue(priv, event, -1);
} }
...@@ -4779,7 +4789,7 @@ remoteDomainBuildEventTrayChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, ...@@ -4779,7 +4789,7 @@ remoteDomainBuildEventTrayChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virDomainFree(dom); virDomainFree(dom);
remoteEventQueue(priv, event); remoteEventQueue(priv, event, -1);
} }
static void static void
...@@ -4801,7 +4811,7 @@ remoteDomainBuildEventPMWakeup(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, ...@@ -4801,7 +4811,7 @@ remoteDomainBuildEventPMWakeup(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virDomainFree(dom); virDomainFree(dom);
remoteEventQueue(priv, event); remoteEventQueue(priv, event, -1);
} }
static void static void
...@@ -4823,7 +4833,7 @@ remoteDomainBuildEventPMSuspend(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, ...@@ -4823,7 +4833,7 @@ remoteDomainBuildEventPMSuspend(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virDomainFree(dom); virDomainFree(dom);
remoteEventQueue(priv, event); remoteEventQueue(priv, event, -1);
} }
...@@ -4845,7 +4855,7 @@ remoteDomainBuildEventBalloonChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED ...@@ -4845,7 +4855,7 @@ remoteDomainBuildEventBalloonChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED
event = virDomainEventBalloonChangeNewFromDom(dom, msg->actual); event = virDomainEventBalloonChangeNewFromDom(dom, msg->actual);
virDomainFree(dom); virDomainFree(dom);
remoteEventQueue(priv, event); remoteEventQueue(priv, event, -1);
} }
...@@ -4868,7 +4878,7 @@ remoteDomainBuildEventPMSuspendDisk(virNetClientProgramPtr prog ATTRIBUTE_UNUSED ...@@ -4868,7 +4878,7 @@ remoteDomainBuildEventPMSuspendDisk(virNetClientProgramPtr prog ATTRIBUTE_UNUSED
virDomainFree(dom); virDomainFree(dom);
remoteEventQueue(priv, event); remoteEventQueue(priv, event, -1);
} }
...@@ -4891,7 +4901,7 @@ remoteDomainBuildEventDeviceRemoved(virNetClientProgramPtr prog ATTRIBUTE_UNUSED ...@@ -4891,7 +4901,7 @@ remoteDomainBuildEventDeviceRemoved(virNetClientProgramPtr prog ATTRIBUTE_UNUSED
virDomainFree(dom); virDomainFree(dom);
remoteEventQueue(priv, event); remoteEventQueue(priv, event, -1);
} }
...@@ -4910,10 +4920,11 @@ remoteNetworkBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, ...@@ -4910,10 +4920,11 @@ remoteNetworkBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
if (!net) if (!net)
return; return;
event = virNetworkEventLifecycleNew(net->name, net->uuid, msg->event, msg->detail); event = virNetworkEventLifecycleNew(net->name, net->uuid, msg->event,
msg->detail);
virNetworkFree(net); virNetworkFree(net);
remoteEventQueue(priv, event); remoteEventQueue(priv, event, -1);
} }
...@@ -5264,7 +5275,7 @@ remoteConnectDomainEventDeregisterAny(virConnectPtr conn, ...@@ -5264,7 +5275,7 @@ remoteConnectDomainEventDeregisterAny(virConnectPtr conn,
remoteDriverLock(priv); remoteDriverLock(priv);
if ((eventID = virObjectEventStateEventID(conn, priv->eventState, if ((eventID = virObjectEventStateEventID(conn, priv->eventState,
callbackID)) < 0) callbackID, NULL)) < 0)
goto done; goto done;
if ((count = virObjectEventStateDeregisterID(conn, priv->eventState, if ((count = virObjectEventStateDeregisterID(conn, priv->eventState,
...@@ -6798,12 +6809,6 @@ done: ...@@ -6798,12 +6809,6 @@ done:
return rv; return rv;
} }
static void
remoteEventQueue(struct private_data *priv, virObjectEventPtr event)
{
if (event)
virObjectEventStateQueue(priv->eventState, event);
}
/* get_nonnull_domain and get_nonnull_network turn an on-wire /* get_nonnull_domain and get_nonnull_network turn an on-wire
* (name, uuid) pair into virDomainPtr or virNetworkPtr object. * (name, uuid) pair into virDomainPtr or virNetworkPtr object.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册