Now that we can filter on this information, we should also make it easy to get at. * tools/virsh-snapshot.c (cmdSnapshotInfo): Add another output row, and switch to XPath queries rather than strstr. --- tools/virsh-snapshot.c | 57 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/tools/virsh-snapshot.c b/tools/virsh-snapshot.c index 7cd2966..36f5b46 100644 --- a/tools/virsh-snapshot.c +++ b/tools/virsh-snapshot.c @@ -797,7 +797,10 @@ cmdSnapshotInfo(vshControl *ctl, const vshCmd *cmd) virDomainSnapshotPtr snapshot = NULL; const char *name; char *doc = NULL; - char *tmp; + xmlDocPtr xmldoc = NULL; + xmlXPathContextPtr ctxt = NULL; + char *state = NULL; + int external; char *parent = NULL; bool ret = false; int count; @@ -839,18 +842,48 @@ cmdSnapshotInfo(vshControl *ctl, const vshCmd *cmd) if (!doc) goto cleanup; - tmp = strstr(doc, "<state>"); - if (!tmp) { + xmldoc = virXMLParseStringCtxt(doc, _("(domain_snapshot)"), &ctxt); + if (!xmldoc) + goto cleanup; + + state = virXPathString("string(/domainsnapshot/state)", ctxt); + if (!state) { vshError(ctl, "%s", _("unexpected problem reading snapshot xml")); goto cleanup; } - tmp += strlen("<state>"); - vshPrint(ctl, "%-15s %.*s\n", _("State:"), - (int) (strchr(tmp, '<') - tmp), tmp); + vshPrint(ctl, "%-15s %s\n", _("State:"), state); + + /* In addition to state, location is useful. If the snapshot has + * a <memory> element, then the existence of snapshot='external' + * prior to <domain> is the deciding factor; for snapshots + * created prior to 1.0.1, a state of disk-only is the only + * external snapshot. */ + switch (virXPathBoolean("boolean(/domainsnapshot/memory)", ctxt)) { + case 1: + external = virXPathBoolean("boolean(/domainsnapshot/memory/@snapshot=external " + "| /domainsnapshot/disks/disk/@snapshot=external)", + ctxt); + break; + case 0: + external = STREQ(state, "disk-snapshot"); + break; + default: + external = -1; + break; - if (vshGetSnapshotParent(ctl, snapshot, &parent) < 0) + } + if (external < 0) { + vshError(ctl, "%s", + _("unexpected problem reading snapshot xml")); goto cleanup; + } + vshPrint(ctl, "%-15s %s\n", _("Location:"), + external ? _("external") : _("internal")); + + /* Since we already have the XML, there's no need to call + * virDomainSnapshotGetParent */ + parent = virXPathString("string(/domainsnapshot/parent/name)", ctxt); vshPrint(ctl, "%-15s %s\n", _("Parent:"), parent ? parent : "-"); /* Children, Descendants. After this point, the fallback to @@ -862,8 +895,13 @@ cmdSnapshotInfo(vshControl *ctl, const vshCmd *cmd) } flags = 0; count = virDomainSnapshotNumChildren(snapshot, flags); - if (count < 0) + if (count < 0) { + if (last_error->code == VIR_ERR_NO_SUPPORT) { + vshResetLibvirtError(); + ret = true; + } goto cleanup; + } vshPrint(ctl, "%-15s %d\n", _("Children:"), count); flags = VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS; count = virDomainSnapshotNumChildren(snapshot, flags); @@ -886,6 +924,9 @@ cmdSnapshotInfo(vshControl *ctl, const vshCmd *cmd) ret = true; cleanup: + VIR_FREE(state); + xmlXPathFreeContext(ctxt); + xmlFreeDoc(xmldoc); VIR_FREE(doc); VIR_FREE(parent); if (snapshot) -- 1.7.11.7 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list