• E
    snapshot: avoid crash when deleting qemu snapshots · cb231b4b
    Eric Blake 提交于
    This one's nasty.  Ever since we fixed virHashForEach to prevent
    nested hash iterations for safety reasons (commit fba550f6),
    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.
    
    Note that this _still_ does not handle CHILDREN correctly if one
    of the children is the current snapshot; that will be next.
    
    * 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.
    cb231b4b
domain_conf.h 55.1 KB