[libvirt] [PATCHv2 4/7] snapshot: virsh fallback for snapshot-list --from children

Daniel Veillard veillard at redhat.com
Mon Oct 10 03:23:41 UTC 2011


On Fri, Sep 30, 2011 at 05:09:26PM -0600, Eric Blake wrote:
> Iterating over one level of children requires parsing all snapshots
> and their parents; a bit of code shuffling makes it pretty easy
> to do this as well.
> 
> * tools/virsh.c (cmdSnapshotList): Add another fallback.
> ---
> 
> v2: fix compilation error, rebase around ctl flag
> 
>  tools/virsh.c |   48 ++++++++++++++++++++++++++++++++----------------
>  1 files changed, 32 insertions(+), 16 deletions(-)
> 
> diff --git a/tools/virsh.c b/tools/virsh.c
> index e3bc364..b2523d3 100644
> --- a/tools/virsh.c
> +++ b/tools/virsh.c
> @@ -13117,6 +13117,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
>                                information needed, 1 for parent column */
>      int numsnaps;
>      char **names = NULL;
> +    char **parents = NULL;
>      int actual = 0;
>      int i;
>      xmlDocPtr xml = NULL;
> @@ -13132,6 +13133,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
>      bool tree = vshCommandOptBool(cmd, "tree");
>      const char *from = NULL;
>      virDomainSnapshotPtr start = NULL;
> +    bool descendants = false;
> 
>      if (vshCommandOptString(cmd, "from", &from) < 0) {
>          vshError(ctl, _("invalid from argument '%s'"), from);
> @@ -13175,27 +13177,29 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
>          goto cleanup;
> 
>      if (from) {
> +        descendants = vshCommandOptBool(cmd, "descendants");
>          start = virDomainSnapshotLookupByName(dom, from, 0);
>          if (!start)
>              goto cleanup;
> -        if (vshCommandOptBool(cmd, "descendants") || tree) {
> +        if (descendants || tree) {
>              flags |= VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS;
>          }
>          numsnaps = ctl->useSnapshotOld ? -1 :
>              virDomainSnapshotNumChildren(start, flags);
> -        /* XXX Is it worth emulating --from without --tree on older servers?  */
> -        if (tree) {
> -            if (numsnaps >= 0) {
> -                numsnaps++;
> -            } else if (ctl->useSnapshotOld ||
> -                       last_error->code == VIR_ERR_NO_SUPPORT) {
> -                /* We can emulate --tree --from.  */
> +        if (numsnaps < 0) {
> +            /* XXX also want to emulate --descendants without --tree */
> +            if ((!descendants || tree) &&
> +                (ctl->useSnapshotOld ||
> +                 last_error->code == VIR_ERR_NO_SUPPORT)) {
> +                /* We can emulate --from.  */
>                  virFreeError(last_error);
>                  last_error = NULL;
>                  ctl->useSnapshotOld = true;
>                  flags &= ~VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS;
>                  numsnaps = virDomainSnapshotNum(dom, flags);
>              }
> +        } else if (tree) {
> +            numsnaps++;
>          }
>      } else {
>          numsnaps = virDomainSnapshotNum(dom, flags);
> @@ -13259,9 +13263,11 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
>      if (actual < 0)
>          goto cleanup;
> 
> -    if (tree) {
> -        char indentBuf[INDENT_BUFLEN];
> -        char **parents = vshCalloc(ctl, sizeof(char *), actual);
> +    if (!tree)
> +        qsort(&names[0], actual, sizeof(char*), namesorter);
> +
> +    if (tree || ctl->useSnapshotOld) {
> +        parents = vshCalloc(ctl, sizeof(char *), actual);
>          for (i = (from && !ctl->useSnapshotOld); i < actual; i++) {
>              /* free up memory from previous iterations of the loop */
>              if (snapshot)
> @@ -13275,6 +13281,9 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
>                  goto cleanup;
>              }
>          }
> +    }
> +    if (tree) {
> +        char indentBuf[INDENT_BUFLEN];
>          for (i = 0 ; i < actual ; i++) {
>              memset(indentBuf, '\0', sizeof indentBuf);
>              if (ctl->useSnapshotOld ? STREQ(names[i], from) : !parents[i])
> @@ -13288,16 +13297,19 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
>                                          0,
>                                          indentBuf);
>          }
> -        for (i = 0 ; i < actual ; i++)
> -            VIR_FREE(parents[i]);
> -        VIR_FREE(parents);
> 
>          ret = true;
>          goto cleanup;
>      } else {
> -        qsort(&names[0], actual, sizeof(char*), namesorter);
> +        if (ctl->useSnapshotOld && descendants) {
> +            /* XXX emulate --descendants as well */
> +            goto cleanup;
> +        }
> 
>          for (i = 0; i < actual; i++) {
> +            if (ctl->useSnapshotOld && STRNEQ_NULLABLE(parents[i], from))
> +                continue;
> +
>              /* free up memory from previous iterations of the loop */
>              VIR_FREE(parent);
>              VIR_FREE(state);
> @@ -13362,9 +13374,13 @@ cleanup:
>      xmlXPathFreeContext(ctxt);
>      xmlFreeDoc(xml);
>      VIR_FREE(doc);
> -    for (i = 0; i < actual; i++)
> +    for (i = 0; i < actual; i++) {
>          VIR_FREE(names[i]);
> +        if (parents)
> +            VIR_FREE(parents[i]);
> +    }
>      VIR_FREE(names);
> +    VIR_FREE(parents);
>      if (dom)
>          virDomainFree(dom);
> 

  Okay, getting parents global to the function as well as associated
cleanup looks a bit simpler actually.

  ACK,

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