None of the other flags made sense anymore, so remove them all. DELETE_CHILDREN means delete *this* snapshot and any children of this snapshot. Signed-off-by: Chris Lalancette <clalance@xxxxxxxxxx> --- include/libvirt/libvirt.h.in | 5 +-- src/qemu/qemu_driver.c | 93 +++++++++++++++++++++++------------------ src/vbox/vbox_tmpl.c | 27 +------------ tools/virsh.c | 17 +------ 4 files changed, 57 insertions(+), 85 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index a8a97e3..9aec351 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1912,10 +1912,7 @@ int virDomainCreateFromSnapshot(virDomainSnapshotPtr snapshot, /* Deactivate a snapshot */ typedef enum { - VIR_DOMAIN_SNAPSHOT_DELETE_MERGE = (1 << 0), - VIR_DOMAIN_SNAPSHOT_DELETE_MERGE_FORCE = (1 << 1), - VIR_DOMAIN_SNAPSHOT_DELETE_DISCARD = (1 << 2), - VIR_DOMAIN_SNAPSHOT_DELETE_DISCARD_FORCE = (1 << 3), + VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN = (1 << 0), } virDomainSnapshotDeleteFlags; int virDomainSnapshotDelete(virDomainSnapshotPtr snapshot, diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 7df15a6..65b499c 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -10792,15 +10792,14 @@ cleanup: static int qemuDomainSnapshotDiscard(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainSnapshotObjPtr snap, - int delete_children ATTRIBUTE_UNUSED) + virDomainSnapshotObjPtr snap) { const char *qemuimgarg[] = { NULL, "snapshot", "-d", NULL, NULL, NULL }; char *snapFile = NULL; int ret = -1; int i; qemuDomainObjPrivatePtr priv; - virDomainSnapshotObjPtr parentsnap = NULL; + virDomainSnapshotObjPtr parentsnap; if (!virDomainObjIsActive(vm)) { qemuimgarg[0] = qemuFindQemuImgBinary(); @@ -10812,26 +10811,22 @@ static int qemuDomainSnapshotDiscard(struct qemud_driver *driver, for (i = 0; i < vm->def->ndisks; i++) { /* FIXME: we also need to handle LVM here */ - /* FIXME: if we fail halfway through this loop, we are in an - * inconsistent state. I'm not quite sure what to do about that - */ if (vm->def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK) { if (!vm->def->disks[i]->driverType || STRNEQ(vm->def->disks[i]->driverType, "qcow2")) { - qemuReportError(VIR_ERR_OPERATION_INVALID, - _("Disk device '%s' does not support snapshotting"), - vm->def->disks[i]->info.alias); - goto cleanup; + /* we continue on even in the face of error, since other + * disks in this VM may have this snapshot in place + */ + continue; } qemuimgarg[4] = vm->def->disks[i]->src; if (virRun(qemuimgarg, NULL) < 0) { - virReportSystemError(errno, - _("Failed to run '%s' to delete snapshot '%s' from disk '%s'"), - qemuimgarg[0], snap->def->name, - vm->def->disks[i]->src); - goto cleanup; + /* we continue on even in the face of error, since other + * disks in this VM may have this snapshot in place + */ + continue; } } } @@ -10839,10 +10834,8 @@ static int qemuDomainSnapshotDiscard(struct qemud_driver *driver, else { priv = vm->privateData; qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuMonitorDeleteSnapshot(priv->mon, snap->def->name) < 0) { - qemuDomainObjExitMonitorWithDriver(driver, vm); - goto cleanup; - } + /* we continue on even in the face of error */ + qemuMonitorDeleteSnapshot(priv->mon, snap->def->name); qemuDomainObjExitMonitorWithDriver(driver, vm); } @@ -10882,6 +10875,36 @@ cleanup: return ret; } +struct snap_remove { + struct qemud_driver *driver; + virDomainObjPtr vm; + char *parent; + int err; +}; + +static void qemuDomainSnapshotDiscardChildren(void *payload, + const char *name ATTRIBUTE_UNUSED, + void *data) +{ + virDomainSnapshotObjPtr snap = payload; + struct snap_remove *curr = data; + struct snap_remove this; + + if (snap->def->parent && STREQ(snap->def->parent, curr->parent)) { + this.driver = curr->driver; + this.vm = curr->vm; + this.parent = snap->def->name; + this.err = 0; + virHashForEach(curr->vm->snapshots.objs, + qemuDomainSnapshotDiscardChildren, &this); + + if (this.err) + curr->err = this.err; + else + this.err = qemuDomainSnapshotDiscard(curr->driver, curr->vm, snap); + } +} + static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot, unsigned int flags) { @@ -10890,6 +10913,7 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot, int ret = -1; virDomainSnapshotObjPtr snap = NULL; char uuidstr[VIR_UUID_STRING_BUFLEN]; + struct snap_remove rem; qemuDriverLock(driver); virUUIDFormat(snapshot->domain->uuid, uuidstr); @@ -10908,31 +10932,18 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot, goto cleanup; } - if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_DISCARD) { - if (qemuDomainSnapshotDiscard(driver, vm, snap, 0) < 0) + if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN) { + rem.driver = driver; + rem.vm = vm; + rem.parent = snap->def->name; + rem.err = 0; + virHashForEach(vm->snapshots.objs, qemuDomainSnapshotDiscardChildren, + &rem); + if (rem.err < 0) goto cleanup; } - else if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_DISCARD_FORCE) { - if (qemuDomainSnapshotDiscard(driver, vm, snap, 1) < 0) - goto cleanup; - } - else if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_MERGE) { - /* FIXME: is this even possible with qemu? */ - if (virDomainSnapshotHasChildren(snap, &vm->snapshots)) { - /* FIXME: we should come up with a list of snapshots that would - * be merged/removed - */ - qemuReportError(VIR_ERR_INTERNAL_ERROR, - _("merging snapshot '%s' would also remove children snapshots"), - snap->def->name); - goto cleanup; - } - } - else if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_MERGE_FORCE) { - /* FIXME: is this even possible with qemu? */ - } - ret = 0; + ret = qemuDomainSnapshotDiscard(driver, vm, snap); cleanup: if (vm) diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index 5827446..185c941 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -5901,15 +5901,6 @@ vboxDomainSnapshotDelete(virDomainSnapshotPtr snapshot, } #endif - if (!(flags & (VIR_DOMAIN_SNAPSHOT_DELETE_MERGE | - VIR_DOMAIN_SNAPSHOT_DELETE_MERGE_FORCE | - VIR_DOMAIN_SNAPSHOT_DELETE_DISCARD | - VIR_DOMAIN_SNAPSHOT_DELETE_DISCARD_FORCE))) { - vboxError(dom->conn, VIR_ERR_INTERNAL_ERROR, "%s", - _("none of the supported flags passed")); - return -1; - } - vboxIIDFromUUID(dom->uuid, domiid); rc = data->vboxObj->vtbl->GetMachine(data->vboxObj, domiid, &machine); @@ -5932,21 +5923,6 @@ vboxDomainSnapshotDelete(virDomainSnapshotPtr snapshot, for (i = 0; i < childrenCount; i++) VBOX_RELEASE(children[i]); - if ((flags & (VIR_DOMAIN_SNAPSHOT_DELETE_MERGE | - VIR_DOMAIN_SNAPSHOT_DELETE_MERGE_FORCE)) - && childrenCount == 0) { - vboxError(dom->conn, VIR_ERR_OPERATION_INVALID, "%s", - _("operation would discard snapshot contents")); - goto cleanup; - } - - if ((flags & VIR_DOMAIN_SNAPSHOT_DELETE_DISCARD) - && childrenCount > 0) { - vboxError(dom->conn, VIR_ERR_OPERATION_INVALID, "%s", - _("operation would discard additional snapshots")); - goto cleanup; - } - rc = data->vboxObj->vtbl->OpenSession(data->vboxObj, data->vboxSession, domiid); if (NS_SUCCEEDED(rc)) @@ -5958,8 +5934,7 @@ vboxDomainSnapshotDelete(virDomainSnapshotPtr snapshot, goto cleanup; } - if ((flags & (VIR_DOMAIN_SNAPSHOT_DELETE_DISCARD | - VIR_DOMAIN_SNAPSHOT_DELETE_DISCARD_FORCE))) + if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN) ret = vboxDomainSnapshotDeleteTree(data, console, snap); else ret = vboxDomainSnapshotDeleteSingle(data, console, snap); diff --git a/tools/virsh.c b/tools/virsh.c index 1eb4bef..2a03442 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -8439,10 +8439,7 @@ static const vshCmdInfo info_snapshot_delete[] = { static const vshCmdOptDef opts_snapshot_delete[] = { {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, {"name", VSH_OT_DATA, VSH_OFLAG_REQ, N_("snapshot name")}, - {"merge", VSH_OT_BOOL, 0, N_("merge snapshot")}, - {"delete", VSH_OT_BOOL, 0, N_("delete snapshot")}, - {"merge-force", VSH_OT_BOOL, 0, N_("merge snapshot, discard children")}, - {"delete-force", VSH_OT_BOOL, 0, N_("delete snapshot and all children")}, + {"children", VSH_OT_BOOL, 0, N_("delete snapshot and all children")}, {NULL, 0, 0, NULL} }; @@ -8466,16 +8463,8 @@ cmdSnapshotDelete(vshControl *ctl, const vshCmd *cmd) if (name == NULL) goto cleanup; - if (vshCommandOptBool(cmd, "merge")) - flags |= VIR_DOMAIN_SNAPSHOT_DELETE_MERGE; - if (vshCommandOptBool(cmd, "delete")) - flags |= VIR_DOMAIN_SNAPSHOT_DELETE_DISCARD; - if (vshCommandOptBool(cmd, "merge-force")) - flags |= VIR_DOMAIN_SNAPSHOT_DELETE_MERGE_FORCE; - if (vshCommandOptBool(cmd, "delete-force")) - flags |= VIR_DOMAIN_SNAPSHOT_DELETE_DISCARD_FORCE; - - /* FIXME: throw an error if more than one flag is passed */ + if (vshCommandOptBool(cmd, "children")) + flags |= VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN; snapshot = virDomainSnapshotLookupByName(dom, name, 0); if (snapshot == NULL) -- 1.6.6.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list