[libvirt] [PATCHv2 7/7] snapshot: implement snapshot children listing in qemu
Daniel Veillard
veillard at redhat.com
Mon Oct 10 03:29:46 UTC 2011
On Fri, Sep 30, 2011 at 05:09:29PM -0600, Eric Blake wrote:
> Not too hard to wire up. The trickiest part is realizing that
> listing children of a snapshot cannot use SNAPSHOT_LIST_ROOTS,
> and that we overloaded that bit to also mean SNAPSHOT_LIST_DESCENDANTS;
> we use that bit to decide which iteration to use, but don't want
> the existing counting/listing functions to see that bit.
>
> * src/conf/domain_conf.h (virDomainSnapshotObjListNumFrom)
> (virDomainSnapshotObjListGetNamesFrom): New prototypes.
> * src/conf/domain_conf.c (virDomainSnapshotObjListNumFrom)
> (virDomainSnapshotObjListGetNamesFrom): New functions.
> * src/libvirt_private.syms (domain_conf.h): Export them.
> * src/qemu/qemu_driver.c (qemuDomainSnapshotNumChildren)
> (qemuDomainSnapshotListChildrenNames): New functions.
> ---
>
> v2: no change, but now virsh changes have been tested both with
> and without this patch
>
> src/conf/domain_conf.c | 51 +++++++++++++++++++++++++++
> src/conf/domain_conf.h | 7 ++++
> src/libvirt_private.syms | 2 +
> src/qemu/qemu_driver.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 147 insertions(+), 0 deletions(-)
>
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index c141982..438e3b6 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -12138,6 +12138,37 @@ cleanup:
> return -1;
> }
>
> +int virDomainSnapshotObjListGetNamesFrom(virDomainSnapshotObjPtr snapshot,
> + virDomainSnapshotObjListPtr snapshots,
> + char **const names, int maxnames,
> + unsigned int flags)
> +{
> + struct virDomainSnapshotNameData data = { 0, 0, maxnames, names, 0 };
> + int i;
> +
> + data.flags = flags & ~VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS;
> +
> + if (flags & VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS)
> + virDomainSnapshotForEachDescendant(snapshots, snapshot,
> + virDomainSnapshotObjListCopyNames,
> + &data);
> + else
> + virDomainSnapshotForEachChild(snapshots, snapshot,
> + virDomainSnapshotObjListCopyNames, &data);
> +
> + if (data.oom) {
> + virReportOOMError();
> + goto cleanup;
> + }
> +
> + return data.numnames;
> +
> +cleanup:
> + for (i = 0; i < data.numnames; i++)
> + VIR_FREE(data.names[i]);
> + return -1;
> +}
> +
> struct virDomainSnapshotNumData {
> int count;
> unsigned int flags;
> @@ -12165,6 +12196,26 @@ int virDomainSnapshotObjListNum(virDomainSnapshotObjListPtr snapshots,
> return data.count;
> }
>
> +int
> +virDomainSnapshotObjListNumFrom(virDomainSnapshotObjPtr snapshot,
> + virDomainSnapshotObjListPtr snapshots,
> + unsigned int flags)
> +{
> + struct virDomainSnapshotNumData data = { 0, 0 };
> +
> + data.flags = flags & ~VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS;
> +
> + if (flags & VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS)
> + virDomainSnapshotForEachDescendant(snapshots, snapshot,
> + virDomainSnapshotObjListCount,
> + &data);
> + else
> + virDomainSnapshotForEachChild(snapshots, snapshot,
> + virDomainSnapshotObjListCount, &data);
> +
> + return data.count;
> +}
> +
> virDomainSnapshotObjPtr
> virDomainSnapshotFindByName(const virDomainSnapshotObjListPtr snapshots,
> const char *name)
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index 0bc0042..1258740 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -1488,6 +1488,13 @@ int virDomainSnapshotObjListGetNames(virDomainSnapshotObjListPtr snapshots,
> unsigned int flags);
> int virDomainSnapshotObjListNum(virDomainSnapshotObjListPtr snapshots,
> unsigned int flags);
> +int virDomainSnapshotObjListGetNamesFrom(virDomainSnapshotObjPtr snapshot,
> + virDomainSnapshotObjListPtr snapshots,
> + char **const names, int maxnames,
> + unsigned int flags);
> +int virDomainSnapshotObjListNumFrom(virDomainSnapshotObjPtr snapshot,
> + virDomainSnapshotObjListPtr snapshots,
> + unsigned int flags);
> virDomainSnapshotObjPtr virDomainSnapshotFindByName(const virDomainSnapshotObjListPtr snapshots,
> const char *name);
> void virDomainSnapshotObjListRemove(virDomainSnapshotObjListPtr snapshots,
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index c2a3fab..6b9ceaa 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -413,7 +413,9 @@ virDomainSnapshotForEachChild;
> virDomainSnapshotForEachDescendant;
> virDomainSnapshotHasChildren;
> virDomainSnapshotObjListGetNames;
> +virDomainSnapshotObjListGetNamesFrom;
> virDomainSnapshotObjListNum;
> +virDomainSnapshotObjListNumFrom;
> virDomainSnapshotObjListRemove;
> virDomainSnapshotStateTypeFromString;
> virDomainSnapshotStateTypeToString;
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 1a171cf..48b0b22 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -9441,6 +9441,91 @@ cleanup:
> return n;
> }
>
> +static int
> +qemuDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot,
> + char **names,
> + int nameslen,
> + unsigned int flags)
> +{
> + struct qemud_driver *driver = snapshot->domain->conn->privateData;
> + virDomainObjPtr vm = NULL;
> + virDomainSnapshotObjPtr snap = NULL;
> + int n = -1;
> +
> + virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS |
> + VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1);
> +
> + qemuDriverLock(driver);
> + vm = virDomainFindByUUID(&driver->domains, snapshot->domain->uuid);
> + if (!vm) {
> + char uuidstr[VIR_UUID_STRING_BUFLEN];
> + virUUIDFormat(snapshot->domain->uuid, uuidstr);
> + qemuReportError(VIR_ERR_NO_DOMAIN,
> + _("no domain with matching uuid '%s'"), uuidstr);
> + goto cleanup;
> + }
> +
> + snap = virDomainSnapshotFindByName(&vm->snapshots, snapshot->name);
> + if (!snap) {
> + qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT,
> + _("no domain snapshot with matching name '%s'"),
> + snapshot->name);
> + goto cleanup;
> + }
> +
> + n = virDomainSnapshotObjListGetNamesFrom(snap, &vm->snapshots,
> + names, nameslen, flags);
> +
> +cleanup:
> + if (vm)
> + virDomainObjUnlock(vm);
> + qemuDriverUnlock(driver);
> + return n;
> +}
> +
> +static int
> +qemuDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot,
> + unsigned int flags)
> +{
> + struct qemud_driver *driver = snapshot->domain->conn->privateData;
> + virDomainObjPtr vm = NULL;
> + virDomainSnapshotObjPtr snap = NULL;
> + int n = -1;
> +
> + virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS |
> + VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1);
> +
> + qemuDriverLock(driver);
> + vm = virDomainFindByUUID(&driver->domains, snapshot->domain->uuid);
> + if (!vm) {
> + char uuidstr[VIR_UUID_STRING_BUFLEN];
> + virUUIDFormat(snapshot->domain->uuid, uuidstr);
> + qemuReportError(VIR_ERR_NO_DOMAIN,
> + _("no domain with matching uuid '%s'"), uuidstr);
> + goto cleanup;
> + }
> +
> + snap = virDomainSnapshotFindByName(&vm->snapshots, snapshot->name);
> + if (!snap) {
> + qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT,
> + _("no domain snapshot with matching name '%s'"),
> + snapshot->name);
> + goto cleanup;
> + }
> +
> + /* All qemu snapshots have libvirt metadata, so
> + * VIR_DOMAIN_SNAPSHOT_LIST_METADATA makes no difference to our
> + * answer. */
> +
> + n = virDomainSnapshotObjListNumFrom(snap, &vm->snapshots, flags);
> +
> +cleanup:
> + if (vm)
> + virDomainObjUnlock(vm);
> + qemuDriverUnlock(driver);
> + return n;
> +}
> +
> static virDomainSnapshotPtr qemuDomainSnapshotLookupByName(virDomainPtr domain,
> const char *name,
> unsigned int flags)
> @@ -10558,6 +10643,8 @@ static virDriver qemuDriver = {
> .domainSnapshotGetXMLDesc = qemuDomainSnapshotGetXMLDesc, /* 0.8.0 */
> .domainSnapshotNum = qemuDomainSnapshotNum, /* 0.8.0 */
> .domainSnapshotListNames = qemuDomainSnapshotListNames, /* 0.8.0 */
> + .domainSnapshotNumChildren = qemuDomainSnapshotNumChildren, /* 0.9.7 */
> + .domainSnapshotListChildrenNames = qemuDomainSnapshotListChildrenNames, /* 0.9.7 */
> .domainSnapshotLookupByName = qemuDomainSnapshotLookupByName, /* 0.8.0 */
> .domainHasCurrentSnapshot = qemuDomainHasCurrentSnapshot, /* 0.8.0 */
> .domainSnapshotGetParent = qemuDomainSnapshotGetParent, /* 0.9.7 */
ACK,
I would tend to be a bit more defensive myself byt not dereferencing 3
layers of pointer as the first instructions in the function, but
if you're confident the structures can't be missing :-)
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel at veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
More information about the libvir-list
mailing list