Add public APIs to allow applications to watch for define and
undefine of secret objects.

Signed-off-by: Daniel P. Berrange <berra...@redhat.com>
---
 include/libvirt/libvirt-secret.h |  91 +++++++++++++++++++++++++++
 src/datatypes.h                  |  14 +++++
 src/driver-secret.h              |  14 +++++
 src/libvirt-secret.c             | 129 +++++++++++++++++++++++++++++++++++++++
 src/libvirt_public.syms          |   2 +
 5 files changed, 250 insertions(+)

diff --git a/include/libvirt/libvirt-secret.h b/include/libvirt/libvirt-secret.h
index 2ae36f6..1bbbf3f 100644
--- a/include/libvirt/libvirt-secret.h
+++ b/include/libvirt/libvirt-secret.h
@@ -110,5 +110,96 @@ int                     virSecretUndefine       
(virSecretPtr secret);
 int                     virSecretRef            (virSecretPtr secret);
 int                     virSecretFree           (virSecretPtr secret);
 
+/**
+ * VIR_SECRET_EVENT_CALLBACK:
+ *
+ * Used to cast the event specific callback into the generic one
+ * for use for virConnectSecretEventRegisterAny()
+ */
+# define 
VIR_SECRET_EVENT_CALLBACK(cb)((virConnectSecretEventGenericCallback)(cb))
+
+/**
+ * virSecretEventID:
+ *
+ * An enumeration of supported eventId parameters for
+ * virConnectSecretEventRegisterAny(). Each event id determines which
+ * signature of callback function will be used.
+ */
+typedef enum {
+    VIR_SECRET_EVENT_ID_LIFECYCLE = 0, /* 
virConnectSecretEventLifecycleCallback */
+
+# ifdef VIR_ENUM_SENTINELS
+    VIR_SECRET_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
+} virSecretEventID;
+
+/**
+ * virConnectSecretEventGenericCallback:
+ * @conn: the connection pointer
+ * @secret: the secret pointer
+ * @opaque: application specified data
+ *
+ * A generic secret event callback handler, for use with
+ * virConnectSecretEventRegisterAny(). Specific events usually
+ * have a customization with extra parameters, often with @opaque being
+ * passed in a different parameter position; use
+ * VIR_SECRET_EVENT_CALLBACK() when registering an appropriate handler.
+ */
+typedef void (*virConnectSecretEventGenericCallback)(virConnectPtr conn,
+                                                     virSecretPtr secret,
+                                                     void *opaque);
+
+/* Use VIR_SECRET_EVENT_CALLBACK() to cast the 'cb' parameter  */
+int virConnectSecretEventRegisterAny(virConnectPtr conn,
+                                     virSecretPtr secret, /* optional, to 
filter */
+                                     int eventID,
+                                     virConnectSecretEventGenericCallback cb,
+                                     void *opaque,
+                                     virFreeCallback freecb);
+
+int virConnectSecretEventDeregisterAny(virConnectPtr conn,
+                                       int callbackID);
+
+/**
+ * virSecretEventLifecycleType:
+ *
+ * a virSecretEventLifecycleType is emitted during secret
+ * lifecycle events
+ */
+typedef enum {
+    VIR_SECRET_EVENT_DEFINED = 0,
+    VIR_SECRET_EVENT_UNDEFINED = 1,
+
+# ifdef VIR_ENUM_SENTINELS
+    VIR_SECRET_EVENT_LAST
+# endif
+} virSecretEventLifecycleType;
+
+/**
+ * virConnectSecretEventLifecycleCallback:
+ * @conn: connection object
+ * @secret: secret on which the event occurred
+ * @event: The specific virSecretEventLifeCycleType which occurred
+ * @detail: contains some details on the reason of the event.
+ * @opaque: application specified data
+ *
+ * This callback is called when a secret lifecycle action is performed,
+ * like added or removed.
+ *
+ * The callback signature to use when registering for an event of type
+ * VIR_SECRET_EVENT_ID_LIFECYCLE with
+ * virConnectSecretEventRegisterAny()
+ */
+typedef void (*virConnectSecretEventLifecycleCallback)(virConnectPtr conn,
+                                                       virSecretPtr secret,
+                                                       int event,
+                                                       int detail,
+                                                       void *opaque);
+
 
 #endif /* __VIR_LIBVIRT_SECRET_H__ */
diff --git a/src/datatypes.h b/src/datatypes.h
index 9a5fbbc..5830482 100644
--- a/src/datatypes.h
+++ b/src/datatypes.h
@@ -223,6 +223,20 @@ extern virClassPtr virAdmClientClass;
         }                                                               \
     } while (0)
 
+# define virCheckSecretGoto(obj, label)                                 \
+    do {                                                                \
+        virSecretPtr _secret = (obj);                                   \
+        if (!virObjectIsClass(_secret, virSecretClass) ||               \
+            !virObjectIsClass(_secret->conn, virConnectClass)) {        \
+            virReportErrorHelper(VIR_FROM_SECRET,                       \
+                                 VIR_ERR_INVALID_SECRET,                \
+                                 __FILE__, __FUNCTION__, __LINE__,      \
+                                 __FUNCTION__);                         \
+            virDispatchError(NULL);                                     \
+            goto label;                                                 \
+        }                                                               \
+    } while (0)
+
 # define virCheckStreamReturn(obj, retval)                              \
     do {                                                                \
         virStreamPtr _st = (obj);                                       \
diff --git a/src/driver-secret.h b/src/driver-secret.h
index c39e0d7..3cd9034 100644
--- a/src/driver-secret.h
+++ b/src/driver-secret.h
@@ -77,6 +77,18 @@ typedef int
                                virSecretPtr **secrets,
                                unsigned int flags);
 
+typedef int
+(*virDrvConnectSecretEventRegisterAny)(virConnectPtr conn,
+                                       virSecretPtr secret,
+                                       int eventID,
+                                       virConnectSecretEventGenericCallback cb,
+                                       void *opaque,
+                                       virFreeCallback freecb);
+
+typedef int
+(*virDrvConnectSecretEventDeregisterAny)(virConnectPtr conn,
+                                         int callbackID);
+
 typedef struct _virSecretDriver virSecretDriver;
 typedef virSecretDriver *virSecretDriverPtr;
 
@@ -98,6 +110,8 @@ struct _virSecretDriver {
     virDrvSecretSetValue secretSetValue;
     virDrvSecretGetValue secretGetValue;
     virDrvSecretUndefine secretUndefine;
+    virDrvConnectSecretEventRegisterAny connectSecretEventRegisterAny;
+    virDrvConnectSecretEventDeregisterAny connectSecretEventDeregisterAny;
 };
 
 
diff --git a/src/libvirt-secret.c b/src/libvirt-secret.c
index db42aec..8a99c8c 100644
--- a/src/libvirt-secret.c
+++ b/src/libvirt-secret.c
@@ -693,3 +693,132 @@ virSecretFree(virSecretPtr secret)
     virObjectUnref(secret);
     return 0;
 }
+
+
+/**
+ * virConnectSecretEventRegisterAny:
+ * @conn: pointer to the connection
+ * @secret: pointer to the secret
+ * @eventID: the event type to receive
+ * @cb: callback to the function handling secret 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 secret events
+ * occurring on a secret. This function requires that an event loop
+ * has been previously registered with virEventRegisterImpl() or
+ * virEventRegisterDefaultImpl().
+ *
+ * If @secret is NULL, then events will be monitored for any secret.
+ * If @secret is non-NULL, then only the specific secret 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_SECRET_EVENT_CALLBACK() macro to cast the
+ * supplied function pointer to match the signature of this method.
+ *
+ * The virSecretPtr 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 secret object after the callback
+ * returns, it shall take a reference to it, by calling virSecretRef().
+ * The reference can be released once the object is no longer required
+ * by calling virSecretFree().
+ *
+ * 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 virConnectSecretEventDeregisterAny() method.
+ *
+ * Returns a callback identifier on success, -1 on failure.
+ */
+int
+virConnectSecretEventRegisterAny(virConnectPtr conn,
+                                 virSecretPtr secret,
+                                 int eventID,
+                                 virConnectSecretEventGenericCallback cb,
+                                 void *opaque,
+                                 virFreeCallback freecb)
+{
+    VIR_DEBUG("conn=%p, secret=%p, eventID=%d, cb=%p, opaque=%p, freecb=%p",
+              conn, secret, eventID, cb, opaque, freecb);
+
+    virResetLastError();
+
+    virCheckConnectReturn(conn, -1);
+    if (secret) {
+        virCheckSecretGoto(secret, error);
+        if (secret->conn != conn) {
+            char uuidstr[VIR_UUID_STRING_BUFLEN];
+            virUUIDFormat(secret->uuid, uuidstr);
+            virReportInvalidArg(secret,
+                                _("secret '%s' in %s must match connection"),
+                                uuidstr, __FUNCTION__);
+            goto error;
+        }
+    }
+    virCheckNonNullArgGoto(cb, error);
+    virCheckNonNegativeArgGoto(eventID, error);
+
+    if (eventID >= VIR_SECRET_EVENT_ID_LAST) {
+        virReportInvalidArg(eventID,
+                            _("eventID in %s must be less than %d"),
+                            __FUNCTION__, VIR_SECRET_EVENT_ID_LAST);
+        goto error;
+    }
+
+    if (conn->secretDriver &&
+        conn->secretDriver->connectSecretEventRegisterAny) {
+        int ret;
+        ret = conn->secretDriver->connectSecretEventRegisterAny(conn,
+                                                                secret,
+                                                                eventID,
+                                                                cb,
+                                                                opaque,
+                                                                freecb);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virReportUnsupportedError();
+ error:
+    virDispatchError(conn);
+    return -1;
+}
+
+
+/**
+ * virConnectSecretEventDeregisterAny:
+ * @conn: pointer to the connection
+ * @callbackID: the callback identifier
+ *
+ * Removes an event callback. The callbackID parameter should be the
+ * value obtained from a previous virConnectSecretEventRegisterAny() method.
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+int
+virConnectSecretEventDeregisterAny(virConnectPtr conn,
+                                   int callbackID)
+{
+    VIR_DEBUG("conn=%p, callbackID=%d", conn, callbackID);
+
+    virResetLastError();
+
+    virCheckConnectReturn(conn, -1);
+    virCheckNonNegativeArgGoto(callbackID, error);
+
+    if (conn->secretDriver &&
+        conn->secretDriver->connectSecretEventDeregisterAny) {
+        int ret;
+        ret = conn->secretDriver->connectSecretEventDeregisterAny(conn,
+                                                                  callbackID);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virReportUnsupportedError();
+ error:
+    virDispatchError(conn);
+    return -1;
+}
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 12ef085..62885ac 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -749,6 +749,8 @@ LIBVIRT_2.2.0 {
 LIBVIRT_3.0.0 {
     global:
         virStorageVolGetInfoFlags;
+        virConnectSecretEventRegisterAny;
+        virConnectSecretEventDeregisterAny;
 } LIBVIRT_2.2.0;
 
 # .... define new API here using predicted next version number ....
-- 
2.9.3

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to