Although a client can already obtain a snapshot's parent by dumping and parsing the xml, then doing a snapshot lookup by name, it is more efficient to get the parent in one step, which in turn will make operations that must traverse a snapshot hierarchy easier to perform. * include/libvirt/libvirt.h.in (virDomainSnapshotGetParent): Declare. * src/libvirt.c (virDomainSnapshotGetParent): New function. * src/libvirt_public.syms: Export it. * src/driver.h (virDrvDomainSnapshotGetParent): New callback. --- include/libvirt/libvirt.h.in | 4 +++ src/driver.h | 5 ++++ src/libvirt.c | 44 ++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 ++++ 4 files changed, 58 insertions(+), 0 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 39155a6..afeb83f 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -2711,6 +2711,10 @@ int virDomainHasCurrentSnapshot(virDomainPtr domain, unsigned int flags); virDomainSnapshotPtr virDomainSnapshotCurrent(virDomainPtr domain, unsigned int flags); +/* Get a handle to the parent snapshot, if one exists */ +virDomainSnapshotPtr virDomainSnapshotGetParent(virDomainSnapshotPtr snapshot, + unsigned int flags); + typedef enum { VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING = 1 << 0, /* Run after revert */ VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED = 1 << 1, /* Pause after revert */ diff --git a/src/driver.h b/src/driver.h index 3792003..7dcab8f 100644 --- a/src/driver.h +++ b/src/driver.h @@ -590,6 +590,10 @@ typedef int (*virDrvDomainHasCurrentSnapshot)(virDomainPtr domain, unsigned int flags); typedef virDomainSnapshotPtr + (*virDrvDomainSnapshotGetParent)(virDomainSnapshotPtr snapshot, + unsigned int flags); + +typedef virDomainSnapshotPtr (*virDrvDomainSnapshotCurrent)(virDomainPtr domain, unsigned int flags); @@ -854,6 +858,7 @@ struct _virDriver { virDrvDomainSnapshotListNames domainSnapshotListNames; virDrvDomainSnapshotLookupByName domainSnapshotLookupByName; virDrvDomainHasCurrentSnapshot domainHasCurrentSnapshot; + virDrvDomainSnapshotGetParent domainSnapshotGetParent; virDrvDomainSnapshotCurrent domainSnapshotCurrent; virDrvDomainRevertToSnapshot domainRevertToSnapshot; virDrvDomainSnapshotDelete domainSnapshotDelete; diff --git a/src/libvirt.c b/src/libvirt.c index 8f94b11..38fcfbc 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -16150,6 +16150,50 @@ error: } /** + * virDomainSnapshotGetParent: + * @snapshot: a snapshot object + * @flags: unused flag parameters; callers should pass 0 + * + * Get the parent snapshot for @snapshot, if any. + * + * Returns a domain snapshot object or NULL in case of failure. If the + * given snapshot is a root (no parent), then the VIR_ERR_NO_DOMAIN_SNAPSHOT + * error is raised. + */ +virDomainSnapshotPtr +virDomainSnapshotGetParent(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 NULL; + } + + conn = snapshot->domain->conn; + + if (conn->driver->domainSnapshotGetParent) { + virDomainSnapshotPtr snap; + snap = conn->driver->domainSnapshotGetParent(snapshot, flags); + if (!snap) + goto error; + return snap; + } + + virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); +error: + virDispatchError(conn); + return NULL; +} + +/** * virDomainRevertToSnapshot: * @snapshot: a domain snapshot object * @flags: bitwise-OR of virDomainSnapshotRevertFlags diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 8a6d55a..cef14f0 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -489,4 +489,9 @@ LIBVIRT_0.9.5 { virDomainSnapshotGetName; } LIBVIRT_0.9.4; +LIBVIRT_0.9.7 { + global: + virDomainSnapshotGetParent; +} LIBVIRT_0.9.5; + # .... define new API here using predicted next version number .... -- 1.7.4.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list