On Wed, Aug 24, 2011 at 09:22:25AM -0600, Eric Blake wrote:
This one's nasty. Ever since we fixed virHashForEach to prevent
nested hash iterations for safety reasons, virDomainSnapshotDelete
with VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN has been broken for qemu:
it deletes children, while leaving grandchildren intact but pointing
to a no-longer-present parent. But even before then, the code would
often appear to succeed to clean up grandchildren, but risked memory
corruption if you have a large and deep hierarchy of snapshots.
For acting on just children, a single virHashForEach is sufficient.
But for acting on an entire subtree, it requires iteration; and
since we declared recursion as invalid, we have to switch to a
while loop. Doing this correctly requires quite a bit of overhaul,
so I added a new helper function to isolate the algorithm from the
actions, so that callers do not have to reinvent the iteration.
* src/conf/domain_conf.h (_virDomainSnapshotDef): Add mark.
(virDomainSnapshotForEachDescendant): New prototype.
* src/libvirt_private.syms (domain_conf.h): Export it.
* src/conf/domain_conf.c (virDomainSnapshotMarkDescendant)
(virDomainSnapshotActOnDescendant)
(virDomainSnapshotForEachDescendant): New functions.
* src/qemu/qemu_driver.c (qemuDomainSnapshotDiscardChildren):
Replace...
(qemuDomainSnapshotDiscardDescenent): ...with callback that
doesn't nest hash traversal.
(qemuDomainSnapshotDelete): Use new function.
---
src/conf/domain_conf.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++
src/conf/domain_conf.h | 8 +++-
src/libvirt_private.syms | 1 +
src/qemu/qemu_driver.c | 35 ++++++----------
4 files changed, 124 insertions(+), 23 deletions(-)
Perhaps I'm mis-understanding what this patch is attempting to fix, but
after applying everything upto this point, I see the following behaviour
which does not appear correct
$ virsh list
Id Name State
----------------------------------
5 vm1 running
$ virsh snapshot-list vm1
Name Creation Time State
---------------------------------------------------
$ virsh snapshot-create vm1
Domain snapshot 1314203761 created
$ virsh snapshot-create vm1
Domain snapshot 1314203763 created
$ virsh snapshot-create vm1
Domain snapshot 1314203767 created
$ virsh snapshot-create vm1
Domain snapshot 1314203777 created
$ virsh snapshot-create vm1
Domain snapshot 1314203781 created
$ virsh snapshot-list vm1
Name Creation Time State
---------------------------------------------------
1314203761 2011-08-24 17:36:01 +0100 running
1314203763 2011-08-24 17:36:03 +0100 running
1314203767 2011-08-24 17:36:07 +0100 running
1314203777 2011-08-24 17:36:17 +0100 running
1314203781 2011-08-24 17:36:21 +0100 running
$ virsh snapshot-delete vm1 --children 1314203767
Domain snapshot 1314203767 deleted
$ virsh snapshot-list vm1
Name Creation Time State
---------------------------------------------------
1314203761 2011-08-24 17:36:01 +0100 running
1314203763 2011-08-24 17:36:03 +0100 running
1314203781 2011-08-24 17:36:21 +0100 running
IIUC, 1314203781 should have been deleted.
I also still saw errors in libvirtd logs
17:36:36.175: 4423: info : libvirt version: 0.9.4
17:36:36.175: 4423: error : virHashSearch:604 : Hash operation not allowed during
iteration
17:36:36.176: 4423: warning : virDomainSnapshotMarkDescendant:11309 : snapshot hash table
is inconsistent!
17:36:36.176: 4423: error : virHashSearch:604 : Hash operation not allowed during
iteration
17:36:36.176: 4423: warning : virDomainSnapshotMarkDescendant:11309 : snapshot hash table
is inconsistent!
17:36:36.176: 4423: error : virHashSearch:604 : Hash operation not allowed during
iteration
17:36:36.176: 4423: warning : virDomainSnapshotMarkDescendant:11309 : snapshot hash table
is inconsistent!
Daniel
--
|:
http://berrange.com -o-
http://www.flickr.com/photos/dberrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|:
http://entangle-photo.org -o-
http://live.gnome.org/gtk-vnc :|