--- tools/virsh-snapshot.c | 65 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 10 deletions(-) diff --git a/tools/virsh-snapshot.c b/tools/virsh-snapshot.c index 7e75772..15bdcd7 100644 --- a/tools/virsh-snapshot.c +++ b/tools/virsh-snapshot.c @@ -1966,37 +1966,82 @@ cmdSnapshotDelete(vshControl *ctl, const vshCmd *cmd) const char *name = NULL; virDomainSnapshotPtr snapshot = NULL; unsigned int flags = 0; + bool snapshotname = false; + 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) { + snapshotname = true; + VSH_EXCLUSIVE_OPTIONS_VAR(current, snapshotname); + } 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 || name) { + if (virDomainSnapshotDeleteByName(dom, name, flags) == 0) + goto finished; + } else { + vshError(ctl, _("--snapshotname or --current is required")); + goto cleanup; + } + + if (last_error && last_error->code == VIR_ERR_NO_SUPPORT) { + vshResetLibvirtError(); + goto fallback; + } + + goto error; + +fallback: 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list