[libvirt] [PATCH 5/9] remote: implement node device lifecycle event APIs
Cole Robinson
crobinso at redhat.com
Tue Jul 26 19:35:17 UTC 2016
On 07/20/2016 09:50 AM, Jovanka Gulicoska wrote:
> ---
> daemon/libvirtd.h | 2 +
> daemon/remote.c | 206 +++++++++++++++++++++++++++++++++++++++++++
> src/remote/remote_driver.c | 139 +++++++++++++++++++++++++++++
> src/remote/remote_protocol.x | 43 ++++++++-
> src/remote_protocol-structs | 19 ++++
> 5 files changed, 408 insertions(+), 1 deletion(-)
>
> diff --git a/daemon/libvirtd.h b/daemon/libvirtd.h
> index cc91266..09d505d 100644
> --- a/daemon/libvirtd.h
> +++ b/daemon/libvirtd.h
> @@ -62,6 +62,8 @@ struct daemonClientPrivate {
> size_t nqemuEventCallbacks;
> daemonClientEventCallbackPtr *storageEventCallbacks;
> size_t nstorageEventCallbacks;
> + daemonClientEventCallbackPtr *nodeDeviceEventCallbacks;
> + size_t nnodeDeviceEventCallbacks;
> bool closeRegistered;
>
> # if WITH_SASL
> diff --git a/daemon/remote.c b/daemon/remote.c
> index 4aa43c2..d07cacd 100644
> --- a/daemon/remote.c
> +++ b/daemon/remote.c
> @@ -91,6 +91,7 @@ static virStorageVolPtr get_nonnull_storage_vol(virConnectPtr conn, remote_nonnu
> static virSecretPtr get_nonnull_secret(virConnectPtr conn, remote_nonnull_secret secret);
> static virNWFilterPtr get_nonnull_nwfilter(virConnectPtr conn, remote_nonnull_nwfilter nwfilter);
> static virDomainSnapshotPtr get_nonnull_domain_snapshot(virDomainPtr dom, remote_nonnull_domain_snapshot snapshot);
> +static virNodeDevicePtr get_nonnull_node_device(virConnectPtr conn, remote_nonnull_node_device dev);
> static void make_nonnull_domain(remote_nonnull_domain *dom_dst, virDomainPtr dom_src);
> static void make_nonnull_network(remote_nonnull_network *net_dst, virNetworkPtr net_src);
> static void make_nonnull_interface(remote_nonnull_interface *interface_dst, virInterfacePtr interface_src);
> @@ -209,6 +210,32 @@ remoteRelayStoragePoolEventCheckACL(virNetServerClientPtr client,
> }
>
> static bool
> +remoteRelayNodeDeviceEventCheckACL(virNetServerClientPtr client,
> + virConnectPtr conn,
> + virNodeDevicePtr dev)
> +{
> + virNodeDeviceDef def;
> + virIdentityPtr identity = NULL;
> + bool ret = false;
> +
> + /* For now, we just create a virNodeDeviceDef with enough contents to
> + * satisfy what viraccessdriverpolkit.c references. This is a bit
> + * fragile, but I don't know of anything better. */
> + def.name = dev->name;
> +
> + if (!(identity = virNetServerClientGetIdentity(client)))
> + goto cleanup;
> + if (virIdentitySetCurrent(identity) < 0)
> + goto cleanup;
> + ret = virConnectNodeDeviceEventRegisterAnyCheckACL(conn, &def);
> +
> + cleanup:
> + ignore_value(virIdentitySetCurrent(NULL));
> + virObjectUnref(identity);
> + return ret;
> +}
> +
> +static bool
> remoteRelayDomainQemuMonitorEventCheckACL(virNetServerClientPtr client,
> virConnectPtr conn, virDomainPtr dom)
> {
> @@ -1329,6 +1356,44 @@ static virConnectStoragePoolEventGenericCallback storageEventCallbacks[] = {
>
> verify(ARRAY_CARDINALITY(storageEventCallbacks) == VIR_STORAGE_POOL_EVENT_ID_LAST);
>
> +static int
> +remoteRelayNodeDeviceEventLifecycle(virConnectPtr conn,
> + virNodeDevicePtr dev,
> + int event,
> + int detail,
> + void *opaque)
> +{
> + daemonClientEventCallbackPtr callback = opaque;
> + remote_node_device_event_lifecycle_msg data;
> +
> + if (callback->callbackID < 0 ||
> + !remoteRelayNodeDeviceEventCheckACL(callback->client, conn, dev))
> + return -1;
> +
> + VIR_DEBUG("Relaying node device lifecycle event %d, detail %d, callback %d",
> + event, detail, callback->callbackID);
> +
> + /* build return data */
> + memset(&data, 0, sizeof(data));
> + make_nonnull_node_device(&data.dev, dev);
> + data.callbackID = callback->callbackID;
> + data.event = event;
> + data.detail = detail;
> +
> + remoteDispatchObjectEventSend(callback->client, remoteProgram,
> + REMOTE_PROC_NODE_DEVICE_EVENT_LIFECYCLE,
> + (xdrproc_t)xdr_remote_node_device_event_lifecycle_msg,
> + &data);
> +
> + return 0;
> +}
> +
> +static virConnectNodeDeviceEventGenericCallback nodeDeviceEventCallbacks[] = {
> + VIR_NODE_DEVICE_EVENT_CALLBACK(remoteRelayNodeDeviceEventLifecycle),
> +};
> +
> +verify(ARRAY_CARDINALITY(nodeDeviceEventCallbacks) == VIR_NODE_DEVICE_EVENT_ID_LAST);
> +
> static void
> remoteRelayDomainQemuMonitorEvent(virConnectPtr conn,
> virDomainPtr dom,
> @@ -1451,6 +1516,21 @@ void remoteClientFreeFunc(void *data)
> }
> VIR_FREE(priv->storageEventCallbacks);
>
> + for (i = 0; i < priv->nnodeDeviceEventCallbacks; i++) {
> + int callbackID = priv->nodeDeviceEventCallbacks[i]->callbackID;
> + if (callbackID < 0) {
> + VIR_WARN("unexpected incomplete node device callback %zu", i);
> + continue;
> + }
> + VIR_DEBUG("Deregistering remote node device event relay %d",
> + callbackID);
> + priv->nodeDeviceEventCallbacks[i]->callbackID = -1;
> + if (virConnectNodeDeviceEventDeregisterAny(priv->conn,
> + callbackID) < 0)
> + VIR_WARN("unexpected node device event deregister failure");
> + }
> + VIR_FREE(priv->nodeDeviceEventCallbacks);
> +
> for (i = 0; i < priv->nqemuEventCallbacks; i++) {
> int callbackID = priv->qemuEventCallbacks[i]->callbackID;
> if (callbackID < 0) {
> @@ -5656,6 +5736,126 @@ remoteDispatchConnectStoragePoolEventDeregisterAny(virNetServerPtr server ATTRIB
> return rv;
> }
>
> +static int
> +remoteDispatchConnectNodeDeviceEventRegisterAny(virNetServerPtr server ATTRIBUTE_UNUSED,
> + virNetServerClientPtr client,
> + virNetMessagePtr msg ATTRIBUTE_UNUSED,
> + virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED,
> + remote_connect_node_device_event_register_any_args *args,
> + remote_connect_node_device_event_register_any_ret *ret)
> +{
> + int callbackID;
> + int rv = -1;
> + daemonClientEventCallbackPtr callback = NULL;
> + daemonClientEventCallbackPtr ref;
> + struct daemonClientPrivate *priv =
> + virNetServerClientGetPrivateData(client);
> + virNodeDevicePtr dev = NULL;
> +
> + if (!priv->conn) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
> + goto cleanup;
> + }
> +
> + virMutexLock(&priv->lock);
> +
> + if (args->dev &&
> + !(dev = get_nonnull_node_device(priv->conn, *args->dev)))
> + goto cleanup;
> +
> + if (args->eventID >= VIR_NODE_DEVICE_EVENT_ID_LAST || args->eventID < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("unsupported storage pool event ID %d"), args->eventID);
> + goto cleanup;
> + }
Error message mentions storage
Otherwise the rest looks fine to me
- Cole
More information about the libvir-list
mailing list