Browse Source

qemu-img: Add -C option for convert with copy offloading

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Fam Zheng 7 years ago
parent
commit
e11ce12f5e
3 changed files with 25 additions and 6 deletions
  1. 1 1
      qemu-img-cmds.hx
  2. 17 4
      qemu-img.c
  3. 7 1
      qemu-img.texi

+ 1 - 1
qemu-img-cmds.hx

@@ -44,7 +44,7 @@ STEXI
 ETEXI
 ETEXI
 
 
 DEF("convert", img_convert,
 DEF("convert", img_convert,
-    "convert [--object objectdef] [--image-opts] [--target-image-opts] [-U] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-B backing_file] [-o options] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] filename [filename2 [...]] output_filename")
+    "convert [--object objectdef] [--image-opts] [--target-image-opts] [-U] [-C] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-B backing_file] [-o options] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] filename [filename2 [...]] output_filename")
 STEXI
 STEXI
 @item convert [--object @var{objectdef}] [--image-opts] [--target-image-opts] [-U] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] [-o @var{options}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename}
 @item convert [--object @var{objectdef}] [--image-opts] [--target-image-opts] [-U] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] [-o @var{options}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename}
 ETEXI
 ETEXI

+ 17 - 4
qemu-img.c

@@ -2024,11 +2024,12 @@ static int img_convert(int argc, char **argv)
          skip_create = false, progress = false, tgt_image_opts = false;
          skip_create = false, progress = false, tgt_image_opts = false;
     int64_t ret = -EINVAL;
     int64_t ret = -EINVAL;
     bool force_share = false;
     bool force_share = false;
+    bool explict_min_sparse = false;
 
 
     ImgConvertState s = (ImgConvertState) {
     ImgConvertState s = (ImgConvertState) {
         /* Need at least 4k of zeros for sparse detection */
         /* Need at least 4k of zeros for sparse detection */
         .min_sparse         = 8,
         .min_sparse         = 8,
-        .copy_range         = true,
+        .copy_range         = false,
         .buf_sectors        = IO_BUF_SIZE / BDRV_SECTOR_SIZE,
         .buf_sectors        = IO_BUF_SIZE / BDRV_SECTOR_SIZE,
         .wr_in_order        = true,
         .wr_in_order        = true,
         .num_coroutines     = 8,
         .num_coroutines     = 8,
@@ -2043,7 +2044,7 @@ static int img_convert(int argc, char **argv)
             {"target-image-opts", no_argument, 0, OPTION_TARGET_IMAGE_OPTS},
             {"target-image-opts", no_argument, 0, OPTION_TARGET_IMAGE_OPTS},
             {0, 0, 0, 0}
             {0, 0, 0, 0}
         };
         };
-        c = getopt_long(argc, argv, ":hf:O:B:co:l:S:pt:T:qnm:WU",
+        c = getopt_long(argc, argv, ":hf:O:B:Cco:l:S:pt:T:qnm:WU",
                         long_options, NULL);
                         long_options, NULL);
         if (c == -1) {
         if (c == -1) {
             break;
             break;
@@ -2067,9 +2068,11 @@ static int img_convert(int argc, char **argv)
         case 'B':
         case 'B':
             out_baseimg = optarg;
             out_baseimg = optarg;
             break;
             break;
+        case 'C':
+            s.copy_range = true;
+            break;
         case 'c':
         case 'c':
             s.compressed = true;
             s.compressed = true;
-            s.copy_range = false;
             break;
             break;
         case 'o':
         case 'o':
             if (!is_valid_option_list(optarg)) {
             if (!is_valid_option_list(optarg)) {
@@ -2112,7 +2115,7 @@ static int img_convert(int argc, char **argv)
             }
             }
 
 
             s.min_sparse = sval / BDRV_SECTOR_SIZE;
             s.min_sparse = sval / BDRV_SECTOR_SIZE;
-            s.copy_range = false;
+            explict_min_sparse = true;
             break;
             break;
         }
         }
         case 'p':
         case 'p':
@@ -2172,6 +2175,16 @@ static int img_convert(int argc, char **argv)
         goto fail_getopt;
         goto fail_getopt;
     }
     }
 
 
+    if (s.compressed && s.copy_range) {
+        error_report("Cannot enable copy offloading when -c is used");
+        goto fail_getopt;
+    }
+
+    if (explict_min_sparse && s.copy_range) {
+        error_report("Cannot enable copy offloading when -S is used");
+        goto fail_getopt;
+    }
+
     if (tgt_image_opts && !skip_create) {
     if (tgt_image_opts && !skip_create) {
         error_report("--target-image-opts requires use of -n flag");
         error_report("--target-image-opts requires use of -n flag");
         goto fail_getopt;
         goto fail_getopt;

+ 7 - 1
qemu-img.texi

@@ -169,6 +169,12 @@ Number of parallel coroutines for the convert process
 Allow out-of-order writes to the destination. This option improves performance,
 Allow out-of-order writes to the destination. This option improves performance,
 but is only recommended for preallocated devices like host devices or other
 but is only recommended for preallocated devices like host devices or other
 raw block devices.
 raw block devices.
+@item -C
+Try to use copy offloading to move data from source image to target. This may
+improve performance if the data is remote, such as with NFS or iSCSI backends,
+but will not automatically sparsify zero sectors, and may result in a fully
+allocated target image depending on the host support for getting allocation
+information.
 @end table
 @end table
 
 
 Parameters to dd subcommand:
 Parameters to dd subcommand:
@@ -319,7 +325,7 @@ Error on reading data
 
 
 @end table
 @end table
 
 
-@item convert [--object @var{objectdef}] [--image-opts] [--target-image-opts] [-U] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] [-o @var{options}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename}
+@item convert [--object @var{objectdef}] [--image-opts] [--target-image-opts] [-U] [-C] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] [-o @var{options}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename}
 
 
 Convert the disk image @var{filename} or a snapshot @var{snapshot_param}
 Convert the disk image @var{filename} or a snapshot @var{snapshot_param}
 to disk image @var{output_filename} using format @var{output_fmt}. It can be optionally compressed (@code{-c}
 to disk image @var{output_filename} using format @var{output_fmt}. It can be optionally compressed (@code{-c}