This commit adds some basic structures to support events for volumes as
libvirt does with pools, networks, domains, secrets, etc. This commit
add only lifecycle event to be included at create and delete actions.
Signed-off-by: Julio Faracco <jcfaracco(a)gmail.com>
---
include/libvirt/libvirt-storage.h | 86 ++++++++++++++++++++
src/libvirt-storage.c | 125 ++++++++++++++++++++++++++++++
src/libvirt_public.syms | 6 ++
3 files changed, 217 insertions(+)
diff --git a/include/libvirt/libvirt-storage.h b/include/libvirt/libvirt-storage.h
index 413d9f6c4c..291742e5ef 100644
--- a/include/libvirt/libvirt-storage.h
+++ b/include/libvirt/libvirt-storage.h
@@ -496,4 +496,90 @@ typedef void
(*virConnectStoragePoolEventLifecycleCallback)(virConnectPtr conn,
int detail,
void *opaque);
+/**
+ * VIR_STORAGE_VOL_EVENT_CALLBACK:
+ *
+ * Used to cast the event specific callback into the generic one
+ * for use for virConnectStorageVolEventRegisterAny()
+ */
+# define
VIR_STORAGE_VOL_EVENT_CALLBACK(cb)((virConnectStorageVolEventGenericCallback)(cb))
+
+/**
+ * virStorageVolEventID:
+ *
+ * An enumeration of supported eventId parameters for
+ * virConnectStorageVolEventRegisterAny(). Each event id determines which
+ * signature of callback function will be used.
+ */
+typedef enum {
+ VIR_STORAGE_VOL_EVENT_ID_LIFECYCLE = 0, /* virConnectStorageVolEventLifecycleCallback
*/
+
+# ifdef VIR_ENUM_SENTINELS
+ VIR_STORAGE_VOL_EVENT_ID_LAST
+# endif
+} virStorageVolEventID;
+
+/**
+ * virConnectStorageVolEventGenericCallback:
+ * @conn: the connection pointer
+ * @vol: the vol pointer
+ * @opaque: application specified data
+ *
+ * A generic storage vol event callback handler, for use with
+ * virConnectStorageVolEventRegisterAny(). Specific events usually
+ * have a customization with extra parameters, often with @opaque being
+ * passed in a different parameter position; use
+ * VIR_STORAGE_VOL_EVENT_CALLBACK() when registering an appropriate handler.
+ */
+typedef void (*virConnectStorageVolEventGenericCallback)(virConnectPtr conn,
+ virStorageVolPtr vol,
+ void *opaque);
+
+/* Use VIR_STORAGE_VOL_EVENT_CALLBACK() to cast the 'cb' parameter */
+int virConnectStorageVolEventRegisterAny(virConnectPtr conn,
+ virStorageVolPtr vol, /* optional, to filter */
+ int eventID,
+ virConnectStorageVolEventGenericCallback cb,
+ void *opaque,
+ virFreeCallback freecb);
+
+int virConnectStorageVolEventDeregisterAny(virConnectPtr conn,
+ int callbackID);
+
+/**
+ * virStorageVolEventLifecycleType:
+ *
+ * a virStorageVolEventLifecycleType is emitted during storage vol
+ * lifecycle events
+ */
+typedef enum {
+ VIR_STORAGE_VOL_EVENT_CREATED = 0,
+ VIR_STORAGE_VOL_EVENT_DELETED = 1,
+
+# ifdef VIR_ENUM_SENTINELS
+ VIR_STORAGE_VOL_EVENT_LAST
+# endif
+} virStorageVolEventLifecycleType;
+
+/**
+ * virConnectStorageVolEventLifecycleCallback:
+ * @conn: connection object
+ * @vol: vol on which the event occurred
+ * @event: The specific virStorageVolEventLifeCycleType which occurred
+ * @detail: contains some details on the reason of the event.
+ * @opaque: application specified data
+ *
+ * This callback is called when a vol lifecycle action is performed, like start
+ * or stop.
+ *
+ * The callback signature to use when registering for an event of type
+ * VIR_STORAGE_VOL_EVENT_ID_LIFECYCLE with
+ * virConnectStorageVolEventRegisterAny()
+ */
+typedef void (*virConnectStorageVolEventLifecycleCallback)(virConnectPtr conn,
+ virStorageVolPtr vol,
+ int event,
+ int detail,
+ void *opaque);
+
#endif /* __VIR_LIBVIRT_STORAGE_H__ */
diff --git a/src/libvirt-storage.c b/src/libvirt-storage.c
index 1879c6bd60..2bb033c98c 100644
--- a/src/libvirt-storage.c
+++ b/src/libvirt-storage.c
@@ -2350,3 +2350,128 @@ virConnectStoragePoolEventDeregisterAny(virConnectPtr conn,
virDispatchError(conn);
return -1;
}
+
+/**
+ * virConnectStorageVolEventRegisterAny:
+ * @conn: pointer to the connection
+ * @vol: pointer to the storage vol
+ * @eventID: the event type to receive
+ * @cb: callback to the function handling network 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 storage vol events
+ * occurring on a storage vol. This function requires that an event loop
+ * has been previously registered with virEventRegisterImpl() or
+ * virEventRegisterDefaultImpl().
+ *
+ * If @vol is NULL, then events will be monitored for any storage vol.
+ * If @vol is non-NULL, then only the specific storage vol 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_STORAGE_VOL_EVENT_CALLBACK() macro to cast the
+ * supplied function pointer to match the signature of this method.
+ *
+ * The virStorageVolPtr 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 storage vol object after the callback
+ * returns, it shall take a reference to it, by calling virStorageVolRef().
+ * The reference can be released once the object is no longer required
+ * by calling virStorageVolFree().
+ *
+ * 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 virConnectStorageVolEventDeregisterAny() method.
+ *
+ * Returns a callback identifier on success, -1 on failure.
+ */
+int
+virConnectStorageVolEventRegisterAny(virConnectPtr conn,
+ virStorageVolPtr vol,
+ int eventID,
+ virConnectStorageVolEventGenericCallback cb,
+ void *opaque,
+ virFreeCallback freecb)
+{
+ VIR_DEBUG("conn=%p, vol=%p, eventID=%d, cb=%p, opaque=%p, freecb=%p",
+ conn, vol, eventID, cb, opaque, freecb);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, -1);
+ if (vol) {
+ virCheckStorageVolGoto(vol, error);
+ if (vol->conn != conn) {
+ virReportInvalidArg(vol,
+ _("storage vol '%s' in %s must match
connection"),
+ vol->name, __FUNCTION__);
+ goto error;
+ }
+ }
+ virCheckNonNullArgGoto(cb, error);
+ virCheckNonNegativeArgGoto(eventID, error);
+
+ if (eventID >= VIR_STORAGE_VOL_EVENT_ID_LAST) {
+ virReportInvalidArg(eventID,
+ _("eventID in %s must be less than %d"),
+ __FUNCTION__, VIR_STORAGE_VOL_EVENT_ID_LAST);
+ goto error;
+ }
+
+ if (conn->storageDriver &&
+ conn->storageDriver->connectStorageVolEventRegisterAny) {
+ int ret;
+ ret = conn->storageDriver->connectStorageVolEventRegisterAny(conn,
+ vol,
+ eventID,
+ cb,
+ opaque,
+ freecb);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+/**
+ * virConnectStorageVolEventDeregisterAny:
+ * @conn: pointer to the connection
+ * @callbackID: the callback identifier
+ *
+ * Removes an event callback. The callbackID parameter should be the
+ * value obtained from a previous virConnectStorageVolEventRegisterAny() method.
+ *
+ * Returns 0 on success, -1 on failure
+ */
+int
+virConnectStorageVolEventDeregisterAny(virConnectPtr conn,
+ int callbackID)
+{
+ VIR_DEBUG("conn=%p, callbackID=%d", conn, callbackID);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, -1);
+ virCheckNonNegativeArgGoto(callbackID, error);
+
+ if (conn->storageDriver &&
+ conn->storageDriver->connectStorageVolEventDeregisterAny) {
+ int ret;
+ ret = conn->storageDriver->connectStorageVolEventDeregisterAny(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 95df3a0dbc..b0dee76771 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -785,4 +785,10 @@ LIBVIRT_4.1.0 {
virStoragePoolLookupByTargetPath;
} LIBVIRT_3.9.0;
+LIBVIRT_4.4.0 {
+ global:
+ virConnectStorageVolEventRegisterAny;
+ virConnectStorageVolEventDeregisterAny;
+} LIBVIRT_4.1.0;
+
# .... define new API here using predicted next version number ....
--
2.17.0