[libvirt] [PATCHv2 1/7] snapshot: new virDomainSnapshotListChildrenNames API

Daniel Veillard veillard at redhat.com
Mon Oct 10 03:13:23 UTC 2011


On Fri, Sep 30, 2011 at 05:09:23PM -0600, Eric Blake wrote:
> The previous API addition allowed traversal up the hierarchy;
> this one makes it easier to traverse down the hierarchy.
> 
> In the python bindings, virDomainSnapshotNumChildren can be
> generated, but virDomainSnapshotListChildrenNames had to copy
> from the hand-written example of virDomainSnapshotListNames.
> 
> * include/libvirt/libvirt.h.in (virDomainSnapshotNumChildren)
> (virDomainSnapshotListChildrenNames): New prototypes.
> (VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS): New flag alias.
> * src/libvirt.c (virDomainSnapshotNumChildren)
> (virDomainSnapshotListChildrenNames): New functions.
> * src/libvirt_public.syms: Export them.
> * src/driver.h (virDrvDomainSnapshotNumChildren)
> (virDrvDomainSnapshotListChildrenNames): New callbacks.
> * python/generator.py (skip_impl, nameFixup): Update lists.
> * python/libvirt-override-api.xml: Likewise.
> * python/libvirt-override.c
> (libvirt_virDomainSnapshotListChildrenNames): New wrapper function.
> ---
> 
> v2: no change
> 
>  include/libvirt/libvirt.h.in    |   27 +++++++--
>  python/generator.py             |    4 ++
>  python/libvirt-override-api.xml |   12 +++-
>  python/libvirt-override.c       |   45 ++++++++++++++++
>  src/driver.h                    |   12 ++++
>  src/libvirt.c                   |  111 +++++++++++++++++++++++++++++++++++++++
>  src/libvirt_public.syms         |    2 +
>  7 files changed, 204 insertions(+), 9 deletions(-)
> 
> diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
> index a832b65..7403a9a 100644
> --- a/include/libvirt/libvirt.h.in
> +++ b/include/libvirt/libvirt.h.in
> @@ -2686,13 +2686,19 @@ virDomainSnapshotPtr virDomainSnapshotCreateXML(virDomainPtr domain,
>  char *virDomainSnapshotGetXMLDesc(virDomainSnapshotPtr snapshot,
>                                    unsigned int flags);
> 
> -/* Flags valid for both virDomainSnapshotNum() and
> - * virDomainSnapshotListNames().  */
> +/* Flags valid for virDomainSnapshotNum(),
> + * virDomainSnapshotListNames(), virDomainSnapshotNumChildren(), and
> + * virDomainSnapshotListChildrenNames().  Note that the interpretation
> + * of flag (1<<0) depends on which function it is passed to.  */
>  typedef enum {
> -    VIR_DOMAIN_SNAPSHOT_LIST_ROOTS    = (1 << 0), /* Filter by snapshots which
> -                                                     have no parents */
> -    VIR_DOMAIN_SNAPSHOT_LIST_METADATA = (1 << 1), /* Filter by snapshots which
> -                                                     have metadata */
> +    VIR_DOMAIN_SNAPSHOT_LIST_ROOTS       = (1 << 0), /* Filter by snapshots
> +                                                        with no parents, when
> +                                                        listing a domain */
> +    VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS = (1 << 0), /* List all descendants,
> +                                                        not just children, when
> +                                                        listing a snapshot */
> +    VIR_DOMAIN_SNAPSHOT_LIST_METADATA    = (1 << 1), /* Filter by snapshots
> +                                                        which have metadata */
>  } virDomainSnapshotListFlags;

  Hum, okay, a tad bit confusing though

>  /* Return the number of snapshots for this domain */
> @@ -2702,6 +2708,15 @@ int virDomainSnapshotNum(virDomainPtr domain, unsigned int flags);
>  int virDomainSnapshotListNames(virDomainPtr domain, char **names, int nameslen,
>                                 unsigned int flags);
> 
> +/* Return the number of child snapshots for this snapshot */
> +int virDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot,
> +                                 unsigned int flags);
> +
> +/* Get the names of all child snapshots for this snapshot */
> +int virDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot,
> +                                       char **names, int nameslen,
> +                                       unsigned int flags);
> +
>  /* Get a handle to a named snapshot */
>  virDomainSnapshotPtr virDomainSnapshotLookupByName(virDomainPtr domain,
>                                                     const char *name,

  Okay

> diff --git a/python/generator.py b/python/generator.py
> index 79558dd..71afdb7 100755
> --- a/python/generator.py
> +++ b/python/generator.py
> @@ -352,6 +352,7 @@ skip_impl = (
>      'virConnectListDefinedInterfaces',
>      'virConnectListNWFilters',
>      'virDomainSnapshotListNames',
> +    'virDomainSnapshotListChildrenNames',
>      'virConnGetLastError',
>      'virGetLastError',
>      'virDomainGetInfo',
> @@ -963,6 +964,9 @@ def nameFixup(name, classe, type, file):
>      elif name[0:26] == "virDomainSnapshotListNames":
>          func = name[9:]
>          func = string.lower(func[0:1]) + func[1:]
> +    elif name[0:28] == "virDomainSnapshotNumChildren":
> +        func = name[17:]
> +        func = string.lower(func[0:1]) + func[1:]
>      elif name[0:20] == "virDomainSnapshotNum":
>          func = name[9:]
>          func = string.lower(func[0:1]) + func[1:]
> diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml
> index 3013e46..ef02f34 100644
> --- a/python/libvirt-override-api.xml
> +++ b/python/libvirt-override-api.xml
> @@ -346,14 +346,20 @@
>      <function name='virDomainSnapshotListNames' file='python'>
>        <info>collect the list of snapshots for the given domain</info>
>        <arg name='dom' type='virDomainPtr' info='pointer to the domain'/>
> -      <arg name='flags' type='unsigned int' info='flags, curently unused'/>
> -      <return type='str *' info='the list of Names of None in case of error'/>
> +      <arg name='flags' type='unsigned int' info='flags'/>
> +      <return type='str *' info='the list of Names or None in case of error'/>
> +    </function>
> +    <function name='virDomainSnapshotListChildrenNames' file='python'>
> +      <info>collect the list of child snapshots for the given snapshot</info>
> +      <arg name='snapshot' type='virDomainSnapshotPtr' info='pointer to the snapshot'/>
> +      <arg name='flags' type='unsigned int' info='flags'/>
> +      <return type='str *' info='the list of Names or None in case of error'/>
>      </function>
>      <function name='virDomainRevertToSnapshot' file='python'>
>        <info>revert the domain to the given snapshot</info>
>        <arg name='dom' type='virDomainPtr' info='dummy domain pointer'/>
>        <arg name='snap' type='virDomainSnapshotPtr' info='pointer to the snapshot'/>
> -      <arg name='flags' type='unsigned int' info='flags, curently unused'/>
> +      <arg name='flags' type='unsigned int' info='flags'/>
>        <return type='int' info="0 on success, -1 on error"/>
>      </function>
>      <function name='virDomainGetBlockJobInfo' file='python'>
> diff --git a/python/libvirt-override.c b/python/libvirt-override.c
> index d65423d..523c03b 100644
> --- a/python/libvirt-override.c
> +++ b/python/libvirt-override.c
> @@ -1727,6 +1727,51 @@ libvirt_virDomainSnapshotListNames(PyObject *self ATTRIBUTE_UNUSED,
>  }
> 
>  static PyObject *
> +libvirt_virDomainSnapshotListChildrenNames(PyObject *self ATTRIBUTE_UNUSED,
> +                                   PyObject *args) {
> +    PyObject *py_retval;
> +    char **names = NULL;
> +    int c_retval, i;
> +    virDomainSnapshotPtr snap;
> +    PyObject *pyobj_snap;
> +    unsigned int flags;
> +
> +    if (!PyArg_ParseTuple(args, (char *)"Oi:virDomainSnapshotListChildrenNames", &pyobj_snap, &flags))
> +        return(NULL);
> +    snap = (virDomainSnapshotPtr) PyvirDomainSnapshot_Get(pyobj_snap);
> +
> +    LIBVIRT_BEGIN_ALLOW_THREADS;
> +    c_retval = virDomainSnapshotNumChildren(snap, flags);
> +    LIBVIRT_END_ALLOW_THREADS;
> +    if (c_retval < 0)
> +        return VIR_PY_NONE;
> +
> +    if (c_retval) {
> +        names = malloc(sizeof(*names) * c_retval);
> +        if (!names)
> +            return VIR_PY_NONE;
> +        LIBVIRT_BEGIN_ALLOW_THREADS;
> +        c_retval = virDomainSnapshotListChildrenNames(snap, names, c_retval, flags);
> +        LIBVIRT_END_ALLOW_THREADS;
> +        if (c_retval < 0) {
> +            free(names);
> +            return VIR_PY_NONE;
> +        }
> +    }
> +    py_retval = PyList_New(c_retval);
> +
> +    if (names) {
> +        for (i = 0;i < c_retval;i++) {
> +            PyList_SetItem(py_retval, i, libvirt_constcharPtrWrap(names[i]));
> +            free(names[i]);
> +        }
> +        free(names);
> +    }
> +
> +    return(py_retval);
> +}
> +
> +static PyObject *
>  libvirt_virDomainRevertToSnapshot(PyObject *self ATTRIBUTE_UNUSED,
>                                    PyObject *args) {
>      int c_retval;
> diff --git a/src/driver.h b/src/driver.h
> index f85a1b1..b899d0e 100644
> --- a/src/driver.h
> +++ b/src/driver.h
> @@ -584,6 +584,16 @@ typedef int
>                                       int nameslen,
>                                       unsigned int flags);
> 
> +typedef int
> +    (*virDrvDomainSnapshotNumChildren)(virDomainSnapshotPtr snapshot,
> +                                       unsigned int flags);
> +
> +typedef int
> +    (*virDrvDomainSnapshotListChildrenNames)(virDomainSnapshotPtr snapshot,
> +                                             char **names,
> +                                             int nameslen,
> +                                             unsigned int flags);
> +
>  typedef virDomainSnapshotPtr
>      (*virDrvDomainSnapshotLookupByName)(virDomainPtr domain,
>                                          const char *name,
> @@ -860,6 +870,8 @@ struct _virDriver {
>      virDrvDomainSnapshotGetXMLDesc domainSnapshotGetXMLDesc;
>      virDrvDomainSnapshotNum domainSnapshotNum;
>      virDrvDomainSnapshotListNames domainSnapshotListNames;
> +    virDrvDomainSnapshotNumChildren domainSnapshotNumChildren;
> +    virDrvDomainSnapshotListChildrenNames domainSnapshotListChildrenNames;
>      virDrvDomainSnapshotLookupByName domainSnapshotLookupByName;
>      virDrvDomainHasCurrentSnapshot domainHasCurrentSnapshot;
>      virDrvDomainSnapshotGetParent domainSnapshotGetParent;
> diff --git a/src/libvirt.c b/src/libvirt.c
> index 7b1d953..c2aabf7 100644
> --- a/src/libvirt.c
> +++ b/src/libvirt.c
> @@ -16068,6 +16068,117 @@ error:
>  }
> 
>  /**
> + * virDomainSnapshotNumChildren:
> + * @snapshot: a domain snapshot object
> + * @flags: bitwise-or of supported virDomainSnapshotListFlags
> + *
> + * Provides the number of child snapshots for this domain snapshot.
> + *
> + * If @flags includes VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS, then the result
> + * includes all descendants, otherwise it is limited to direct children.
> + *
> + * If @flags includes VIR_DOMAIN_SNAPSHOT_LIST_METADATA, then the result is
> + * the number of snapshots that also include metadata that would prevent
> + * the removal of the last reference to a domain; this value will either
> + * be 0 or the same value as if the flag were not given.
> + *
> + * Returns the number of domain snapshots found or -1 in case of error.
> + */
> +int
> +virDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot, unsigned int flags)
> +{
> +    virConnectPtr conn;
> +
> +    VIR_DEBUG("snapshot=%p, flags=%x", snapshot, flags);
> +
> +    virResetLastError();
> +
> +    if (!VIR_IS_DOMAIN_SNAPSHOT(snapshot)) {
> +        virLibDomainSnapshotError(VIR_ERR_INVALID_DOMAIN_SNAPSHOT,
> +                                  __FUNCTION__);
> +        virDispatchError(NULL);
> +        return -1;
> +    }
> +
> +    conn = snapshot->domain->conn;
> +    if (conn->driver->domainSnapshotNumChildren) {
> +        int ret = conn->driver->domainSnapshotNumChildren(snapshot, flags);
> +        if (ret < 0)
> +            goto error;
> +        return ret;
> +    }
> +
> +    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
> +error:
> +    virDispatchError(conn);
> +    return -1;
> +}
> +
> +/**
> + * virDomainSnapshotListChildrenNames:
> + * @snapshot: a domain snapshot object
> + * @names: array to collect the list of names of snapshots
> + * @nameslen: size of @names
> + * @flags: bitwise-or of supported virDomainSnapshotListFlags
> + *
> + * Collect the list of domain snapshots that are children of the given
> + * snapshot, and store their names in @names.  Caller is responsible for
> + * freeing each member of the array.  The value to use for @nameslen can
> + * be determined by virDomainSnapshotNumChildren() with the same @flags.
> + *
> + * If @flags includes VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS, then the result
> + * includes all descendants, otherwise it is limited to direct children.
> + *
> + * If @flags includes VIR_DOMAIN_SNAPSHOT_LIST_METADATA, then the result is
> + * the number of snapshots that also include metadata that would prevent
> + * the removal of the last reference to a domain; this value will either
> + * be 0 or the same value as if the flag were not given.
> + *
> + * Returns the number of domain snapshots found or -1 in case of error.
> + */
> +int
> +virDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot,
> +                                   char **names, int nameslen,
> +                                   unsigned int flags)
> +{
> +    virConnectPtr conn;
> +
> +    VIR_DEBUG("snapshot=%p, names=%p, nameslen=%d, flags=%x",
> +              snapshot, names, nameslen, flags);
> +
> +    virResetLastError();
> +
> +    if (!VIR_IS_DOMAIN_SNAPSHOT(snapshot)) {
> +        virLibDomainSnapshotError(VIR_ERR_INVALID_DOMAIN_SNAPSHOT,
> +                                  __FUNCTION__);
> +        virDispatchError(NULL);
> +        return -1;
> +    }
> +
> +    conn = snapshot->domain->conn;
> +
> +    if ((names == NULL) || (nameslen < 0)) {
> +        virLibConnError(VIR_ERR_INVALID_ARG, __FUNCTION__);
> +        goto error;
> +    }
> +
> +    if (conn->driver->domainSnapshotListChildrenNames) {
> +        int ret = conn->driver->domainSnapshotListChildrenNames(snapshot,
> +                                                                names,
> +                                                                nameslen,
> +                                                                flags);
> +        if (ret < 0)
> +            goto error;
> +        return ret;
> +    }
> +
> +    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
> +error:
> +    virDispatchError(conn);
> +    return -1;
> +}
> +
> +/**
>   * virDomainSnapshotLookupByName:
>   * @domain: a domain object
>   * @name: name for the domain snapshot
> diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
> index afea29b..9762fc4 100644
> --- a/src/libvirt_public.syms
> +++ b/src/libvirt_public.syms
> @@ -493,6 +493,8 @@ LIBVIRT_0.9.7 {
>      global:
>          virDomainReset;
>          virDomainSnapshotGetParent;
> +        virDomainSnapshotListChildrenNames;
> +        virDomainSnapshotNumChildren;
>  } LIBVIRT_0.9.5;
> 
>  # .... define new API here using predicted next version number ....

  ACK

Daniel

-- 
Daniel Veillard      | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
daniel at veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/




More information about the libvir-list mailing list