* [PATCH 0/2] Let 'qemu-img convert --bitmaps' skip inconsistent bitmaps @ 2021-07-08 1:29 Eric Blake 2021-07-08 1:30 ` [PATCH 1/2] iotests: Improve and rename test 291 to qemu-img-bitmap Eric Blake ` (2 more replies) 0 siblings, 3 replies; 9+ messages in thread From: Eric Blake @ 2021-07-08 1:29 UTC (permalink / raw) To: qemu-devel; +Cc: nsoffer, vsementsov, qemu-block This is mostly a convenience factor as one could already use 'qemu-img info' to learn which bitmaps are broken and then 'qemu-img bitmap --remove' to nuke them before calling 'qemu-img convert --bitmaps', but it does have the advantage that the copied file is usable without extra efforts and the broken bitmap is not deleted from the source file. Eric Blake (2): iotests: Improve and rename test 291 to qemu-img-bitmap qemu-img: Add --skip-broken for 'convert --bitmaps' docs/tools/qemu-img.rst | 8 +++- block/dirty-bitmap.c | 2 +- qemu-img.c | 20 +++++++- .../{291 => tests/qemu-img-bitmaps} | 17 ++++++- .../{291.out => tests/qemu-img-bitmaps.out} | 46 ++++++++++++++++++- 5 files changed, 87 insertions(+), 6 deletions(-) rename tests/qemu-iotests/{291 => tests/qemu-img-bitmaps} (88%) rename tests/qemu-iotests/{291.out => tests/qemu-img-bitmaps.out} (76%) -- 2.31.1 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/2] iotests: Improve and rename test 291 to qemu-img-bitmap 2021-07-08 1:29 [PATCH 0/2] Let 'qemu-img convert --bitmaps' skip inconsistent bitmaps Eric Blake @ 2021-07-08 1:30 ` Eric Blake 2021-07-09 6:33 ` Vladimir Sementsov-Ogievskiy 2021-07-08 1:30 ` [PATCH 2/2] qemu-img: Add --skip-broken for 'convert --bitmaps' Eric Blake 2021-07-09 9:50 ` [PATCH 0/2] Let 'qemu-img convert --bitmaps' skip inconsistent bitmaps Vladimir Sementsov-Ogievskiy 2 siblings, 1 reply; 9+ messages in thread From: Eric Blake @ 2021-07-08 1:30 UTC (permalink / raw) To: qemu-devel Cc: Kevin Wolf, vsementsov, qemu-block, Max Reitz, nsoffer, John Snow Enhance the test to demonstrate behavior of qemu-img with a qcow2 image containing an inconsistent bitmap, and rename it now that we support useful iotest names. While at it, fix a missing newline in the error message thus exposed. Signed-off-by: Eric Blake <eblake@redhat.com> --- block/dirty-bitmap.c | 2 +- .../{291 => tests/qemu-img-bitmaps} | 13 +++++++- .../{291.out => tests/qemu-img-bitmaps.out} | 32 ++++++++++++++++++- 3 files changed, 44 insertions(+), 3 deletions(-) rename tests/qemu-iotests/{291 => tests/qemu-img-bitmaps} (92%) rename tests/qemu-iotests/{291.out => tests/qemu-img-bitmaps.out} (82%) diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c index 68d295d6e3ed..0ef46163e3ea 100644 --- a/block/dirty-bitmap.c +++ b/block/dirty-bitmap.c @@ -193,7 +193,7 @@ int bdrv_dirty_bitmap_check(const BdrvDirtyBitmap *bitmap, uint32_t flags, error_setg(errp, "Bitmap '%s' is inconsistent and cannot be used", bitmap->name); error_append_hint(errp, "Try block-dirty-bitmap-remove to delete" - " this bitmap from disk"); + " this bitmap from disk\n"); return -1; } diff --git a/tests/qemu-iotests/291 b/tests/qemu-iotests/tests/qemu-img-bitmaps similarity index 92% rename from tests/qemu-iotests/291 rename to tests/qemu-iotests/tests/qemu-img-bitmaps index 20efb080a6c0..76cd9e31e850 100755 --- a/tests/qemu-iotests/291 +++ b/tests/qemu-iotests/tests/qemu-img-bitmaps @@ -3,7 +3,7 @@ # # Test qemu-img bitmap handling # -# Copyright (C) 2018-2020 Red Hat, Inc. +# Copyright (C) 2018-2021 Red Hat, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -32,6 +32,7 @@ _cleanup() trap "_cleanup; exit \$status" 0 1 2 3 15 # get standard environment, filters and checks +cd .. . ./common.rc . ./common.filter . ./common.nbd @@ -129,6 +130,16 @@ $QEMU_IMG map --output=json --image-opts \ nbd_server_stop +echo +echo "=== Check handling of inconsistent bitmap ===" +echo + +$QEMU_IO -c abort "$TEST_IMG" 2>/dev/null +$QEMU_IMG bitmap --add "$TEST_IMG" b4 +$QEMU_IMG bitmap --remove "$TEST_IMG" b1 +_img_info --format-specific | _filter_irrelevant_img_info +$QEMU_IMG convert --bitmaps -O qcow2 "$TEST_IMG" "$TEST_IMG.copy" + # success, all done echo '*** done' rm -f $seq.full diff --git a/tests/qemu-iotests/291.out b/tests/qemu-iotests/tests/qemu-img-bitmaps.out similarity index 82% rename from tests/qemu-iotests/291.out rename to tests/qemu-iotests/tests/qemu-img-bitmaps.out index 018d6b103f87..17b34eaed30f 100644 --- a/tests/qemu-iotests/291.out +++ b/tests/qemu-iotests/tests/qemu-img-bitmaps.out @@ -1,4 +1,4 @@ -QA output created by 291 +QA output created by qemu-img-bitmaps === Initial image setup === @@ -115,4 +115,34 @@ Format specific information: [{ "start": 0, "length": 2097152, "depth": 0, "present": true, "zero": false, "data": true, "offset": OFFSET}, { "start": 2097152, "length": 1048576, "depth": 0, "present": false, "zero": false, "data": false}, { "start": 3145728, "length": 7340032, "depth": 0, "present": true, "zero": false, "data": true, "offset": OFFSET}] + +=== Check handling of inconsistent bitmap === + +image: TEST_DIR/t.IMGFMT +file format: IMGFMT +virtual size: 10 MiB (10485760 bytes) +cluster_size: 65536 +backing file: TEST_DIR/t.IMGFMT.base +backing file format: IMGFMT +Format specific information: + bitmaps: + [0]: + flags: + [0]: in-use + [1]: auto + name: b2 + granularity: 65536 + [1]: + flags: + [0]: in-use + name: b0 + granularity: 65536 + [2]: + flags: + [0]: auto + name: b4 + granularity: 65536 + corrupt: false +qemu-img: Failed to populate bitmap b0: Bitmap 'b0' is inconsistent and cannot be used +Try block-dirty-bitmap-remove to delete this bitmap from disk *** done -- 2.31.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] iotests: Improve and rename test 291 to qemu-img-bitmap 2021-07-08 1:30 ` [PATCH 1/2] iotests: Improve and rename test 291 to qemu-img-bitmap Eric Blake @ 2021-07-09 6:33 ` Vladimir Sementsov-Ogievskiy 2021-07-09 13:16 ` Eric Blake 0 siblings, 1 reply; 9+ messages in thread From: Vladimir Sementsov-Ogievskiy @ 2021-07-09 6:33 UTC (permalink / raw) To: Eric Blake, qemu-devel Cc: nsoffer, qemu-block, John Snow, Kevin Wolf, Max Reitz 08.07.2021 04:30, Eric Blake wrote: > Enhance the test to demonstrate behavior of qemu-img with a qcow2 > image containing an inconsistent bitmap, and rename it now that we > support useful iotest names. > > While at it, fix a missing newline in the error message thus exposed. > > Signed-off-by: Eric Blake <eblake@redhat.com> > --- > block/dirty-bitmap.c | 2 +- > .../{291 => tests/qemu-img-bitmaps} | 13 +++++++- > .../{291.out => tests/qemu-img-bitmaps.out} | 32 ++++++++++++++++++- > 3 files changed, 44 insertions(+), 3 deletions(-) > rename tests/qemu-iotests/{291 => tests/qemu-img-bitmaps} (92%) > rename tests/qemu-iotests/{291.out => tests/qemu-img-bitmaps.out} (82%) > > diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c > index 68d295d6e3ed..0ef46163e3ea 100644 > --- a/block/dirty-bitmap.c > +++ b/block/dirty-bitmap.c > @@ -193,7 +193,7 @@ int bdrv_dirty_bitmap_check(const BdrvDirtyBitmap *bitmap, uint32_t flags, > error_setg(errp, "Bitmap '%s' is inconsistent and cannot be used", > bitmap->name); > error_append_hint(errp, "Try block-dirty-bitmap-remove to delete" > - " this bitmap from disk"); > + " this bitmap from disk\n"); > return -1; > } > > diff --git a/tests/qemu-iotests/291 b/tests/qemu-iotests/tests/qemu-img-bitmaps > similarity index 92% > rename from tests/qemu-iotests/291 > rename to tests/qemu-iotests/tests/qemu-img-bitmaps > index 20efb080a6c0..76cd9e31e850 100755 > --- a/tests/qemu-iotests/291 > +++ b/tests/qemu-iotests/tests/qemu-img-bitmaps > @@ -3,7 +3,7 @@ > # > # Test qemu-img bitmap handling > # > -# Copyright (C) 2018-2020 Red Hat, Inc. > +# Copyright (C) 2018-2021 Red Hat, Inc. > # > # This program is free software; you can redistribute it and/or modify > # it under the terms of the GNU General Public License as published by > @@ -32,6 +32,7 @@ _cleanup() > trap "_cleanup; exit \$status" 0 1 2 3 15 > > # get standard environment, filters and checks > +cd .. > . ./common.rc > . ./common.filter > . ./common.nbd > @@ -129,6 +130,16 @@ $QEMU_IMG map --output=json --image-opts \ > > nbd_server_stop > > +echo > +echo "=== Check handling of inconsistent bitmap ===" > +echo > + > +$QEMU_IO -c abort "$TEST_IMG" 2>/dev/null > +$QEMU_IMG bitmap --add "$TEST_IMG" b4 > +$QEMU_IMG bitmap --remove "$TEST_IMG" b1 > +_img_info --format-specific | _filter_irrelevant_img_info > +$QEMU_IMG convert --bitmaps -O qcow2 "$TEST_IMG" "$TEST_IMG.copy" Worth then removing remaining inconsistent bitmaps and try again? I think you should now remove $TEST_IMG.copy in _cleanup with squashed in --- a/tests/qemu-iotests/tests/qemu-img-bitmaps +++ b/tests/qemu-iotests/tests/qemu-img-bitmaps @@ -27,6 +27,7 @@ status=1 # failure is the default! _cleanup() { _cleanup_test_img + _rm_test_img "$TEST_IMG.copy" nbd_server_stop } trap "_cl Tested-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> > + > # success, all done > echo '*** done' > rm -f $seq.full > diff --git a/tests/qemu-iotests/291.out b/tests/qemu-iotests/tests/qemu-img-bitmaps.out > similarity index 82% > rename from tests/qemu-iotests/291.out > rename to tests/qemu-iotests/tests/qemu-img-bitmaps.out > index 018d6b103f87..17b34eaed30f 100644 > --- a/tests/qemu-iotests/291.out > +++ b/tests/qemu-iotests/tests/qemu-img-bitmaps.out > @@ -1,4 +1,4 @@ > -QA output created by 291 > +QA output created by qemu-img-bitmaps > > === Initial image setup === > > @@ -115,4 +115,34 @@ Format specific information: > [{ "start": 0, "length": 2097152, "depth": 0, "present": true, "zero": false, "data": true, "offset": OFFSET}, > { "start": 2097152, "length": 1048576, "depth": 0, "present": false, "zero": false, "data": false}, > { "start": 3145728, "length": 7340032, "depth": 0, "present": true, "zero": false, "data": true, "offset": OFFSET}] > + > +=== Check handling of inconsistent bitmap === > + > +image: TEST_DIR/t.IMGFMT > +file format: IMGFMT > +virtual size: 10 MiB (10485760 bytes) > +cluster_size: 65536 > +backing file: TEST_DIR/t.IMGFMT.base > +backing file format: IMGFMT > +Format specific information: > + bitmaps: > + [0]: > + flags: > + [0]: in-use > + [1]: auto > + name: b2 > + granularity: 65536 > + [1]: > + flags: > + [0]: in-use > + name: b0 > + granularity: 65536 > + [2]: > + flags: > + [0]: auto > + name: b4 > + granularity: 65536 > + corrupt: false > +qemu-img: Failed to populate bitmap b0: Bitmap 'b0' is inconsistent and cannot be used > +Try block-dirty-bitmap-remove to delete this bitmap from disk > *** done > -- Best regards, Vladimir ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] iotests: Improve and rename test 291 to qemu-img-bitmap 2021-07-09 6:33 ` Vladimir Sementsov-Ogievskiy @ 2021-07-09 13:16 ` Eric Blake 2021-07-09 13:49 ` Vladimir Sementsov-Ogievskiy 0 siblings, 1 reply; 9+ messages in thread From: Eric Blake @ 2021-07-09 13:16 UTC (permalink / raw) To: Vladimir Sementsov-Ogievskiy Cc: Kevin Wolf, qemu-block, qemu-devel, Max Reitz, nsoffer, John Snow On Fri, Jul 09, 2021 at 09:33:50AM +0300, Vladimir Sementsov-Ogievskiy wrote: > > +++ b/tests/qemu-iotests/tests/qemu-img-bitmaps > > +echo > > +echo "=== Check handling of inconsistent bitmap ===" > > +echo > > + > > +$QEMU_IO -c abort "$TEST_IMG" 2>/dev/null > > +$QEMU_IMG bitmap --add "$TEST_IMG" b4 > > +$QEMU_IMG bitmap --remove "$TEST_IMG" b1 > > +_img_info --format-specific | _filter_irrelevant_img_info > > +$QEMU_IMG convert --bitmaps -O qcow2 "$TEST_IMG" "$TEST_IMG.copy" > > Worth then removing remaining inconsistent bitmaps and try again? > > I think you should now remove $TEST_IMG.copy in _cleanup $TEST_IMG.copy isn't created on failure (or if it is, that in itself is a problem we should be avoiding), so as written, there was nothing that should have needed cleaning up until patch 2. But your idea (here and in patch 2) of demonstrating manual cleanup for recovery (in addition to the goal of patch 2 of skipping broken bitmaps in the first place) is reasonable, so I'll incorporate that into v2. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] iotests: Improve and rename test 291 to qemu-img-bitmap 2021-07-09 13:16 ` Eric Blake @ 2021-07-09 13:49 ` Vladimir Sementsov-Ogievskiy 2021-07-09 14:17 ` Eric Blake 0 siblings, 1 reply; 9+ messages in thread From: Vladimir Sementsov-Ogievskiy @ 2021-07-09 13:49 UTC (permalink / raw) To: Eric Blake Cc: qemu-devel, nsoffer, qemu-block, John Snow, Kevin Wolf, Max Reitz 09.07.2021 16:16, Eric Blake wrote: > On Fri, Jul 09, 2021 at 09:33:50AM +0300, Vladimir Sementsov-Ogievskiy wrote: >>> +++ b/tests/qemu-iotests/tests/qemu-img-bitmaps > >>> +echo >>> +echo "=== Check handling of inconsistent bitmap ===" >>> +echo >>> + >>> +$QEMU_IO -c abort "$TEST_IMG" 2>/dev/null >>> +$QEMU_IMG bitmap --add "$TEST_IMG" b4 >>> +$QEMU_IMG bitmap --remove "$TEST_IMG" b1 >>> +_img_info --format-specific | _filter_irrelevant_img_info >>> +$QEMU_IMG convert --bitmaps -O qcow2 "$TEST_IMG" "$TEST_IMG.copy" >> >> Worth then removing remaining inconsistent bitmaps and try again? >> >> I think you should now remove $TEST_IMG.copy in _cleanup > > $TEST_IMG.copy isn't created on failure (or if it is, that in itself > is a problem we should be avoiding), Seems that's the case: ./build/qemu-img create -f qcow2 x 1M ./build/qemu-img bitmap --add x b1 ./build/qemu-io x qemu-io> abort Aborted (core dumped) ./build/qemu-img info x image: x file format: qcow2 virtual size: 1 MiB (1048576 bytes) disk size: 204 KiB cluster_size: 65536 Format specific information: compat: 1.1 compression type: zlib lazy refcounts: false bitmaps: [0]: flags: [0]: in-use [1]: auto name: b1 granularity: 65536 refcount bits: 16 corrupt: false extended l2: false ls y ls: cannot access 'y': No such file or directory ./build/qemu-img convert --bitmaps -O qcow2 x y qemu-img: Failed to populate bitmap b1: Bitmap 'b1' is inconsistent and cannot be used Try block-dirty-bitmap-remove to delete this bitmap from disk[root@kvm master]# # ls y y ./build/qemu-img info y image: y file format: qcow2 virtual size: 1 MiB (1048576 bytes) disk size: 204 KiB cluster_size: 65536 Format specific information: compat: 1.1 compression type: zlib lazy refcounts: false bitmaps: [0]: flags: name: b1 granularity: 65536 refcount bits: 16 corrupt: false extended l2: false WOW! It even contains the bitmap not marked in-use. That's a real bug. > so as written, there was nothing > that should have needed cleaning up until patch 2. But your idea > (here and in patch 2) of demonstrating manual cleanup for recovery (in > addition to the goal of patch 2 of skipping broken bitmaps in the > first place) is reasonable, so I'll incorporate that into v2. > -- Best regards, Vladimir ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] iotests: Improve and rename test 291 to qemu-img-bitmap 2021-07-09 13:49 ` Vladimir Sementsov-Ogievskiy @ 2021-07-09 14:17 ` Eric Blake 0 siblings, 0 replies; 9+ messages in thread From: Eric Blake @ 2021-07-09 14:17 UTC (permalink / raw) To: Vladimir Sementsov-Ogievskiy Cc: Kevin Wolf, qemu-block, qemu-devel, Max Reitz, nsoffer, John Snow On Fri, Jul 09, 2021 at 04:49:01PM +0300, Vladimir Sementsov-Ogievskiy wrote: > 09.07.2021 16:16, Eric Blake wrote: > > On Fri, Jul 09, 2021 at 09:33:50AM +0300, Vladimir Sementsov-Ogievskiy wrote: > > > > +++ b/tests/qemu-iotests/tests/qemu-img-bitmaps > > > > > > +echo > > > > +echo "=== Check handling of inconsistent bitmap ===" > > > > +echo > > > > + > > > > +$QEMU_IO -c abort "$TEST_IMG" 2>/dev/null > > > > +$QEMU_IMG bitmap --add "$TEST_IMG" b4 > > > > +$QEMU_IMG bitmap --remove "$TEST_IMG" b1 > > > > +_img_info --format-specific | _filter_irrelevant_img_info > > > > +$QEMU_IMG convert --bitmaps -O qcow2 "$TEST_IMG" "$TEST_IMG.copy" > > > > > > Worth then removing remaining inconsistent bitmaps and try again? > > > > > > I think you should now remove $TEST_IMG.copy in _cleanup > > > > $TEST_IMG.copy isn't created on failure (or if it is, that in itself > > is a problem we should be avoiding), > > Seems that's the case: Oh. Thanks for checking. Yeah, re-reading the code, we don't attempt to copy the bitmaps until after the rest of the convert operation is done. Which means a fix to pre-validate bitmaps before starting the convert requires more code, but may be the right thing (failing at the very end of a long convert attempt, but leaving the file around, is not ideal compared to failing fast). Looks like my v2 will be a bit more beefy. > ./build/qemu-img convert --bitmaps -O qcow2 x y > qemu-img: Failed to populate bitmap b1: Bitmap 'b1' is inconsistent and cannot be used > Try block-dirty-bitmap-remove to delete this bitmap from disk[root@kvm master]# > # ls y > y > ./build/qemu-img info y > image: y > file format: qcow2 > virtual size: 1 MiB (1048576 bytes) > disk size: 204 KiB > cluster_size: 65536 > Format specific information: > compat: 1.1 > compression type: zlib > lazy refcounts: false > bitmaps: > [0]: > flags: > name: b1 > granularity: 65536 > refcount bits: 16 > corrupt: false > extended l2: false > > > WOW! It even contains the bitmap not marked in-use. That's a real bug. So we left things dangling with a bitmap that has completely different contents than in the original file. Yeah, that looks like an issue worth improving. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/2] qemu-img: Add --skip-broken for 'convert --bitmaps' 2021-07-08 1:29 [PATCH 0/2] Let 'qemu-img convert --bitmaps' skip inconsistent bitmaps Eric Blake 2021-07-08 1:30 ` [PATCH 1/2] iotests: Improve and rename test 291 to qemu-img-bitmap Eric Blake @ 2021-07-08 1:30 ` Eric Blake 2021-07-09 6:54 ` Vladimir Sementsov-Ogievskiy 2021-07-09 9:50 ` [PATCH 0/2] Let 'qemu-img convert --bitmaps' skip inconsistent bitmaps Vladimir Sementsov-Ogievskiy 2 siblings, 1 reply; 9+ messages in thread From: Eric Blake @ 2021-07-08 1:30 UTC (permalink / raw) To: qemu-devel; +Cc: nsoffer, Kevin Wolf, vsementsov, qemu-block, Max Reitz The point of 'qemu-img convert --bitmaps' is to be a convenience for actions that are already possible through a string of smaller 'qemu-img bitmap' sub-commands. One situation not accounted for already is that if a source image contains an inconsistent bitmap (for example, because a qemu process died abruptly before flushing bitmap state), the user MUST delete those inconsistent bitmaps before anything else useful can be done with the image. We don't want to delete inconsistent bitmaps by default: although a corrupt bitmap is only a loss of optimization rather than a corruption of user-visible data, it is still nice to require the user to opt in to the fact that they are aware of the loss of the bitmap. Still, requiring the user to check 'qemu-img info' to see whether bitmaps are consistent, then use 'qemu-img bitmap --remove' to remove offenders, all before using 'qemu-img convert', is a lot more work than just adding a knob 'qemu-img convert --bitmaps --skip-broken' which opts in to skipping the broken bitmaps. Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1946084 Signed-off-by: Eric Blake <eblake@redhat.com> --- docs/tools/qemu-img.rst | 8 +++++++- qemu-img.c | 20 +++++++++++++++++-- tests/qemu-iotests/tests/qemu-img-bitmaps | 4 ++++ tests/qemu-iotests/tests/qemu-img-bitmaps.out | 14 +++++++++++++ 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst index 1d8470eada0e..5cf1c764597b 100644 --- a/docs/tools/qemu-img.rst +++ b/docs/tools/qemu-img.rst @@ -414,7 +414,7 @@ Command description: 4 Error on reading data -.. option:: convert [--object OBJECTDEF] [--image-opts] [--target-image-opts] [--target-is-zero] [--bitmaps] [-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] [-r RATE_LIMIT] [-m NUM_COROUTINES] [-W] FILENAME [FILENAME2 [...]] OUTPUT_FILENAME +.. option:: convert [--object OBJECTDEF] [--image-opts] [--target-image-opts] [--target-is-zero] [--bitmaps [--skip-broken]] [-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] [-r RATE_LIMIT] [-m NUM_COROUTINES] [-W] FILENAME [FILENAME2 [...]] OUTPUT_FILENAME Convert the disk image *FILENAME* or a snapshot *SNAPSHOT_PARAM* to disk image *OUTPUT_FILENAME* using format *OUTPUT_FMT*. It can @@ -456,6 +456,12 @@ Command description: *NUM_COROUTINES* specifies how many coroutines work in parallel during the convert process (defaults to 8). + Use of ``--bitmaps`` requests that any persistent bitmaps present in + the original are also copied to the destination. If any bitmap is + inconsistent in the source, the conversion will fail unless + ``--skip-broken`` is also specified to copy only the consistent + bitmaps. + .. option:: create [--object OBJECTDEF] [-q] [-f FMT] [-b BACKING_FILE] [-F BACKING_FMT] [-u] [-o OPTIONS] FILENAME [SIZE] Create the new disk image *FILENAME* of size *SIZE* and format diff --git a/qemu-img.c b/qemu-img.c index 68a4d298098f..e8b012f39c0c 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -82,6 +82,7 @@ enum { OPTION_MERGE = 274, OPTION_BITMAPS = 275, OPTION_FORCE = 276, + OPTION_SKIP_BROKEN = 277, }; typedef enum OutputFormat { @@ -2101,7 +2102,8 @@ static int convert_do_copy(ImgConvertState *s) return s->ret; } -static int convert_copy_bitmaps(BlockDriverState *src, BlockDriverState *dst) +static int convert_copy_bitmaps(BlockDriverState *src, BlockDriverState *dst, + bool skip_broken) { BdrvDirtyBitmap *bm; Error *err = NULL; @@ -2113,6 +2115,10 @@ static int convert_copy_bitmaps(BlockDriverState *src, BlockDriverState *dst) continue; } name = bdrv_dirty_bitmap_name(bm); + if (skip_broken && bdrv_dirty_bitmap_inconsistent(bm)) { + warn_report("Skipping inconsistent bitmap %s", name); + continue; + } qmp_block_dirty_bitmap_add(dst->node_name, name, true, bdrv_dirty_bitmap_granularity(bm), true, true, @@ -2167,6 +2173,7 @@ static int img_convert(int argc, char **argv) bool force_share = false; bool explict_min_sparse = false; bool bitmaps = false; + bool skip_broken = false; int64_t rate_limit = 0; ImgConvertState s = (ImgConvertState) { @@ -2188,6 +2195,7 @@ static int img_convert(int argc, char **argv) {"salvage", no_argument, 0, OPTION_SALVAGE}, {"target-is-zero", no_argument, 0, OPTION_TARGET_IS_ZERO}, {"bitmaps", no_argument, 0, OPTION_BITMAPS}, + {"skip-broken", no_argument, 0, OPTION_SKIP_BROKEN}, {0, 0, 0, 0} }; c = getopt_long(argc, argv, ":hf:O:B:Cco:l:S:pt:T:qnm:WUr:", @@ -2316,6 +2324,9 @@ static int img_convert(int argc, char **argv) case OPTION_BITMAPS: bitmaps = true; break; + case OPTION_SKIP_BROKEN: + skip_broken = true; + break; } } @@ -2323,6 +2334,11 @@ static int img_convert(int argc, char **argv) out_fmt = "raw"; } + if (skip_broken && !bitmaps) { + error_report("Use of --skip-broken requires --bitmaps"); + goto fail_getopt; + } + if (s.compressed && s.copy_range) { error_report("Cannot enable copy offloading when -c is used"); goto fail_getopt; @@ -2678,7 +2694,7 @@ static int img_convert(int argc, char **argv) /* Now copy the bitmaps */ if (bitmaps && ret == 0) { - ret = convert_copy_bitmaps(blk_bs(s.src[0]), out_bs); + ret = convert_copy_bitmaps(blk_bs(s.src[0]), out_bs, skip_broken); } out: diff --git a/tests/qemu-iotests/tests/qemu-img-bitmaps b/tests/qemu-iotests/tests/qemu-img-bitmaps index 76cd9e31e850..3e1a39bc81e4 100755 --- a/tests/qemu-iotests/tests/qemu-img-bitmaps +++ b/tests/qemu-iotests/tests/qemu-img-bitmaps @@ -28,6 +28,7 @@ _cleanup() { _cleanup_test_img nbd_server_stop + _rm_test_img "$TEST_DIR/t.$IMGFMT.copy" } trap "_cleanup; exit \$status" 0 1 2 3 15 @@ -139,6 +140,9 @@ $QEMU_IMG bitmap --add "$TEST_IMG" b4 $QEMU_IMG bitmap --remove "$TEST_IMG" b1 _img_info --format-specific | _filter_irrelevant_img_info $QEMU_IMG convert --bitmaps -O qcow2 "$TEST_IMG" "$TEST_IMG.copy" +$QEMU_IMG convert --bitmaps --skip-broken -O qcow2 "$TEST_IMG" "$TEST_IMG.copy" +TEST_IMG="$TEST_IMG.copy" _img_info --format-specific \ + | _filter_irrelevant_img_info # success, all done echo '*** done' diff --git a/tests/qemu-iotests/tests/qemu-img-bitmaps.out b/tests/qemu-iotests/tests/qemu-img-bitmaps.out index 17b34eaed30f..685bde6d1d63 100644 --- a/tests/qemu-iotests/tests/qemu-img-bitmaps.out +++ b/tests/qemu-iotests/tests/qemu-img-bitmaps.out @@ -145,4 +145,18 @@ Format specific information: corrupt: false qemu-img: Failed to populate bitmap b0: Bitmap 'b0' is inconsistent and cannot be used Try block-dirty-bitmap-remove to delete this bitmap from disk +qemu-img: warning: Skipping inconsistent bitmap b0 +qemu-img: warning: Skipping inconsistent bitmap b2 +image: TEST_DIR/t.IMGFMT.copy +file format: IMGFMT +virtual size: 10 MiB (10485760 bytes) +cluster_size: 65536 +Format specific information: + bitmaps: + [0]: + flags: + [0]: auto + name: b4 + granularity: 65536 + corrupt: false *** done -- 2.31.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] qemu-img: Add --skip-broken for 'convert --bitmaps' 2021-07-08 1:30 ` [PATCH 2/2] qemu-img: Add --skip-broken for 'convert --bitmaps' Eric Blake @ 2021-07-09 6:54 ` Vladimir Sementsov-Ogievskiy 0 siblings, 0 replies; 9+ messages in thread From: Vladimir Sementsov-Ogievskiy @ 2021-07-09 6:54 UTC (permalink / raw) To: Eric Blake, qemu-devel; +Cc: nsoffer, qemu-block, Kevin Wolf, Max Reitz 08.07.2021 04:30, Eric Blake wrote: > The point of 'qemu-img convert --bitmaps' is to be a convenience for > actions that are already possible through a string of smaller > 'qemu-img bitmap' sub-commands. One situation not accounted for > already is that if a source image contains an inconsistent bitmap (for > example, because a qemu process died abruptly before flushing bitmap > state), the user MUST delete those inconsistent bitmaps before > anything else useful can be done with the image. > > We don't want to delete inconsistent bitmaps by default: although a > corrupt bitmap is only a loss of optimization rather than a corruption > of user-visible data, it is still nice to require the user to opt in > to the fact that they are aware of the loss of the bitmap. Still, > requiring the user to check 'qemu-img info' to see whether bitmaps are > consistent, then use 'qemu-img bitmap --remove' to remove offenders, > all before using 'qemu-img convert', is a lot more work than just > adding a knob 'qemu-img convert --bitmaps --skip-broken' which opts in > to skipping the broken bitmaps. > > Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1946084 > Signed-off-by: Eric Blake <eblake@redhat.com> > --- > docs/tools/qemu-img.rst | 8 +++++++- > qemu-img.c | 20 +++++++++++++++++-- > tests/qemu-iotests/tests/qemu-img-bitmaps | 4 ++++ > tests/qemu-iotests/tests/qemu-img-bitmaps.out | 14 +++++++++++++ > 4 files changed, 43 insertions(+), 3 deletions(-) > > diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst > index 1d8470eada0e..5cf1c764597b 100644 > --- a/docs/tools/qemu-img.rst > +++ b/docs/tools/qemu-img.rst > @@ -414,7 +414,7 @@ Command description: > 4 > Error on reading data > > -.. option:: convert [--object OBJECTDEF] [--image-opts] [--target-image-opts] [--target-is-zero] [--bitmaps] [-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] [-r RATE_LIMIT] [-m NUM_COROUTINES] [-W] FILENAME [FILENAME2 [...]] OUTPUT_FILENAME > +.. option:: convert [--object OBJECTDEF] [--image-opts] [--target-image-opts] [--target-is-zero] [--bitmaps [--skip-broken]] [-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] [-r RATE_LIMIT] [-m NUM_COROUTINES] [-W] FILENAME [FILENAME2 [...]] OUTPUT_FILENAME Of course, [--bitmaps [--skip-broken]] looks like --skip-broken is a suboption.. But actually it's not so. So, shouldn't it be named more explicit, like --skip-broken-bitmaps ? To be sure that we will not interfere in future with some other broken things we want to skip? And to avoid strange but correct command lines like qemu-img convert --skip-broken <someother options> --bitmaps <some other options> src dst > > Convert the disk image *FILENAME* or a snapshot *SNAPSHOT_PARAM* > to disk image *OUTPUT_FILENAME* using format *OUTPUT_FMT*. It can > @@ -456,6 +456,12 @@ Command description: > *NUM_COROUTINES* specifies how many coroutines work in parallel during > the convert process (defaults to 8). > > + Use of ``--bitmaps`` requests that any persistent bitmaps present in > + the original are also copied to the destination. If any bitmap is > + inconsistent in the source, the conversion will fail unless > + ``--skip-broken`` is also specified to copy only the consistent > + bitmaps. > + > .. option:: create [--object OBJECTDEF] [-q] [-f FMT] [-b BACKING_FILE] [-F BACKING_FMT] [-u] [-o OPTIONS] FILENAME [SIZE] > > Create the new disk image *FILENAME* of size *SIZE* and format > diff --git a/qemu-img.c b/qemu-img.c > index 68a4d298098f..e8b012f39c0c 100644 > --- a/qemu-img.c > +++ b/qemu-img.c > @@ -82,6 +82,7 @@ enum { > OPTION_MERGE = 274, > OPTION_BITMAPS = 275, > OPTION_FORCE = 276, > + OPTION_SKIP_BROKEN = 277, > }; > > typedef enum OutputFormat { > @@ -2101,7 +2102,8 @@ static int convert_do_copy(ImgConvertState *s) > return s->ret; > } > > -static int convert_copy_bitmaps(BlockDriverState *src, BlockDriverState *dst) > +static int convert_copy_bitmaps(BlockDriverState *src, BlockDriverState *dst, > + bool skip_broken) > { > BdrvDirtyBitmap *bm; > Error *err = NULL; > @@ -2113,6 +2115,10 @@ static int convert_copy_bitmaps(BlockDriverState *src, BlockDriverState *dst) > continue; > } > name = bdrv_dirty_bitmap_name(bm); > + if (skip_broken && bdrv_dirty_bitmap_inconsistent(bm)) { > + warn_report("Skipping inconsistent bitmap %s", name); > + continue; > + } > qmp_block_dirty_bitmap_add(dst->node_name, name, > true, bdrv_dirty_bitmap_granularity(bm), > true, true, > @@ -2167,6 +2173,7 @@ static int img_convert(int argc, char **argv) > bool force_share = false; > bool explict_min_sparse = false; > bool bitmaps = false; > + bool skip_broken = false; > int64_t rate_limit = 0; > > ImgConvertState s = (ImgConvertState) { > @@ -2188,6 +2195,7 @@ static int img_convert(int argc, char **argv) > {"salvage", no_argument, 0, OPTION_SALVAGE}, > {"target-is-zero", no_argument, 0, OPTION_TARGET_IS_ZERO}, > {"bitmaps", no_argument, 0, OPTION_BITMAPS}, > + {"skip-broken", no_argument, 0, OPTION_SKIP_BROKEN}, > {0, 0, 0, 0} > }; > c = getopt_long(argc, argv, ":hf:O:B:Cco:l:S:pt:T:qnm:WUr:", > @@ -2316,6 +2324,9 @@ static int img_convert(int argc, char **argv) > case OPTION_BITMAPS: > bitmaps = true; > break; > + case OPTION_SKIP_BROKEN: > + skip_broken = true; > + break; > } > } > > @@ -2323,6 +2334,11 @@ static int img_convert(int argc, char **argv) > out_fmt = "raw"; > } > > + if (skip_broken && !bitmaps) { > + error_report("Use of --skip-broken requires --bitmaps"); > + goto fail_getopt; > + } > + > if (s.compressed && s.copy_range) { > error_report("Cannot enable copy offloading when -c is used"); > goto fail_getopt; > @@ -2678,7 +2694,7 @@ static int img_convert(int argc, char **argv) > > /* Now copy the bitmaps */ > if (bitmaps && ret == 0) { > - ret = convert_copy_bitmaps(blk_bs(s.src[0]), out_bs); > + ret = convert_copy_bitmaps(blk_bs(s.src[0]), out_bs, skip_broken); > } > > out: > diff --git a/tests/qemu-iotests/tests/qemu-img-bitmaps b/tests/qemu-iotests/tests/qemu-img-bitmaps > index 76cd9e31e850..3e1a39bc81e4 100755 > --- a/tests/qemu-iotests/tests/qemu-img-bitmaps > +++ b/tests/qemu-iotests/tests/qemu-img-bitmaps > @@ -28,6 +28,7 @@ _cleanup() > { > _cleanup_test_img > nbd_server_stop > + _rm_test_img "$TEST_DIR/t.$IMGFMT.copy" Aha here it is. It should appear in a previous patch.. Also, it may be simply _rm_test_img "$TEST_IMG.copy" , like in 110. > } > trap "_cleanup; exit \$status" 0 1 2 3 15 > > @@ -139,6 +140,9 @@ $QEMU_IMG bitmap --add "$TEST_IMG" b4 > $QEMU_IMG bitmap --remove "$TEST_IMG" b1 > _img_info --format-specific | _filter_irrelevant_img_info > $QEMU_IMG convert --bitmaps -O qcow2 "$TEST_IMG" "$TEST_IMG.copy" > +$QEMU_IMG convert --bitmaps --skip-broken -O qcow2 "$TEST_IMG" "$TEST_IMG.copy" > +TEST_IMG="$TEST_IMG.copy" _img_info --format-specific \ > + | _filter_irrelevant_img_info We still can now remove remaining inconsistent bitmaps and retry convert without --skip-broken, just to cover more nearby cases. > > # success, all done > echo '*** done' > diff --git a/tests/qemu-iotests/tests/qemu-img-bitmaps.out b/tests/qemu-iotests/tests/qemu-img-bitmaps.out > index 17b34eaed30f..685bde6d1d63 100644 > --- a/tests/qemu-iotests/tests/qemu-img-bitmaps.out > +++ b/tests/qemu-iotests/tests/qemu-img-bitmaps.out > @@ -145,4 +145,18 @@ Format specific information: > corrupt: false > qemu-img: Failed to populate bitmap b0: Bitmap 'b0' is inconsistent and cannot be used > Try block-dirty-bitmap-remove to delete this bitmap from disk > +qemu-img: warning: Skipping inconsistent bitmap b0 > +qemu-img: warning: Skipping inconsistent bitmap b2 > +image: TEST_DIR/t.IMGFMT.copy > +file format: IMGFMT > +virtual size: 10 MiB (10485760 bytes) > +cluster_size: 65536 > +Format specific information: > + bitmaps: > + [0]: > + flags: > + [0]: auto > + name: b4 > + granularity: 65536 > + corrupt: false > *** done > -- Best regards, Vladimir ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/2] Let 'qemu-img convert --bitmaps' skip inconsistent bitmaps 2021-07-08 1:29 [PATCH 0/2] Let 'qemu-img convert --bitmaps' skip inconsistent bitmaps Eric Blake 2021-07-08 1:30 ` [PATCH 1/2] iotests: Improve and rename test 291 to qemu-img-bitmap Eric Blake 2021-07-08 1:30 ` [PATCH 2/2] qemu-img: Add --skip-broken for 'convert --bitmaps' Eric Blake @ 2021-07-09 9:50 ` Vladimir Sementsov-Ogievskiy 2 siblings, 0 replies; 9+ messages in thread From: Vladimir Sementsov-Ogievskiy @ 2021-07-09 9:50 UTC (permalink / raw) To: Eric Blake, qemu-devel; +Cc: nsoffer, qemu-block 08.07.2021 04:29, Eric Blake wrote: > This is mostly a convenience factor as one could already use 'qemu-img > info' to learn which bitmaps are broken and then 'qemu-img bitmap > --remove' to nuke them before calling 'qemu-img convert --bitmaps', > but it does have the advantage that the copied file is usable without > extra efforts and the broken bitmap is not deleted from the source > file. > > Eric Blake (2): > iotests: Improve and rename test 291 to qemu-img-bitmap > qemu-img: Add --skip-broken for 'convert --bitmaps' > > docs/tools/qemu-img.rst | 8 +++- > block/dirty-bitmap.c | 2 +- > qemu-img.c | 20 +++++++- > .../{291 => tests/qemu-img-bitmaps} | 17 ++++++- > .../{291.out => tests/qemu-img-bitmaps.out} | 46 ++++++++++++++++++- > 5 files changed, 87 insertions(+), 6 deletions(-) > rename tests/qemu-iotests/{291 => tests/qemu-img-bitmaps} (88%) > rename tests/qemu-iotests/{291.out => tests/qemu-img-bitmaps.out} (76%) > I've applied this onto your nbd branch. This doesn't apply on master. -- Best regards, Vladimir ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2021-07-09 14:18 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-07-08 1:29 [PATCH 0/2] Let 'qemu-img convert --bitmaps' skip inconsistent bitmaps Eric Blake 2021-07-08 1:30 ` [PATCH 1/2] iotests: Improve and rename test 291 to qemu-img-bitmap Eric Blake 2021-07-09 6:33 ` Vladimir Sementsov-Ogievskiy 2021-07-09 13:16 ` Eric Blake 2021-07-09 13:49 ` Vladimir Sementsov-Ogievskiy 2021-07-09 14:17 ` Eric Blake 2021-07-08 1:30 ` [PATCH 2/2] qemu-img: Add --skip-broken for 'convert --bitmaps' Eric Blake 2021-07-09 6:54 ` Vladimir Sementsov-Ogievskiy 2021-07-09 9:50 ` [PATCH 0/2] Let 'qemu-img convert --bitmaps' skip inconsistent bitmaps Vladimir Sementsov-Ogievskiy
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.