[libvirt] [v3 31/32] Add network events to the remote driver
Daniel P. Berrange
berrange at redhat.com
Tue Dec 10 13:27:52 UTC 2013
On Mon, Dec 02, 2013 at 05:39:49PM +0100, Cédric Bosdonnat wrote:
> ---
> daemon/libvirtd.h | 1 +
> daemon/remote.c | 140 +++++++++++++++++++++++++++++++++++++++++++
> src/remote/remote_driver.c | 127 +++++++++++++++++++++++++++++++++++++++
> src/remote/remote_protocol.x | 46 +++++++++++++-
> 4 files changed, 313 insertions(+), 1 deletion(-)
>
> @@ -5216,6 +5260,102 @@ cleanup:
> }
>
>
> +static int
> +remoteDispatchConnectNetworkEventRegisterAny(virNetServerPtr server ATTRIBUTE_UNUSED,
> + virNetServerClientPtr client ATTRIBUTE_UNUSED,
> + virNetMessagePtr msg ATTRIBUTE_UNUSED,
> + virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED,
> + remote_connect_network_event_register_any_args *args,
> + remote_connect_network_event_register_any_ret *ret ATTRIBUTE_UNUSED)
> +{
> + int callbackID;
> + int rv = -1;
> + struct daemonClientPrivate *priv =
> + virNetServerClientGetPrivateData(client);
> +
> + if (!priv->conn) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
> + goto cleanup;
> + }
> +
> + virMutexLock(&priv->lock);
> +
> + if ((args->eventID & 0xFF) >= VIR_NETWORK_EVENT_ID_LAST ||
> + ((args->eventID & 0xFF00) >> 8) != VIR_EVENT_NAMESPACE_NETWORK) {
This is wrong - VIR_EVENT_NAMESPACE_NETWORK should not be visible in the wire
protocol.
> + virReportError(VIR_ERR_INTERNAL_ERROR, _("unsupported event ID %d"), args->eventID);
> + goto cleanup;
> + }
> +
> + if (priv->networkEventCallbackID[args->eventID & 0xFF] != -1) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, _("network event %d already registered"), args->eventID);
> + goto cleanup;
> + }
> +
> + if ((callbackID = virConnectNetworkEventRegisterAny(priv->conn,
> + NULL,
> + args->eventID,
Just add VIR_EVENT_NAMESPACE_NETWORK in here.
> + networkEventCallbacks[args->eventID & 0xFF],
> + client, NULL)) < 0)
> + goto cleanup;
> +
> + priv->networkEventCallbackID[args->eventID & 0xFF] = callbackID;
> +
> + rv = 0;
> +
> +cleanup:
> + if (rv < 0)
> + virNetMessageSaveError(rerr);
> + virMutexUnlock(&priv->lock);
> + return rv;
> +}
> +
> +
> +static int
> +remoteDispatchConnectNetworkEventDeregisterAny(virNetServerPtr server ATTRIBUTE_UNUSED,
> + virNetServerClientPtr client ATTRIBUTE_UNUSED,
> + virNetMessagePtr msg ATTRIBUTE_UNUSED,
> + virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED,
> + remote_connect_network_event_deregister_any_args *args,
> + remote_connect_network_event_deregister_any_ret *ret ATTRIBUTE_UNUSED)
> +{
> + int callbackID = -1;
> + int rv = -1;
> + struct daemonClientPrivate *priv =
> + virNetServerClientGetPrivateData(client);
> +
> + if (!priv->conn) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
> + goto cleanup;
> + }
> +
> + virMutexLock(&priv->lock);
> +
> + if ((args->eventID & 0xFF) >= VIR_NETWORK_EVENT_ID_LAST ||
> + ((args->eventID & 0xFF00) >> 8) != VIR_EVENT_NAMESPACE_NETWORK) {
Same point as above.
> + virReportError(VIR_ERR_INTERNAL_ERROR, _("unsupported event ID %d"), args->eventID);
> + goto cleanup;
> + }
> +
> + callbackID = priv->networkEventCallbackID[args->eventID & 0xFF];
> + if (callbackID < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, _("network event %d not registered"), args->eventID);
> + goto cleanup;
> + }
> +
> + if (virConnectNetworkEventDeregisterAny(priv->conn, callbackID) < 0)
> + goto cleanup;
> +
> + priv->networkEventCallbackID[args->eventID & 0xFF] = -1;
> +
> + rv = 0;
> +
> +cleanup:
> + if (rv < 0)
> + virNetMessageSaveError(rerr);
> + virMutexUnlock(&priv->lock);
> + return rv;
> +}
> +
>
> /*----- Helpers. -----*/
>
> diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
> index 4a84a52..046f424 100644
> --- a/src/remote/remote_driver.c
> +++ b/src/remote/remote_driver.c
> @@ -2902,6 +2912,99 @@ done:
> }
>
> static int
> +remoteConnectNetworkEventRegisterAny(virConnectPtr conn,
> + virNetworkPtr net,
> + int eventID,
> + virConnectNetworkEventGenericCallback callback,
> + void *opaque,
> + virFreeCallback freecb)
> +{
> + int rv = -1;
> + struct private_data *priv = conn->privateData;
> + remote_connect_network_event_register_any_args args;
> + int callbackID;
> + int count;
> +
> + remoteDriverLock(priv);
> +
> + if ((count = virNetworkEventStateRegisterID(conn,
> + priv->domainEventState,
> + net, eventID,
Can add VIR_EVENT_NAMESPACE_NETWORK here
> + VIR_OBJECT_EVENT_CALLBACK(callback),
> + opaque, freecb,
> + &callbackID)) < 0) {
> + virReportError(VIR_ERR_RPC, "%s", _("adding cb to list"));
> + goto done;
> + }
> +
> + /* If this is the first callback for this eventID, we need to enable
> + * events on the server */
> + if (count == 1) {
> + args.eventID = eventID;
but this must be the raw eventID without VIR_EVENT_NAMESPACE_NETWORK
> +
> + if (call(conn, priv, 0, REMOTE_PROC_CONNECT_NETWORK_EVENT_REGISTER_ANY,
> + (xdrproc_t) xdr_remote_connect_network_event_register_any_args, (char *) &args,
> + (xdrproc_t) xdr_void, (char *)NULL) == -1) {
> + virObjectEventStateDeregisterID(conn,
> + priv->domainEventState,
> + callbackID);
> + goto done;
> + }
> + }
> +
> + rv = callbackID;
> +
> +done:
> + remoteDriverUnlock(priv);
> + return rv;
> +}
> +
> +
> +static int
> +remoteConnectNetworkEventDeregisterAny(virConnectPtr conn,
> + int callbackID)
> +{
> + struct private_data *priv = conn->privateData;
> + int rv = -1;
> + remote_connect_network_event_deregister_any_args args;
> + int eventID;
> + int count;
> +
> + remoteDriverLock(priv);
> +
> + if ((eventID = virObjectEventStateEventID(conn,
> + priv->domainEventState,
> + callbackID)) < 0) {
> + virReportError(VIR_ERR_RPC, _("unable to find callback ID %d"), callbackID);
> + goto done;
> + }
> +
> + if ((count = virObjectEventStateDeregisterID(conn,
> + priv->domainEventState,
> + callbackID)) < 0) {
> + virReportError(VIR_ERR_RPC, _("unable to find callback ID %d"), callbackID);
> + goto done;
> + }
> +
> + /* If that was the last callback for this eventID, we need to disable
> + * events on the server */
> + if (count == 0) {
> + args.eventID = eventID
> +
> + if (call(conn, priv, 0, REMOTE_PROC_CONNECT_NETWORK_EVENT_DEREGISTER_ANY,
> + (xdrproc_t) xdr_remote_connect_network_event_deregister_any_args, (char *) &args,
> + (xdrproc_t) xdr_void, (char *) NULL) == -1)
> + goto done;
> + }
> +
> + rv = 0;
> +
> +done:
> + remoteDriverUnlock(priv);
> + return rv;
> +}
> +
> +static int
> remoteConnectListAllInterfaces(virConnectPtr conn,
> virInterfacePtr **ifaces,
> unsigned int flags)
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
More information about the libvir-list
mailing list