[libvirt] [PATCH 6/6] Snapshot virsh implementation.
Matthias Bolte
matthias.bolte at googlemail.com
Sat Apr 3 15:30:39 UTC 2010
2010/4/3 Chris Lalancette <clalance at redhat.com>:
> Signed-off-by: Chris Lalancette <clalance at 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
More information about the libvir-list
mailing list