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.
This commit is contained in:
Eric Blake 2011-09-24 19:56:26 -06:00
parent de6431a3d6
commit f2013c9dd1
7 changed files with 204 additions and 9 deletions

View File

@ -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,

View File

@ -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:]

View File

@ -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'>

View File

@ -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) {

View File

@ -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;

View File

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

View File

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