The counterpart to VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED. https://bugzilla.redhat.com/show_bug.cgi?id=1206114 --- daemon/remote.c | 37 +++++++++++++++++++ include/libvirt/libvirt-domain.h | 18 ++++++++++ src/conf/domain_event.c | 77 ++++++++++++++++++++++++++++++++++++++++ src/conf/domain_event.h | 6 ++++ src/libvirt_private.syms | 2 ++ src/remote/remote_driver.c | 29 +++++++++++++++ src/remote/remote_protocol.x | 14 +++++++- src/remote_protocol-structs | 6 ++++ tools/virsh-domain.c | 20 +++++++++++ 9 files changed, 208 insertions(+), 1 deletion(-) diff --git a/daemon/remote.c b/daemon/remote.c index 2e1f973..3a3f168 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -1045,6 +1045,42 @@ remoteRelayDomainEventAgentLifecycle(virConnectPtr conn, } +static int +remoteRelayDomainEventDeviceAdded(virConnectPtr conn, + virDomainPtr dom, + const char *devAlias, + void *opaque) +{ + daemonClientEventCallbackPtr callback = opaque; + remote_domain_event_callback_device_added_msg data; + + if (callback->callbackID < 0 || + !remoteRelayDomainEventCheckACL(callback->client, conn, dom)) + return -1; + + VIR_DEBUG("Relaying domain device added event %s %d %s, callback %d", + dom->name, dom->id, devAlias, callback->callbackID); + + /* build return data */ + memset(&data, 0, sizeof(data)); + + if (VIR_STRDUP(data.devAlias, devAlias) < 0) + return -1; + + make_nonnull_domain(&data.dom, dom); + data.callbackID = callback->callbackID, + + remoteDispatchObjectEventSend(callback->client, remoteProgram, + REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_ADDED, + (xdrproc_t)xdr_remote_domain_event_callback_device_added_msg, + &data); + + return 0; +} + + + + static virConnectDomainEventGenericCallback domainEventCallbacks[] = { VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot), @@ -1065,6 +1101,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = { VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventBlockJob2), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventTunable), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventAgentLifecycle), + VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventDeviceAdded), }; verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST); diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 7be4219..8a4fe53 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -3202,6 +3202,23 @@ typedef void (*virConnectDomainEventDeviceRemovedCallback)(virConnectPtr conn, void *opaque); /** + * virConnectDomainEventDeviceAddedCallback: + * @conn: connection object + * @dom: domain on which the event occurred + * @devAlias: device alias + * @opaque: application specified data + * + * This callback occurs when a device is added to the domain. + * + * The callback signature to use when registering for an event of type + * VIR_DOMAIN_EVENT_ID_DEVICE_ADDED with virConnectDomainEventRegisterAny() + */ +typedef void (*virConnectDomainEventDeviceAddedCallback)(virConnectPtr conn, + virDomainPtr dom, + const char *devAlias, + void *opaque); + +/** * VIR_DOMAIN_TUNABLE_CPU_VCPUPIN: * * Macro represents formatted pinning for one vcpu specified by id which is @@ -3483,6 +3500,7 @@ typedef enum { VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2 = 16, /* virConnectDomainEventBlockJobCallback */ VIR_DOMAIN_EVENT_ID_TUNABLE = 17, /* virConnectDomainEventTunableCallback */ VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE = 18,/* virConnectDomainEventAgentLifecycleCallback */ + VIR_DOMAIN_EVENT_ID_DEVICE_ADDED = 19, /* virConnectDomainEventDeviceAddedCallback */ # ifdef VIR_ENUM_SENTINELS VIR_DOMAIN_EVENT_ID_LAST diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c index 2786c1e..20d66e1 100644 --- a/src/conf/domain_event.c +++ b/src/conf/domain_event.c @@ -55,6 +55,7 @@ static virClassPtr virDomainEventPMClass; static virClassPtr virDomainQemuMonitorEventClass; static virClassPtr virDomainEventTunableClass; static virClassPtr virDomainEventAgentLifecycleClass; +static virClassPtr virDomainEventDeviceAddedClass; static void virDomainEventDispose(void *obj); @@ -72,6 +73,7 @@ static void virDomainEventPMDispose(void *obj); static void virDomainQemuMonitorEventDispose(void *obj); static void virDomainEventTunableDispose(void *obj); static void virDomainEventAgentLifecycleDispose(void *obj); +static void virDomainEventDeviceAddedDispose(void *obj); static void virDomainEventDispatchDefaultFunc(virConnectPtr conn, @@ -189,6 +191,14 @@ struct _virDomainEventDeviceRemoved { typedef struct _virDomainEventDeviceRemoved virDomainEventDeviceRemoved; typedef virDomainEventDeviceRemoved *virDomainEventDeviceRemovedPtr; +struct _virDomainEventDeviceAdded { + virDomainEvent parent; + + char *devAlias; +}; +typedef struct _virDomainEventDeviceAdded virDomainEventDeviceAdded; +typedef virDomainEventDeviceAdded *virDomainEventDeviceAddedPtr; + struct _virDomainEventPM { virDomainEvent parent; @@ -296,6 +306,12 @@ virDomainEventsOnceInit(void) sizeof(virDomainEventDeviceRemoved), virDomainEventDeviceRemovedDispose))) return -1; + if (!(virDomainEventDeviceAddedClass = + virClassNew(virDomainEventClass, + "virDomainEventDeviceAdded", + sizeof(virDomainEventDeviceAdded), + virDomainEventDeviceAddedDispose))) + return -1; if (!(virDomainEventPMClass = virClassNew(virDomainEventClass, "virDomainEventPM", @@ -439,6 +455,15 @@ virDomainEventDeviceRemovedDispose(void *obj) } static void +virDomainEventDeviceAddedDispose(void *obj) +{ + virDomainEventDeviceAddedPtr event = obj; + VIR_DEBUG("obj=%p", event); + + VIR_FREE(event->devAlias); +} + +static void virDomainEventPMDispose(void *obj) { virDomainEventPMPtr event = obj; @@ -1226,6 +1251,47 @@ virDomainEventDeviceRemovedNewFromDom(virDomainPtr dom, devAlias); } +static virObjectEventPtr +virDomainEventDeviceAddedNew(int id, + const char *name, + unsigned char *uuid, + const char *devAlias) +{ + virDomainEventDeviceAddedPtr ev; + + if (virDomainEventsInitialize() < 0) + return NULL; + + if (!(ev = virDomainEventNew(virDomainEventDeviceAddedClass, + VIR_DOMAIN_EVENT_ID_DEVICE_ADDED, + id, name, uuid))) + return NULL; + + if (VIR_STRDUP(ev->devAlias, devAlias) < 0) + goto error; + + return (virObjectEventPtr)ev; + + error: + virObjectUnref(ev); + return NULL; +} + +virObjectEventPtr +virDomainEventDeviceAddedNewFromObj(virDomainObjPtr obj, + const char *devAlias) +{ + return virDomainEventDeviceAddedNew(obj->def->id, obj->def->name, + obj->def->uuid, devAlias); +} + +virObjectEventPtr +virDomainEventDeviceAddedNewFromDom(virDomainPtr dom, + const char *devAlias) +{ + return virDomainEventDeviceAddedNew(dom->id, dom->name, dom->uuid, + devAlias); +} static virObjectEventPtr virDomainEventAgentLifecycleNew(int id, @@ -1537,6 +1603,17 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn, goto cleanup; } + case VIR_DOMAIN_EVENT_ID_DEVICE_ADDED: + { + virDomainEventDeviceAddedPtr deviceAddedEvent; + + deviceAddedEvent = (virDomainEventDeviceAddedPtr)event; + ((virConnectDomainEventDeviceAddedCallback)cb)(conn, dom, + deviceAddedEvent->devAlias, + cbopaque); + goto cleanup; + } + case VIR_DOMAIN_EVENT_ID_LAST: break; } diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h index 534ff9e..afbed89 100644 --- a/src/conf/domain_event.h +++ b/src/conf/domain_event.h @@ -185,6 +185,12 @@ virObjectEventPtr virDomainEventDeviceRemovedNewFromDom(virDomainPtr dom, const char *devAlias); virObjectEventPtr +virDomainEventDeviceAddedNewFromObj(virDomainObjPtr obj, + const char *devAlias); +virObjectEventPtr +virDomainEventDeviceAddedNewFromDom(virDomainPtr dom, + const char *devAlias); +virObjectEventPtr virDomainEventTunableNewFromObj(virDomainObjPtr obj, virTypedParameterPtr params, int nparams); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 9f82926..cbd8089 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -486,6 +486,8 @@ virDomainEventBlockJobNewFromDom; virDomainEventBlockJobNewFromObj; virDomainEventControlErrorNewFromDom; virDomainEventControlErrorNewFromObj; +virDomainEventDeviceAddedNewFromDom; +virDomainEventDeviceAddedNewFromObj; virDomainEventDeviceRemovedNewFromDom; virDomainEventDeviceRemovedNewFromObj; virDomainEventDiskChangeNewFromDom; diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index b275d86..9c3b53f 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -321,6 +321,10 @@ static void remoteDomainBuildEventCallbackDeviceRemoved(virNetClientProgramPtr prog, virNetClientPtr client, void *evdata, void *opaque); +static void +remoteDomainBuildEventCallbackDeviceAdded(virNetClientProgramPtr prog, + virNetClientPtr client, + void *evdata, void *opaque); static void remoteDomainBuildEventBlockJob2(virNetClientProgramPtr prog, @@ -496,6 +500,10 @@ static virNetClientProgramEvent remoteEvents[] = { remoteDomainBuildEventCallbackAgentLifecycle, sizeof(remote_domain_event_callback_agent_lifecycle_msg), (xdrproc_t)xdr_remote_domain_event_callback_agent_lifecycle_msg }, + { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_ADDED, + remoteDomainBuildEventCallbackDeviceAdded, + sizeof(remote_domain_event_callback_device_added_msg), + (xdrproc_t)xdr_remote_domain_event_callback_device_added_msg }, }; @@ -5431,6 +5439,27 @@ remoteDomainBuildEventCallbackDeviceRemoved(virNetClientProgramPtr prog ATTRIBUT remoteDomainBuildEventDeviceRemovedHelper(conn, &msg->msg, msg->callbackID); } +static void +remoteDomainBuildEventCallbackDeviceAdded(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, + virNetClientPtr client ATTRIBUTE_UNUSED, + void *evdata, void *opaque) +{ + virConnectPtr conn = opaque; + remote_domain_event_callback_device_added_msg *msg = evdata; + struct private_data *priv = conn->privateData; + virDomainPtr dom; + virObjectEventPtr event = NULL; + + dom = get_nonnull_domain(conn, msg->dom); + if (!dom) + return; + + event = virDomainEventDeviceAddedNewFromDom(dom, msg->devAlias); + + virObjectUnref(dom); + + remoteEventQueue(priv, event, msg->callbackID); +} static void remoteDomainBuildEventCallbackTunable(virNetClientProgramPtr prog ATTRIBUTE_UNUSED, diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index d90e6b5..b02e58c 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -3045,6 +3045,12 @@ struct remote_domain_event_callback_tunable_msg { remote_typed_param params<REMOTE_DOMAIN_EVENT_TUNABLE_MAX>; }; +struct remote_domain_event_callback_device_added_msg { + int callbackID; + remote_nonnull_domain dom; + remote_nonnull_string devAlias; +}; + struct remote_connect_get_cpu_model_names_args { remote_nonnull_string arch; int need_results; @@ -5643,5 +5649,11 @@ enum remote_procedure { * @generate: none * @acl: domain:read */ - REMOTE_PROC_DOMAIN_INTERFACE_ADDRESSES = 353 + REMOTE_PROC_DOMAIN_INTERFACE_ADDRESSES = 353, + + /** + * @generate: both + * @acl: none + */ + REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_ADDED = 354 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index e614f77..2b6b47a 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -2487,6 +2487,11 @@ struct remote_domain_event_callback_tunable_msg { remote_typed_param * params_val; } params; }; +struct remote_domain_event_callback_device_added_msg { + int callbackID; + remote_nonnull_domain dom; + remote_nonnull_string devAlias; +}; struct remote_connect_get_cpu_model_names_args { remote_nonnull_string arch; int need_results; @@ -3017,4 +3022,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_GET_IOTHREAD_INFO = 351, REMOTE_PROC_DOMAIN_PIN_IOTHREAD = 352, REMOTE_PROC_DOMAIN_INTERFACE_ADDRESSES = 353, + REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_ADDED = 354, }; diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 020a308..aeacf59 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -11959,6 +11959,24 @@ vshEventDeviceRemovedPrint(virConnectPtr conn ATTRIBUTE_UNUSED, } static void +vshEventDeviceAddedPrint(virConnectPtr conn ATTRIBUTE_UNUSED, + virDomainPtr dom, + const char *alias, + void *opaque) +{ + vshDomEventData *data = opaque; + + if (!data->loop && *data->count) + return; + vshPrint(data->ctl, + _("event 'device-added' for domain %s: %s\n"), + virDomainGetName(dom), alias); + (*data->count)++; + if (!data->loop) + vshEventDone(data->ctl); +} + +static void vshEventTunablePrint(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, virTypedParameterPtr params, @@ -12063,6 +12081,8 @@ static vshEventCallback vshEventCallbacks[] = { VIR_DOMAIN_EVENT_CALLBACK(vshEventTunablePrint), }, { "agent-lifecycle", VIR_DOMAIN_EVENT_CALLBACK(vshEventAgentLifecyclePrint), }, + { "device-added", + VIR_DOMAIN_EVENT_CALLBACK(vshEventDeviceAddedPrint), }, }; verify(VIR_DOMAIN_EVENT_ID_LAST == ARRAY_CARDINALITY(vshEventCallbacks)); -- 2.0.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list