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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list