aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Blake <eblake@redhat.com>2012-09-17 11:56:27 -0600
committerEric Blake <eblake@redhat.com>2012-09-17 21:28:08 -0600
commitef1e024df89cba592cf3c3aecd75ff319111946d (patch)
treee9facf5922c2f35a81cb41e4c50e7ea4c877d167 /include
parentqemu: drop unused arguments for dump-guest-memory (diff)
downloadlibvirt-ef1e024df89cba592cf3c3aecd75ff319111946d.tar.gz
libvirt-ef1e024df89cba592cf3c3aecd75ff319111946d.tar.bz2
libvirt-ef1e024df89cba592cf3c3aecd75ff319111946d.zip
blockjob: add virDomainBlockCommit
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.
Diffstat (limited to 'include')
-rw-r--r--include/libvirt/libvirt.h.in20
1 files changed, 20 insertions, 0 deletions
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index b12f7e3e4..d9bfb6e76 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -2062,11 +2062,14 @@ int virDomainUpdateDeviceFlags(virDomainPtr domain,
* virDomainBlockRebase without flags), job ends on completion
* VIR_DOMAIN_BLOCK_JOB_TYPE_COPY: Block Copy (virDomainBlockRebase with
* flags), job exists as long as mirroring is active
+ * VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT: Block Commit (virDomainBlockCommit),
+ * job ends on completion
*/
typedef enum {
VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN = 0,
VIR_DOMAIN_BLOCK_JOB_TYPE_PULL = 1,
VIR_DOMAIN_BLOCK_JOB_TYPE_COPY = 2,
+ VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT = 3,
#ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_BLOCK_JOB_TYPE_LAST
@@ -2131,6 +2134,23 @@ int virDomainBlockRebase(virDomainPtr dom, const char *disk,
const char *base, unsigned long bandwidth,
unsigned int flags);
+/**
+ * virDomainBlockCommitFlags:
+ *
+ * Flags available for virDomainBlockCommit().
+ */
+typedef enum {
+ VIR_DOMAIN_BLOCK_COMMIT_SHALLOW = 1 << 0, /* NULL base means next backing
+ file, not whole chain */
+ VIR_DOMAIN_BLOCK_COMMIT_DELETE = 1 << 1, /* Delete any files that are now
+ invalid after their contents
+ have been committed */
+} virDomainBlockCommitFlags;
+
+int virDomainBlockCommit(virDomainPtr dom, const char *disk, const char *base,
+ const char *top, unsigned long bandwidth,
+ unsigned int flags);
+
/* Block I/O throttling support */