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 a3c581d..3c7f278 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;
/* 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,
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 9080b2f..2b2f6be 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 ....
--
1.7.4.4