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

event: prepare client to track domain callbackID

We want to convert over to server-side events, even for older
APIs.  To do that, the client side of the remote driver wants
to distinguish between legacy virConnectDomainEventRegister and
normal virConnectDomainEventRegisterAny, while knowing the
client callbackID and the server's serverID for both types of
registration.  The client also needs to probe whether the
server supports server-side filtering.  However, for ease of
review, we don't actually use the new RPCs until a later patch.

* src/conf/object_event_private.h (virObjectEventStateCallbackID):
Add parameter.
* src/conf/object_event.c (virObjectEventCallbackListAddID)
(virObjectEventStateRegisterID): Separate legacy from callbackID.
(virObjectEventStateCallbackID): Pass through parameter.
(virObjectEventCallbackLookup): Let legacy and global domain
lifecycle events share a common remoteID.
* src/conf/network_event.c (virNetworkEventStateRegisterID):
Update caller.
* src/conf/domain_event.c (virDomainEventStateRegister)
(virDomainEventStateRegisterID, virDomainEventStateDeregister):
Likewise.
(virDomainEventStateRegisterClient)
(virDomainEventStateCallbackID): Implement new functions.
* src/conf/domain_event.h (virDomainEventStateRegisterClient)
(virDomainEventStateCallbackID): New prototypes.
* src/remote/remote_driver.c (private_data): Add field.
(doRemoteOpen): Probe server feature.
(remoteConnectDomainEventRegister)
(remoteConnectDomainEventRegisterAny): Use new function.
Signed-off-by: NEric Blake <eblake@redhat.com>
上级 03722957
...@@ -1281,6 +1281,8 @@ virDomainEventStateRegister(virConnectPtr conn, ...@@ -1281,6 +1281,8 @@ virDomainEventStateRegister(virConnectPtr conn,
void *opaque, void *opaque,
virFreeCallback freecb) virFreeCallback freecb)
{ {
int callbackID;
if (virDomainEventsInitialize() < 0) if (virDomainEventsInitialize() < 0)
return -1; return -1;
...@@ -1288,7 +1290,8 @@ virDomainEventStateRegister(virConnectPtr conn, ...@@ -1288,7 +1290,8 @@ virDomainEventStateRegister(virConnectPtr conn,
NULL, NULL, virDomainEventClass, NULL, NULL, virDomainEventClass,
VIR_DOMAIN_EVENT_ID_LIFECYCLE, VIR_DOMAIN_EVENT_ID_LIFECYCLE,
VIR_OBJECT_EVENT_CALLBACK(callback), VIR_OBJECT_EVENT_CALLBACK(callback),
opaque, freecb, NULL, false); opaque, freecb,
true, &callbackID, false);
} }
...@@ -1326,7 +1329,75 @@ virDomainEventStateRegisterID(virConnectPtr conn, ...@@ -1326,7 +1329,75 @@ virDomainEventStateRegisterID(virConnectPtr conn,
NULL, NULL, NULL, NULL,
virDomainEventClass, eventID, virDomainEventClass, eventID,
VIR_OBJECT_EVENT_CALLBACK(cb), VIR_OBJECT_EVENT_CALLBACK(cb),
opaque, freecb, callbackID, false); opaque, freecb,
false, callbackID, false);
}
/**
* virDomainEventStateRegisterClient:
* @conn: connection to associate with callback
* @state: object event state
* @dom: optional domain for filtering the event
* @eventID: ID of the event type to register for
* @cb: function to invoke when event fires
* @opaque: data blob to pass to @callback
* @freecb: callback to free @opaque
* @legacy: true if callback is tracked by function instead of callbackID
* @callbackID: filled with callback ID
* @remoteID: true if server supports filtering
*
* 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
virDomainEventStateRegisterClient(virConnectPtr conn,
virObjectEventStatePtr state,
virDomainPtr dom,
int eventID,
virConnectDomainEventGenericCallback cb,
void *opaque,
virFreeCallback freecb,
bool legacy,
int *callbackID,
bool remoteID)
{
if (virDomainEventsInitialize() < 0)
return -1;
return virObjectEventStateRegisterID(conn, state, dom ? dom->uuid : NULL,
NULL, NULL,
virDomainEventClass, eventID,
VIR_OBJECT_EVENT_CALLBACK(cb),
opaque, freecb,
legacy, callbackID, remoteID);
}
/**
* virDomainEventStateCallbackID:
* @conn: connection associated with callback
* @state: object event state
* @cb: function registered as a callback with virDomainEventStateRegister()
* @remoteID: associated remote id of the callback
*
* Returns the callbackID of @cb, or -1 with an error issued if the
* function is not currently registered.
*/
int
virDomainEventStateCallbackID(virConnectPtr conn,
virObjectEventStatePtr state,
virConnectDomainEventCallback cb,
int *remoteID)
{
return virObjectEventStateCallbackID(conn, state, virDomainEventClass,
VIR_DOMAIN_EVENT_ID_LIFECYCLE,
VIR_OBJECT_EVENT_CALLBACK(cb),
remoteID);
} }
...@@ -1351,7 +1422,8 @@ virDomainEventStateDeregister(virConnectPtr conn, ...@@ -1351,7 +1422,8 @@ virDomainEventStateDeregister(virConnectPtr conn,
callbackID = virObjectEventStateCallbackID(conn, state, callbackID = virObjectEventStateCallbackID(conn, state,
virDomainEventClass, virDomainEventClass,
VIR_DOMAIN_EVENT_ID_LIFECYCLE, VIR_DOMAIN_EVENT_ID_LIFECYCLE,
VIR_OBJECT_EVENT_CALLBACK(cb)); VIR_OBJECT_EVENT_CALLBACK(cb),
NULL);
if (callbackID < 0) if (callbackID < 0)
return -1; return -1;
return virObjectEventStateDeregisterID(conn, state, callbackID); return virObjectEventStateDeregisterID(conn, state, callbackID);
......
...@@ -192,6 +192,28 @@ virDomainEventStateRegisterID(virConnectPtr conn, ...@@ -192,6 +192,28 @@ virDomainEventStateRegisterID(virConnectPtr conn,
int *callbackID) int *callbackID)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(5); ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(5);
int int
virDomainEventStateRegisterClient(virConnectPtr conn,
virObjectEventStatePtr state,
virDomainPtr dom,
int eventID,
virConnectDomainEventGenericCallback cb,
void *opaque,
virFreeCallback freecb,
bool legacy,
int *callbackID,
bool remoteID)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(5)
ATTRIBUTE_NONNULL(9);
int
virDomainEventStateCallbackID(virConnectPtr conn,
virObjectEventStatePtr state,
virConnectDomainEventCallback callback,
int *remoteID)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
ATTRIBUTE_NONNULL(4);
int
virDomainEventStateDeregister(virConnectPtr conn, virDomainEventStateDeregister(virConnectPtr conn,
virObjectEventStatePtr state, virObjectEventStatePtr state,
virConnectDomainEventCallback callback) virConnectDomainEventCallback callback)
......
...@@ -155,7 +155,8 @@ virNetworkEventStateRegisterID(virConnectPtr conn, ...@@ -155,7 +155,8 @@ virNetworkEventStateRegisterID(virConnectPtr conn,
NULL, NULL, NULL, NULL,
virNetworkEventClass, eventID, virNetworkEventClass, eventID,
VIR_OBJECT_EVENT_CALLBACK(cb), VIR_OBJECT_EVENT_CALLBACK(cb),
opaque, freecb, callbackID, false); opaque, freecb,
false, callbackID, false);
} }
...@@ -194,7 +195,8 @@ virNetworkEventStateRegisterClient(virConnectPtr conn, ...@@ -194,7 +195,8 @@ virNetworkEventStateRegisterClient(virConnectPtr conn,
NULL, NULL, NULL, NULL,
virNetworkEventClass, eventID, virNetworkEventClass, eventID,
VIR_OBJECT_EVENT_CALLBACK(cb), VIR_OBJECT_EVENT_CALLBACK(cb),
opaque, freecb, callbackID, true); opaque, freecb,
false, callbackID, true);
} }
......
...@@ -334,13 +334,13 @@ virObjectEventCallbackLookup(virConnectPtr conn, ...@@ -334,13 +334,13 @@ virObjectEventCallbackLookup(virConnectPtr conn,
if (cb->klass == klass && if (cb->klass == klass &&
cb->eventID == eventID && cb->eventID == eventID &&
cb->conn == conn && cb->conn == conn &&
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))) {
if (remoteID) if (remoteID)
*remoteID = cb->remoteID; *remoteID = cb->remoteID;
if (cb->cb == callback) if (cb->legacy == legacy &&
cb->cb == callback)
return cb->callbackID; return cb->callbackID;
} }
} }
...@@ -360,6 +360,7 @@ virObjectEventCallbackLookup(virConnectPtr conn, ...@@ -360,6 +360,7 @@ virObjectEventCallbackLookup(virConnectPtr conn,
* @callback: the callback to add * @callback: the callback to add
* @opaque: opaque data to pass to @callback * @opaque: opaque data to pass to @callback
* @freecb: callback to free @opaque * @freecb: callback to free @opaque
* @legacy: true if callback is tracked by function instead of callbackID
* @callbackID: filled with callback ID * @callbackID: filled with callback ID
* @serverFilter: true if server supports object filtering * @serverFilter: true if server supports object filtering
* *
...@@ -376,6 +377,7 @@ virObjectEventCallbackListAddID(virConnectPtr conn, ...@@ -376,6 +377,7 @@ virObjectEventCallbackListAddID(virConnectPtr conn,
virConnectObjectEventGenericCallback callback, virConnectObjectEventGenericCallback callback,
void *opaque, void *opaque,
virFreeCallback freecb, virFreeCallback freecb,
bool legacy,
int *callbackID, int *callbackID,
bool serverFilter) bool serverFilter)
{ {
...@@ -384,9 +386,10 @@ virObjectEventCallbackListAddID(virConnectPtr conn, ...@@ -384,9 +386,10 @@ virObjectEventCallbackListAddID(virConnectPtr conn,
int remoteID = -1; int remoteID = -1;
VIR_DEBUG("conn=%p cblist=%p uuid=%p filter=%p filter_opaque=%p " VIR_DEBUG("conn=%p cblist=%p uuid=%p filter=%p filter_opaque=%p "
"klass=%p eventID=%d callback=%p opaque=%p", "klass=%p eventID=%d callback=%p opaque=%p "
conn, cbList, uuid, filter, filter_opaque, "legacy=%d callbackID=%p serverFilter=%d",
klass, eventID, callback, opaque); conn, cbList, uuid, filter, filter_opaque, klass, eventID,
callback, opaque, legacy, callbackID, serverFilter);
/* Check incoming */ /* Check incoming */
if (!cbList) { if (!cbList) {
...@@ -395,8 +398,7 @@ virObjectEventCallbackListAddID(virConnectPtr conn, ...@@ -395,8 +398,7 @@ 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, legacy,
!callbackID,
serverFilter ? &remoteID : NULL) != -1) { serverFilter ? &remoteID : NULL) != -1) {
virReportError(VIR_ERR_INVALID_ARG, "%s", virReportError(VIR_ERR_INVALID_ARG, "%s",
_("event callback already tracked")); _("event callback already tracked"));
...@@ -406,7 +408,7 @@ virObjectEventCallbackListAddID(virConnectPtr conn, ...@@ -406,7 +408,7 @@ virObjectEventCallbackListAddID(virConnectPtr conn,
if (VIR_ALLOC(event) < 0) if (VIR_ALLOC(event) < 0)
goto cleanup; goto cleanup;
event->conn = virObjectRef(conn); event->conn = virObjectRef(conn);
event->callbackID = cbList->nextID++; *callbackID = event->callbackID = cbList->nextID++;
event->cb = callback; event->cb = callback;
event->klass = klass; event->klass = klass;
event->eventID = eventID; event->eventID = eventID;
...@@ -423,11 +425,7 @@ virObjectEventCallbackListAddID(virConnectPtr conn, ...@@ -423,11 +425,7 @@ virObjectEventCallbackListAddID(virConnectPtr conn,
} }
event->filter = filter; event->filter = filter;
event->filter_opaque = filter_opaque; event->filter_opaque = filter_opaque;
event->legacy = legacy;
if (callbackID)
*callbackID = event->callbackID;
else
event->legacy = true;
if (VIR_APPEND_ELEMENT(cbList->callbacks, cbList->count, event) < 0) if (VIR_APPEND_ELEMENT(cbList->callbacks, cbList->count, event) < 0)
goto cleanup; goto cleanup;
...@@ -833,6 +831,7 @@ virObjectEventStateFlush(virObjectEventStatePtr state) ...@@ -833,6 +831,7 @@ virObjectEventStateFlush(virObjectEventStatePtr state)
* @cb: function to invoke when event occurs * @cb: function to invoke when event occurs
* @opaque: data blob to pass to @callback * @opaque: data blob to pass to @callback
* @freecb: callback to free @opaque * @freecb: callback to free @opaque
* @legacy: true if callback is tracked by function instead of callbackID
* @callbackID: filled with callback ID * @callbackID: filled with callback ID
* @serverFilter: true if server supports object filtering * @serverFilter: true if server supports object filtering
* *
...@@ -867,6 +866,7 @@ virObjectEventStateRegisterID(virConnectPtr conn, ...@@ -867,6 +866,7 @@ virObjectEventStateRegisterID(virConnectPtr conn,
virConnectObjectEventGenericCallback cb, virConnectObjectEventGenericCallback cb,
void *opaque, void *opaque,
virFreeCallback freecb, virFreeCallback freecb,
bool legacy,
int *callbackID, int *callbackID,
bool serverFilter) bool serverFilter)
{ {
...@@ -889,7 +889,7 @@ virObjectEventStateRegisterID(virConnectPtr conn, ...@@ -889,7 +889,7 @@ virObjectEventStateRegisterID(virConnectPtr conn,
uuid, filter, filter_opaque, uuid, filter, filter_opaque,
klass, eventID, klass, eventID,
cb, opaque, freecb, cb, opaque, freecb,
callbackID, serverFilter); legacy, callbackID, serverFilter);
if (ret == -1 && if (ret == -1 &&
state->callbacks->count == 0 && state->callbacks->count == 0 &&
...@@ -949,6 +949,7 @@ virObjectEventStateDeregisterID(virConnectPtr conn, ...@@ -949,6 +949,7 @@ virObjectEventStateDeregisterID(virConnectPtr conn,
* @klass: the base event class * @klass: the base event class
* @eventID: the event ID * @eventID: the event ID
* @callback: function registered as a callback * @callback: function registered as a callback
* @remoteID: optional output, containing resulting remote id
* *
* Returns the callbackID of @callback, or -1 with an error issued if the * Returns the callbackID of @callback, or -1 with an error issued if the
* function is not currently registered. This only finds functions * function is not currently registered. This only finds functions
...@@ -960,13 +961,15 @@ virObjectEventStateCallbackID(virConnectPtr conn, ...@@ -960,13 +961,15 @@ virObjectEventStateCallbackID(virConnectPtr conn,
virObjectEventStatePtr state, virObjectEventStatePtr state,
virClassPtr klass, virClassPtr klass,
int eventID, int eventID,
virConnectObjectEventGenericCallback callback) virConnectObjectEventGenericCallback callback,
int *remoteID)
{ {
int ret = -1; int ret = -1;
virObjectEventStateLock(state); virObjectEventStateLock(state);
ret = virObjectEventCallbackLookup(conn, state->callbacks, NULL, ret = virObjectEventCallbackLookup(conn, state->callbacks, NULL,
klass, eventID, callback, true, NULL); klass, eventID, callback, true,
remoteID);
virObjectEventStateUnlock(state); virObjectEventStateUnlock(state);
if (ret < 0) if (ret < 0)
......
...@@ -80,17 +80,19 @@ virObjectEventStateRegisterID(virConnectPtr conn, ...@@ -80,17 +80,19 @@ virObjectEventStateRegisterID(virConnectPtr conn,
virConnectObjectEventGenericCallback cb, virConnectObjectEventGenericCallback cb,
void *opaque, void *opaque,
virFreeCallback freecb, virFreeCallback freecb,
bool legacy,
int *callbackID, int *callbackID,
bool remoteFilter) bool remoteFilter)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(6) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(6)
ATTRIBUTE_NONNULL(8); ATTRIBUTE_NONNULL(8) ATTRIBUTE_NONNULL(12);
int int
virObjectEventStateCallbackID(virConnectPtr conn, virObjectEventStateCallbackID(virConnectPtr conn,
virObjectEventStatePtr state, virObjectEventStatePtr state,
virClassPtr klass, virClassPtr klass,
int eventID, int eventID,
virConnectObjectEventGenericCallback callback) virConnectObjectEventGenericCallback callback,
int *remoteID)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
ATTRIBUTE_NONNULL(5); ATTRIBUTE_NONNULL(5);
......
...@@ -92,6 +92,7 @@ struct private_data { ...@@ -92,6 +92,7 @@ struct private_data {
int localUses; /* Ref count for private data */ int localUses; /* Ref count for private data */
char *hostname; /* Original hostname */ char *hostname; /* Original hostname */
bool serverKeepAlive; /* Does server support keepalive protocol? */ bool serverKeepAlive; /* Does server support keepalive protocol? */
bool serverEventFilter; /* Does server support modern event filtering */
virObjectEventStatePtr eventState; virObjectEventStatePtr eventState;
}; };
...@@ -890,8 +891,26 @@ doRemoteOpen(virConnectPtr conn, ...@@ -890,8 +891,26 @@ doRemoteOpen(virConnectPtr conn,
goto failed; goto failed;
} }
/* Set up events */
if (!(priv->eventState = virObjectEventStateNew())) if (!(priv->eventState = virObjectEventStateNew()))
goto failed; goto failed;
{
remote_connect_supports_feature_args args =
{ VIR_DRV_FEATURE_REMOTE_EVENT_CALLBACK };
remote_connect_supports_feature_ret ret = { 0 };
int rc;
rc = call(conn, priv, 0, REMOTE_PROC_CONNECT_SUPPORTS_FEATURE,
(xdrproc_t)xdr_remote_connect_supports_feature_args, (char *) &args,
(xdrproc_t)xdr_remote_connect_supports_feature_ret, (char *) &ret);
if (rc != -1 && ret.supported) {
priv->serverEventFilter = true;
} else {
VIR_INFO("Avoiding server event filtering since it is not "
"supported by the server");
}
}
/* Successful. */ /* Successful. */
retcode = VIR_DRV_OPEN_SUCCESS; retcode = VIR_DRV_OPEN_SUCCESS;
...@@ -4421,14 +4440,19 @@ remoteConnectDomainEventRegister(virConnectPtr conn, ...@@ -4421,14 +4440,19 @@ remoteConnectDomainEventRegister(virConnectPtr conn,
void *opaque, void *opaque,
virFreeCallback freecb) virFreeCallback freecb)
{ {
int callbackID;
int rv = -1; int rv = -1;
struct private_data *priv = conn->privateData; struct private_data *priv = conn->privateData;
int count; int count;
remoteDriverLock(priv); remoteDriverLock(priv);
if ((count = virDomainEventStateRegister(conn, priv->eventState, if ((count = virDomainEventStateRegisterClient(conn, priv->eventState,
callback, opaque, freecb)) < 0) NULL,
VIR_DOMAIN_EVENT_ID_LIFECYCLE,
VIR_DOMAIN_EVENT_CALLBACK(callback),
opaque, freecb, true,
&callbackID, false)) < 0)
goto done; goto done;
if (count == 1) { if (count == 1) {
...@@ -5245,10 +5269,10 @@ remoteConnectDomainEventRegisterAny(virConnectPtr conn, ...@@ -5245,10 +5269,10 @@ remoteConnectDomainEventRegisterAny(virConnectPtr conn,
remoteDriverLock(priv); remoteDriverLock(priv);
if ((count = virDomainEventStateRegisterID(conn, priv->eventState, if ((count = virDomainEventStateRegisterClient(conn, priv->eventState,
dom, eventID, dom, eventID, callback,
callback, opaque, freecb, opaque, freecb, false,
&callbackID)) < 0) &callbackID, false)) < 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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册