提交 90ea06b8 编写于 作者: E Eric Blake

snapshot: track current domain across deletion of children

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.
上级 cb231b4b
...@@ -9167,9 +9167,11 @@ cleanup: ...@@ -9167,9 +9167,11 @@ cleanup:
return ret; return ret;
} }
static int qemuDomainSnapshotDiscard(struct qemud_driver *driver, static int
virDomainObjPtr vm, qemuDomainSnapshotDiscard(struct qemud_driver *driver,
virDomainSnapshotObjPtr snap) virDomainObjPtr vm,
virDomainSnapshotObjPtr snap,
bool update_current)
{ {
char *snapFile = NULL; char *snapFile = NULL;
int ret = -1; int ret = -1;
...@@ -9195,7 +9197,7 @@ static int qemuDomainSnapshotDiscard(struct qemud_driver *driver, ...@@ -9195,7 +9197,7 @@ static int qemuDomainSnapshotDiscard(struct qemud_driver *driver,
} }
if (snap == vm->current_snapshot) { if (snap == vm->current_snapshot) {
if (snap->def->parent) { if (update_current && snap->def->parent) {
parentsnap = virDomainSnapshotFindByName(&vm->snapshots, parentsnap = virDomainSnapshotFindByName(&vm->snapshots,
snap->def->parent); snap->def->parent);
if (!parentsnap) { if (!parentsnap) {
...@@ -9231,6 +9233,7 @@ struct snap_remove { ...@@ -9231,6 +9233,7 @@ struct snap_remove {
struct qemud_driver *driver; struct qemud_driver *driver;
virDomainObjPtr vm; virDomainObjPtr vm;
int err; int err;
bool current;
}; };
static void static void
...@@ -9242,7 +9245,9 @@ qemuDomainSnapshotDiscardDescendant(void *payload, ...@@ -9242,7 +9245,9 @@ qemuDomainSnapshotDiscardDescendant(void *payload,
struct snap_remove *curr = data; struct snap_remove *curr = data;
int err; 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) if (err && !curr->err)
curr->err = err; curr->err = err;
} }
...@@ -9321,12 +9326,15 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot, ...@@ -9321,12 +9326,15 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
rem.driver = driver; rem.driver = driver;
rem.vm = vm; rem.vm = vm;
rem.err = 0; rem.err = 0;
rem.current = false;
virDomainSnapshotForEachDescendant(&vm->snapshots, virDomainSnapshotForEachDescendant(&vm->snapshots,
snap, snap,
qemuDomainSnapshotDiscardDescendant, qemuDomainSnapshotDiscardDescendant,
&rem); &rem);
if (rem.err < 0) if (rem.err < 0)
goto endjob; goto endjob;
if (rem.current)
vm->current_snapshot = snap;
} else { } else {
rep.driver = driver; rep.driver = driver;
rep.snap = snap; rep.snap = snap;
...@@ -9338,7 +9346,7 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot, ...@@ -9338,7 +9346,7 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
goto endjob; goto endjob;
} }
ret = qemuDomainSnapshotDiscard(driver, vm, snap); ret = qemuDomainSnapshotDiscard(driver, vm, snap, true);
endjob: endjob:
if (qemuDomainObjEndJob(driver, vm) == 0) if (qemuDomainObjEndJob(driver, vm) == 0)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册