[--shallow] [--reuse-external] [bandwidth]
[--wait [--async] [--verbose]] [{--pivot | --finish}]
[--timeout seconds] [granularity] [buf-size] [--bytes]
- [--transient-job]
+ [--transient-job] [--synchronous-writes]
Copy a disk backing image chain to a destination. Either *dest* as
the destination file name, or *--xml* with the name of an XML file containing
flag removes the restriction of copy jobs to transient domains if that
restriction is applied by the hypervisor.
+If *--synchronous-writes* is specified the block job will wait for guest writes
+to be propagated both to the original image and to the destination of the copy
+so that it's guaranteed that the job converges if the destination storage is
+slower. This may impact performance of writes while the blockjob is running.
+
blockjob
--------
/* Don't force usage of recoverable job for the copy operation */
VIR_DOMAIN_BLOCK_COPY_TRANSIENT_JOB = 1 << 2,
+
+ /* Force the copy job to synchronously propagate guest writes into
+ * the destination image, so that the copy is guaranteed to converge */
+ VIR_DOMAIN_BLOCK_COPY_SYNCHRONOUS_WRITES = 1 << 3,
} virDomainBlockCopyFlags;
/**
* remove the restriction of copy jobs to transient domains. Note that this flag
* is automatically implied if the VM is transient at the time it's started.
*
+ * If @flags contains VIR_DOMAIN_BLOCK_COPY_SYNCHRONOUS_WRITES the job will wait
+ * for guest writes to be propagated both to the original image and to the
+ * destination of the copy so that it's guaranteed that the job converges if
+ * the destination storage is slower. This may impact performance of writes
+ * while the blockjob is running.
+ *
* The @disk parameter is either an unambiguous source name of the
* block device (the <source file='...'/> sub-element, such as
* "/path/to/image"), or the device target shorthand (the
.type = VSH_OT_BOOL,
.help = N_("the copy job is not persisted if VM is turned off")
},
+ {.name = "synchronous-writes",
+ .type = VSH_OT_BOOL,
+ .help = N_("the copy job forces guest writes to be synchronously written to the destination")
+ },
{.name = NULL}
};
bool async = vshCommandOptBool(cmd, "async");
bool bytes = vshCommandOptBool(cmd, "bytes");
bool transientjob = vshCommandOptBool(cmd, "transient-job");
+ bool syncWrites = vshCommandOptBool(cmd, "synchronous-writes");
int timeout = 0;
const char *path = NULL;
int abort_flags = 0;
flags |= VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT;
if (transientjob)
flags |= VIR_DOMAIN_BLOCK_COPY_TRANSIENT_JOB;
+ if (syncWrites)
+ flags |= VIR_DOMAIN_BLOCK_COPY_SYNCHRONOUS_WRITES;
if (vshCommandOptTimeoutToMs(ctl, cmd, &timeout) < 0)
return false;
}
if (granularity || buf_size || (format && STRNEQ(format, "raw")) || xml ||
- transientjob) {
+ transientjob || syncWrites) {
/* New API */
if (bandwidth || granularity || buf_size) {
params = g_new0(virTypedParameter, 3);