77c23f
From af4d66e07c86d7593f7d18ae4b6a2151123b529b Mon Sep 17 00:00:00 2001
77c23f
From: Eric Blake <eblake@redhat.com>
77c23f
Date: Tue, 2 Jun 2020 02:34:17 +0100
77c23f
Subject: [PATCH 12/26] qcow2: Expose bitmaps' size during measure
77c23f
77c23f
RH-Author: Eric Blake <eblake@redhat.com>
77c23f
Message-id: <20200602023420.2133649-10-eblake@redhat.com>
77c23f
Patchwork-id: 97072
77c23f
O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 09/12] qcow2: Expose bitmaps' size during measure
77c23f
Bugzilla: 1779893 1779904
77c23f
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
77c23f
RH-Acked-by: Max Reitz <mreitz@redhat.com>
77c23f
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
77c23f
77c23f
It's useful to know how much space can be occupied by qcow2 persistent
77c23f
bitmaps, even though such metadata is unrelated to the guest-visible
77c23f
data.  Report this value as an additional QMP field, present when
77c23f
measuring an existing image and output format that both support
77c23f
bitmaps.  Update iotest 178 and 190 to updated output, as well as new
77c23f
coverage in 190 demonstrating non-zero values made possible with the
77c23f
recently-added qemu-img bitmap command (see 3b51ab4b).
77c23f
77c23f
The new 'bitmaps size:' field is displayed automatically as part of
77c23f
'qemu-img measure' any time it is present in QMP (that is, any time
77c23f
both the source image being measured and destination format support
77c23f
bitmaps, even if the measurement is 0 because there are no bitmaps
77c23f
present).  If the field is absent, it means that no bitmaps can be
77c23f
copied (source, destination, or both lack bitmaps, including when
77c23f
measuring based on size rather than on a source image).  This behavior
77c23f
is compatible with an upcoming patch adding 'qemu-img convert
77c23f
--bitmaps': that command will fail in the same situations where this
77c23f
patch omits the field.
77c23f
77c23f
The addition of a new field demonstrates why we should always
77c23f
zero-initialize qapi C structs; while the qcow2 driver still fully
77c23f
populates all fields, the raw and crypto drivers had to be tweaked to
77c23f
avoid uninitialized data.
77c23f
77c23f
Consideration was also given towards having a 'qemu-img measure
77c23f
--bitmaps' which errors out when bitmaps are not possible, and
77c23f
otherwise sums the bitmaps into the existing allocation totals rather
77c23f
than displaying as a separate field, as a potential convenience
77c23f
factor.  But this was ultimately decided to be more complexity than
77c23f
necessary when the QMP interface was sufficient enough with bitmaps
77c23f
remaining a separate field.
77c23f
77c23f
See also: https://bugzilla.redhat.com/1779904
77c23f
77c23f
Reported-by: Nir Soffer <nsoffer@redhat.com>
77c23f
Signed-off-by: Eric Blake <eblake@redhat.com>
77c23f
Message-Id: <20200521192137.1120211-3-eblake@redhat.com>
77c23f
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
77c23f
(cherry picked from commit 5d72c68b49769c927e90b78af6d90f6a384b26ac)
77c23f
77c23f
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
77c23f
77c23f
Conflicts:
77c23f
	block/crypto.c - commit a9da6e49 not present (no measure support)
77c23f
	docs/tools/qemu-img.rst - changes in qemu-img.texi instead
77c23f
Signed-off-by: Eric Blake <eblake@redhat.com>
77c23f
77c23f
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
77c23f
---
77c23f
 block/qcow2-bitmap.c             | 36 ++++++++++++++++++++++++++++++
77c23f
 block/qcow2.c                    | 14 +++++++++---
77c23f
 block/qcow2.h                    |  2 ++
77c23f
 block/raw-format.c               |  2 +-
77c23f
 qapi/block-core.json             | 16 +++++++++-----
77c23f
 qemu-img.c                       |  3 +++
77c23f
 qemu-img.texi                    |  7 ++++++
77c23f
 tests/qemu-iotests/178.out.qcow2 | 16 ++++++++++++++
77c23f
 tests/qemu-iotests/190           | 47 ++++++++++++++++++++++++++++++++++++++--
77c23f
 tests/qemu-iotests/190.out       | 27 ++++++++++++++++++++++-
77c23f
 10 files changed, 158 insertions(+), 12 deletions(-)
77c23f
77c23f
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
77c23f
index cbac905..10d1297 100644
77c23f
--- a/block/qcow2-bitmap.c
77c23f
+++ b/block/qcow2-bitmap.c
77c23f
@@ -1766,3 +1766,39 @@ bool qcow2_supports_persistent_dirty_bitmap(BlockDriverState *bs)
77c23f
 
77c23f
     return s->qcow_version >= 3;
77c23f
 }
77c23f
+
77c23f
+/*
77c23f
+ * Compute the space required for bitmaps in @bs.
77c23f
+ *
77c23f
+ * The computation is based as if copying to a new image with the
77c23f
+ * given @cluster_size, which may differ from the cluster size in @bs.
77c23f
+ */
77c23f
+uint64_t qcow2_get_persistent_dirty_bitmap_size(BlockDriverState *bs,
77c23f
+                                                uint32_t cluster_size)
77c23f
+{
77c23f
+    uint64_t bitmaps_size = 0;
77c23f
+    BdrvDirtyBitmap *bm;
77c23f
+    size_t bitmap_dir_size = 0;
77c23f
+
77c23f
+    FOR_EACH_DIRTY_BITMAP(bs, bm) {
77c23f
+        if (bdrv_dirty_bitmap_get_persistence(bm)) {
77c23f
+            const char *name = bdrv_dirty_bitmap_name(bm);
77c23f
+            uint32_t granularity = bdrv_dirty_bitmap_granularity(bm);
77c23f
+            uint64_t bmbytes =
77c23f
+                get_bitmap_bytes_needed(bdrv_dirty_bitmap_size(bm),
77c23f
+                                        granularity);
77c23f
+            uint64_t bmclusters = DIV_ROUND_UP(bmbytes, cluster_size);
77c23f
+
77c23f
+            /* Assume the entire bitmap is allocated */
77c23f
+            bitmaps_size += bmclusters * cluster_size;
77c23f
+            /* Also reserve space for the bitmap table entries */
77c23f
+            bitmaps_size += ROUND_UP(bmclusters * sizeof(uint64_t),
77c23f
+                                     cluster_size);
77c23f
+            /* And space for contribution to bitmap directory size */
77c23f
+            bitmap_dir_size += calc_dir_entry_size(strlen(name), 0);
77c23f
+        }
77c23f
+    }
77c23f
+    bitmaps_size += ROUND_UP(bitmap_dir_size, cluster_size);
77c23f
+
77c23f
+    return bitmaps_size;
77c23f
+}
77c23f
diff --git a/block/qcow2.c b/block/qcow2.c
77c23f
index 36b0f7d..dbd870a 100644
77c23f
--- a/block/qcow2.c
77c23f
+++ b/block/qcow2.c
77c23f
@@ -4751,16 +4751,24 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
77c23f
         required = virtual_size;
77c23f
     }
77c23f
 
77c23f
-    info = g_new(BlockMeasureInfo, 1);
77c23f
+    info = g_new0(BlockMeasureInfo, 1);
77c23f
     info->fully_allocated =
77c23f
         qcow2_calc_prealloc_size(virtual_size, cluster_size,
77c23f
                                  ctz32(refcount_bits)) + luks_payload_size;
77c23f
 
77c23f
-    /* Remove data clusters that are not required.  This overestimates the
77c23f
+    /*
77c23f
+     * Remove data clusters that are not required.  This overestimates the
77c23f
      * required size because metadata needed for the fully allocated file is
77c23f
-     * still counted.
77c23f
+     * still counted.  Show bitmaps only if both source and destination
77c23f
+     * would support them.
77c23f
      */
77c23f
     info->required = info->fully_allocated - virtual_size + required;
77c23f
+    info->has_bitmaps = version >= 3 && in_bs &&
77c23f
+        bdrv_supports_persistent_dirty_bitmap(in_bs);
77c23f
+    if (info->has_bitmaps) {
77c23f
+        info->bitmaps = qcow2_get_persistent_dirty_bitmap_size(in_bs,
77c23f
+                                                               cluster_size);
77c23f
+    }
77c23f
     return info;
77c23f
 
77c23f
 err:
77c23f
diff --git a/block/qcow2.h b/block/qcow2.h
77c23f
index ceb1ceb..3297e6b 100644
77c23f
--- a/block/qcow2.h
77c23f
+++ b/block/qcow2.h
77c23f
@@ -768,6 +768,8 @@ int qcow2_co_remove_persistent_dirty_bitmap(BlockDriverState *bs,
77c23f
                                             const char *name,
77c23f
                                             Error **errp);
77c23f
 bool qcow2_supports_persistent_dirty_bitmap(BlockDriverState *bs);
77c23f
+uint64_t qcow2_get_persistent_dirty_bitmap_size(BlockDriverState *bs,
77c23f
+                                                uint32_t cluster_size);
77c23f
 
77c23f
 ssize_t coroutine_fn
77c23f
 qcow2_co_compress(BlockDriverState *bs, void *dest, size_t dest_size,
77c23f
diff --git a/block/raw-format.c b/block/raw-format.c
77c23f
index 93b25e1..4bb54f4 100644
77c23f
--- a/block/raw-format.c
77c23f
+++ b/block/raw-format.c
77c23f
@@ -346,7 +346,7 @@ static BlockMeasureInfo *raw_measure(QemuOpts *opts, BlockDriverState *in_bs,
77c23f
                             BDRV_SECTOR_SIZE);
77c23f
     }
77c23f
 
77c23f
-    info = g_new(BlockMeasureInfo, 1);
77c23f
+    info = g_new0(BlockMeasureInfo, 1);
77c23f
     info->required = required;
77c23f
 
77c23f
     /* Unallocated sectors count towards the file size in raw images */
77c23f
diff --git a/qapi/block-core.json b/qapi/block-core.json
77c23f
index a64ad81..2893209 100644
77c23f
--- a/qapi/block-core.json
77c23f
+++ b/qapi/block-core.json
77c23f
@@ -689,18 +689,24 @@
77c23f
 # efficiently so file size may be smaller than virtual disk size.
77c23f
 #
77c23f
 # The values are upper bounds that are guaranteed to fit the new image file.
77c23f
-# Subsequent modification, such as internal snapshot or bitmap creation, may
77c23f
-# require additional space and is not covered here.
77c23f
+# Subsequent modification, such as internal snapshot or further bitmap
77c23f
+# creation, may require additional space and is not covered here.
77c23f
 #
77c23f
-# @required: Size required for a new image file, in bytes.
77c23f
+# @required: Size required for a new image file, in bytes, when copying just
77c23f
+#            allocated guest-visible contents.
77c23f
 #
77c23f
 # @fully-allocated: Image file size, in bytes, once data has been written
77c23f
-#                   to all sectors.
77c23f
+#                   to all sectors, when copying just guest-visible contents.
77c23f
+#
77c23f
+# @bitmaps: Additional size required if all the top-level bitmap metadata
77c23f
+#           in the source image were to be copied to the destination,
77c23f
+#           present only when source and destination both support
77c23f
+#           persistent bitmaps. (since 5.1)
77c23f
 #
77c23f
 # Since: 2.10
77c23f
 ##
77c23f
 { 'struct': 'BlockMeasureInfo',
77c23f
-  'data': {'required': 'int', 'fully-allocated': 'int'} }
77c23f
+  'data': {'required': 'int', 'fully-allocated': 'int', '*bitmaps': 'int'} }
77c23f
 
77c23f
 ##
77c23f
 # @query-block:
77c23f
diff --git a/qemu-img.c b/qemu-img.c
77c23f
index 11a4537..b57856e 100644
77c23f
--- a/qemu-img.c
77c23f
+++ b/qemu-img.c
77c23f
@@ -5212,6 +5212,9 @@ static int img_measure(int argc, char **argv)
77c23f
     if (output_format == OFORMAT_HUMAN) {
77c23f
         printf("required size: %" PRIu64 "\n", info->required);
77c23f
         printf("fully allocated size: %" PRIu64 "\n", info->fully_allocated);
77c23f
+        if (info->has_bitmaps) {
77c23f
+            printf("bitmaps size: %" PRIu64 "\n", info->bitmaps);
77c23f
+        }
77c23f
     } else {
77c23f
         dump_json_block_measure_info(info);
77c23f
     }
77c23f
diff --git a/qemu-img.texi b/qemu-img.texi
77c23f
index abf2771..3670b96 100644
77c23f
--- a/qemu-img.texi
77c23f
+++ b/qemu-img.texi
77c23f
@@ -576,6 +576,7 @@ The following fields are reported:
77c23f
 @example
77c23f
 required size: 524288
77c23f
 fully allocated size: 1074069504
77c23f
+bitmaps size: 0
77c23f
 @end example
77c23f
 
77c23f
 The @code{required size} is the file size of the new image.  It may be smaller
77c23f
@@ -586,6 +587,12 @@ been written to all sectors.  This is the maximum size that the image file can
77c23f
 occupy with the exception of internal snapshots, dirty bitmaps, vmstate data,
77c23f
 and other advanced image format features.
77c23f
 
77c23f
+The @code{bitmaps size} is the additional size required in order to
77c23f
+copy bitmaps from a source image in addition to the guest-visible
77c23f
+data; the line is omitted if either source or destination lacks
77c23f
+bitmap support, or 0 if bitmaps are supported but there is nothing to
77c23f
+copy.
77c23f
+
77c23f
 @item snapshot [--object @var{objectdef}] [--image-opts] [-U] [-q] [-l | -a @var{snapshot} | -c @var{snapshot} | -d @var{snapshot}] @var{filename}
77c23f
 
77c23f
 List, apply, create or delete snapshots in image @var{filename}.
77c23f
diff --git a/tests/qemu-iotests/178.out.qcow2 b/tests/qemu-iotests/178.out.qcow2
77c23f
index 345eab3..b9ed41b 100644
77c23f
--- a/tests/qemu-iotests/178.out.qcow2
77c23f
+++ b/tests/qemu-iotests/178.out.qcow2
77c23f
@@ -37,6 +37,7 @@ qemu-img: The image size is too large (try using a larger cluster size)
77c23f
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=0
77c23f
 required size: 196608
77c23f
 fully allocated size: 196608
77c23f
+bitmaps size: 0
77c23f
 
77c23f
 converted image file size in bytes: 196608
77c23f
 
77c23f
@@ -45,6 +46,7 @@ converted image file size in bytes: 196608
77c23f
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
77c23f
 required size: 393216
77c23f
 fully allocated size: 1074135040
77c23f
+bitmaps size: 0
77c23f
 wrote 512/512 bytes at offset 512
77c23f
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
77c23f
 wrote 65536/65536 bytes at offset 65536
77c23f
@@ -53,6 +55,7 @@ wrote 64512/64512 bytes at offset 134217728
77c23f
 63 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
77c23f
 required size: 589824
77c23f
 fully allocated size: 1074135040
77c23f
+bitmaps size: 0
77c23f
 
77c23f
 converted image file size in bytes: 524288
77c23f
 
77c23f
@@ -60,6 +63,7 @@ converted image file size in bytes: 524288
77c23f
 
77c23f
 required size: 524288
77c23f
 fully allocated size: 1074135040
77c23f
+bitmaps size: 0
77c23f
 
77c23f
 converted image file size in bytes: 458752
77c23f
 
77c23f
@@ -67,16 +71,19 @@ converted image file size in bytes: 458752
77c23f
 
77c23f
 required size: 1074135040
77c23f
 fully allocated size: 1074135040
77c23f
+bitmaps size: 0
77c23f
 
77c23f
 == qcow2 input image and LUKS encryption ==
77c23f
 
77c23f
 required size: 2686976
77c23f
 fully allocated size: 1076232192
77c23f
+bitmaps size: 0
77c23f
 
77c23f
 == qcow2 input image and preallocation (human) ==
77c23f
 
77c23f
 required size: 1074135040
77c23f
 fully allocated size: 1074135040
77c23f
+bitmaps size: 0
77c23f
 
77c23f
 converted image file size in bytes: 1074135040
77c23f
 
77c23f
@@ -87,6 +94,7 @@ wrote 8388608/8388608 bytes at offset 0
77c23f
 8 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
77c23f
 required size: 8716288
77c23f
 fully allocated size: 8716288
77c23f
+bitmaps size: 0
77c23f
 
77c23f
 converted image file size in bytes: 8716288
77c23f
 
77c23f
@@ -173,6 +181,7 @@ qemu-img: The image size is too large (try using a larger cluster size)
77c23f
 
77c23f
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=0
77c23f
 {
77c23f
+    "bitmaps": 0,
77c23f
     "required": 196608,
77c23f
     "fully-allocated": 196608
77c23f
 }
77c23f
@@ -183,6 +192,7 @@ converted image file size in bytes: 196608
77c23f
 
77c23f
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
77c23f
 {
77c23f
+    "bitmaps": 0,
77c23f
     "required": 393216,
77c23f
     "fully-allocated": 1074135040
77c23f
 }
77c23f
@@ -193,6 +203,7 @@ wrote 65536/65536 bytes at offset 65536
77c23f
 wrote 64512/64512 bytes at offset 134217728
77c23f
 63 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
77c23f
 {
77c23f
+    "bitmaps": 0,
77c23f
     "required": 589824,
77c23f
     "fully-allocated": 1074135040
77c23f
 }
77c23f
@@ -202,6 +213,7 @@ converted image file size in bytes: 524288
77c23f
 == qcow2 input image with internal snapshot (json) ==
77c23f
 
77c23f
 {
77c23f
+    "bitmaps": 0,
77c23f
     "required": 524288,
77c23f
     "fully-allocated": 1074135040
77c23f
 }
77c23f
@@ -211,6 +223,7 @@ converted image file size in bytes: 458752
77c23f
 == qcow2 input image and a backing file (json) ==
77c23f
 
77c23f
 {
77c23f
+    "bitmaps": 0,
77c23f
     "required": 1074135040,
77c23f
     "fully-allocated": 1074135040
77c23f
 }
77c23f
@@ -218,6 +231,7 @@ converted image file size in bytes: 458752
77c23f
 == qcow2 input image and LUKS encryption ==
77c23f
 
77c23f
 {
77c23f
+    "bitmaps": 0,
77c23f
     "required": 2686976,
77c23f
     "fully-allocated": 1076232192
77c23f
 }
77c23f
@@ -225,6 +239,7 @@ converted image file size in bytes: 458752
77c23f
 == qcow2 input image and preallocation (json) ==
77c23f
 
77c23f
 {
77c23f
+    "bitmaps": 0,
77c23f
     "required": 1074135040,
77c23f
     "fully-allocated": 1074135040
77c23f
 }
77c23f
@@ -237,6 +252,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=8388608
77c23f
 wrote 8388608/8388608 bytes at offset 0
77c23f
 8 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
77c23f
 {
77c23f
+    "bitmaps": 0,
77c23f
     "required": 8716288,
77c23f
     "fully-allocated": 8716288
77c23f
 }
77c23f
diff --git a/tests/qemu-iotests/190 b/tests/qemu-iotests/190
77c23f
index eb766ad..5084ccd 100755
77c23f
--- a/tests/qemu-iotests/190
77c23f
+++ b/tests/qemu-iotests/190
77c23f
@@ -2,7 +2,7 @@
77c23f
 #
77c23f
 # qemu-img measure sub-command tests on huge qcow2 files
77c23f
 #
77c23f
-# Copyright (C) 2017 Red Hat, Inc.
77c23f
+# Copyright (C) 2017-2020 Red Hat, Inc.
77c23f
 #
77c23f
 # This program is free software; you can redistribute it and/or modify
77c23f
 # it under the terms of the GNU General Public License as published by
77c23f
@@ -42,7 +42,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
77c23f
 _supported_fmt qcow2
77c23f
 _supported_proto file
77c23f
 
77c23f
-echo "== Huge file =="
77c23f
+echo "== Huge file without bitmaps =="
77c23f
 echo
77c23f
 
77c23f
 IMGOPTS='cluster_size=2M' _make_test_img 2T
77c23f
@@ -51,6 +51,49 @@ $QEMU_IMG measure -O raw -f qcow2 "$TEST_IMG"
77c23f
 $QEMU_IMG measure -O qcow2 -o cluster_size=64k -f qcow2 "$TEST_IMG"
77c23f
 $QEMU_IMG measure -O qcow2 -o cluster_size=2M -f qcow2 "$TEST_IMG"
77c23f
 
77c23f
+echo
77c23f
+echo "== Huge file with bitmaps =="
77c23f
+echo
77c23f
+
77c23f
+$QEMU_IMG bitmap --add --granularity 512 -f qcow2 "$TEST_IMG" b1
77c23f
+$QEMU_IMG bitmap --add -g 2M -f qcow2 "$TEST_IMG" b2
77c23f
+
77c23f
+# No bitmap without a source
77c23f
+$QEMU_IMG measure -O qcow2 --size 10M
77c23f
+# No bitmap output, since raw does not support it
77c23f
+$QEMU_IMG measure -O raw -f qcow2 "$TEST_IMG"
77c23f
+# No bitmap output, since no bitmaps on raw source. Munge required size, as
77c23f
+# some filesystems store the qcow2 file with less sparseness than others
77c23f
+$QEMU_IMG measure -O qcow2 -f raw "$TEST_IMG" |
77c23f
+    sed '/^required size:/ s/[0-9][0-9]*/SIZE/'
77c23f
+# No bitmap output, since v2 does not support it
77c23f
+$QEMU_IMG measure -O qcow2 -o compat=0.10 -f qcow2 "$TEST_IMG"
77c23f
+
77c23f
+# Compute expected output: bitmap clusters + bitmap tables + bitmaps directory
77c23f
+echo
77c23f
+val2T=$((2*1024*1024*1024*1024))
77c23f
+cluster=$((64*1024))
77c23f
+b1clusters=$(( (val2T/512/8 + cluster - 1) / cluster ))
77c23f
+b2clusters=$(( (val2T/2/1024/1024/8 + cluster - 1) / cluster ))
77c23f
+echo expected bitmap $((b1clusters * cluster +
77c23f
+                        (b1clusters * 8 + cluster - 1) / cluster * cluster +
77c23f
+                        b2clusters * cluster +
77c23f
+                        (b2clusters * 8 + cluster - 1) / cluster * cluster +
77c23f
+                        cluster))
77c23f
+$QEMU_IMG measure -O qcow2 -o cluster_size=64k -f qcow2 "$TEST_IMG"
77c23f
+
77c23f
+# Compute expected output: bitmap clusters + bitmap tables + bitmaps directory
77c23f
+echo
77c23f
+cluster=$((2*1024*1024))
77c23f
+b1clusters=$(( (val2T/512/8 + cluster - 1) / cluster ))
77c23f
+b2clusters=$(( (val2T/2/1024/1024/8 + cluster - 1) / cluster ))
77c23f
+echo expected bitmap $((b1clusters * cluster +
77c23f
+                        (b1clusters * 8 + cluster - 1) / cluster * cluster +
77c23f
+                        b2clusters * cluster +
77c23f
+                        (b2clusters * 8 + cluster - 1) / cluster * cluster +
77c23f
+                        cluster))
77c23f
+$QEMU_IMG measure --output=json -O qcow2 -o cluster_size=2M -f qcow2 "$TEST_IMG"
77c23f
+
77c23f
 # success, all done
77c23f
 echo "*** done"
77c23f
 rm -f $seq.full
77c23f
diff --git a/tests/qemu-iotests/190.out b/tests/qemu-iotests/190.out
77c23f
index d001942..ed9d821 100644
77c23f
--- a/tests/qemu-iotests/190.out
77c23f
+++ b/tests/qemu-iotests/190.out
77c23f
@@ -1,11 +1,36 @@
77c23f
 QA output created by 190
77c23f
-== Huge file ==
77c23f
+== Huge file without bitmaps ==
77c23f
 
77c23f
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2199023255552
77c23f
 required size: 2199023255552
77c23f
 fully allocated size: 2199023255552
77c23f
 required size: 335806464
77c23f
 fully allocated size: 2199359062016
77c23f
+bitmaps size: 0
77c23f
 required size: 18874368
77c23f
 fully allocated size: 2199042129920
77c23f
+bitmaps size: 0
77c23f
+
77c23f
+== Huge file with bitmaps ==
77c23f
+
77c23f
+required size: 327680
77c23f
+fully allocated size: 10813440
77c23f
+required size: 2199023255552
77c23f
+fully allocated size: 2199023255552
77c23f
+required size: SIZE
77c23f
+fully allocated size: 17170432
77c23f
+required size: 335806464
77c23f
+fully allocated size: 2199359062016
77c23f
+
77c23f
+expected bitmap 537198592
77c23f
+required size: 335806464
77c23f
+fully allocated size: 2199359062016
77c23f
+bitmaps size: 537198592
77c23f
+
77c23f
+expected bitmap 545259520
77c23f
+{
77c23f
+    "bitmaps": 545259520,
77c23f
+    "required": 18874368,
77c23f
+    "fully-allocated": 2199042129920
77c23f
+}
77c23f
 *** done
77c23f
-- 
77c23f
1.8.3.1
77c23f