[libvirt] [PATCH 3/4] snapshot: expose location through virsh snapshot-info
Eric Blake
eblake at redhat.com
Wed Nov 14 23:20:34 UTC 2012
On 11/14/2012 11:43 AM, Eric Blake wrote:
>> Bleah. Raw XML parsing. Wouldn't it be easier in and cleaner convert
>> this piece code to use the XML parser and xpath?
>
> Not the first time we've done this. I agree that using the XML parser
> and xpath is probably nicer, but it actually takes more code than a
> simple strstr.
>
>> The code looks OK in what it should be doing, but I don't like the raw
>> XML parse-hacking stuff. The only reason to put this in as-is would be
>> if it would be really complicated/overheading to use xpath here.
>
> I'll post an interdiff that shows what it would take to use xpath, and
> we can decide based on how nice or ugly it looks.
Here's the diff; any decisions on whether to go with xpath?
tools/virsh-snapshot.c | 61
+++++++++++++++++++++++++++++++++-----------------
1 file changed, 40 insertions(+), 21 deletions(-)
diff --git i/tools/virsh-snapshot.c w/tools/virsh-snapshot.c
index e38ce84..36f5b46 100644
--- i/tools/virsh-snapshot.c
+++ w/tools/virsh-snapshot.c
@@ -797,8 +797,10 @@ cmdSnapshotInfo(vshControl *ctl, const vshCmd *cmd)
virDomainSnapshotPtr snapshot = NULL;
const char *name;
char *doc = NULL;
- char *state;
- bool internal;
+ xmlDocPtr xmldoc = NULL;
+ xmlXPathContextPtr ctxt = NULL;
+ char *state = NULL;
+ int external;
char *parent = NULL;
bool ret = false;
int count;
@@ -840,39 +842,48 @@ cmdSnapshotInfo(vshControl *ctl, const vshCmd *cmd)
if (!doc)
goto cleanup;
- state = strstr(doc, "<state>");
+ 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;
}
- state += strlen("<state>");
- vshPrint(ctl, "%-15s %.*s\n", _("State:"),
- (int) (strchr(state, '<') - state), state);
+ 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. */
- if (strstr(state, "<memory")) {
- char *domain = strstr(state, "<domain");
+ 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 (!domain) {
- vshError(ctl, "%s",
- _("unexpected problem reading snapshot xml"));
- goto cleanup;
- }
- internal = !memmem(state, domain - state, "snapshot='external'",
- strlen("snapshot='external'"));
- } else {
- internal = !STRPREFIX(state, "disk-snapshot");
+ }
+ if (external < 0) {
+ vshError(ctl, "%s",
+ _("unexpected problem reading snapshot xml"));
+ goto cleanup;
}
vshPrint(ctl, "%-15s %s\n", _("Location:"),
- internal ? _("internal") : _("external"));
+ external ? _("external") : _("internal"));
- if (vshGetSnapshotParent(ctl, snapshot, &parent) < 0)
- goto cleanup;
+ /* 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
@@ -884,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);
@@ -908,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)
--
Eric Blake eblake at redhat.com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 617 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20121114/830f4563/attachment-0001.sig>
More information about the libvir-list
mailing list