]> xenbits.xensource.com Git - libvirt.git/commitdiff
virDomainBlockCopy: Introduce VIR_DOMAIN_BLOCK_COPY_SYNCHRONOUS_WRITES flag
authorPeter Krempa <pkrempa@redhat.com>
Wed, 1 Dec 2021 14:09:45 +0000 (15:09 +0100)
committerPeter Krempa <pkrempa@redhat.com>
Tue, 7 Dec 2021 08:00:39 +0000 (09:00 +0100)
In cases when the destination storage is slower than the normal VM
storage and the VM does intensive I/O to the disk a block copy job may
never converge.

Switching it to synchronous mode will ensure that all writes done by the
guest are propagated to the destination at the cost of slowing down I/O
of the guest to the synchronous speed.

This patch adds the new API flag and implements virsh support.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
docs/manpages/virsh.rst
include/libvirt/libvirt-domain.h
src/libvirt-domain.c
tools/virsh-domain.c

index 39636a565e661ab0ced5a6629ade00fd577c4df9..9728f36a78f510d9b827c4fbddc083b4d31a16c6 100644 (file)
@@ -1218,7 +1218,7 @@ blockcopy
       [--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
@@ -1278,6 +1278,11 @@ be recovered if the VM crashes or is turned off before the job completes. This
 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
 --------
index dddcae86a40473e603a076d489416b26822b8723..3a76aec90f7a748d02d33d168f63a8e10bbb0002 100644 (file)
@@ -2598,6 +2598,10 @@ typedef enum {
 
     /* 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;
 
 /**
index ce7cafde3670877256126692a9d92c100babe659..8ee249086793841cb8939e0229921675c122686e 100644 (file)
@@ -10509,6 +10509,12 @@ virDomainBlockRebase(virDomainPtr dom, const char *disk,
  * 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
index e179e24ca9c375fba7c39d4bd1fd5c11c95ac450..a00b4cc243592935247cccdb357177dfd4d9a204 100644 (file)
@@ -2284,6 +2284,10 @@ static const vshCmdOptDef opts_blockcopy[] = {
      .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}
 };
 
@@ -2306,6 +2310,7 @@ cmdBlockcopy(vshControl *ctl, const vshCmd *cmd)
     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;
@@ -2337,6 +2342,8 @@ cmdBlockcopy(vshControl *ctl, const vshCmd *cmd)
         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;
 
@@ -2386,7 +2393,7 @@ cmdBlockcopy(vshControl *ctl, const vshCmd *cmd)
     }
 
     if (granularity || buf_size || (format && STRNEQ(format, "raw")) || xml ||
-        transientjob) {
+        transientjob || syncWrites) {
         /* New API */
         if (bandwidth || granularity || buf_size) {
             params = g_new0(virTypedParameter, 3);