---
tools/virsh-snapshot.c | 64 ++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 54 insertions(+), 10 deletions(-)
diff --git a/tools/virsh-snapshot.c b/tools/virsh-snapshot.c
index 7e75772..4044e9b 100644
--- a/tools/virsh-snapshot.c
+++ b/tools/virsh-snapshot.c
@@ -1966,37 +1966,81 @@ cmdSnapshotDelete(vshControl *ctl, const vshCmd *cmd)
const char *name = NULL;
virDomainSnapshotPtr snapshot = NULL;
unsigned int flags = 0;
+ bool children = vshCommandOptBool(cmd, "children");
+ bool metadata = vshCommandOptBool(cmd, "metadata");
+ bool children_only = vshCommandOptBool(cmd, "children-only");
+ bool current = vshCommandOptBool(cmd, "current");
+
+ VSH_EXCLUSIVE_OPTIONS_VAR(children, children_only);
+
+ if (vshCommandOptStringReq(ctl, cmd, "snapshotname", &name) < 0)
+ goto cleanup;
+
+ if (!current && !name){
+ vshError(ctl, _("--snapshotname or --current is required"));
+ goto cleanup;
+ }
dom = vshCommandOptDomain(ctl, cmd, NULL);
if (dom == NULL)
goto cleanup;
+ if (children)
+ flags |= VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN;
+ if (metadata)
+ flags |= VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY;
+ if (children_only)
+ flags |= VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY;
+ if (current)
+ flags |= VIR_DOMAIN_SNAPSHOT_DELETE_CURRENT;
+
+ if (virDomainSnapshotDeleteByName(dom, name, flags) == 0)
+ goto finished;
+
+ if (last_error && last_error->code == VIR_ERR_NO_SUPPORT) {
+ vshResetLibvirtError();
+ goto fallback;
+ }
+
+ goto error;
+
+fallback:
+ /* virDomainSnapshotDelete doesn't support DELETE_CURRENT flag */
+ flags &= ~VIR_DOMAIN_SNAPSHOT_DELETE_CURRENT;
+
if (vshLookupSnapshot(ctl, cmd, "snapshotname", true, dom,
&snapshot, &name) < 0)
goto cleanup;
- if (vshCommandOptBool(cmd, "children"))
- flags |= VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN;
- if (vshCommandOptBool(cmd, "children-only"))
- flags |= VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY;
- if (vshCommandOptBool(cmd, "metadata"))
- flags |= VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY;
-
/* XXX If we wanted, we could emulate DELETE_CHILDREN_ONLY even on
* older servers that reject the flag, by manually computing the
* list of descendants. But that's a lot of code to maintain. */
- if (virDomainSnapshotDelete(snapshot, flags) == 0) {
+ if (virDomainSnapshotDelete(snapshot, flags) < 0)
+ goto error;
+
+finished:
+ if (name) {
if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY)
vshPrint(ctl, _("Domain snapshot %s children deleted\n"), name);
else
vshPrint(ctl, _("Domain snapshot %s deleted\n"), name);
} else {
- vshError(ctl, _("Failed to delete snapshot %s"), name);
- goto cleanup;
+ if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY)
+ vshPrint(ctl, _("Domain current snapshot children deleted\n"));
+ else
+ vshPrint(ctl, _("Domain current snapshot deleted\n"));
}
ret = true;
+error:
+ if (ret == false) {
+ if (name)
+ vshError(ctl, _("Failed to delete snapshot %s"), name);
+ else
+ vshError(ctl, _("Failed to delete current snapshot"));
+ }
+
cleanup:
if (snapshot)
virDomainSnapshotFree(snapshot);
--
1.8.1.4