qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v6 4/5] qemu-img: Add convert --bitmaps option


From: Vladimir Sementsov-Ogievskiy
Subject: Re: [PATCH v6 4/5] qemu-img: Add convert --bitmaps option
Date: Mon, 25 May 2020 10:51:51 +0300
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.8.0

21.05.2020 22:21, Eric Blake wrote:
Make it easier to copy all the persistent bitmaps of (the top layer
of) a source image along with its guest-visible contents, by adding a
boolean flag for use with qemu-img convert.  This is basically
shorthand, as the same effect could be accomplished with a series of
'qemu-img bitmap --add' and 'qemu-img bitmap --merge -b source'
commands, or by their corresponding QMP commands.

Note that this command will fail in the same scenarios where 'qemu-img
measure' omits a 'bitmaps size:' line, namely, when either the source
or the destination lacks persistent bitmap support altogether.

See also https://bugzilla.redhat.com/show_bug.cgi?id=1779893

While touching this, clean up a couple coding issues spotted in the
same function: an extra blank line, and merging back-to-back 'if
(!skip_create)' blocks.

Signed-off-by: Eric Blake <address@hidden>
---

[..]

diff --git a/qemu-img.c b/qemu-img.c
index 0778d8f56614..8ecebe178890 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -78,6 +78,7 @@ enum {
      OPTION_ENABLE = 272,
      OPTION_DISABLE = 273,
      OPTION_MERGE = 274,

[..]


  static int img_convert(int argc, char **argv)
@@ -2160,6 +2195,8 @@ static int img_convert(int argc, char **argv)
      int64_t ret = -EINVAL;
      bool force_share = false;
      bool explict_min_sparse = false;
+    bool bitmaps = false;
+    size_t nbitmaps = 0;

      ImgConvertState s = (ImgConvertState) {
          /* Need at least 4k of zeros for sparse detection */
@@ -2179,6 +2216,7 @@ static int img_convert(int argc, char **argv)
              {"target-image-opts", no_argument, 0, OPTION_TARGET_IMAGE_OPTS},
              {"salvage", no_argument, 0, OPTION_SALVAGE},
              {"target-is-zero", no_argument, 0, OPTION_TARGET_IS_ZERO},
+            {"bitmaps", no_argument, 0, OPTION_BITMAPS},
              {0, 0, 0, 0}
          };
          c = getopt_long(argc, argv, ":hf:O:B:Cco:l:S:pt:T:qnm:WU",
@@ -2304,6 +2342,9 @@ static int img_convert(int argc, char **argv)
               */
              s.has_zero_init = true;
              break;
+        case OPTION_BITMAPS:
+            bitmaps = true;
+            break;
          }
      }

@@ -2365,7 +2406,6 @@ static int img_convert(int argc, char **argv)
          goto fail_getopt;
      }

-
      /* ret is still -EINVAL until here */
      ret = bdrv_parse_cache_mode(src_cache, &src_flags, &src_writethrough);
      if (ret < 0) {
@@ -2525,6 +2565,27 @@ static int img_convert(int argc, char **argv)
          }
      }

+    /* Determine how many bitmaps need copying */
+    if (bitmaps) {
+        BdrvDirtyBitmap *bm;
+
+        if (s.src_num > 1) {
+            error_report("Copying bitmaps only possible with single source");
+            ret = -1;
+            goto out;
+        }
+        if (!bdrv_supports_persistent_dirty_bitmap(blk_bs(s.src[0]))) {
+            error_report("Source lacks bitmap support");
+            ret = -1;
+            goto out;
+        }
+        FOR_EACH_DIRTY_BITMAP(blk_bs(s.src[0]), bm) {
+            if (bdrv_dirty_bitmap_get_persistence(bm)) {
+                nbitmaps++;
+            }
+        }
+    }
+
      /*
       * The later open call will need any decryption secrets, and
       * bdrv_create() will purge "opts", so extract them now before
@@ -2533,9 +2594,7 @@ static int img_convert(int argc, char **argv)
      if (!skip_create) {
          open_opts = qdict_new();
          qemu_opt_foreach(opts, img_add_key_secrets, open_opts, &error_abort);
-    }

-    if (!skip_create) {
          /* Create the new image */
          ret = bdrv_create(drv, out_filename, opts, &local_err);
          if (ret < 0) {
@@ -2573,6 +2632,13 @@ static int img_convert(int argc, char **argv)
      }
      out_bs = blk_bs(s.target);

+    if (nbitmaps > 0 && !bdrv_supports_persistent_dirty_bitmap(out_bs)) {

We will not fail, if target doesn't support bitmaps, source supports them but 
has no bitmaps? Doesn't seem to be a problem, but a bit less strict than you 
write in commit message.

So, maybe, s/nbitmaps > 0/bitmaps/

+        error_report("Format driver '%s' does not support bitmaps",
+                     out_fmt);

Hmm seems, out_fmt may be NULL at this point, consider the path:
const char *out_fmt = NULL
...
[no -O option]
--target-image-opts, so out_fmt doesn't default to "raw" but remains NULL
...

So, with s/out_fmt/out_bs->drv->format_name/ (and with or without s/nbitmaps > 
0/bitmaps/):


Reviewed-by: Vladimir Sementsov-Ogievskiy <address@hidden>


--
Best regards,
Vladimir



reply via email to

[Prev in Thread] Current Thread [Next in Thread]