summaryrefslogtreecommitdiffstats
path: root/qemu-img.c
diff options
context:
space:
mode:
authorEric Blake2021-07-09 17:39:50 +0200
committerEric Blake2021-07-21 21:14:41 +0200
commit74a4320f30632fa539507861b3835698282e462e (patch)
tree726ed608ae7eb0881adc5ab0cae3d51e38ac53ec /qemu-img.c
parentiotests: Improve and rename test 291 to qemu-img-bitmap (diff)
downloadqemu-74a4320f30632fa539507861b3835698282e462e.tar.gz
qemu-74a4320f30632fa539507861b3835698282e462e.tar.xz
qemu-74a4320f30632fa539507861b3835698282e462e.zip
qemu-img: Fail fast on convert --bitmaps with inconsistent bitmap
Waiting until the end of the convert operation (a potentially time-consuming task) to finally detect that we can't copy a bitmap is bad, comparing to failing fast up front. Furthermore, this prevents us from leaving a file behind with a bitmap that is not marked as inconsistent even though it does not have sane contents. This fixes the problems exposed in the previous patch to the iotest: it adds a fast failure up front, and even if we don't fail early, it ensures that any bitmap we add but do not properly populate is removed again rather than left behind incomplete. Signed-off-by: Eric Blake <eblake@redhat.com> Message-Id: <20210709153951.2801666-3-eblake@redhat.com> [eblake: add a hint to the warning message, simplify name computation] Reviewed-by: Nir Soffer <nsoffer@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Diffstat (limited to 'qemu-img.c')
-rw-r--r--qemu-img.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/qemu-img.c b/qemu-img.c
index 797742a443..c5496e82e0 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -2101,6 +2101,29 @@ static int convert_do_copy(ImgConvertState *s)
return s->ret;
}
+/* Check that bitmaps can be copied, or output an error */
+static int convert_check_bitmaps(BlockDriverState *src)
+{
+ BdrvDirtyBitmap *bm;
+
+ if (!bdrv_supports_persistent_dirty_bitmap(src)) {
+ error_report("Source lacks bitmap support");
+ return -1;
+ }
+ FOR_EACH_DIRTY_BITMAP(src, bm) {
+ if (!bdrv_dirty_bitmap_get_persistence(bm)) {
+ continue;
+ }
+ if (bdrv_dirty_bitmap_inconsistent(bm)) {
+ error_report("Cannot copy inconsistent bitmap '%s'",
+ bdrv_dirty_bitmap_name(bm));
+ error_printf("Try 'qemu-img bitmap --remove' to delete it\n");
+ return -1;
+ }
+ }
+ return 0;
+}
+
static int convert_copy_bitmaps(BlockDriverState *src, BlockDriverState *dst)
{
BdrvDirtyBitmap *bm;
@@ -2127,6 +2150,7 @@ static int convert_copy_bitmaps(BlockDriverState *src, BlockDriverState *dst)
&err);
if (err) {
error_reportf_err(err, "Failed to populate bitmap %s: ", name);
+ qmp_block_dirty_bitmap_remove(dst->node_name, name, NULL);
return -1;
}
}
@@ -2554,9 +2578,8 @@ static int img_convert(int argc, char **argv)
ret = -1;
goto out;
}
- if (!bdrv_supports_persistent_dirty_bitmap(blk_bs(s.src[0]))) {
- error_report("Source lacks bitmap support");
- ret = -1;
+ ret = convert_check_bitmaps(blk_bs(s.src[0]));
+ if (ret < 0) {
goto out;
}
}