2010/4/3 Chris Lalancette <clalance(a)redhat.com>:
Signed-off-by: Chris Lalancette <clalance(a)redhat.com>
---
tools/virsh.c | 451 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 451 insertions(+), 0 deletions(-)
+
+/*
+ * "snapshot-list" command
+ */
+static const vshCmdInfo info_snapshot_list[] = {
+ {"help", N_("List snapshots for a domain")},
+ {"desc", N_("Snapshot List")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_snapshot_list[] = {
+ {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or
uuid")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
+{
+ virDomainPtr dom = NULL;
+ int ret = FALSE;
+ int numsnaps;
+ char **names = NULL;
+ int actual;
+ int i;
+ xmlDocPtr xml = NULL;
+ xmlXPathContextPtr ctxt = NULL;
+ char *doc = NULL;
+ virDomainSnapshotPtr snapshot = NULL;
+ char *state = NULL;
+ long creation;
+ char timestr[100];
+ struct tm time_info;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ goto cleanup;
+
+ dom = vshCommandOptDomain(ctl, cmd, NULL);
+ if (dom == NULL)
+ goto cleanup;
+
+ numsnaps = virDomainSnapshotNum(dom, 0);
+
+ if (numsnaps < 0)
+ goto cleanup;
+
+ vshPrint(ctl, " %-20s %-20s %s\n", _("Name"), _("Creation
Time"), _("State"));
+ vshPrint(ctl, "---------------------------------------------------\n");
+
+ if (numsnaps) {
+ if (VIR_ALLOC_N(names, numsnaps) < 0)
+ goto cleanup;
+
+ actual = virDomainSnapshotListNames(dom, names, numsnaps, 0);
+ if (actual < 0)
+ goto cleanup;
+
+ qsort(&names[0], actual, sizeof(char*), namesorter);
+
+ for (i = 0; i < actual; i++) {
+ /* free up memory from previous iterations of the loop */
+ VIR_FREE(state);
+ if (snapshot)
+ virDomainSnapshotFree(snapshot);
+ xmlXPathFreeContext(ctxt);
+ if (xml)
+ xmlFreeDoc(xml);
+ VIR_FREE(doc);
+
+ snapshot = virDomainSnapshotLookupByName(dom, names[i], 0);
+ if (snapshot == NULL)
+ continue;
+
+ doc = virDomainSnapshotGetXMLDesc(snapshot, 0);
+ if (!doc)
+ continue;
+
+ xml = xmlReadDoc((const xmlChar *) doc, "domainsnapshot.xml",
NULL,
+ XML_PARSE_NOENT | XML_PARSE_NONET |
+ XML_PARSE_NOWARNING);
+ if (!xml)
+ continue;
+ ctxt = xmlXPathNewContext(xml);
+ if (!ctxt)
+ continue;
+
+ state = virXPathString("string(/domainsnapshot/state)", ctxt);
+ if (state == NULL)
+ continue;
+ if (virXPathLong("string(/domainsnapshot/creationTime)", ctxt,
+ &creation) < 0)
+ continue;
+ gmtime_r(&creation, &time_info);
+ strftime(timestr, sizeof(timestr), "%F %T", &time_info);
If we use gmtime_r here then we should indicate that the printed time
is in UTC, maybe using
strftime(timestr, sizeof(timestr), "%F %T UTC", &time_info);
or changing the header line from "Creation Time" to "Creation Time
(UTC)", or really use localtime_r instead of gmtime_r and maybe
indicate the timezone offset using %z as recommended in RFC 2822:
strftime(timestr, sizeof(timestr), "%F %T %z", &time_info);
+ vshPrint(ctl, " %-20s %-20s %s\n", names[i],
timestr, state);
+ }
+ }
+
+ ret = TRUE;
+
+cleanup:
+ /* this frees up memory from the last iteration of the loop */
+ VIR_FREE(state);
+ if (snapshot)
+ virDomainSnapshotFree(snapshot);
+ xmlXPathFreeContext(ctxt);
+ if (xml)
+ xmlFreeDoc(xml);
+ VIR_FREE(doc);
+ VIR_FREE(names);
+ if (dom)
+ virDomainFree(dom);
+
+ return ret;
+}
+
+
+/*
+ * "snapshot-delete" command
+ */
+static const vshCmdInfo info_snapshot_delete[] = {
+ {"help", N_("Delete a domain snapshot")},
+ {"desc", N_("Snapshot Delete")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_snapshot_delete[] = {
+ {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or
uuid")},
+ {"snapshotname", VSH_OT_DATA, VSH_OFLAG_REQ, N_("snapshot
name")},
+ {"children", VSH_OT_BOOL, 0, N_("delete snapshot and all
children")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdSnapshotDelete(vshControl *ctl, const vshCmd *cmd)
+{
+ virDomainPtr dom = NULL;
+ int ret = FALSE;
+ char *name;
+ virDomainSnapshotPtr snapshot = NULL;
+ unsigned int flags = 0;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ goto cleanup;
+
+ dom = vshCommandOptDomain(ctl, cmd, NULL);
+ if (dom == NULL)
+ goto cleanup;
+
+ name = vshCommandOptString(cmd, "snapshotname", NULL);
+ if (name == NULL) {
+ vshError(ctl, "%s", _("cmdDomainRevertToSnapshot: Missing
snapshotname"));
Copy&paste error: cmdDomainRevertToSnapshot
Actually the error message should not contain the function name. The
same goes for the other new functions.
ACK.
Matthias