[libvirt] [PATCH 1/2] Add VIR_DOMAIN_EVENT_ID_DEVICE_ADDED event

Ján Tomko jtomko at redhat.com
Sat Apr 4 17:16:47 UTC 2015


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




More information about the libvir-list mailing list