aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Blake <eblake@redhat.com>2012-04-02 16:56:07 -0600
committerEric Blake <eblake@redhat.com>2012-04-23 07:44:29 -0600
commit36484692587c1af5077630694f0c51b4864ecff7 (patch)
tree1eaf04166d121ac2bb3596efff616df1810bec87 /include
parentcpu: Improve error reporting on incompatible CPUs (diff)
downloadlibvirt-36484692587c1af5077630694f0c51b4864ecff7.tar.gz
libvirt-36484692587c1af5077630694f0c51b4864ecff7.tar.bz2
libvirt-36484692587c1af5077630694f0c51b4864ecff7.zip
blockjob: add new API flags
This patch introduces a new block job, useful for live storage migration using pre-copy streaming. Justification for including this under virDomainBlockRebase rather than adding a new command includes: 1) there are now two possible block jobs in qemu, with virDomainBlockRebase starting either type of command, and virDomainBlockJobInfo and virDomainBlockJobAbort working to end either type; 2) reusing this command allows distros to backport this feature to the libvirt 0.9.10 API without a .so bump. Note that a future patch may add a more powerful interface named virDomainBlockJobCopy, dedicated to just the block copy job, in order to expose even more options (such as setting an arbitrary format type for the destination without having to probe it from a pre-existing destination file); adding a new command for targetting just block copy would be similar to how we already have virDomainBlockPull for targetting just the block pull job. Using a live VM with the backing chain: base <- snap1 <- snap2 as the starting point, we have: - virDomainBlockRebase(dom, disk, "/path/to/copy", 0, VIR_DOMAIN_BLOCK_REBASE_COPY) creates /path/to/copy with the same format as snap2, with no backing file, so entire chain is copied and flattened - virDomainBlockRebase(dom, disk, "/path/to/copy", 0, VIR_DOMAIN_BLOCK_REBASE_COPY|VIR_DOMAIN_BLOCK_REBASE_COPY_RAW) creates /path/to/copy as a raw file, so entire chain is copied and flattened - virDomainBlockRebase(dom, disk, "/path/to/copy", 0, VIR_DOMAIN_BLOCK_REBASE_COPY|VIR_DOMAIN_BLOCK_REBASE_SHALLOW) creates /path/to/copy with the same format as snap2, but with snap1 as a backing file, so only snap2 is copied. - virDomainBlockRebase(dom, disk, "/path/to/copy", 0, VIR_DOMAIN_BLOCK_REBASE_COPY|VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT) reuse existing /path/to/copy (must have empty contents, and format is probed[*] from the metadata), and copy the full chain - virDomainBlockRebase(dom, disk, "/path/to/copy", 0, VIR_DOMAIN_BLOCK_REBASE_COPY|VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT| VIR_DOMAIN_BLOCK_REBASE_SHALLOW) reuse existing /path/to/copy (contents must be identical to snap1, and format is probed[*] from the metadata), and copy only the contents of snap2 - virDomainBlockRebase(dom, disk, "/path/to/copy", 0, VIR_DOMAIN_BLOCK_REBASE_COPY|VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT| VIR_DOMAIN_BLOCK_REBASE_SHALLOW|VIR_DOMAIN_BLOCK_REBASE_COPY_RAW) reuse existing /path/to/copy (must be raw volume with contents identical to snap1), and copy only the contents of snap2 Less useful combinations: - virDomainBlockRebase(dom, disk, "/path/to/copy", 0, VIR_DOMAIN_BLOCK_REBASE_COPY|VIR_DOMAIN_BLOCK_REBASE_SHALLOW| VIR_DOMAIN_BLOCK_REBASE_COPY_RAW) fail if source is not raw, otherwise create /path/to/copy as raw and the single file is copied (no chain involved) - virDomainBlockRebase(dom, disk, "/path/to/copy", 0, VIR_DOMAIN_BLOCK_REBASE_COPY|VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT| VIR_DOMAIN_BLOCK_REBASE_COPY_RAW) makes little sense: the destination must be raw but have no contents, meaning that it is an empty file, so there is nothing to reuse The other three flags are rejected without VIR_DOMAIN_BLOCK_COPY. [*] Note that probing an existing file for its format can be a security risk _if_ there is a possibility that the existing file is 'raw', in which case the guest can manipulate the file to appear like some other format. But, by virtue of the VIR_DOMAIN_BLOCK_REBASE_COPY_RAW flag, it is possible to avoid probing of raw files, at which point, probing of any remaining file type is no longer a security risk. It would be nice if we could issue an event when pivoting from phase 1 to phase 2, but qemu hasn't implemented that, and we would have to poll in order to synthesize it ourselves. Meanwhile, qemu will give us a distinct job info and completion event when we either cancel or pivot to end the job. Pivoting is accomplished via the new: virDomainBlockJobAbort(dom, disk, VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT) Management applications can pre-create the copy with a relative backing file name, and use the VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT flag to have qemu reuse the metadata; if the management application also copies the backing files to a new location, this can be used to perform live storage migration of an entire backing chain. * include/libvirt/libvirt.h.in (VIR_DOMAIN_BLOCK_JOB_TYPE_COPY): New block job type. (virDomainBlockJobAbortFlags, virDomainBlockRebaseFlags): New enums. * src/libvirt.c (virDomainBlockRebase): Document the new flags, and implement general restrictions on flag combinations. (virDomainBlockJobAbort): Document the new flag. (virDomainSaveFlags, virDomainSnapshotCreateXML) (virDomainRevertToSnapshot, virDomainDetachDeviceFlags): Document restrictions. * include/libvirt/virterror.h (VIR_ERR_BLOCK_COPY_ACTIVE): New error. * src/util/virterror.c (virErrorMsg): Define it.
Diffstat (limited to 'include')
-rw-r--r--include/libvirt/libvirt.h.in24
-rw-r--r--include/libvirt/virterror.h1
2 files changed, 23 insertions, 2 deletions
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 97ad99d93..ac5df95e3 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1934,12 +1934,15 @@ int virDomainUpdateDeviceFlags(virDomainPtr domain,
/**
* virDomainBlockJobType:
*
- * VIR_DOMAIN_BLOCK_JOB_TYPE_PULL: Block Pull (virDomainBlockPull or
- * virDomainBlockRebase)
+ * VIR_DOMAIN_BLOCK_JOB_TYPE_PULL: Block Pull (virDomainBlockPull, or
+ * 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
*/
typedef enum {
VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN = 0,
VIR_DOMAIN_BLOCK_JOB_TYPE_PULL = 1,
+ VIR_DOMAIN_BLOCK_JOB_TYPE_COPY = 2,
#ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_BLOCK_JOB_TYPE_LAST
@@ -1950,9 +1953,11 @@ typedef enum {
* virDomainBlockJobAbortFlags:
*
* VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC: Request only, do not wait for completion
+ * VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT: Pivot to mirror when ending a copy job
*/
typedef enum {
VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC = 1 << 0,
+ VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT = 1 << 1,
} virDomainBlockJobAbortFlags;
/* An iterator for monitoring block job operations */
@@ -1983,6 +1988,21 @@ int virDomainBlockJobSetSpeed(virDomainPtr dom, const char *disk,
int virDomainBlockPull(virDomainPtr dom, const char *disk,
unsigned long bandwidth, unsigned int flags);
+
+/**
+ * virDomainBlockRebaseFlags:
+ *
+ * Flags available for virDomainBlockRebase().
+ */
+typedef enum {
+ VIR_DOMAIN_BLOCK_REBASE_SHALLOW = 1 << 0, /* Limit copy to top of source
+ backing chain */
+ VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT = 1 << 1, /* Reuse existing external
+ file for a copy */
+ VIR_DOMAIN_BLOCK_REBASE_COPY_RAW = 1 << 2, /* Make destination file raw */
+ VIR_DOMAIN_BLOCK_REBASE_COPY = 1 << 3, /* Start a copy job */
+} virDomainBlockRebaseFlags;
+
int virDomainBlockRebase(virDomainPtr dom, const char *disk,
const char *base, unsigned long bandwidth,
unsigned int flags);
diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h
index cda15ff72..72832075a 100644
--- a/include/libvirt/virterror.h
+++ b/include/libvirt/virterror.h
@@ -250,6 +250,7 @@ typedef enum {
VIR_ERR_NO_DOMAIN_METADATA = 80, /* The metadata is not present */
VIR_ERR_MIGRATE_UNSAFE = 81, /* Migration is not safe */
VIR_ERR_OVERFLOW = 82, /* integer overflow */
+ VIR_ERR_BLOCK_COPY_ACTIVE = 83, /* action prevented by block copy job */
} virErrorNumber;
/**