• E
    blockjob: add virDomainBlockCommit · ef1e024d
    Eric Blake 提交于
    A block commit moves data in the opposite direction of block pull.
    Block pull reduces the chain length by dropping backing files after
    data has been pulled into the top overlay, and is always safe; block
    commit reduces the chain length by dropping overlays after data has
    been committed into the backing file, and any files that depended
    on base but not on top are invalidated at any point where they have
    unallocated data that is now pointing to changed contents in base.
    Both directions are useful, however: a qcow2 layer that is more than
    50% allocated will typically be faster with a pull operation, while
    a qcow2 layer with less than 50% allocation will be faster as a
    commit operation.  Committing across multiple layers can be more
    efficient than repeatedly committing one layer at a time, but
    requires extra support from the hypervisor.
    
    This API matches Jeff Cody's proposed qemu command 'block-commit':
    https://lists.gnu.org/archive/html/qemu-devel/2012-09/msg02226.html
    
    Jeff's command is still in the works for qemu 1.3, and may gain
    further enhancements, such as the ability to control on-error
    handling (it will be comparable to the error handling Paolo is
    adding to 'drive-mirror', so a similar solution will be needed
    when I finally propose virDomainBlockCopy with more functionality
    than the basics supported by virDomainBlockRebase).  However, even
    without qemu support, this API will be useful for _offline_ block
    commits, by wrapping qemu-img calls and turning them into a block
    job, so this API is worth committing now.
    
    For some examples of how this will be implemented, all starting
    with the chain: base <- snap1 <- snap2 <- active
    
    + These are equivalent:
     virDomainBlockCommit(dom, disk, NULL, NULL, 0, 0)
     virDomainBlockCommit(dom, disk, NULL, "active", 0, 0)
     virDomainBlockCommit(dom, disk, "base", NULL, 0, 0)
     virDomainBlockCommit(dom, disk, "base", "active", 0, 0)
    but cannot be implemented for online qemu with round 1 of
    Jeff's patches; and for offline images, it would require
    three back-to-back qemu-img invocations unless qemu-img
    is patched to allow more efficient multi-layer commits;
    the end result would be 'base' as the active disk with
    contents from all three other files, where 'snap1' and
    'snap2' are invalid right away, and 'active' is invalid
    once any further changes to 'base' are made.
    
    + These are equivalent:
     virDomainBlockCommit(dom, disk, "snap2", NULL, 0, 0)
     virDomainBlockCommit(dom, disk, NULL, NULL, 0, _SHALLOW)
    they cannot be implemented for online qemu, but for offline,
    it is a matter of 'qemu-img commit active', so that 'snap2'
    is now the active disk with contents formerly in 'active'.
    
    + Similarly:
     virDomainBlockCommit(dom, disk, "snap2", NULL, 0, _DELETE)
    for an offline domain will merge 'active' into 'snap2', then
    delete 'active' to avoid leaving a potentially invalid file
    around.
    
    + This version:
     virDomainBlockCommit(dom, disk, NULL, "snap2", 0, _SHALLOW)
    can be implemented online with 'block-commit' passing a base of
    snap1 and a top of snap2; and can be implemented offline by
    'qemu-img commit snap2' followed by 'qemu-img rebase -u
    -b snap1 active'
    
    * include/libvirt/libvirt.h.in (virDomainBlockCommit): New API.
    * src/libvirt.c (virDomainBlockCommit): Implement it.
    * src/libvirt_public.syms (LIBVIRT_0.10.2): Export it.
    * src/driver.h (virDrvDomainBlockCommit): New driver callback.
    * docs/apibuild.py (CParser.parseSignature): Add exception.
    ef1e024d
driver.h 70.9 KB