[libvirt] [PATCHv3 26/43] snapshot: reflect recent options in virsh

Eric Blake eblake at redhat.com
Wed Aug 24 15:22:43 UTC 2011


New flag bits are worth exposing via virsh.  Additionally, even
though I recently added 'virsh snapshot-parent', doing it one
snapshot at a time is painful, so make it possible to expand the
snapshot-list table at once.  In the case of snapshot-list --roots,
it's possible to emulate this even when talking to an older server
that lacks the bit; whereas --metadata requires a newer server.

* tools/virsh.c (cmdSnapshotDumpXML, cmdSnapshotCurrent): Add
--security-info.
(cmdSnapshotList): Add --parent, --roots, --metadata.
* tools/virsh.pod (snapshot-dumpxml, snapshot-current)
(snapshot-list): Document these.
---
 tools/virsh.c   |   81 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 tools/virsh.pod |   22 +++++++++++---
 2 files changed, 90 insertions(+), 13 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index 8069a8c..db6c71e 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -12303,6 +12303,8 @@ static const vshCmdInfo info_snapshot_current[] = {
 static const vshCmdOptDef opts_snapshot_current[] = {
     {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
     {"name", VSH_OT_BOOL, 0, N_("list the name, rather than the full xml")},
+    {"security-info", VSH_OT_BOOL, 0,
+     N_("include security sensitive information in XML dump")},
     {NULL, 0, 0, NULL}
 };

@@ -12314,6 +12316,10 @@ cmdSnapshotCurrent(vshControl *ctl, const vshCmd *cmd)
     int current;
     virDomainSnapshotPtr snapshot = NULL;
     char *xml = NULL;
+    int flags = 0;
+
+    if (vshCommandOptBool(cmd, "security-info"))
+        flags |= VIR_DOMAIN_XML_SECURE;

     if (!vshConnectionUsability(ctl, ctl->conn))
         goto cleanup;
@@ -12331,7 +12337,7 @@ cmdSnapshotCurrent(vshControl *ctl, const vshCmd *cmd)
         if (!(snapshot = virDomainSnapshotCurrent(dom, 0)))
             goto cleanup;

-        xml = virDomainSnapshotGetXMLDesc(snapshot, 0);
+        xml = virDomainSnapshotGetXMLDesc(snapshot, flags);
         if (!xml)
             goto cleanup;

@@ -12377,6 +12383,10 @@ static const vshCmdInfo info_snapshot_list[] = {

 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")},
+    {"metadata", VSH_OT_BOOL, 0,
+     N_("list only snapshots that have metadata that would prevent undefine")},
     {NULL, 0, 0, NULL}
 };

@@ -12385,6 +12395,9 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
 {
     virDomainPtr dom = NULL;
     bool ret = false;
+    int flags = 0;
+    int parent_filter = 0; /* -1 for roots filtering, 0 for no parent
+                              information needed, 1 for parent column */
     int numsnaps;
     char **names = NULL;
     int actual = 0;
@@ -12394,11 +12407,27 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
     char *doc = NULL;
     virDomainSnapshotPtr snapshot = NULL;
     char *state = NULL;
+    char *parent = NULL;
     long long creation_longlong;
     time_t creation_time_t;
     char timestr[100];
     struct tm time_info;

+    if (vshCommandOptBool(cmd, "parent")) {
+        if (vshCommandOptBool(cmd, "roots")) {
+            vshError(ctl, "%s",
+                     _("--parent and --roots are mutually exlusive"));
+            return false;
+        }
+        parent_filter = 1;
+    } else if (vshCommandOptBool(cmd, "roots")) {
+        flags |= VIR_DOMAIN_SNAPSHOT_LIST_ROOTS;
+    }
+
+    if (vshCommandOptBool(cmd, "metadata")) {
+        flags |= VIR_DOMAIN_SNAPSHOT_LIST_METADATA;
+    }
+
     if (!vshConnectionUsability(ctl, ctl->conn))
         goto cleanup;

@@ -12406,19 +12435,35 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
     if (dom == NULL)
         goto cleanup;

-    numsnaps = virDomainSnapshotNum(dom, 0);
+    numsnaps = virDomainSnapshotNum(dom, flags);
+
+    /* Fall back to simulation if --roots was unsupported.  */
+    if (numsnaps < 0 && last_error->code == VIR_ERR_INVALID_ARG &&
+        (flags & VIR_DOMAIN_SNAPSHOT_LIST_ROOTS)) {
+        virFreeError(last_error);
+        last_error = NULL;
+        parent_filter = -1;
+        flags &= ~VIR_DOMAIN_SNAPSHOT_LIST_ROOTS;
+        numsnaps = virDomainSnapshotNum(dom, flags);
+    }

     if (numsnaps < 0)
         goto cleanup;

-    vshPrintExtra(ctl, " %-20s %-25s %s\n", _("Name"), _("Creation Time"), _("State"));
-    vshPrintExtra(ctl, "---------------------------------------------------\n");
+    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;

-        actual = virDomainSnapshotListNames(dom, names, numsnaps, 0);
+        actual = virDomainSnapshotListNames(dom, names, numsnaps, flags);
         if (actual < 0)
             goto cleanup;

@@ -12426,6 +12471,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)

         for (i = 0; i < actual; i++) {
             /* free up memory from previous iterations of the loop */
+            VIR_FREE(parent);
             VIR_FREE(state);
             if (snapshot)
                 virDomainSnapshotFree(snapshot);
@@ -12445,6 +12491,13 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
             if (!xml)
                 continue;

+            if (parent_filter) {
+                parent = virXPathString("string(/domainsnapshot/parent/name)",
+                                        ctxt);
+                if (!parent && parent_filter < 0)
+                    continue;
+            }
+
             state = virXPathString("string(/domainsnapshot/state)", ctxt);
             if (state == NULL)
                 continue;
@@ -12457,9 +12510,14 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
                 continue;
             }
             localtime_r(&creation_time_t, &time_info);
-            strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S %z", &time_info);
+            strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S %z",
+                     &time_info);

-            vshPrint(ctl, " %-20s %-25s %s\n", names[i], timestr, state);
+            if (parent)
+                vshPrint(ctl, " %-20s %-25s %-15s %s\n",
+                         names[i], timestr, state, parent);
+            else
+                vshPrint(ctl, " %-20s %-25s %s\n", names[i], timestr, state);
         }
     }

@@ -12467,6 +12525,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)

 cleanup:
     /* this frees up memory from the last iteration of the loop */
+    VIR_FREE(parent);
     VIR_FREE(state);
     if (snapshot)
         virDomainSnapshotFree(snapshot);
@@ -12494,6 +12553,8 @@ static const vshCmdInfo info_snapshot_dumpxml[] = {
 static const vshCmdOptDef opts_snapshot_dumpxml[] = {
     {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
     {"snapshotname", VSH_OT_DATA, VSH_OFLAG_REQ, N_("snapshot name")},
+    {"security-info", VSH_OT_BOOL, 0,
+     N_("include security sensitive information in XML dump")},
     {NULL, 0, 0, NULL}
 };

@@ -12505,6 +12566,10 @@ cmdSnapshotDumpXML(vshControl *ctl, const vshCmd *cmd)
     const char *name = NULL;
     virDomainSnapshotPtr snapshot = NULL;
     char *xml = NULL;
+    int flags = 0;
+
+    if (vshCommandOptBool(cmd, "security-info"))
+        flags |= VIR_DOMAIN_XML_SECURE;

     if (!vshConnectionUsability(ctl, ctl->conn))
         goto cleanup;
@@ -12520,7 +12585,7 @@ cmdSnapshotDumpXML(vshControl *ctl, const vshCmd *cmd)
     if (snapshot == NULL)
         goto cleanup;

-    xml = virDomainSnapshotGetXMLDesc(snapshot, 0);
+    xml = virDomainSnapshotGetXMLDesc(snapshot, flags);
     if (!xml)
         goto cleanup;

diff --git a/tools/virsh.pod b/tools/virsh.pod
index 337fcf4..0b319ee 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -527,7 +527,7 @@ Output the domain information as an XML dump to stdout, this format can be used
 by the B<create> command. Additional options affecting the XML dump may be
 used. I<--inactive> tells virsh to dump domain configuration that will be used
 on next start of the domain as opposed to the current domain configuration.
-Using I<--security-info> security sensitive information will also be included
+Using I<--security-info> will also include security sensitive information
 in the XML dump. I<--update-cpu> updates domain CPU requirements according to
 host CPU.

@@ -1607,19 +1607,31 @@ Create a snapshot for domain I<domain> with the given <name> and
 value.  If I<--print-xml> is specified, then XML appropriate for
 I<snapshot-create> is output, rather than actually creating a snapshot.

-=item B<snapshot-current> I<domain> [I<--name>]
+=item B<snapshot-current> I<domain> [I<--name>] [I<--security-info>]

 Output the snapshot XML for the domain's current snapshot (if any).
 If I<--name> is specified, just list the snapshot name instead of the
-full xml.
+full xml.  Otherwise, using I<--security-info> will also include security
+sensitive information.

-=item B<snapshot-list> I<domain>
+=item B<snapshot-list> I<domain> [{I<--parent> | I<--roots>}] [I<--metadata>]

 List all of the available snapshots for the given domain.

-=item B<snapshot-dumpxml> I<domain> I<snapshot>
+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>.
+
+If I<--metadata> is specified, the list will be filtered to just
+snapshots that involve libvirt metadata, and thus would interfere in
+using the B<undefine> or B<destroy> commands on that domain.
+
+=item B<snapshot-dumpxml> I<domain> I<snapshot> [I<--security-info>]

 Output the snapshot XML for the domain's snapshot named I<snapshot>.
+Using I<--security-info> will also include security sensitive information.

 =item B<snapshot-parent> I<domain> I<snapshot>

-- 
1.7.4.4




More information about the libvir-list mailing list