Down the road, I want to add virDomainSnapshotGetParent, and use the new API rather than xml scraping; but this virsh command can be implemented even without the new API. * tools/virsh.c (cmdSnapshotParent): New command. * tools/virsh.pod (snapshot-parent): Document it. --- Adding this will make it a bit easier to track relationships between snapshots, especially since 'virsh snapshot-list' covers everything except the relationship. tools/virsh.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/virsh.pod | 4 +++ 2 files changed, 82 insertions(+), 0 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index 1d660d0..ee08c01 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -12285,6 +12285,82 @@ cleanup: } /* + * "snapshot-parent" command + */ +static const vshCmdInfo info_snapshot_parent[] = { + {"help", N_("Get the name of the parent of the current snapshot")}, + {"desc", N_("Extract the snapshot's parent, if any")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_snapshot_parent[] = { + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, + {"snapshotname", VSH_OT_DATA, VSH_OFLAG_REQ, N_("snapshot name")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdSnapshotParent(vshControl *ctl, const vshCmd *cmd) +{ + virDomainPtr dom = NULL; + bool ret = false; + const char *name = NULL; + virDomainSnapshotPtr snapshot = NULL; + char *xml = NULL; + char *parent = NULL; + xmlDocPtr xmldoc = NULL; + xmlXPathContextPtr ctxt = NULL; + + if (!vshConnectionUsability(ctl, ctl->conn)) + goto cleanup; + + dom = vshCommandOptDomain(ctl, cmd, NULL); + if (dom == NULL) + goto cleanup; + + if (vshCommandOptString(cmd, "snapshotname", &name) <= 0) + goto cleanup; + + snapshot = virDomainSnapshotLookupByName(dom, name, 0); + if (snapshot == NULL) + goto cleanup; + + xml = virDomainSnapshotGetXMLDesc(snapshot, 0); + if (!xml) + goto cleanup; + + xmldoc = xmlReadDoc((const xmlChar *) xml, "domainsnapshot.xml", NULL, + XML_PARSE_NOENT | XML_PARSE_NONET | + XML_PARSE_NOWARNING); + if (!xmldoc) + goto cleanup; + ctxt = xmlXPathNewContext(xmldoc); + if (!ctxt) + goto cleanup; + + parent = virXPathString("string(/domainsnapshot/parent/name)", ctxt); + if (!parent) + goto cleanup; + + vshPrint(ctl, "%s", parent); + + ret = true; + +cleanup: + VIR_FREE(parent); + xmlXPathFreeContext(ctxt); + if (xmldoc) + xmlFreeDoc(xmldoc); + VIR_FREE(xml); + if (snapshot) + virDomainSnapshotFree(snapshot); + if (dom) + virDomainFree(dom); + + return ret; +} + +/* * "snapshot-revert" command */ static const vshCmdInfo info_snapshot_revert[] = { @@ -12754,6 +12830,8 @@ static const vshCmdDef snapshotCmds[] = { info_snapshot_dumpxml, 0}, {"snapshot-list", cmdSnapshotList, opts_snapshot_list, info_snapshot_list, 0}, + {"snapshot-parent", cmdSnapshotParent, opts_snapshot_parent, + info_snapshot_parent, 0}, {"snapshot-revert", cmdDomainSnapshotRevert, opts_snapshot_revert, info_snapshot_revert, 0}, {NULL, NULL, NULL, NULL, 0} diff --git a/tools/virsh.pod b/tools/virsh.pod index a6af1e6..1893c23 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -1583,6 +1583,10 @@ List all of the available snapshots for the given domain. Output the snapshot XML for the domain's snapshot named I<snapshot>. +=item B<snapshot-parent> I<domain> I<snapshot> + +Output the name of the parent snapshot for the given I<snapshot>, if any. + =item B<snapshot-revert> I<domain> I<snapshot> Revert the given domain to the snapshot specified by I<snapshot>. Be aware -- 1.7.4.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list