From f2013c9dd1ce468b8620ee35c232a93ef7026fb0 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Sat, 24 Sep 2011 19:56:26 -0600 Subject: snapshot: new virDomainSnapshotListChildrenNames API 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. --- 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 1e4b2a2af..c991dfcde 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -2688,13 +2688,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; /* Return the number of snapshots for this domain */ @@ -2704,6 +2710,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, diff --git a/python/generator.py b/python/generator.py index 79558ddbd..71afdb771 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 3013e46d2..ef02f34e3 100644 --- a/python/libvirt-override-api.xml +++ b/python/libvirt-override-api.xml @@ -346,14 +346,20 @@ collect the list of snapshots for the given domain - - + + + + + collect the list of child snapshots for the given snapshot + + + revert the domain to the given snapshot - + diff --git a/python/libvirt-override.c b/python/libvirt-override.c index d65423d39..523c03bf4 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -1726,6 +1726,51 @@ libvirt_virDomainSnapshotListNames(PyObject *self ATTRIBUTE_UNUSED, return(py_retval); } +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) { diff --git a/src/driver.h b/src/driver.h index f85a1b1fe..b899d0ea1 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 182e031f9..f07c720bf 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -16067,6 +16067,117 @@ error: return -1; } +/** + * 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 diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index afea29ba4..9762fc47b 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 .... -- cgit v1.2.3-65-gdbad