From 7e111c6fe621f1ef4a0ce3c7a2ee9f643b9b4619 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Wed, 13 Jun 2012 21:59:48 -0600 Subject: [PATCH] snapshot: merge domain and snapshot computation Now that domain listing is a thin wrapper around child listing, it's easier to have a common entry point. This restores the hashForEach optimization lost in the previous patch when there are no snapshots being filtered out of the entire list. * src/conf/domain_conf.h (virDomainSnapshotObjListGetNames) (virDomainSnapshotObjListNum): Add parameter. (virDomainSnapshotObjListGetNamesFrom) (virDomainSnapshotObjListNumFrom): Delete. * src/libvirt_private.syms (domain_conf.h): Drop deleted functions. * src/conf/domain_conf.c (virDomainSnapshotObjListGetNames): Merge, and (re)add an optimization. * src/qemu/qemu_driver.c (qemuDomainUndefineFlags) (qemuDomainSnapshotListNames, qemuDomainSnapshotNum) (qemuDomainSnapshotListChildrenNames) (qemuDomainSnapshotNumChildren): Update callers. * src/qemu/qemu_migration.c (qemuMigrationIsAllowed): Likewise. * src/conf/virdomainlist.c (virDomainListPopulate): Likewise. --- src/conf/domain_conf.c | 88 +++++++++++++++++++++------------------ src/conf/domain_conf.h | 7 +--- src/conf/virdomainlist.c | 2 +- src/libvirt_private.syms | 2 - src/qemu/qemu_driver.c | 11 ++--- src/qemu/qemu_migration.c | 3 +- 6 files changed, 58 insertions(+), 55 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 43872d1c73..abe9d47b39 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -14286,34 +14286,37 @@ static void virDomainSnapshotObjListCopyNames(void *payload, } } -int virDomainSnapshotObjListGetNames(virDomainSnapshotObjListPtr snapshots, - char **const names, int maxnames, - unsigned int flags) -{ - /* LIST_ROOTS and LIST_DESCENDANTS have the same bit value, but - * opposite semantics. Toggle here to get the correct traversal - * on the metaroot. */ - flags ^= VIR_DOMAIN_SNAPSHOT_LIST_ROOTS; - return virDomainSnapshotObjListGetNamesFrom(&snapshots->metaroot, names, - maxnames, flags); -} - -int virDomainSnapshotObjListGetNamesFrom(virDomainSnapshotObjPtr snapshot, - char **const names, int maxnames, - unsigned int flags) +int +virDomainSnapshotObjListGetNames(virDomainSnapshotObjListPtr snapshots, + virDomainSnapshotObjPtr from, + char **const names, int maxnames, + unsigned int flags) { struct virDomainSnapshotNameData data = { 0, 0, maxnames, names, 0 }; int i; + if (!from) { + /* LIST_ROOTS and LIST_DESCENDANTS have the same bit value, + * but opposite semantics. Toggle here to get the correct + * traversal on the metaroot. */ + flags ^= VIR_DOMAIN_SNAPSHOT_LIST_ROOTS; + from = &snapshots->metaroot; + } + data.flags = flags & ~VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS; - if (flags & VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS) - virDomainSnapshotForEachDescendant(snapshot, - virDomainSnapshotObjListCopyNames, - &data); - else - virDomainSnapshotForEachChild(snapshot, + if (flags & VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS) { + if (from->def) + virDomainSnapshotForEachDescendant(from, + virDomainSnapshotObjListCopyNames, + &data); + else + virHashForEach(snapshots->objs, virDomainSnapshotObjListCopyNames, + &data); + } else { + virDomainSnapshotForEachChild(from, virDomainSnapshotObjListCopyNames, &data); + } if (data.oom) { virReportOOMError(); @@ -14348,33 +14351,36 @@ static void virDomainSnapshotObjListCount(void *payload, data->count++; } -int virDomainSnapshotObjListNum(virDomainSnapshotObjListPtr snapshots, - unsigned int flags) -{ - /* LIST_ROOTS and LIST_DESCENDANTS have the same bit value, but - * opposite semantics. Toggle here to get the correct traversal - * on the metaroot. */ - flags ^= VIR_DOMAIN_SNAPSHOT_LIST_ROOTS; - return virDomainSnapshotObjListNumFrom(&snapshots->metaroot, flags); -} - int -virDomainSnapshotObjListNumFrom(virDomainSnapshotObjPtr snapshot, - unsigned int flags) +virDomainSnapshotObjListNum(virDomainSnapshotObjListPtr snapshots, + virDomainSnapshotObjPtr from, + unsigned int flags) { struct virDomainSnapshotNumData data = { 0, 0 }; + if (!from) { + /* LIST_ROOTS and LIST_DESCENDANTS have the same bit value, + * but opposite semantics. Toggle here to get the correct + * traversal on the metaroot. */ + flags ^= VIR_DOMAIN_SNAPSHOT_LIST_ROOTS; + from = &snapshots->metaroot; + } + data.flags = flags & ~VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS; - if (flags & VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS) - virDomainSnapshotForEachDescendant(snapshot, - virDomainSnapshotObjListCount, - &data); - else if (data.flags) - virDomainSnapshotForEachChild(snapshot, + if (flags & VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS) { + if (data.flags || from->def) + virDomainSnapshotForEachDescendant(from, + virDomainSnapshotObjListCount, + &data); + else + data.count = virHashSize(snapshots->objs); + } else if (data.flags) { + virDomainSnapshotForEachChild(from, virDomainSnapshotObjListCount, &data); - else - data.count = snapshot->nchildren; + } else { + data.count = from->nchildren; + } return data.count; } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index e3a3679268..86c1e63093 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1769,15 +1769,12 @@ virDomainSnapshotObjPtr virDomainSnapshotAssignDef(virDomainSnapshotObjListPtr s int virDomainSnapshotObjListInit(virDomainSnapshotObjListPtr objs); int virDomainSnapshotObjListGetNames(virDomainSnapshotObjListPtr snapshots, + virDomainSnapshotObjPtr from, char **const names, int maxnames, unsigned int flags); int virDomainSnapshotObjListNum(virDomainSnapshotObjListPtr snapshots, + virDomainSnapshotObjPtr from, unsigned int flags); -int virDomainSnapshotObjListGetNamesFrom(virDomainSnapshotObjPtr snapshot, - char **const names, int maxnames, - unsigned int flags); -int virDomainSnapshotObjListNumFrom(virDomainSnapshotObjPtr snapshot, - unsigned int flags); virDomainSnapshotObjPtr virDomainSnapshotFindByName(const virDomainSnapshotObjListPtr snapshots, const char *name); void virDomainSnapshotObjListRemove(virDomainSnapshotObjListPtr snapshots, diff --git a/src/conf/virdomainlist.c b/src/conf/virdomainlist.c index 107e693ec6..e673af5ad6 100644 --- a/src/conf/virdomainlist.c +++ b/src/conf/virdomainlist.c @@ -106,7 +106,7 @@ virDomainListPopulate(void *payload, /* filter by snapshot existence */ if (MATCH(VIR_CONNECT_LIST_FILTERS_SNAPSHOT)) { - int nsnap = virDomainSnapshotObjListNum(&vm->snapshots, 0); + int nsnap = virDomainSnapshotObjListNum(&vm->snapshots, NULL, 0); if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT) && nsnap > 0) || (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT) && nsnap <= 0))) goto cleanup; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 5a94b8bd64..b37fe6859c 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -457,9 +457,7 @@ virDomainSnapshotFindByName; virDomainSnapshotForEachChild; virDomainSnapshotForEachDescendant; virDomainSnapshotObjListGetNames; -virDomainSnapshotObjListGetNamesFrom; virDomainSnapshotObjListNum; -virDomainSnapshotObjListNumFrom; virDomainSnapshotObjListRemove; virDomainSnapshotStateTypeFromString; virDomainSnapshotStateTypeToString; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 1ff2af4887..89cdb422ef 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -5139,7 +5139,7 @@ qemuDomainUndefineFlags(virDomainPtr dom, } if (!virDomainObjIsActive(vm) && - (nsnapshots = virDomainSnapshotObjListNum(&vm->snapshots, 0))) { + (nsnapshots = virDomainSnapshotObjListNum(&vm->snapshots, NULL, 0))) { if (!(flags & VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA)) { qemuReportError(VIR_ERR_OPERATION_INVALID, _("cannot delete inactive domain with %d " @@ -10663,7 +10663,7 @@ static int qemuDomainSnapshotListNames(virDomainPtr domain, char **names, goto cleanup; } - n = virDomainSnapshotObjListGetNames(&vm->snapshots, names, nameslen, + n = virDomainSnapshotObjListGetNames(&vm->snapshots, NULL, names, nameslen, flags); cleanup: @@ -10698,7 +10698,7 @@ static int qemuDomainSnapshotNum(virDomainPtr domain, * VIR_DOMAIN_SNAPSHOT_LIST_METADATA makes no difference to our * answer. */ - n = virDomainSnapshotObjListNum(&vm->snapshots, flags); + n = virDomainSnapshotObjListNum(&vm->snapshots, NULL, flags); cleanup: if (vm) @@ -10740,7 +10740,8 @@ qemuDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot, goto cleanup; } - n = virDomainSnapshotObjListGetNamesFrom(snap, names, nameslen, flags); + n = virDomainSnapshotObjListGetNames(&vm->snapshots, snap, names, nameslen, + flags); cleanup: if (vm) @@ -10784,7 +10785,7 @@ qemuDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot, * VIR_DOMAIN_SNAPSHOT_LIST_METADATA makes no difference to our * answer. */ - n = virDomainSnapshotObjListNumFrom(snap, flags); + n = virDomainSnapshotObjListNum(&vm->snapshots, snap, flags); cleanup: if (vm) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index b893fd5422..48369d65ec 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -807,7 +807,8 @@ qemuMigrationIsAllowed(struct qemud_driver *driver, virDomainObjPtr vm, "%s", _("domain is marked for auto destroy")); return false; } - if ((nsnapshots = virDomainSnapshotObjListNum(&vm->snapshots, 0))) { + if ((nsnapshots = virDomainSnapshotObjListNum(&vm->snapshots, NULL, + 0))) { qemuReportError(VIR_ERR_OPERATION_INVALID, _("cannot migrate domain with %d snapshots"), nsnapshots);