[libvirt] [PATCH 4/5] snapshot: add virsh snapshot-list --tree

Daniel Veillard veillard at redhat.com
Wed Sep 28 13:21:28 UTC 2011


On Sat, Sep 24, 2011 at 06:30:05PM -0600, Eric Blake wrote:
> Reuse the tree listing of nodedev-list, coupled with the new helper
> function to efficiently grab snapshot parent names, to produce
> tree output for a snapshot hierarchy.  For example:
> 
> $ virsh snapshot-list dom --tree
> root1
>  |
>   +- sibling1
>   +- sibling2
>   |   |
>   |   +- grandchild
>   |
>   +- sibling3
> 
> root2
>  |
>   +- child
> 
> * tools/virsh.c (cmdSnapshotList): Add --tree.
> * tools/virsh.pod (snapshot-list): Document it.
> ---
>  tools/virsh.c   |   83 +++++++++++++++++++++++++++++++++++++++++++++---------
>  tools/virsh.pod |   14 +++++----
>  2 files changed, 77 insertions(+), 20 deletions(-)
> 
> diff --git a/tools/virsh.c b/tools/virsh.c
> index 035b209..7e7b65d 100644
> --- a/tools/virsh.c
> +++ b/tools/virsh.c
> @@ -12987,7 +12987,7 @@ vshGetSnapshotParent(vshControl *ctl, virDomainSnapshotPtr snapshot)
>          parent = virDomainSnapshotGetParent(snapshot, 0);
>          if (parent) {
>              /* API works, and virDomainSnapshotGetName will succeed */
> -            parent_name = vshStrdup(ctl, virDomainSnapshotGetName(snapshot));
> +            parent_name = vshStrdup(ctl, virDomainSnapshotGetName(parent));
>              goto cleanup;
>          }
>          if (last_error->code == VIR_ERR_NO_DOMAIN_SNAPSHOT) {

  That looks like a bug fix squashed in here instead of previous patch,
what am I missing ?

> @@ -13032,6 +13032,7 @@ static const vshCmdOptDef opts_snapshot_list[] = {
>      {"roots", VSH_OT_BOOL, 0, N_("list only snapshots without parents")},
>      {"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")},
>      {NULL, 0, 0, NULL}
>  };
> 
> @@ -13057,6 +13058,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
>      time_t creation_time_t;
>      char timestr[100];
>      struct tm time_info;
> +    bool tree = vshCommandOptBool(cmd, "tree");
> 
>      if (vshCommandOptBool(cmd, "parent")) {
>          if (vshCommandOptBool(cmd, "roots")) {
> @@ -13064,8 +13066,18 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
>                       _("--parent and --roots are mutually exlusive"));
>              return false;
>          }
> +        if (tree) {
> +            vshError(ctl, "%s",
> +                     _("--parent and --tree are mutually exlusive"));
> +            return false;
> +        }
>          parent_filter = 1;
>      } else if (vshCommandOptBool(cmd, "roots")) {
> +        if (tree) {
> +            vshError(ctl, "%s",
> +                     _("--roots and --tree are mutually exlusive"));
> +            return false;
> +        }
>          flags |= VIR_DOMAIN_SNAPSHOT_LIST_ROOTS;
>      }
> 
> @@ -13095,23 +13107,66 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
>      if (numsnaps < 0)
>          goto cleanup;
> 
> -    if (parent_filter > 0)
> -        vshPrintExtra(ctl, " %-20s %-25s %-15s %s",
> -                      _("Name"), _("Creation Time"), _("State"), _("Parent"));
> -    else
> -        vshPrintExtra(ctl, " %-20s %-25s %s",
> -                      _("Name"), _("Creation Time"), _("State"));
> -    vshPrintExtra(ctl, "\n\
> +    if (!tree) {
> +        if (parent_filter > 0)
> +            vshPrintExtra(ctl, " %-20s %-25s %-15s %s",
> +                          _("Name"), _("Creation Time"), _("State"),
> +                          _("Parent"));
> +        else
> +            vshPrintExtra(ctl, " %-20s %-25s %s",
> +                          _("Name"), _("Creation Time"), _("State"));
> +        vshPrintExtra(ctl, "\n\
>  ------------------------------------------------------------\n");
> +    }
> 
> -    if (numsnaps) {
> -        if (VIR_ALLOC_N(names, numsnaps) < 0)
> -            goto cleanup;
> +    if (!numsnaps) {
> +        ret = true;
> +        goto cleanup;
> +    }
> 
> -        actual = virDomainSnapshotListNames(dom, names, numsnaps, flags);
> -        if (actual < 0)
> -            goto cleanup;
> +    if (VIR_ALLOC_N(names, numsnaps) < 0)
> +        goto cleanup;
> +
> +    actual = virDomainSnapshotListNames(dom, names, numsnaps, flags);
> +    if (actual < 0)
> +        goto cleanup;
> 
> +    if (tree) {
> +        char indentBuf[INDENT_BUFLEN];
> +        char **parents = vshMalloc(ctl, sizeof(char *) * actual);
> +        for (i = 0; i < actual; i++) {
> +            /* free up memory from previous iterations of the loop */
> +            if (snapshot)
> +                virDomainSnapshotFree(snapshot);
> +            snapshot = virDomainSnapshotLookupByName(dom, names[i], 0);
> +            if (!snapshot) {
> +                while (--i >= 0)
> +                    VIR_FREE(parents[i]);
> +                VIR_FREE(parents);
> +                goto cleanup;
> +            }
> +            parents[i] = vshGetSnapshotParent(ctl, snapshot);
> +        }
> +        for (i = 0 ; i < actual ; i++) {
> +            memset(indentBuf, '\0', sizeof indentBuf);
> +            if (parents[i] == NULL)
> +                cmdNodeListDevicesPrint(ctl,
> +                                        names,
> +                                        parents,
> +                                        actual,
> +                                        i,
> +                                        i,
> +                                        0,
> +                                        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);
> 
>          for (i = 0; i < actual; i++) {
> diff --git a/tools/virsh.pod b/tools/virsh.pod
> index ddf7578..49aa42a 100644
> --- a/tools/virsh.pod
> +++ b/tools/virsh.pod
> @@ -1934,15 +1934,17 @@ except that it does some error checking.
>  The editor used can be supplied by the C<$VISUAL> or C<$EDITOR> environment
>  variables, and defaults to C<vi>.
> 
> -=item B<snapshot-list> I<domain> [{I<--parent> | I<--roots>}] [I<--metadata>]
> +=item B<snapshot-list> I<domain> [{I<--parent> | I<--roots> | I<--tree>}]
> +[I<--metadata>]
> 
> -List all of the available snapshots for the given domain.
> +List all of the available snapshots for the given domain, defaulting
> +to show columns for the snapshot name, creation time, and domain state.
> 
>  If I<--parent> is specified, add a column to the output table giving
> -the name of the parent of each snapshot.
> -
> -If I<--roots> is specified, the list will be filtered to just snapshots
> -that have no parents; this option is not compatible with I<--parent>.
> +the name of the parent of each snapshot.  If I<--roots> is specified,
> +the list will be filtered to just snapshots that have no parents.
> +If I<--tree> is specified, the output will be in a tree format, listing
> +just snapshot names.  These three options are mutually exclusive.
> 
>  If I<--metadata> is specified, the list will be filtered to just
>  snapshots that involve libvirt metadata, and thus would prevent

  ACK, great improvement,

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