Deleting a snapshot and all its descendants had problems with tracking the current snapshot. The deletion does not necessarily proceed in depth-first order, so a parent could be deleted before a child, wreaking havoc on passing the notion of the current snapshot to the parent. Furthermore, even if traversal were depth-first, doing multiple file writes to pass current up the chain one snapshot at a time is wasteful, comparing to a single update to the current snapshot at the end of the algorithm. * src/qemu/qemu_driver.c (snap_remove): Add field. (qemuDomainSnapshotDiscard): Add parameter. (qemuDomainSnapshotDiscardDescendant): Adjust accordingly. (qemuDomainSnapshotDelete): Properly reset current. --- src/qemu/qemu_driver.c | 20 ++++++++++++++------ 1 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 242708c..a96ec84 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -9166,9 +9166,11 @@ cleanup: return ret; } -static int qemuDomainSnapshotDiscard(struct qemud_driver *driver, - virDomainObjPtr vm, - virDomainSnapshotObjPtr snap) +static int +qemuDomainSnapshotDiscard(struct qemud_driver *driver, + virDomainObjPtr vm, + virDomainSnapshotObjPtr snap, + bool update_current) { const char *qemuimgarg[] = { NULL, "snapshot", "-d", NULL, NULL, NULL }; char *snapFile = NULL; @@ -9221,7 +9223,7 @@ static int qemuDomainSnapshotDiscard(struct qemud_driver *driver, } if (snap == vm->current_snapshot) { - if (snap->def->parent) { + if (update_current && snap->def->parent) { parentsnap = virDomainSnapshotFindByName(&vm->snapshots, snap->def->parent); if (!parentsnap) { @@ -9258,6 +9260,7 @@ struct snap_remove { struct qemud_driver *driver; virDomainObjPtr vm; int err; + bool current; }; static void @@ -9269,7 +9272,9 @@ qemuDomainSnapshotDiscardDescendant(void *payload, struct snap_remove *curr = data; int err; - err = qemuDomainSnapshotDiscard(curr->driver, curr->vm, snap); + if (snap->def->current) + curr->current = true; + err = qemuDomainSnapshotDiscard(curr->driver, curr->vm, snap, false); if (err && !curr->err) curr->err = err; } @@ -9348,12 +9353,15 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot, rem.driver = driver; rem.vm = vm; rem.err = 0; + rem.current = false; virDomainSnapshotForEachDescendant(&vm->snapshots, snap, qemuDomainSnapshotDiscardDescendant, &rem); if (rem.err < 0) goto endjob; + if (rem.current) + vm->current_snapshot = snap; } else { rep.driver = driver; rep.snap = snap; @@ -9365,7 +9373,7 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot, goto endjob; } - ret = qemuDomainSnapshotDiscard(driver, vm, snap); + ret = qemuDomainSnapshotDiscard(driver, vm, snap, true); endjob: if (qemuDomainObjEndJob(driver, vm) == 0) -- 1.7.4.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list