提交 f2013c9d 编写于 作者: E Eric Blake

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.
上级 de6431a3
...@@ -2688,13 +2688,19 @@ virDomainSnapshotPtr virDomainSnapshotCreateXML(virDomainPtr domain, ...@@ -2688,13 +2688,19 @@ virDomainSnapshotPtr virDomainSnapshotCreateXML(virDomainPtr domain,
char *virDomainSnapshotGetXMLDesc(virDomainSnapshotPtr snapshot, char *virDomainSnapshotGetXMLDesc(virDomainSnapshotPtr snapshot,
unsigned int flags); unsigned int flags);
/* Flags valid for both virDomainSnapshotNum() and /* Flags valid for virDomainSnapshotNum(),
* virDomainSnapshotListNames(). */ * virDomainSnapshotListNames(), virDomainSnapshotNumChildren(), and
* virDomainSnapshotListChildrenNames(). Note that the interpretation
* of flag (1<<0) depends on which function it is passed to. */
typedef enum { typedef enum {
VIR_DOMAIN_SNAPSHOT_LIST_ROOTS = (1 << 0), /* Filter by snapshots which VIR_DOMAIN_SNAPSHOT_LIST_ROOTS = (1 << 0), /* Filter by snapshots
have no parents */ with no parents, when
VIR_DOMAIN_SNAPSHOT_LIST_METADATA = (1 << 1), /* Filter by snapshots which listing a domain */
have metadata */ 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; } virDomainSnapshotListFlags;
/* Return the number of snapshots for this domain */ /* Return the number of snapshots for this domain */
...@@ -2704,6 +2710,15 @@ int virDomainSnapshotNum(virDomainPtr domain, unsigned int flags); ...@@ -2704,6 +2710,15 @@ int virDomainSnapshotNum(virDomainPtr domain, unsigned int flags);
int virDomainSnapshotListNames(virDomainPtr domain, char **names, int nameslen, int virDomainSnapshotListNames(virDomainPtr domain, char **names, int nameslen,
unsigned int flags); 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 */ /* Get a handle to a named snapshot */
virDomainSnapshotPtr virDomainSnapshotLookupByName(virDomainPtr domain, virDomainSnapshotPtr virDomainSnapshotLookupByName(virDomainPtr domain,
const char *name, const char *name,
......
...@@ -352,6 +352,7 @@ skip_impl = ( ...@@ -352,6 +352,7 @@ skip_impl = (
'virConnectListDefinedInterfaces', 'virConnectListDefinedInterfaces',
'virConnectListNWFilters', 'virConnectListNWFilters',
'virDomainSnapshotListNames', 'virDomainSnapshotListNames',
'virDomainSnapshotListChildrenNames',
'virConnGetLastError', 'virConnGetLastError',
'virGetLastError', 'virGetLastError',
'virDomainGetInfo', 'virDomainGetInfo',
...@@ -963,6 +964,9 @@ def nameFixup(name, classe, type, file): ...@@ -963,6 +964,9 @@ def nameFixup(name, classe, type, file):
elif name[0:26] == "virDomainSnapshotListNames": elif name[0:26] == "virDomainSnapshotListNames":
func = name[9:] func = name[9:]
func = string.lower(func[0:1]) + func[1:] 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": elif name[0:20] == "virDomainSnapshotNum":
func = name[9:] func = name[9:]
func = string.lower(func[0:1]) + func[1:] func = string.lower(func[0:1]) + func[1:]
......
...@@ -346,14 +346,20 @@ ...@@ -346,14 +346,20 @@
<function name='virDomainSnapshotListNames' file='python'> <function name='virDomainSnapshotListNames' file='python'>
<info>collect the list of snapshots for the given domain</info> <info>collect the list of snapshots for the given domain</info>
<arg name='dom' type='virDomainPtr' info='pointer to the domain'/> <arg name='dom' type='virDomainPtr' info='pointer to the domain'/>
<arg name='flags' type='unsigned int' info='flags, curently unused'/> <arg name='flags' type='unsigned int' info='flags'/>
<return type='str *' info='the list of Names of None in case of error'/> <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>
<function name='virDomainRevertToSnapshot' file='python'> <function name='virDomainRevertToSnapshot' file='python'>
<info>revert the domain to the given snapshot</info> <info>revert the domain to the given snapshot</info>
<arg name='dom' type='virDomainPtr' info='dummy domain pointer'/> <arg name='dom' type='virDomainPtr' info='dummy domain pointer'/>
<arg name='snap' type='virDomainSnapshotPtr' info='pointer to the snapshot'/> <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"/> <return type='int' info="0 on success, -1 on error"/>
</function> </function>
<function name='virDomainGetBlockJobInfo' file='python'> <function name='virDomainGetBlockJobInfo' file='python'>
......
...@@ -1726,6 +1726,51 @@ libvirt_virDomainSnapshotListNames(PyObject *self ATTRIBUTE_UNUSED, ...@@ -1726,6 +1726,51 @@ libvirt_virDomainSnapshotListNames(PyObject *self ATTRIBUTE_UNUSED,
return(py_retval); 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 * static PyObject *
libvirt_virDomainRevertToSnapshot(PyObject *self ATTRIBUTE_UNUSED, libvirt_virDomainRevertToSnapshot(PyObject *self ATTRIBUTE_UNUSED,
PyObject *args) { PyObject *args) {
......
...@@ -584,6 +584,16 @@ typedef int ...@@ -584,6 +584,16 @@ typedef int
int nameslen, int nameslen,
unsigned int flags); 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 typedef virDomainSnapshotPtr
(*virDrvDomainSnapshotLookupByName)(virDomainPtr domain, (*virDrvDomainSnapshotLookupByName)(virDomainPtr domain,
const char *name, const char *name,
...@@ -860,6 +870,8 @@ struct _virDriver { ...@@ -860,6 +870,8 @@ struct _virDriver {
virDrvDomainSnapshotGetXMLDesc domainSnapshotGetXMLDesc; virDrvDomainSnapshotGetXMLDesc domainSnapshotGetXMLDesc;
virDrvDomainSnapshotNum domainSnapshotNum; virDrvDomainSnapshotNum domainSnapshotNum;
virDrvDomainSnapshotListNames domainSnapshotListNames; virDrvDomainSnapshotListNames domainSnapshotListNames;
virDrvDomainSnapshotNumChildren domainSnapshotNumChildren;
virDrvDomainSnapshotListChildrenNames domainSnapshotListChildrenNames;
virDrvDomainSnapshotLookupByName domainSnapshotLookupByName; virDrvDomainSnapshotLookupByName domainSnapshotLookupByName;
virDrvDomainHasCurrentSnapshot domainHasCurrentSnapshot; virDrvDomainHasCurrentSnapshot domainHasCurrentSnapshot;
virDrvDomainSnapshotGetParent domainSnapshotGetParent; virDrvDomainSnapshotGetParent domainSnapshotGetParent;
......
...@@ -16067,6 +16067,117 @@ error: ...@@ -16067,6 +16067,117 @@ error:
return -1; 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: * virDomainSnapshotLookupByName:
* @domain: a domain object * @domain: a domain object
......
...@@ -493,6 +493,8 @@ LIBVIRT_0.9.7 { ...@@ -493,6 +493,8 @@ LIBVIRT_0.9.7 {
global: global:
virDomainReset; virDomainReset;
virDomainSnapshotGetParent; virDomainSnapshotGetParent;
virDomainSnapshotListChildrenNames;
virDomainSnapshotNumChildren;
} LIBVIRT_0.9.5; } LIBVIRT_0.9.5;
# .... define new API here using predicted next version number .... # .... define new API here using predicted next version number ....
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册