virsh-snapshot: Refactor virsh snapshot-list

Simplify error handling and mutually exclusive option checking.
This commit is contained in:
Peter Krempa 2013-03-01 16:27:04 +01:00
parent 7e437ee78f
commit 55b3b15cd0

View File

@ -1527,66 +1527,34 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
virDomainPtr dom = NULL; virDomainPtr dom = NULL;
bool ret = false; bool ret = false;
unsigned int flags = 0; unsigned int flags = 0;
bool show_parent = false;
int i; int i;
xmlDocPtr xml = NULL; xmlDocPtr xml = NULL;
xmlXPathContextPtr ctxt = NULL; xmlXPathContextPtr ctxt = NULL;
char *doc = NULL; char *doc = NULL;
virDomainSnapshotPtr snapshot = NULL; virDomainSnapshotPtr snapshot = NULL;
char *state = NULL; char *state = NULL;
char *parent = NULL;
long long creation_longlong; long long creation_longlong;
time_t creation_time_t; time_t creation_time_t;
char timestr[100]; char timestr[100];
struct tm time_info; struct tm time_info;
bool tree = vshCommandOptBool(cmd, "tree"); bool tree = vshCommandOptBool(cmd, "tree");
bool name = vshCommandOptBool(cmd, "name"); bool name = vshCommandOptBool(cmd, "name");
const char *from = NULL; bool from = vshCommandOptBool(cmd, "from");
bool parent = vshCommandOptBool(cmd, "parent");
bool roots = vshCommandOptBool(cmd, "roots");
bool current = vshCommandOptBool(cmd, "current");
const char *from_snap = NULL;
char *parent_snap = NULL;
virDomainSnapshotPtr start = NULL; virDomainSnapshotPtr start = NULL;
vshSnapshotListPtr snaplist = NULL; vshSnapshotListPtr snaplist = NULL;
if (tree && name) { VSH_EXCLUSIVE_OPTIONS_VAR(tree, name);
vshError(ctl, "%s", VSH_EXCLUSIVE_OPTIONS_VAR(parent, roots);
_("--tree and --name are mutually exclusive")); VSH_EXCLUSIVE_OPTIONS_VAR(parent, tree);
return false; VSH_EXCLUSIVE_OPTIONS_VAR(roots, tree);
} VSH_EXCLUSIVE_OPTIONS_VAR(roots, from);
VSH_EXCLUSIVE_OPTIONS_VAR(roots, current);
dom = vshCommandOptDomain(ctl, cmd, NULL);
if (dom == NULL)
goto cleanup;
if ((vshCommandOptBool(cmd, "from") ||
vshCommandOptBool(cmd, "current")) &&
vshLookupSnapshot(ctl, cmd, "from", true, dom, &start, &from) < 0)
goto cleanup;
if (vshCommandOptBool(cmd, "parent")) {
if (vshCommandOptBool(cmd, "roots")) {
vshError(ctl, "%s",
_("--parent and --roots are mutually exclusive"));
goto cleanup;
}
if (tree) {
vshError(ctl, "%s",
_("--parent and --tree are mutually exclusive"));
goto cleanup;
}
show_parent = true;
} else if (vshCommandOptBool(cmd, "roots")) {
if (tree) {
vshError(ctl, "%s",
_("--roots and --tree are mutually exclusive"));
goto cleanup;
}
if (from) {
vshError(ctl, "%s",
vshCommandOptBool(cmd, "current") ?
_("--roots and --current are mutually exclusive") :
_("--roots and --from are mutually exclusive"));
goto cleanup;
}
flags |= VIR_DOMAIN_SNAPSHOT_LIST_ROOTS;
}
#define FILTER(option, flag) \ #define FILTER(option, flag) \
do { \ do { \
if (vshCommandOptBool(cmd, option)) { \ if (vshCommandOptBool(cmd, option)) { \
@ -1594,7 +1562,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
vshError(ctl, \ vshError(ctl, \
_("--%s and --tree are mutually exclusive"), \ _("--%s and --tree are mutually exclusive"), \
option); \ option); \
goto cleanup; \ return false; \
} \ } \
flags |= VIR_DOMAIN_SNAPSHOT_LIST_ ## flag; \ flags |= VIR_DOMAIN_SNAPSHOT_LIST_ ## flag; \
} \ } \
@ -1609,28 +1577,36 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
FILTER("external", EXTERNAL); FILTER("external", EXTERNAL);
#undef FILTER #undef FILTER
if (vshCommandOptBool(cmd, "metadata")) { if (roots)
flags |= VIR_DOMAIN_SNAPSHOT_LIST_ROOTS;
if (vshCommandOptBool(cmd, "metadata"))
flags |= VIR_DOMAIN_SNAPSHOT_LIST_METADATA; flags |= VIR_DOMAIN_SNAPSHOT_LIST_METADATA;
}
if (vshCommandOptBool(cmd, "no-metadata")) { if (vshCommandOptBool(cmd, "no-metadata"))
flags |= VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA; flags |= VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA;
}
if (vshCommandOptBool(cmd, "descendants")) { if (vshCommandOptBool(cmd, "descendants")) {
if (!from) { if (!from && !current) {
vshError(ctl, "%s", vshError(ctl, "%s",
_("--descendants requires either --from or --current")); _("--descendants requires either --from or --current"));
goto cleanup; return false;
} }
flags |= VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS; flags |= VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS;
} }
if ((snaplist = vshSnapshotListCollect(ctl, dom, start, flags, if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
tree)) == NULL) return false;
if ((from || current) &&
vshLookupSnapshot(ctl, cmd, "from", true, dom, &start, &from_snap) < 0)
goto cleanup;
if (!(snaplist = vshSnapshotListCollect(ctl, dom, start, flags, tree)))
goto cleanup; goto cleanup;
if (!tree && !name) { if (!tree && !name) {
if (show_parent) if (parent)
vshPrintExtra(ctl, " %-20s %-25s %-15s %s", vshPrintExtra(ctl, " %-20s %-25s %-15s %s",
_("Name"), _("Creation Time"), _("State"), _("Name"), _("Creation Time"), _("State"),
_("Parent")); _("Parent"));
@ -1638,12 +1614,8 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
vshPrintExtra(ctl, " %-20s %-25s %s", vshPrintExtra(ctl, " %-20s %-25s %s",
_("Name"), _("Creation Time"), _("State")); _("Name"), _("Creation Time"), _("State"));
vshPrintExtra(ctl, "\n" vshPrintExtra(ctl, "\n"
"------------------------------------------------------------\n"); "------------------------------"
} "------------------------------\n");
if (!snaplist->nsnaps) {
ret = true;
goto cleanup;
} }
if (tree) { if (tree) {
@ -1661,7 +1633,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
const char *snap_name; const char *snap_name;
/* free up memory from previous iterations of the loop */ /* free up memory from previous iterations of the loop */
VIR_FREE(parent); VIR_FREE(parent_snap);
VIR_FREE(state); VIR_FREE(state);
xmlXPathFreeContext(ctxt); xmlXPathFreeContext(ctxt);
xmlFreeDoc(xml); xmlFreeDoc(xml);
@ -1672,25 +1644,24 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
assert(snap_name); assert(snap_name);
if (name) { if (name) {
/* just print the snapshot name */
vshPrint(ctl, "%s\n", snap_name); vshPrint(ctl, "%s\n", snap_name);
continue; continue;
} }
doc = virDomainSnapshotGetXMLDesc(snapshot, 0); if (!(doc = virDomainSnapshotGetXMLDesc(snapshot, 0)))
if (!doc)
continue; continue;
xml = virXMLParseStringCtxt(doc, _("(domain_snapshot)"), &ctxt); if (!(xml = virXMLParseStringCtxt(doc, _("(domain_snapshot)"), &ctxt)))
if (!xml)
continue; continue;
if (show_parent) if (parent)
parent = virXPathString("string(/domainsnapshot/parent/name)", parent_snap = virXPathString("string(/domainsnapshot/parent/name)",
ctxt); ctxt);
state = virXPathString("string(/domainsnapshot/state)", ctxt); if (!(state = virXPathString("string(/domainsnapshot/state)", ctxt)))
if (state == NULL)
continue; continue;
if (virXPathLongLong("string(/domainsnapshot/creationTime)", ctxt, if (virXPathLongLong("string(/domainsnapshot/creationTime)", ctxt,
&creation_longlong) < 0) &creation_longlong) < 0)
continue; continue;
@ -1705,7 +1676,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
if (parent) if (parent)
vshPrint(ctl, " %-20s %-25s %-15s %s\n", vshPrint(ctl, " %-20s %-25s %-15s %s\n",
snap_name, timestr, state, parent); snap_name, timestr, state, parent_snap);
else else
vshPrint(ctl, " %-20s %-25s %s\n", snap_name, timestr, state); vshPrint(ctl, " %-20s %-25s %s\n", snap_name, timestr, state);
} }
@ -1715,14 +1686,12 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
cleanup: cleanup:
/* this frees up memory from the last iteration of the loop */ /* this frees up memory from the last iteration of the loop */
vshSnapshotListFree(snaplist); vshSnapshotListFree(snaplist);
VIR_FREE(parent); VIR_FREE(parent_snap);
VIR_FREE(state); VIR_FREE(state);
if (start)
virDomainSnapshotFree(start); virDomainSnapshotFree(start);
xmlXPathFreeContext(ctxt); xmlXPathFreeContext(ctxt);
xmlFreeDoc(xml); xmlFreeDoc(xml);
VIR_FREE(doc); VIR_FREE(doc);
if (dom)
virDomainFree(dom); virDomainFree(dom);
return ret; return ret;