[libvirt] [PATCH 0/3] snapshot: another snapshot-list filter

Previously, we could filter 'virsh snapshot-list --roots' to show just snapshots lacking parents, which is good for top-down algorithms. But sometimes you want just snapshots lacking children, for bottom-up algorithms - this implements that. Once again, I can only compile-test esx. Also, I haven't yet spent time with the vbox code to write up this patch, partly because the previous round of factoring it into reusable recursive iteration is still in churn in an edit-compile-test cycle between Matthias and me. I'm still debating on whether to emulate --leaves when talking to an 0.9.5 server. Probably not too hard... Eric Blake (3): snapshot: add API for filtering by leaves snapshot: implement LIST_LEAVES flag in qemu snapshot: implement LIST_LEAVES flag in esx include/libvirt/libvirt.h.in | 2 ++ src/conf/domain_conf.c | 8 ++++++-- src/esx/esx_driver.c | 29 +++++++++++++++++++++-------- src/esx/esx_vi.c | 27 ++++++++++++++++----------- src/esx/esx_vi.h | 4 ++-- src/libvirt.c | 16 ++++++++++++++-- src/qemu/qemu_driver.c | 12 ++++++++---- tools/virsh.c | 12 ++++++++++++ tools/virsh.pod | 7 ++++++- 9 files changed, 87 insertions(+), 30 deletions(-) -- 1.7.4.4

Counterpart to --roots. * include/libvirt/libvirt.h.in (VIR_DOMAIN_SNAPSHOT_LIST_LEAVES): New flag. * src/libvirt.c (virDomainSnapshotNum, virDomainSnapshotListNames) (virDomainSnapshotNumChildren) (virDomainSnapshotListChildrenNames): Document it. * tools/virsh.c (cmdSnapshotList): Expose it. * tools/virsh.pod (snapshot-list): Document --leaves. --- include/libvirt/libvirt.h.in | 2 ++ src/libvirt.c | 16 ++++++++++++++-- tools/virsh.c | 12 ++++++++++++ tools/virsh.pod | 7 ++++++- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 1fc0dae..c81f928 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -2701,6 +2701,8 @@ typedef enum { listing a snapshot */ VIR_DOMAIN_SNAPSHOT_LIST_METADATA = (1 << 1), /* Filter by snapshots which have metadata */ + VIR_DOMAIN_SNAPSHOT_LIST_LEAVES = (1 << 2), /* Filter by snapshots + with no children */ } virDomainSnapshotListFlags; /* Return the number of snapshots for this domain */ diff --git a/src/libvirt.c b/src/libvirt.c index f07c720..35eb6b4 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -15969,7 +15969,10 @@ error: * Provides the number of domain snapshots for this domain. * * If @flags includes VIR_DOMAIN_SNAPSHOT_LIST_ROOTS, then the result is - * filtered to the number of snapshots that have no parents. + * filtered to the number of snapshots that have no parents. Likewise, + * if @flags includes VIR_DOMAIN_SNAPSHOT_LIST_LEAVES, then the result is + * filtered to the number of snapshots that have no children. Both flags + * can be used together to find unrelated snapshots. * * If @flags includes VIR_DOMAIN_SNAPSHOT_LIST_METADATA, then the result is * the number of snapshots that also include metadata that would prevent @@ -16020,7 +16023,10 @@ error: * virDomainSnapshotNum() with the same @flags. * * If @flags includes VIR_DOMAIN_SNAPSHOT_LIST_ROOTS, then the result is - * filtered to the number of snapshots that have no parents. + * filtered to the number of snapshots that have no parents. Likewise, + * if @flags includes VIR_DOMAIN_SNAPSHOT_LIST_LEAVES, then the result is + * filtered to the number of snapshots that have no children. Both flags + * can be used together to find unrelated snapshots. * * If @flags includes VIR_DOMAIN_SNAPSHOT_LIST_METADATA, then the result is * the number of snapshots that also include metadata that would prevent @@ -16077,6 +16083,9 @@ error: * 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_LEAVES, then the result is + * filtered to the number of snapshots that have no 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 @@ -16129,6 +16138,9 @@ error: * 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_LEAVES, then the result is + * filtered to the number of snapshots that have no 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 diff --git a/tools/virsh.c b/tools/virsh.c index bcf0603..0624bd8 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -13180,6 +13180,7 @@ static const vshCmdOptDef opts_snapshot_list[] = { {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, {"parent", VSH_OT_BOOL, 0, N_("add a column showing parent snapshot")}, {"roots", VSH_OT_BOOL, 0, N_("list only snapshots without parents")}, + {"leaves", VSH_OT_BOOL, 0, N_("list only snapshots without children")}, {"metadata", VSH_OT_BOOL, 0, N_("list only snapshots that have metadata that would prevent undefine")}, {"tree", VSH_OT_BOOL, 0, N_("list snapshots in a tree")}, @@ -13214,6 +13215,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd) char timestr[100]; struct tm time_info; bool tree = vshCommandOptBool(cmd, "tree"); + bool leaves = vshCommandOptBool(cmd, "leaves"); const char *from = NULL; virDomainSnapshotPtr start = NULL; int start_index = -1; @@ -13255,6 +13257,14 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd) } flags |= VIR_DOMAIN_SNAPSHOT_LIST_ROOTS; } + if (leaves) { + if (tree) { + vshError(ctl, "%s", + _("--leaves and --tree are mutually exclusive")); + return false; + } + flags |= VIR_DOMAIN_SNAPSHOT_LIST_LEAVES; + } if (vshCommandOptBool(cmd, "metadata")) { flags |= VIR_DOMAIN_SNAPSHOT_LIST_METADATA; @@ -13271,6 +13281,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd) if (ctl->useSnapshotOld || last_error->code == VIR_ERR_NO_SUPPORT) { /* We can emulate --from. */ + /* XXX can we also emulate --leaves? */ virFreeError(last_error); last_error = NULL; ctl->useSnapshotOld = true; @@ -13284,6 +13295,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd) numsnaps = virDomainSnapshotNum(dom, flags); /* Fall back to simulation if --roots was unsupported. */ + /* XXX can we also emulate --leaves? */ if (numsnaps < 0 && last_error->code == VIR_ERR_INVALID_ARG && (flags & VIR_DOMAIN_SNAPSHOT_LIST_ROOTS)) { virFreeError(last_error); diff --git a/tools/virsh.pod b/tools/virsh.pod index 07df28e..ddafee4 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -1977,7 +1977,8 @@ will create a cloned snapshot. If neither is specified, then the edits must not change the snapshot name. =item B<snapshot-list> I<domain> [{I<--parent> | I<--roots> | I<--tree>}] -[I<--metadata>] [{[I<--from>] B<snapshot> | I<--current>} [I<--descendants>]] +[{[I<--from>] B<snapshot> | I<--current>} [I<--descendants>]] +[I<--metadata>] [I<--leaves>] List all of the available snapshots for the given domain, defaulting to show columns for the snapshot name, creation time, and domain state. @@ -1996,6 +1997,10 @@ I<--descendants> is also present. When used with I<--tree>, the use of I<--descendants> is implied. This option is not compatible with I<--roots>. +If I<--leaves> is specified, the list will be filtered to just +snapshots that have no children. This option is not compatible +with I<--tree>. + If I<--metadata> is specified, the list will be filtered to just snapshots that involve libvirt metadata, and thus would prevent B<undefine> of a persistent domain, or be lost on B<destroy> of -- 1.7.4.4

On Fri, Oct 07, 2011 at 08:37:03PM -0600, Eric Blake wrote:
Counterpart to --roots.
* include/libvirt/libvirt.h.in (VIR_DOMAIN_SNAPSHOT_LIST_LEAVES): New flag. * src/libvirt.c (virDomainSnapshotNum, virDomainSnapshotListNames) (virDomainSnapshotNumChildren) (virDomainSnapshotListChildrenNames): Document it. * tools/virsh.c (cmdSnapshotList): Expose it. * tools/virsh.pod (snapshot-list): Document --leaves. --- include/libvirt/libvirt.h.in | 2 ++ src/libvirt.c | 16 ++++++++++++++-- tools/virsh.c | 12 ++++++++++++ tools/virsh.pod | 7 ++++++- 4 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 1fc0dae..c81f928 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -2701,6 +2701,8 @@ typedef enum { listing a snapshot */ VIR_DOMAIN_SNAPSHOT_LIST_METADATA = (1 << 1), /* Filter by snapshots which have metadata */ + VIR_DOMAIN_SNAPSHOT_LIST_LEAVES = (1 << 2), /* Filter by snapshots + with no children */ } virDomainSnapshotListFlags;
/* Return the number of snapshots for this domain */ diff --git a/src/libvirt.c b/src/libvirt.c index f07c720..35eb6b4 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -15969,7 +15969,10 @@ error: * Provides the number of domain snapshots for this domain. * * If @flags includes VIR_DOMAIN_SNAPSHOT_LIST_ROOTS, then the result is - * filtered to the number of snapshots that have no parents. + * filtered to the number of snapshots that have no parents. Likewise, + * if @flags includes VIR_DOMAIN_SNAPSHOT_LIST_LEAVES, then the result is + * filtered to the number of snapshots that have no children. Both flags + * can be used together to find unrelated snapshots. * * If @flags includes VIR_DOMAIN_SNAPSHOT_LIST_METADATA, then the result is * the number of snapshots that also include metadata that would prevent @@ -16020,7 +16023,10 @@ error: * virDomainSnapshotNum() with the same @flags. * * If @flags includes VIR_DOMAIN_SNAPSHOT_LIST_ROOTS, then the result is - * filtered to the number of snapshots that have no parents. + * filtered to the number of snapshots that have no parents. Likewise, + * if @flags includes VIR_DOMAIN_SNAPSHOT_LIST_LEAVES, then the result is + * filtered to the number of snapshots that have no children. Both flags + * can be used together to find unrelated snapshots. * * If @flags includes VIR_DOMAIN_SNAPSHOT_LIST_METADATA, then the result is * the number of snapshots that also include metadata that would prevent @@ -16077,6 +16083,9 @@ error: * 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_LEAVES, then the result is + * filtered to the number of snapshots that have no 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 @@ -16129,6 +16138,9 @@ error: * 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_LEAVES, then the result is + * filtered to the number of snapshots that have no 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 diff --git a/tools/virsh.c b/tools/virsh.c index bcf0603..0624bd8 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -13180,6 +13180,7 @@ static const vshCmdOptDef opts_snapshot_list[] = { {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, {"parent", VSH_OT_BOOL, 0, N_("add a column showing parent snapshot")}, {"roots", VSH_OT_BOOL, 0, N_("list only snapshots without parents")}, + {"leaves", VSH_OT_BOOL, 0, N_("list only snapshots without children")}, {"metadata", VSH_OT_BOOL, 0, N_("list only snapshots that have metadata that would prevent undefine")}, {"tree", VSH_OT_BOOL, 0, N_("list snapshots in a tree")}, @@ -13214,6 +13215,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd) char timestr[100]; struct tm time_info; bool tree = vshCommandOptBool(cmd, "tree"); + bool leaves = vshCommandOptBool(cmd, "leaves"); const char *from = NULL; virDomainSnapshotPtr start = NULL; int start_index = -1; @@ -13255,6 +13257,14 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd) } flags |= VIR_DOMAIN_SNAPSHOT_LIST_ROOTS; } + if (leaves) { + if (tree) { + vshError(ctl, "%s", + _("--leaves and --tree are mutually exclusive")); + return false; + } + flags |= VIR_DOMAIN_SNAPSHOT_LIST_LEAVES; + }
if (vshCommandOptBool(cmd, "metadata")) { flags |= VIR_DOMAIN_SNAPSHOT_LIST_METADATA; @@ -13271,6 +13281,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd) if (ctl->useSnapshotOld || last_error->code == VIR_ERR_NO_SUPPORT) { /* We can emulate --from. */ + /* XXX can we also emulate --leaves? */ virFreeError(last_error); last_error = NULL; ctl->useSnapshotOld = true; @@ -13284,6 +13295,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd) numsnaps = virDomainSnapshotNum(dom, flags);
/* Fall back to simulation if --roots was unsupported. */ + /* XXX can we also emulate --leaves? */ if (numsnaps < 0 && last_error->code == VIR_ERR_INVALID_ARG && (flags & VIR_DOMAIN_SNAPSHOT_LIST_ROOTS)) { virFreeError(last_error); diff --git a/tools/virsh.pod b/tools/virsh.pod index 07df28e..ddafee4 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -1977,7 +1977,8 @@ will create a cloned snapshot. If neither is specified, then the edits must not change the snapshot name.
=item B<snapshot-list> I<domain> [{I<--parent> | I<--roots> | I<--tree>}] -[I<--metadata>] [{[I<--from>] B<snapshot> | I<--current>} [I<--descendants>]] +[{[I<--from>] B<snapshot> | I<--current>} [I<--descendants>]] +[I<--metadata>] [I<--leaves>]
List all of the available snapshots for the given domain, defaulting to show columns for the snapshot name, creation time, and domain state. @@ -1996,6 +1997,10 @@ I<--descendants> is also present. When used with I<--tree>, the use of I<--descendants> is implied. This option is not compatible with I<--roots>.
+If I<--leaves> is specified, the list will be filtered to just +snapshots that have no children. This option is not compatible +with I<--tree>. + If I<--metadata> is specified, the list will be filtered to just snapshots that involve libvirt metadata, and thus would prevent B<undefine> of a persistent domain, or be lost on B<destroy> of
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

With the recent refactoring of qemu snapshot relationships, it is now trivial to filter on leaves. * src/conf/domain_conf.c (virDomainSnapshotObjListCount) (virDomainSnapshotObjListCopyNames): Handle new flag. * src/qemu/qemu_driver.c (qemuDomainSnapshotListNames) (qemuDomainSnapshotNum, qemuDomainSnapshotListChildrenNames) (qemuDomainSnapshotNumChildren): Pass new flag through. --- src/conf/domain_conf.c | 8 ++++++-- src/qemu/qemu_driver.c | 12 ++++++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index d52a79f..c2f599f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -12148,7 +12148,9 @@ static void virDomainSnapshotObjListCopyNames(void *payload, if (data->oom) return; - if ((data->flags & VIR_DOMAIN_SNAPSHOT_LIST_ROOTS) && obj->def->parent) + /* LIST_ROOTS/LIST_DESCENDANTS was handled by caller, + * LIST_METADATA is a no-op if we get this far. */ + if ((data->flags & VIR_DOMAIN_SNAPSHOT_LIST_LEAVES) && obj->nchildren) return; if (data->numnames < data->maxnames) { @@ -12233,7 +12235,9 @@ static void virDomainSnapshotObjListCount(void *payload, virDomainSnapshotObjPtr obj = payload; struct virDomainSnapshotNumData *data = opaque; - if ((data->flags & VIR_DOMAIN_SNAPSHOT_LIST_ROOTS) && obj->def->parent) + /* LIST_ROOTS/LIST_DESCENDANTS was handled by caller, + * LIST_METADATA is a no-op if we get this far. */ + if ((data->flags & VIR_DOMAIN_SNAPSHOT_LIST_LEAVES) && obj->nchildren) return; data->count++; } diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 7a134e3..3264d2c 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -9415,7 +9415,8 @@ static int qemuDomainSnapshotListNames(virDomainPtr domain, char **names, int n = -1; virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS | - VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1); + VIR_DOMAIN_SNAPSHOT_LIST_METADATA | + VIR_DOMAIN_SNAPSHOT_LIST_LEAVES, -1); qemuDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, domain->uuid); @@ -9445,7 +9446,8 @@ static int qemuDomainSnapshotNum(virDomainPtr domain, int n = -1; virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS | - VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1); + VIR_DOMAIN_SNAPSHOT_LIST_METADATA | + VIR_DOMAIN_SNAPSHOT_LIST_LEAVES, -1); qemuDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, domain->uuid); @@ -9482,7 +9484,8 @@ qemuDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot, int n = -1; virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS | - VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1); + VIR_DOMAIN_SNAPSHOT_LIST_METADATA | + VIR_DOMAIN_SNAPSHOT_LIST_LEAVES, -1); qemuDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, snapshot->domain->uuid); @@ -9521,7 +9524,8 @@ qemuDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot, int n = -1; virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS | - VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1); + VIR_DOMAIN_SNAPSHOT_LIST_METADATA | + VIR_DOMAIN_SNAPSHOT_LIST_LEAVES, -1); qemuDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, snapshot->domain->uuid); -- 1.7.4.4

On Fri, Oct 07, 2011 at 08:37:04PM -0600, Eric Blake wrote:
With the recent refactoring of qemu snapshot relationships, it is now trivial to filter on leaves.
* src/conf/domain_conf.c (virDomainSnapshotObjListCount) (virDomainSnapshotObjListCopyNames): Handle new flag. * src/qemu/qemu_driver.c (qemuDomainSnapshotListNames) (qemuDomainSnapshotNum, qemuDomainSnapshotListChildrenNames) (qemuDomainSnapshotNumChildren): Pass new flag through. --- src/conf/domain_conf.c | 8 ++++++-- src/qemu/qemu_driver.c | 12 ++++++++---- 2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index d52a79f..c2f599f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -12148,7 +12148,9 @@ static void virDomainSnapshotObjListCopyNames(void *payload,
if (data->oom) return; - if ((data->flags & VIR_DOMAIN_SNAPSHOT_LIST_ROOTS) && obj->def->parent) + /* LIST_ROOTS/LIST_DESCENDANTS was handled by caller, + * LIST_METADATA is a no-op if we get this far. */ + if ((data->flags & VIR_DOMAIN_SNAPSHOT_LIST_LEAVES) && obj->nchildren) return;
if (data->numnames < data->maxnames) { @@ -12233,7 +12235,9 @@ static void virDomainSnapshotObjListCount(void *payload, virDomainSnapshotObjPtr obj = payload; struct virDomainSnapshotNumData *data = opaque;
- if ((data->flags & VIR_DOMAIN_SNAPSHOT_LIST_ROOTS) && obj->def->parent) + /* LIST_ROOTS/LIST_DESCENDANTS was handled by caller, + * LIST_METADATA is a no-op if we get this far. */ + if ((data->flags & VIR_DOMAIN_SNAPSHOT_LIST_LEAVES) && obj->nchildren) return; data->count++; } diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 7a134e3..3264d2c 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -9415,7 +9415,8 @@ static int qemuDomainSnapshotListNames(virDomainPtr domain, char **names, int n = -1;
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS | - VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1); + VIR_DOMAIN_SNAPSHOT_LIST_METADATA | + VIR_DOMAIN_SNAPSHOT_LIST_LEAVES, -1);
qemuDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, domain->uuid); @@ -9445,7 +9446,8 @@ static int qemuDomainSnapshotNum(virDomainPtr domain, int n = -1;
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS | - VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1); + VIR_DOMAIN_SNAPSHOT_LIST_METADATA | + VIR_DOMAIN_SNAPSHOT_LIST_LEAVES, -1);
qemuDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, domain->uuid); @@ -9482,7 +9484,8 @@ qemuDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot, int n = -1;
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS | - VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1); + VIR_DOMAIN_SNAPSHOT_LIST_METADATA | + VIR_DOMAIN_SNAPSHOT_LIST_LEAVES, -1);
qemuDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, snapshot->domain->uuid); @@ -9521,7 +9524,8 @@ qemuDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot, int n = -1;
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS | - VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1); + VIR_DOMAIN_SNAPSHOT_LIST_METADATA | + VIR_DOMAIN_SNAPSHOT_LIST_LEAVES, -1);
qemuDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, snapshot->domain->uuid);
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On 10/12/2011 08:22 AM, Daniel Veillard wrote:
On Fri, Oct 07, 2011 at 08:37:04PM -0600, Eric Blake wrote:
With the recent refactoring of qemu snapshot relationships, it is now trivial to filter on leaves.
* src/conf/domain_conf.c (virDomainSnapshotObjListCount) (virDomainSnapshotObjListCopyNames): Handle new flag. * src/qemu/qemu_driver.c (qemuDomainSnapshotListNames) (qemuDomainSnapshotNum, qemuDomainSnapshotListChildrenNames) (qemuDomainSnapshotNumChildren): Pass new flag through. --- src/conf/domain_conf.c | 8 ++++++-- src/qemu/qemu_driver.c | 12 ++++++++---- 2 files changed, 14 insertions(+), 6 deletions(-)
ACK,
Thanks; I've pushed 1 and 2. I'll wait to push 3 until Matthias has had a chance to test it on ESX. Which reminds me - I should probably post a series of all my pending snapshot patches. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

Relatively straight-forward filtering. * src/esx/esx_vi.h (esxVI_GetNumberOfSnapshotTrees) (esxVI_GetSnapshotTreeNames): Add parameter. * src/esx/esx_vi.c (esxVI_GetNumberOfSnapshotTrees) (esxVI_GetSnapshotTreeNames): Allow leaf filtering. * src/esx/esx_driver.c (esxDomainSnapshotNum) (esxDomainSnapshotListNames, esxDomainSnapshotNumChildren) (esxDomainSnapshotListChildrenNames): Pass new flag through. --- src/esx/esx_driver.c | 29 +++++++++++++++++++++-------- src/esx/esx_vi.c | 27 ++++++++++++++++----------- src/esx/esx_vi.h | 4 ++-- 3 files changed, 39 insertions(+), 21 deletions(-) diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index bcf2406..f2a8f64 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -4359,11 +4359,14 @@ esxDomainSnapshotNum(virDomainPtr domain, unsigned int flags) esxPrivate *priv = domain->conn->privateData; esxVI_VirtualMachineSnapshotTree *rootSnapshotTreeList = NULL; bool recurse; + bool leaves; virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS | - VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1); + VIR_DOMAIN_SNAPSHOT_LIST_METADATA | + VIR_DOMAIN_SNAPSHOT_LIST_LEAVES, -1); recurse = (flags & VIR_DOMAIN_SNAPSHOT_LIST_ROOTS) == 0; + leaves = (flags & VIR_DOMAIN_SNAPSHOT_LIST_LEAVES) != 0; if (esxVI_EnsureSession(priv->primary) < 0) { return -1; @@ -4378,7 +4381,8 @@ esxDomainSnapshotNum(virDomainPtr domain, unsigned int flags) return -1; } - count = esxVI_GetNumberOfSnapshotTrees(rootSnapshotTreeList, recurse); + count = esxVI_GetNumberOfSnapshotTrees(rootSnapshotTreeList, recurse, + leaves); esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotTreeList); @@ -4395,11 +4399,14 @@ esxDomainSnapshotListNames(virDomainPtr domain, char **names, int nameslen, esxPrivate *priv = domain->conn->privateData; esxVI_VirtualMachineSnapshotTree *rootSnapshotTreeList = NULL; bool recurse; + bool leaves; virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS | - VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1); + VIR_DOMAIN_SNAPSHOT_LIST_METADATA | + VIR_DOMAIN_SNAPSHOT_LIST_LEAVES, -1); recurse = (flags & VIR_DOMAIN_SNAPSHOT_LIST_ROOTS) == 0; + leaves = (flags & VIR_DOMAIN_SNAPSHOT_LIST_LEAVES) != 0; if (names == NULL || nameslen < 0) { ESX_ERROR(VIR_ERR_INVALID_ARG, "%s", _("Invalid argument")); @@ -4420,7 +4427,7 @@ esxDomainSnapshotListNames(virDomainPtr domain, char **names, int nameslen, } result = esxVI_GetSnapshotTreeNames(rootSnapshotTreeList, names, nameslen, - recurse); + recurse, leaves); esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotTreeList); @@ -4437,11 +4444,14 @@ esxDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot, unsigned int flags) esxVI_VirtualMachineSnapshotTree *rootSnapshotTreeList = NULL; esxVI_VirtualMachineSnapshotTree *snapshotTree = NULL; bool recurse; + bool leaves; virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS | - VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1); + VIR_DOMAIN_SNAPSHOT_LIST_METADATA | + VIR_DOMAIN_SNAPSHOT_LIST_LEAVES, -1); recurse = (flags & VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS) != 0; + leaves = (flags & VIR_DOMAIN_SNAPSHOT_LIST_LEAVES) != 0; if (esxVI_EnsureSession(priv->primary) < 0) { return -1; @@ -4462,7 +4472,7 @@ esxDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot, unsigned int flags) } count = esxVI_GetNumberOfSnapshotTrees(snapshotTree->childSnapshotList, - recurse); + recurse, leaves); cleanup: esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotTreeList); @@ -4482,11 +4492,14 @@ esxDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot, esxVI_VirtualMachineSnapshotTree *rootSnapshotTreeList = NULL; esxVI_VirtualMachineSnapshotTree *snapshotTree = NULL; bool recurse; + bool leaves; virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS | - VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1); + VIR_DOMAIN_SNAPSHOT_LIST_METADATA | + VIR_DOMAIN_SNAPSHOT_LIST_LEAVES, -1); recurse = (flags & VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS) != 0; + leaves = (flags & VIR_DOMAIN_SNAPSHOT_LIST_LEAVES) != 0; if (names == NULL || nameslen < 0) { ESX_ERROR(VIR_ERR_INVALID_ARG, "%s", _("Invalid argument")); @@ -4516,7 +4529,7 @@ esxDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot, } result = esxVI_GetSnapshotTreeNames(snapshotTree->childSnapshotList, - names, nameslen, recurse); + names, nameslen, recurse, leaves); cleanup: esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotTreeList); diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c index 4a8c709..55a388a 100644 --- a/src/esx/esx_vi.c +++ b/src/esx/esx_vi.c @@ -2164,17 +2164,19 @@ esxVI_GetVirtualMachineIdentity(esxVI_ObjectContent *virtualMachine, int esxVI_GetNumberOfSnapshotTrees - (esxVI_VirtualMachineSnapshotTree *snapshotTreeList, bool recurse) + (esxVI_VirtualMachineSnapshotTree *snapshotTreeList, bool recurse, + bool leaves) { int count = 0; esxVI_VirtualMachineSnapshotTree *snapshotTree; for (snapshotTree = snapshotTreeList; snapshotTree != NULL; snapshotTree = snapshotTree->_next) { - count++; + if (!(leaves && snapshotTree->childSnapshotList)) + count++; if (recurse) count += esxVI_GetNumberOfSnapshotTrees - (snapshotTree->childSnapshotList, true); + (snapshotTree->childSnapshotList, true, leaves); } return count; @@ -2184,7 +2186,8 @@ esxVI_GetNumberOfSnapshotTrees int esxVI_GetSnapshotTreeNames(esxVI_VirtualMachineSnapshotTree *snapshotTreeList, - char **names, int nameslen, bool recurse) + char **names, int nameslen, bool recurse, + bool leaves) { int count = 0; int result; @@ -2194,14 +2197,16 @@ esxVI_GetSnapshotTreeNames(esxVI_VirtualMachineSnapshotTree *snapshotTreeList, for (snapshotTree = snapshotTreeList; snapshotTree != NULL && count < nameslen; snapshotTree = snapshotTree->_next) { - names[count] = strdup(snapshotTree->name); + if (!(leaves && snapshotTree->childSnapshotList)) { + names[count] = strdup(snapshotTree->name); - if (names[count] == NULL) { - virReportOOMError(); - goto failure; - } + if (names[count] == NULL) { + virReportOOMError(); + goto failure; + } - count++; + count++; + } if (count >= nameslen) { break; @@ -2211,7 +2216,7 @@ esxVI_GetSnapshotTreeNames(esxVI_VirtualMachineSnapshotTree *snapshotTreeList, result = esxVI_GetSnapshotTreeNames(snapshotTree->childSnapshotList, names + count, nameslen - count, - true); + true, leaves); if (result < 0) { goto failure; diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h index 05ed3d0..b8e921f 100644 --- a/src/esx/esx_vi.h +++ b/src/esx/esx_vi.h @@ -359,11 +359,11 @@ int esxVI_GetVirtualMachineIdentity(esxVI_ObjectContent *virtualMachine, int esxVI_GetNumberOfSnapshotTrees (esxVI_VirtualMachineSnapshotTree *snapshotTreeList, - bool recurse); + bool recurse, bool leaves); int esxVI_GetSnapshotTreeNames (esxVI_VirtualMachineSnapshotTree *snapshotTreeList, char **names, - int nameslen, bool recurse); + int nameslen, bool recurse, bool leaves); int esxVI_GetSnapshotTreeByName (esxVI_VirtualMachineSnapshotTree *snapshotTreeList, const char *name, -- 1.7.4.4

On Fri, Oct 07, 2011 at 08:37:05PM -0600, Eric Blake wrote:
Relatively straight-forward filtering.
* src/esx/esx_vi.h (esxVI_GetNumberOfSnapshotTrees) (esxVI_GetSnapshotTreeNames): Add parameter. * src/esx/esx_vi.c (esxVI_GetNumberOfSnapshotTrees) (esxVI_GetSnapshotTreeNames): Allow leaf filtering. * src/esx/esx_driver.c (esxDomainSnapshotNum) (esxDomainSnapshotListNames, esxDomainSnapshotNumChildren) (esxDomainSnapshotListChildrenNames): Pass new flag through. --- src/esx/esx_driver.c | 29 +++++++++++++++++++++-------- src/esx/esx_vi.c | 27 ++++++++++++++++----------- src/esx/esx_vi.h | 4 ++-- 3 files changed, 39 insertions(+), 21 deletions(-)
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index bcf2406..f2a8f64 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -4359,11 +4359,14 @@ esxDomainSnapshotNum(virDomainPtr domain, unsigned int flags) esxPrivate *priv = domain->conn->privateData; esxVI_VirtualMachineSnapshotTree *rootSnapshotTreeList = NULL; bool recurse; + bool leaves;
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS | - VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1); + VIR_DOMAIN_SNAPSHOT_LIST_METADATA | + VIR_DOMAIN_SNAPSHOT_LIST_LEAVES, -1);
recurse = (flags & VIR_DOMAIN_SNAPSHOT_LIST_ROOTS) == 0; + leaves = (flags & VIR_DOMAIN_SNAPSHOT_LIST_LEAVES) != 0;
if (esxVI_EnsureSession(priv->primary) < 0) { return -1; @@ -4378,7 +4381,8 @@ esxDomainSnapshotNum(virDomainPtr domain, unsigned int flags) return -1; }
- count = esxVI_GetNumberOfSnapshotTrees(rootSnapshotTreeList, recurse); + count = esxVI_GetNumberOfSnapshotTrees(rootSnapshotTreeList, recurse, + leaves);
esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotTreeList);
@@ -4395,11 +4399,14 @@ esxDomainSnapshotListNames(virDomainPtr domain, char **names, int nameslen, esxPrivate *priv = domain->conn->privateData; esxVI_VirtualMachineSnapshotTree *rootSnapshotTreeList = NULL; bool recurse; + bool leaves;
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS | - VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1); + VIR_DOMAIN_SNAPSHOT_LIST_METADATA | + VIR_DOMAIN_SNAPSHOT_LIST_LEAVES, -1);
recurse = (flags & VIR_DOMAIN_SNAPSHOT_LIST_ROOTS) == 0; + leaves = (flags & VIR_DOMAIN_SNAPSHOT_LIST_LEAVES) != 0;
if (names == NULL || nameslen < 0) { ESX_ERROR(VIR_ERR_INVALID_ARG, "%s", _("Invalid argument")); @@ -4420,7 +4427,7 @@ esxDomainSnapshotListNames(virDomainPtr domain, char **names, int nameslen, }
result = esxVI_GetSnapshotTreeNames(rootSnapshotTreeList, names, nameslen, - recurse); + recurse, leaves);
esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotTreeList);
@@ -4437,11 +4444,14 @@ esxDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot, unsigned int flags) esxVI_VirtualMachineSnapshotTree *rootSnapshotTreeList = NULL; esxVI_VirtualMachineSnapshotTree *snapshotTree = NULL; bool recurse; + bool leaves;
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS | - VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1); + VIR_DOMAIN_SNAPSHOT_LIST_METADATA | + VIR_DOMAIN_SNAPSHOT_LIST_LEAVES, -1);
recurse = (flags & VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS) != 0; + leaves = (flags & VIR_DOMAIN_SNAPSHOT_LIST_LEAVES) != 0;
if (esxVI_EnsureSession(priv->primary) < 0) { return -1; @@ -4462,7 +4472,7 @@ esxDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot, unsigned int flags) }
count = esxVI_GetNumberOfSnapshotTrees(snapshotTree->childSnapshotList, - recurse); + recurse, leaves);
cleanup: esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotTreeList); @@ -4482,11 +4492,14 @@ esxDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot, esxVI_VirtualMachineSnapshotTree *rootSnapshotTreeList = NULL; esxVI_VirtualMachineSnapshotTree *snapshotTree = NULL; bool recurse; + bool leaves;
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS | - VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1); + VIR_DOMAIN_SNAPSHOT_LIST_METADATA | + VIR_DOMAIN_SNAPSHOT_LIST_LEAVES, -1);
recurse = (flags & VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS) != 0; + leaves = (flags & VIR_DOMAIN_SNAPSHOT_LIST_LEAVES) != 0;
if (names == NULL || nameslen < 0) { ESX_ERROR(VIR_ERR_INVALID_ARG, "%s", _("Invalid argument")); @@ -4516,7 +4529,7 @@ esxDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot, }
result = esxVI_GetSnapshotTreeNames(snapshotTree->childSnapshotList, - names, nameslen, recurse); + names, nameslen, recurse, leaves);
cleanup: esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotTreeList); diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c index 4a8c709..55a388a 100644 --- a/src/esx/esx_vi.c +++ b/src/esx/esx_vi.c @@ -2164,17 +2164,19 @@ esxVI_GetVirtualMachineIdentity(esxVI_ObjectContent *virtualMachine,
int esxVI_GetNumberOfSnapshotTrees - (esxVI_VirtualMachineSnapshotTree *snapshotTreeList, bool recurse) + (esxVI_VirtualMachineSnapshotTree *snapshotTreeList, bool recurse, + bool leaves) { int count = 0; esxVI_VirtualMachineSnapshotTree *snapshotTree;
for (snapshotTree = snapshotTreeList; snapshotTree != NULL; snapshotTree = snapshotTree->_next) { - count++; + if (!(leaves && snapshotTree->childSnapshotList)) + count++; if (recurse) count += esxVI_GetNumberOfSnapshotTrees - (snapshotTree->childSnapshotList, true); + (snapshotTree->childSnapshotList, true, leaves); }
return count; @@ -2184,7 +2186,8 @@ esxVI_GetNumberOfSnapshotTrees
int esxVI_GetSnapshotTreeNames(esxVI_VirtualMachineSnapshotTree *snapshotTreeList, - char **names, int nameslen, bool recurse) + char **names, int nameslen, bool recurse, + bool leaves) { int count = 0; int result; @@ -2194,14 +2197,16 @@ esxVI_GetSnapshotTreeNames(esxVI_VirtualMachineSnapshotTree *snapshotTreeList, for (snapshotTree = snapshotTreeList; snapshotTree != NULL && count < nameslen; snapshotTree = snapshotTree->_next) { - names[count] = strdup(snapshotTree->name); + if (!(leaves && snapshotTree->childSnapshotList)) { + names[count] = strdup(snapshotTree->name);
- if (names[count] == NULL) { - virReportOOMError(); - goto failure; - } + if (names[count] == NULL) { + virReportOOMError(); + goto failure; + }
- count++; + count++; + }
if (count >= nameslen) { break; @@ -2211,7 +2216,7 @@ esxVI_GetSnapshotTreeNames(esxVI_VirtualMachineSnapshotTree *snapshotTreeList, result = esxVI_GetSnapshotTreeNames(snapshotTree->childSnapshotList, names + count, nameslen - count, - true); + true, leaves);
if (result < 0) { goto failure; diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h index 05ed3d0..b8e921f 100644 --- a/src/esx/esx_vi.h +++ b/src/esx/esx_vi.h @@ -359,11 +359,11 @@ int esxVI_GetVirtualMachineIdentity(esxVI_ObjectContent *virtualMachine,
int esxVI_GetNumberOfSnapshotTrees (esxVI_VirtualMachineSnapshotTree *snapshotTreeList, - bool recurse); + bool recurse, bool leaves);
int esxVI_GetSnapshotTreeNames (esxVI_VirtualMachineSnapshotTree *snapshotTreeList, char **names, - int nameslen, bool recurse); + int nameslen, bool recurse, bool leaves);
int esxVI_GetSnapshotTreeByName (esxVI_VirtualMachineSnapshotTree *snapshotTreeList, const char *name,
ACK looks fine but it may be better if Matthias could have a look :-) Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

2011/10/8 Eric Blake <eblake@redhat.com>:
Relatively straight-forward filtering.
* src/esx/esx_vi.h (esxVI_GetNumberOfSnapshotTrees) (esxVI_GetSnapshotTreeNames): Add parameter. * src/esx/esx_vi.c (esxVI_GetNumberOfSnapshotTrees) (esxVI_GetSnapshotTreeNames): Allow leaf filtering. * src/esx/esx_driver.c (esxDomainSnapshotNum) (esxDomainSnapshotListNames, esxDomainSnapshotNumChildren) (esxDomainSnapshotListChildrenNames): Pass new flag through. ---
Tested, works, ACK. -- Matthias Bolte http://photron.blogspot.com

On 10/15/2011 04:47 PM, Matthias Bolte wrote:
2011/10/8 Eric Blake<eblake@redhat.com>:
Relatively straight-forward filtering.
* src/esx/esx_vi.h (esxVI_GetNumberOfSnapshotTrees) (esxVI_GetSnapshotTreeNames): Add parameter. * src/esx/esx_vi.c (esxVI_GetNumberOfSnapshotTrees) (esxVI_GetSnapshotTreeNames): Allow leaf filtering. * src/esx/esx_driver.c (esxDomainSnapshotNum) (esxDomainSnapshotListNames, esxDomainSnapshotNumChildren) (esxDomainSnapshotListChildrenNames): Pass new flag through. ---
Tested, works, ACK.
Thanks; pushed. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org
participants (3)
-
Daniel Veillard
-
Eric Blake
-
Matthias Bolte