Blame SOURCES/kvm-qemu-img-Allow-source-cache-mode-specification.patch

958e1b
From a4e7f2adeadd8c03acd509028c07c7114379af10 Mon Sep 17 00:00:00 2001
958e1b
From: Max Reitz <mreitz@redhat.com>
958e1b
Date: Fri, 24 Oct 2014 08:17:57 +0200
958e1b
Subject: [PATCH 09/19] qemu-img: Allow source cache mode specification
958e1b
958e1b
Message-id: <1414138680-19600-2-git-send-email-mreitz@redhat.com>
958e1b
Patchwork-id: 61862
958e1b
O-Subject: [RHEL-7.1 qemu-kvm PATCH v2 1/4] qemu-img: Allow source cache mode specification
958e1b
Bugzilla: 1138691
958e1b
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
958e1b
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
958e1b
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
958e1b
958e1b
Many qemu-img subcommands only read the source file(s) once. For these
958e1b
use cases, a full write-back cache is unnecessary and mainly clutters
958e1b
host cache memory. Though this is generally no concern as cache memory
958e1b
is freely available and can be scaled by the host OS, it may become a
958e1b
concern with thin provisioning.
958e1b
958e1b
For these cases, it makes sense to allow users to freely specify the
958e1b
source cache mode (e.g. use no cache at all).
958e1b
958e1b
This commit adds a new switch (-T) for the qemu-img subcommands check,
958e1b
compare, convert and rebase to specify the cache to be used for source
958e1b
images (the backing file in case of rebase).
958e1b
958e1b
Signed-off-by: Max Reitz <mreitz@redhat.com>
958e1b
Reviewed-by: Eric Blake <eblake@redhat.com>
958e1b
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
958e1b
(cherry picked from commit 40055951a7afbfc037c6c7351d72a5c5d83ed99b)
958e1b
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
958e1b
958e1b
Conflicts:
958e1b
	qemu-img-cmds.hx
958e1b
	qemu-img.c
958e1b
	qemu-img.texi
958e1b
958e1b
Conflicts due to bdrv_open() working differently downstream
958e1b
(pre-O_PROTOCOL and no reference parameter), and there are more options
958e1b
to qemu-img convert upstream.
958e1b
958e1b
Signed-off-by: Max Reitz <mreitz@redhat.com>
958e1b
---
958e1b
 qemu-img-cmds.hx | 16 ++++++------
958e1b
 qemu-img.c       | 76 +++++++++++++++++++++++++++++++++++++++++++++-----------
958e1b
 qemu-img.texi    | 14 ++++++++---
958e1b
 3 files changed, 79 insertions(+), 27 deletions(-)
958e1b
958e1b
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
958e1b
index da1d965..e590d46 100644
958e1b
--- a/qemu-img-cmds.hx
958e1b
+++ b/qemu-img-cmds.hx
958e1b
@@ -10,9 +10,9 @@ STEXI
958e1b
 ETEXI
958e1b
 
958e1b
 DEF("check", img_check,
958e1b
-    "check [-q] [-f fmt] [--output=ofmt]  [-r [leaks | all]] filename")
958e1b
+    "check [-q] [-f fmt] [--output=ofmt] [-r [leaks | all]] [-T src_cache] filename")
958e1b
 STEXI
958e1b
-@item check [-q] [-f @var{fmt}] [--output=@var{ofmt}] [-r [leaks | all]] @var{filename}
958e1b
+@item check [-q] [-f @var{fmt}] [--output=@var{ofmt}] [-r [leaks | all]] [-T @var{src_cache}] @var{filename}
958e1b
 ETEXI
958e1b
 
958e1b
 DEF("create", img_create,
958e1b
@@ -28,15 +28,15 @@ STEXI
958e1b
 ETEXI
958e1b
 
958e1b
 DEF("compare", img_compare,
958e1b
-    "compare [-f fmt] [-F fmt] [-p] [-q] [-s] filename1 filename2")
958e1b
+    "compare [-f fmt] [-F fmt] [-T src_cache] [-p] [-q] [-s] filename1 filename2")
958e1b
 STEXI
958e1b
-@item compare [-f @var{fmt}] [-F @var{fmt}] [-p] [-q] [-s] @var{filename1} @var{filename2}
958e1b
+@item compare [-f @var{fmt}] [-F @var{fmt}] [-T @var{src_cache}] [-p] [-q] [-s] @var{filename1} @var{filename2}
958e1b
 ETEXI
958e1b
 
958e1b
 DEF("convert", img_convert,
958e1b
-    "convert [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-O output_fmt] [-o options] [-s snapshot_name] [-S sparse_size] filename [filename2 [...]] output_filename")
958e1b
+    "convert [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-o options] [-s snapshot_name] [-S sparse_size] filename [filename2 [...]] output_filename")
958e1b
 STEXI
958e1b
-@item convert [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
958e1b
+@item convert [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
958e1b
 ETEXI
958e1b
 
958e1b
 DEF("info", img_info,
958e1b
@@ -58,9 +58,9 @@ STEXI
958e1b
 ETEXI
958e1b
 
958e1b
 DEF("rebase", img_rebase,
958e1b
-    "rebase [-q] [-f fmt] [-t cache] [-p] [-u] -b backing_file [-F backing_fmt] filename")
958e1b
+    "rebase [-q] [-f fmt] [-t cache] [-T src_cache] [-p] [-u] -b backing_file [-F backing_fmt] filename")
958e1b
 STEXI
958e1b
-@item rebase [-q] [-f @var{fmt}] [-t @var{cache}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
958e1b
+@item rebase [-q] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
958e1b
 ETEXI
958e1b
 
958e1b
 DEF("resize", img_resize,
958e1b
diff --git a/qemu-img.c b/qemu-img.c
958e1b
index fe0ac65..25fdc37 100644
958e1b
--- a/qemu-img.c
958e1b
+++ b/qemu-img.c
958e1b
@@ -84,6 +84,7 @@ static void help(void)
958e1b
            "  'cache' is the cache mode used to write the output disk image, the valid\n"
958e1b
            "    options are: 'none', 'writeback' (default, except for convert), 'writethrough',\n"
958e1b
            "    'directsync' and 'unsafe' (default for convert)\n"
958e1b
+           "  'src_cache' in contrast is the cache mode used to read input disk images\n"
958e1b
            "  'size' is the disk image size in bytes. Optional suffixes\n"
958e1b
            "    'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M)\n"
958e1b
            "    and T (terabyte, 1024G) are supported. 'b' is ignored.\n"
958e1b
@@ -553,7 +554,7 @@ static int img_check(int argc, char **argv)
958e1b
 {
958e1b
     int c, ret;
958e1b
     OutputFormat output_format = OFORMAT_HUMAN;
958e1b
-    const char *filename, *fmt, *output;
958e1b
+    const char *filename, *fmt, *output, *cache;
958e1b
     BlockDriverState *bs;
958e1b
     int fix = 0;
958e1b
     int flags = BDRV_O_FLAGS | BDRV_O_CHECK;
958e1b
@@ -562,6 +563,7 @@ static int img_check(int argc, char **argv)
958e1b
 
958e1b
     fmt = NULL;
958e1b
     output = NULL;
958e1b
+    cache = BDRV_DEFAULT_CACHE;
958e1b
     for(;;) {
958e1b
         int option_index = 0;
958e1b
         static const struct option long_options[] = {
958e1b
@@ -571,7 +573,7 @@ static int img_check(int argc, char **argv)
958e1b
             {"output", required_argument, 0, OPTION_OUTPUT},
958e1b
             {0, 0, 0, 0}
958e1b
         };
958e1b
-        c = getopt_long(argc, argv, "f:hr:q",
958e1b
+        c = getopt_long(argc, argv, "hf:r:T:q",
958e1b
                         long_options, &option_index);
958e1b
         if (c == -1) {
958e1b
             break;
958e1b
@@ -598,6 +600,9 @@ static int img_check(int argc, char **argv)
958e1b
         case OPTION_OUTPUT:
958e1b
             output = optarg;
958e1b
             break;
958e1b
+        case 'T':
958e1b
+            cache = optarg;
958e1b
+            break;
958e1b
         case 'q':
958e1b
             quiet = true;
958e1b
             break;
958e1b
@@ -617,6 +622,12 @@ static int img_check(int argc, char **argv)
958e1b
         return 1;
958e1b
     }
958e1b
 
958e1b
+    ret = bdrv_parse_cache_flags(cache, &flags);
958e1b
+    if (ret < 0) {
958e1b
+        error_report("Invalid source cache option: %s", cache);
958e1b
+        return 1;
958e1b
+    }
958e1b
+
958e1b
     bs = bdrv_new_open("image", filename, fmt, flags, true, quiet);
958e1b
     if (!bs) {
958e1b
         return 1;
958e1b
@@ -911,7 +922,7 @@ static int check_empty_sectors(BlockDriverState *bs, int64_t sect_num,
958e1b
  */
958e1b
 static int img_compare(int argc, char **argv)
958e1b
 {
958e1b
-    const char *fmt1 = NULL, *fmt2 = NULL, *filename1, *filename2;
958e1b
+    const char *fmt1 = NULL, *fmt2 = NULL, *cache, *filename1, *filename2;
958e1b
     BlockDriverState *bs1, *bs2;
958e1b
     int64_t total_sectors1, total_sectors2;
958e1b
     uint8_t *buf1 = NULL, *buf2 = NULL;
958e1b
@@ -919,6 +930,7 @@ static int img_compare(int argc, char **argv)
958e1b
     int allocated1, allocated2;
958e1b
     int ret = 0; /* return value - 0 Ident, 1 Different, >1 Error */
958e1b
     bool progress = false, quiet = false, strict = false;
958e1b
+    int flags;
958e1b
     int64_t total_sectors;
958e1b
     int64_t sector_num = 0;
958e1b
     int64_t nb_sectors;
958e1b
@@ -926,8 +938,9 @@ static int img_compare(int argc, char **argv)
958e1b
     uint64_t bs_sectors;
958e1b
     uint64_t progress_base;
958e1b
 
958e1b
+    cache = BDRV_DEFAULT_CACHE;
958e1b
     for (;;) {
958e1b
-        c = getopt(argc, argv, "hpf:F:sq");
958e1b
+        c = getopt(argc, argv, "hf:F:T:pqs");
958e1b
         if (c == -1) {
958e1b
             break;
958e1b
         }
958e1b
@@ -942,6 +955,9 @@ static int img_compare(int argc, char **argv)
958e1b
         case 'F':
958e1b
             fmt2 = optarg;
958e1b
             break;
958e1b
+        case 'T':
958e1b
+            cache = optarg;
958e1b
+            break;
958e1b
         case 'p':
958e1b
             progress = true;
958e1b
             break;
958e1b
@@ -966,17 +982,25 @@ static int img_compare(int argc, char **argv)
958e1b
     filename1 = argv[optind++];
958e1b
     filename2 = argv[optind++];
958e1b
 
958e1b
+    flags = BDRV_O_FLAGS;
958e1b
+    ret = bdrv_parse_cache_flags(cache, &flags);
958e1b
+    if (ret < 0) {
958e1b
+        error_report("Invalid source cache option: %s", cache);
958e1b
+        ret = 2;
958e1b
+        goto out3;
958e1b
+    }
958e1b
+
958e1b
     /* Initialize before goto out */
958e1b
     qemu_progress_init(progress, 2.0);
958e1b
 
958e1b
-    bs1 = bdrv_new_open("image 1", filename1, fmt1, BDRV_O_FLAGS, true, quiet);
958e1b
+    bs1 = bdrv_new_open("image 1", filename1, fmt1, flags, true, quiet);
958e1b
     if (!bs1) {
958e1b
         error_report("Can't open file %s", filename1);
958e1b
         ret = 2;
958e1b
         goto out3;
958e1b
     }
958e1b
 
958e1b
-    bs2 = bdrv_new_open("image 2", filename2, fmt2, BDRV_O_FLAGS, true, quiet);
958e1b
+    bs2 = bdrv_new_open("image 2", filename2, fmt2, flags, true, quiet);
958e1b
     if (!bs2) {
958e1b
         error_report("Can't open file %s", filename2);
958e1b
         ret = 2;
958e1b
@@ -1145,8 +1169,8 @@ static int img_convert(int argc, char **argv)
958e1b
 {
958e1b
     int c, n, n1, bs_n, bs_i, compress, cluster_sectors, skip_create;
958e1b
     int64_t ret = 0;
958e1b
-    int progress = 0, flags;
958e1b
-    const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename;
958e1b
+    int progress = 0, flags, src_flags;
958e1b
+    const char *fmt, *out_fmt, *cache, *src_cache, *out_baseimg, *out_filename;
958e1b
     BlockDriver *drv, *proto_drv;
958e1b
     BlockDriverState **bs = NULL, *out_bs = NULL;
958e1b
     int64_t total_sectors, nb_sectors, sector_num, bs_offset,
958e1b
@@ -1167,11 +1191,12 @@ static int img_convert(int argc, char **argv)
958e1b
     fmt = NULL;
958e1b
     out_fmt = "raw";
958e1b
     cache = "unsafe";
958e1b
+    src_cache = BDRV_DEFAULT_CACHE;
958e1b
     out_baseimg = NULL;
958e1b
     compress = 0;
958e1b
     skip_create = 0;
958e1b
     for(;;) {
958e1b
-        c = getopt(argc, argv, "f:O:B:s:hce6o:pS:t:qn");
958e1b
+        c = getopt(argc, argv, "hf:O:B:ce6o:s:S:pt:T:qn");
958e1b
         if (c == -1) {
958e1b
             break;
958e1b
         }
958e1b
@@ -1239,6 +1264,9 @@ static int img_convert(int argc, char **argv)
958e1b
         case 't':
958e1b
             cache = optarg;
958e1b
             break;
958e1b
+        case 'T':
958e1b
+            src_cache = optarg;
958e1b
+            break;
958e1b
         case 'q':
958e1b
             quiet = true;
958e1b
             break;
958e1b
@@ -1275,6 +1303,13 @@ static int img_convert(int argc, char **argv)
958e1b
         goto out;
958e1b
     }
958e1b
 
958e1b
+    src_flags = BDRV_O_FLAGS;
958e1b
+    ret = bdrv_parse_cache_flags(src_cache, &src_flags);
958e1b
+    if (ret < 0) {
958e1b
+        error_report("Invalid source cache option: %s", src_cache);
958e1b
+        goto out;
958e1b
+    }
958e1b
+
958e1b
     qemu_progress_print(0, 100);
958e1b
 
958e1b
     bs = g_malloc0(bs_n * sizeof(BlockDriverState *));
958e1b
@@ -1283,7 +1318,7 @@ static int img_convert(int argc, char **argv)
958e1b
     for (bs_i = 0; bs_i < bs_n; bs_i++) {
958e1b
         char *id = bs_n > 1 ? g_strdup_printf("source %d", bs_i)
958e1b
                             : g_strdup("source");
958e1b
-        bs[bs_i] = bdrv_new_open(id, argv[optind + bs_i], fmt, BDRV_O_FLAGS,
958e1b
+        bs[bs_i] = bdrv_new_open(id, argv[optind + bs_i], fmt, src_flags,
958e1b
                                  true, quiet);
958e1b
         g_free(id);
958e1b
         if (!bs[bs_i]) {
958e1b
@@ -2197,8 +2232,8 @@ static int img_rebase(int argc, char **argv)
958e1b
     BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
958e1b
     BlockDriver *old_backing_drv, *new_backing_drv;
958e1b
     char *filename;
958e1b
-    const char *fmt, *cache, *out_basefmt, *out_baseimg;
958e1b
-    int c, flags, ret;
958e1b
+    const char *fmt, *cache, *src_cache, *out_basefmt, *out_baseimg;
958e1b
+    int c, flags, src_flags, ret;
958e1b
     int unsafe = 0;
958e1b
     int progress = 0;
958e1b
     bool quiet = false;
958e1b
@@ -2207,10 +2242,11 @@ static int img_rebase(int argc, char **argv)
958e1b
     /* Parse commandline parameters */
958e1b
     fmt = NULL;
958e1b
     cache = BDRV_DEFAULT_CACHE;
958e1b
+    src_cache = BDRV_DEFAULT_CACHE;
958e1b
     out_baseimg = NULL;
958e1b
     out_basefmt = NULL;
958e1b
     for(;;) {
958e1b
-        c = getopt(argc, argv, "uhf:F:b:pt:q");
958e1b
+        c = getopt(argc, argv, "hf:F:b:upt:T:q");
958e1b
         if (c == -1) {
958e1b
             break;
958e1b
         }
958e1b
@@ -2237,6 +2273,9 @@ static int img_rebase(int argc, char **argv)
958e1b
         case 't':
958e1b
             cache = optarg;
958e1b
             break;
958e1b
+        case 'T':
958e1b
+            src_cache = optarg;
958e1b
+            break;
958e1b
         case 'q':
958e1b
             quiet = true;
958e1b
             break;
958e1b
@@ -2262,6 +2301,13 @@ static int img_rebase(int argc, char **argv)
958e1b
         return -1;
958e1b
     }
958e1b
 
958e1b
+    src_flags = BDRV_O_FLAGS;
958e1b
+    ret = bdrv_parse_cache_flags(src_cache, &src_flags);
958e1b
+    if (ret < 0) {
958e1b
+        error_report("Invalid source cache option: %s", src_cache);
958e1b
+        return -1;
958e1b
+    }
958e1b
+
958e1b
     /*
958e1b
      * Open the images.
958e1b
      *
958e1b
@@ -2305,7 +2351,7 @@ static int img_rebase(int argc, char **argv)
958e1b
 
958e1b
         bs_old_backing = bdrv_new("old_backing", &error_abort);
958e1b
         bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
958e1b
-        ret = bdrv_open(bs_old_backing, backing_name, NULL, BDRV_O_FLAGS,
958e1b
+        ret = bdrv_open(bs_old_backing, backing_name, NULL, src_flags,
958e1b
                         old_backing_drv, &local_err);
958e1b
         if (ret) {
958e1b
             error_report("Could not open old backing file '%s': %s",
958e1b
@@ -2315,7 +2361,7 @@ static int img_rebase(int argc, char **argv)
958e1b
         }
958e1b
         if (out_baseimg[0]) {
958e1b
             bs_new_backing = bdrv_new("new_backing", &error_abort);
958e1b
-            ret = bdrv_open(bs_new_backing, out_baseimg, NULL, BDRV_O_FLAGS,
958e1b
+            ret = bdrv_open(bs_new_backing, out_baseimg, NULL, src_flags,
958e1b
                         new_backing_drv, &local_err);
958e1b
             if (ret) {
958e1b
                 error_report("Could not open new backing file '%s': %s",
958e1b
diff --git a/qemu-img.texi b/qemu-img.texi
958e1b
index 7c28759..3d06e91 100644
958e1b
--- a/qemu-img.texi
958e1b
+++ b/qemu-img.texi
958e1b
@@ -68,6 +68,9 @@ down to the nearest 512 bytes. You may use the common size suffixes like
958e1b
 specifies the cache mode that should be used with the (destination) file. See
958e1b
 the documentation of the emulator's @code{-drive cache=...} option for allowed
958e1b
 values.
958e1b
+@item -T @var{src_cache}
958e1b
+in contrast specifies the cache mode that should be used with the source
958e1b
+file(s).
958e1b
 @end table
958e1b
 
958e1b
 Parameters to snapshot subcommand:
958e1b
@@ -109,7 +112,7 @@ Skip the creation of the target volume
958e1b
 Command description:
958e1b
 
958e1b
 @table @option
958e1b
-@item check [-f @var{fmt}] [--output=@var{ofmt}] [-r [leaks | all]] @var{filename}
958e1b
+@item check [-f @var{fmt}] [--output=@var{ofmt}] [-r [leaks | all]] [-T @var{src_cache}] @var{filename}
958e1b
 
958e1b
 Perform a consistency check on the disk image @var{filename}. The command can
958e1b
 output in the format @var{ofmt} which is either @code{human} or @code{json}.
958e1b
@@ -145,7 +148,7 @@ the backing file, the backing file will not be truncated.  If you want the
958e1b
 backing file to match the size of the smaller snapshot, you can safely truncate
958e1b
 it yourself once the commit operation successfully completes.
958e1b
 
958e1b
-@item compare [-f @var{fmt}] [-F @var{fmt}] [-p] [-s] [-q] @var{filename1} @var{filename2}
958e1b
+@item compare [-f @var{fmt}] [-F @var{fmt}] [-T @var{src_cache}] [-p] [-s] [-q] @var{filename1} @var{filename2}
958e1b
 
958e1b
 Check if two images have the same content. You can compare images with
958e1b
 different format or settings.
958e1b
@@ -186,7 +189,7 @@ Error on reading data
958e1b
 
958e1b
 @end table
958e1b
 
958e1b
-@item convert [-c] [-p] [-n] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
958e1b
+@item convert [-c] [-p] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
958e1b
 
958e1b
 Convert the disk image @var{filename} or a snapshot @var{snapshot_name} to disk image @var{output_filename}
958e1b
 using format @var{output_fmt}. It can be optionally compressed (@code{-c}
958e1b
@@ -298,7 +301,7 @@ source code.
958e1b
 
958e1b
 List, apply, create or delete snapshots in image @var{filename}.
958e1b
 
958e1b
-@item rebase [-f @var{fmt}] [-t @var{cache}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
958e1b
+@item rebase [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
958e1b
 
958e1b
 Changes the backing file of an image. Only the formats @code{qcow2} and
958e1b
 @code{qed} support changing the backing file.
958e1b
@@ -309,6 +312,9 @@ The backing file is changed to @var{backing_file} and (if the image format of
958e1b
 string), then the image is rebased onto no backing file (i.e. it will exist
958e1b
 independently of any backing file).
958e1b
 
958e1b
+@var{cache} specifies the cache mode to be used for @var{filename}, whereas
958e1b
+@var{src_cache} specifies the cache mode for reading the new backing file.
958e1b
+
958e1b
 There are two different modes in which @code{rebase} can operate:
958e1b
 @table @option
958e1b
 @item Safe mode
958e1b
-- 
958e1b
1.8.3.1
958e1b