[libvirt] [PATCH 1/5] storage: adding a skeleton for libvirt volume events.

John Ferlan jferlan at redhat.com
Wed May 30 23:06:24 UTC 2018



On 05/27/2018 03:25 PM, Julio Faracco wrote:
> 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 at gmail.com>
> ---
>  include/libvirt/libvirt-storage.h |  86 ++++++++++++++++++++
>  src/libvirt-storage.c             | 125 ++++++++++++++++++++++++++++++
>  src/libvirt_public.syms           |   6 ++
>  3 files changed, 217 insertions(+)
> 

To "augment" what Peter notes - volumes can be created, deleted,
resized, uploaded, downloaded, and wiped. A subclass of creation is that
you can create a volume from another volume.  Actually in volume terms
it's "build" or "buildVolFrom" (see _virStorageBackend for various
functions).

As for the refresh conundrum - all storage pools do the same thing w/r/t
recreating the metadata or volume list on refresh and hence redetects
everything. Thus anything you do keep track of a list would need to be
generic for all backing store types. It's been a long term goal/desire
to "fix" the algorithm to not recreate every time, but rather use "some"
mechanism to detect stale entries, but it's never received high enough
priority to make it to the top of a todo list.

John

> 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 ....
> 




More information about the libvir-list mailing list