]> xenbits.xensource.com Git - libvirt.git/commitdiff
Introduce node device lifecycle event APIs
authorJovanka Gulicoska <jovanka.gulicoska@gmail.com>
Thu, 28 Jul 2016 12:02:50 +0000 (14:02 +0200)
committerCole Robinson <crobinso@redhat.com>
Tue, 2 Aug 2016 13:52:00 +0000 (09:52 -0400)
Node device lifecycle event API entry points for registering and
deregistering node deivce events, as well as types of events
associated with node device.
These entry points will be used for implementing asynchronous
lifecycle events.

Node device API:
virConnectNodeDeviceEventRegisterAny
virConnectNodeDeviceEventDeregisterAny
virNodeDeviceEventLifecycleType which has events CREATED and DELETED

include/libvirt/libvirt-nodedev.h
po/POTFILES.in
src/datatypes.h
src/driver-nodedev.h
src/libvirt-nodedev.c
src/libvirt_public.syms

index cd0b5486fc7b6b55ed65f232d25fc09d5f4881ef..4ab6917a9dad4a619d0ba726af9d129d3343241b 100644 (file)
@@ -121,5 +121,95 @@ virNodeDevicePtr        virNodeDeviceCreateXML  (virConnectPtr conn,
 
 int                     virNodeDeviceDestroy    (virNodeDevicePtr dev);
 
+/**
+ * VIR_NODE_DEVICE_EVENT_CALLBACK:
+ *
+ * Used to cast the event specific callback into the generic one
+ * for use for virConnectNodeDeviceEventRegisterAny()
+ */
+# define VIR_NODE_DEVICE_EVENT_CALLBACK(cb)((virConnectNodeDeviceEventGenericCallback)(cb))
+
+/**
+ * virNodeDeviceEventID:
+ *
+ * An enumeration of supported eventId parameters for
+ * virConnectNodeDeviceEventRegisterAny(). Each event id determines which
+ * signature of callback function will be used.
+ */
+typedef enum {
+    VIR_NODE_DEVICE_EVENT_ID_LIFECYCLE = 0, /* virConnectNodeDeviceEventLifecycleCallback */
+
+# ifdef VIR_ENUM_SENTINELS
+    VIR_NODE_DEVICE_EVENT_ID_LAST
+    /*
+     * NB: this enum value will increase over time as new events are
+     * added to the libvirt API. It reflects the last event ID supported
+     * by this version of the libvirt API.
+     */
+# endif
+} virNodeDeviceEventID;
+
+/**
+ * virConnectNodeDeviceEventGenericCallback:
+ * @conn: the connection pointer
+ * @dev: the node device pointer
+ * @opaque: application specified data
+ *
+ * A generic node device event callback handler, for use with
+ * virConnectNodeDeviceEventRegisterAny(). Specific events usually
+ * have a customization with extra parameters, often with @opaque being
+ * passed in a different parameter position; use
+ * VIR_NODE_DEVICE_EVENT_CALLBACK() when registering an appropriate handler.
+ */
+typedef void (*virConnectNodeDeviceEventGenericCallback)(virConnectPtr conn,
+                                                         virNodeDevicePtr dev,
+                                                         void *opaque);
+
+/* Use VIR_NODE_DEVICE_EVENT_CALLBACK() to cast the 'cb' parameter  */
+int virConnectNodeDeviceEventRegisterAny(virConnectPtr conn,
+                                         virNodeDevicePtr dev, /* optional, to filter */
+                                         int eventID,
+                                         virConnectNodeDeviceEventGenericCallback cb,
+                                         void *opaque,
+                                         virFreeCallback freecb);
+
+int virConnectNodeDeviceEventDeregisterAny(virConnectPtr conn,
+                                           int callbackID);
+
+/**
+ * virNodeDeviceEventLifecycleType:
+ *
+ * a virNodeDeviceEventLifecycleType is emitted during node device
+ * lifecycle events
+ */
+typedef enum {
+    VIR_NODE_DEVICE_EVENT_CREATED = 0,
+    VIR_NODE_DEVICE_EVENT_DELETED = 1,
+
+# ifdef VIR_ENUM_SENTINELS
+    VIR_NODE_DEVICE_EVENT_LAST
+# endif
+} virNodeDeviceEventLifecycleType;
+
+/**
+ * virConnectNodeDeviceEventLifecycleCallback:
+ * @conn: connection object
+ * @dev: node device on which the event occurred
+ * @event: The specific virNodeDeviceEventLifeCycleType which occurred
+ * @detail: contains some details on the reason of the event.
+ * @opaque: application specified data
+ *
+ * This callback is called when a node device lifecycle action is performed,
+ * like added or removed.
+ *
+ * The callback signature to use when registering for an event of type
+ * VIR_NODE_DEVICE_EVENT_ID_LIFECYCLE with
+ * virConnectNodeDeviceEventRegisterAny()
+ */
+typedef void (*virConnectNodeDeviceEventLifecycleCallback)(virConnectPtr conn,
+                                                           virNodeDevicePtr dev,
+                                                           int event,
+                                                           int detail,
+                                                           void *opaque);
 
 #endif /* __VIR_LIBVIRT_NODEDEV_H__ */
index a6b6c9cf124c8b862ec7d49284ee75e4e4bdbfb4..25dbc842d866c607c8da4efefd23a83925ae5c60 100644 (file)
@@ -70,6 +70,7 @@ src/libvirt-domain.c
 src/libvirt-host.c
 src/libvirt-lxc.c
 src/libvirt-network.c
+src/libvirt-nodedev.c
 src/libvirt-nwfilter.c
 src/libvirt-qemu.c
 src/libvirt-secret.c
index 996506b6d57adfe047eca1562c6cdb204a4970d3..2b6adb4c45b0703cd16f58e392040d43fb0d0984 100644 (file)
@@ -196,6 +196,19 @@ extern virClassPtr virAdmClientClass;
         }                                                               \
     } while (0)
 
+# define virCheckNodeDeviceGoto(obj, label)                             \
+    do {                                                                \
+        virNodeDevicePtr _dev= (obj);                                   \
+        if (!virObjectIsClass(_dev, virNodeDeviceClass) ||              \
+            !virObjectIsClass(_dev->conn, virConnectClass)) {           \
+            virReportErrorHelper(VIR_FROM_NODEDEV,                      \
+                                 VIR_ERR_INVALID_NODE_DEVICE,           \
+                                 __FILE__, __FUNCTION__, __LINE__,      \
+                                 __FUNCTION__);                         \
+            goto label;                                                 \
+        }                                                               \
+    } while (0)
+
 # define virCheckSecretReturn(obj, retval)                              \
     do {                                                                \
         virSecretPtr _secret = (obj);                                   \
index e846612d3179cf4ed8bc232e2d5096445c230c20..5eae2391c7145fec19bd9a6a4d73d843b21305ed 100644 (file)
@@ -75,6 +75,18 @@ typedef virNodeDevicePtr
 typedef int
 (*virDrvNodeDeviceDestroy)(virNodeDevicePtr dev);
 
+typedef int
+(*virDrvConnectNodeDeviceEventRegisterAny)(virConnectPtr conn,
+                                           virNodeDevicePtr dev,
+                                           int eventID,
+                                           virConnectNodeDeviceEventGenericCallback cb,
+                                           void *opaque,
+                                           virFreeCallback freecb);
+
+typedef int
+(*virDrvConnectNodeDeviceEventDeregisterAny)(virConnectPtr conn,
+                                             int callbackID);
+
 
 
 typedef struct _virNodeDeviceDriver virNodeDeviceDriver;
@@ -92,6 +104,8 @@ struct _virNodeDeviceDriver {
     virDrvNodeNumOfDevices nodeNumOfDevices;
     virDrvNodeListDevices nodeListDevices;
     virDrvConnectListAllNodeDevices connectListAllNodeDevices;
+    virDrvConnectNodeDeviceEventRegisterAny connectNodeDeviceEventRegisterAny;
+    virDrvConnectNodeDeviceEventDeregisterAny connectNodeDeviceEventDeregisterAny;
     virDrvNodeDeviceLookupByName nodeDeviceLookupByName;
     virDrvNodeDeviceLookupSCSIHostByWWN nodeDeviceLookupSCSIHostByWWN;
     virDrvNodeDeviceGetXMLDesc nodeDeviceGetXMLDesc;
index c1ca5750511a5f025106bd024893442de8707bd8..e4e98368ff79d9d7eb928bd34c3cefb9804b11d4 100644 (file)
@@ -753,3 +753,130 @@ virNodeDeviceDestroy(virNodeDevicePtr dev)
     virDispatchError(dev->conn);
     return -1;
 }
+
+
+/**
+ * virConnectNodeDeviceEventRegisterAny:
+ * @conn: pointer to the connection
+ * @dev: pointer to the node device
+ * @eventID: the event type to receive
+ * @cb: callback to the function handling node device events
+ * @opaque: opaque data to pass on to the callback
+ * @freecb: optional function to deallocate opaque when not used anymore
+ *
+ * Adds a callback to receive notifications of arbitrary node device events
+ * occurring on a node device. This function requires that an event loop
+ * has been previously registered with virEventRegisterImpl() or
+ * virEventRegisterDefaultImpl().
+ *
+ * If @dev is NULL, then events will be monitored for any node device.
+ * If @dev is non-NULL, then only the specific node device will be monitored.
+ *
+ * Most types of events have a callback providing a custom set of parameters
+ * for the event. When registering an event, it is thus necessary to use
+ * the VIR_NODE_DEVICE_EVENT_CALLBACK() macro to cast the
+ * supplied function pointer to match the signature of this method.
+ *
+ * The virNodeDevicePtr object handle passed into the callback upon delivery
+ * of an event is only valid for the duration of execution of the callback.
+ * If the callback wishes to keep the node device object after the callback
+ * returns, it shall take a reference to it, by calling virNodeDeviceRef().
+ * The reference can be released once the object is no longer required
+ * by calling virNodeDeviceFree().
+ *
+ * The return value from this method is a positive integer identifier
+ * for the callback. To unregister a callback, this callback ID should
+ * be passed to the virConnectNodeDeviceEventDeregisterAny() method.
+ *
+ * Returns a callback identifier on success, -1 on failure.
+ */
+int
+virConnectNodeDeviceEventRegisterAny(virConnectPtr conn,
+                                     virNodeDevicePtr dev,
+                                     int eventID,
+                                     virConnectNodeDeviceEventGenericCallback cb,
+                                     void *opaque,
+                                     virFreeCallback freecb)
+{
+    VIR_DEBUG("conn=%p, nodeDevice=%p, eventID=%d, cb=%p, opaque=%p, freecb=%p",
+              conn, dev, eventID, cb, opaque, freecb);
+
+    virResetLastError();
+
+    virCheckConnectReturn(conn, -1);
+    if (dev) {
+        virCheckNodeDeviceGoto(dev, error);
+        if (dev->conn != conn) {
+            virReportInvalidArg(dev,
+                                _("node device '%s' in %s must match connection"),
+                                dev->name, __FUNCTION__);
+            goto error;
+        }
+    }
+    virCheckNonNullArgGoto(cb, error);
+    virCheckNonNegativeArgGoto(eventID, error);
+
+    if (eventID >= VIR_NODE_DEVICE_EVENT_ID_LAST) {
+        virReportInvalidArg(eventID,
+                            _("eventID in %s must be less than %d"),
+                            __FUNCTION__, VIR_NODE_DEVICE_EVENT_ID_LAST);
+        goto error;
+    }
+
+    if (conn->nodeDeviceDriver &&
+        conn->nodeDeviceDriver->connectNodeDeviceEventRegisterAny) {
+        int ret;
+        ret = conn->nodeDeviceDriver->connectNodeDeviceEventRegisterAny(conn,
+                                                                        dev,
+                                                                        eventID,
+                                                                        cb,
+                                                                        opaque,
+                                                                        freecb);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virReportUnsupportedError();
+ error:
+    virDispatchError(conn);
+    return -1;
+}
+
+
+/**
+ * virConnectNodeDeviceEventDeregisterAny:
+ * @conn: pointer to the connection
+ * @callbackID: the callback identifier
+ *
+ * Removes an event callback. The callbackID parameter should be the
+ * value obtained from a previous virConnectNodeDeviceEventRegisterAny() method.
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+int
+virConnectNodeDeviceEventDeregisterAny(virConnectPtr conn,
+                                       int callbackID)
+{
+    VIR_DEBUG("conn=%p, callbackID=%d", conn, callbackID);
+
+    virResetLastError();
+
+    virCheckConnectReturn(conn, -1);
+    virCheckNonNegativeArgGoto(callbackID, error);
+
+    if (conn->nodeDeviceDriver &&
+        conn->nodeDeviceDriver->connectNodeDeviceEventDeregisterAny) {
+        int ret;
+        ret = conn->nodeDeviceDriver->connectNodeDeviceEventDeregisterAny(conn,
+                                                                          callbackID);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virReportUnsupportedError();
+ error:
+    virDispatchError(conn);
+    return -1;
+}
index b6d2dfdba3271211561772ea4b708946f98b1ea4..e01604cad8540ef1e8604e3ad6b089b368bb2146 100644 (file)
@@ -740,4 +740,10 @@ LIBVIRT_2.0.0 {
         virDomainSetGuestVcpus;
 } LIBVIRT_1.3.3;
 
+LIBVIRT_2.2.0 {
+    global:
+        virConnectNodeDeviceEventRegisterAny;
+        virConnectNodeDeviceEventDeregisterAny;
+} LIBVIRT_2.0.0;
+
 # .... define new API here using predicted next version number ....