* [PATCH] qemu-nbd: Add --all-bitmaps option
@ 2026-10-19 22:22 Eric Blake
2026-10-20 10:57 ` Denis V. Lunev
2026-10-30 11:01 ` Kevin Wolf
0 siblings, 2 replies; 3+ messages in thread
From: Eric Blake @ 2026-10-19 22:22 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-block, Denis V. Lunev, Vladimir Sementsov-Ogievskiy,
Pierrick Bouvier, Kevin Wolf, Hanna Reitz
When exporting bitmaps over NBD, we previously required a user to pass
one '-B name' per bitmap, which they would have to use 'qemu-img info'
to learn the list of names to pass. More convenient is an option to
export all possible bitmaps at once, as discussed here [1].
Implementation-wise, mixing --all-bitmaps and -B is harmless (grabbing
all bitmap names already requires crawling the backing chain and
deduplicating, so either the -B name is already detected as a
duplicate from adding the name again, or it is an invalid name that
will still cause a later error about bitmap not found). I also tested
that mixing -s and --all-bitmaps still works (the temporary overlay
image to make -s work has no bitmaps of its own, so starting the crawl
for bitmap names at the original bs is just fine).
Also, now that parallels can have bitmaps (and not just qcow2), a
slight doc wording change for -B is warranted.
[1] https://lists.nongnu.org/archive/html/qemu-devel/2026-10/msg01234.html
Signed-off-by: Eric Blake <eblake@redhat.com>
CC: Denis V. Lunev <den@openvz.org>
---
docs/tools/qemu-nbd.rst | 12 +++-
qemu-nbd.c | 57 ++++++++++++++++++-
tests/qemu-iotests/tests/qemu-img-bitmaps | 13 +++++
tests/qemu-iotests/tests/qemu-img-bitmaps.out | 12 ++++
4 files changed, 90 insertions(+), 4 deletions(-)
diff --git a/docs/tools/qemu-nbd.rst b/docs/tools/qemu-nbd.rst
index 336b4aa46e7..a966c282be2 100644
--- a/docs/tools/qemu-nbd.rst
+++ b/docs/tools/qemu-nbd.rst
@@ -83,9 +83,15 @@ driver options if :option:`--image-opts` is specified.
.. option:: -B, --bitmap=NAME
- If *filename* has a qcow2 persistent bitmap *NAME*, expose
- that bitmap via the ``qemu:dirty-bitmap:NAME`` metadata context
- accessible through NBD_OPT_SET_META_CONTEXT.
+ If *filename* has a persistent bitmap *NAME* (possibly via a backing
+ chain), expose that bitmap via the ``qemu:dirty-bitmap:NAME`` metadata
+ context accessible through NBD_OPT_SET_META_CONTEXT.
+
+.. option:: --all-bitmaps
+
+ If *filename* has any persistent bitmaps (possibly via a backing
+ chain), expose one ``qemu:dirty-bitmap:NAME`` metadata context per
+ bitmap, accessible through NBD_OPT_SET_META_CONTEXT.
.. option:: -s, --snapshot
diff --git a/qemu-nbd.c b/qemu-nbd.c
index fcca88932a3..fa28609d7dc 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -28,6 +28,7 @@
#include "system/runstate.h" /* for qemu_system_killed() prototype */
#include "block/block_int.h"
#include "block/nbd.h"
+#include "block/dirty-bitmap.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "qemu/option.h"
@@ -71,6 +72,7 @@
#define QEMU_NBD_OPT_SELINUX_LABEL 266
#define QEMU_NBD_OPT_TLSHOSTNAME 267
#define QEMU_NBD_OPT_HANDSHAKE_LIMIT 268
+#define QEMU_NBD_OPT_ALL_BITMAPS 269
#define MBR_SIZE 512
@@ -109,6 +111,7 @@ static void usage(const char *name)
" -o, --offset=OFFSET offset into the image\n"
" -A, --allocation-depth expose the allocation depth\n"
" -B, --bitmap=NAME expose a persistent dirty bitmap\n"
+" --all-bitmaps expose all persistent dirty bitmaps\n"
"\n"
"General purpose options:\n"
" -L, --list list exports available from another NBD server\n"
@@ -530,6 +533,48 @@ static void qemu_nbd_shutdown(void)
bdrv_close_all();
}
+/* Helpers to implement --all-bitmaps option. */
+static bool is_duplicate_bitmap(BlockDirtyBitmapOrStrList *bitmaps,
+ const char *name)
+{
+ /* Treat an anonymous bitmap as a duplicate. */
+ if (!name) {
+ return true;
+ }
+ for (; bitmaps; bitmaps = bitmaps->next) {
+ if (bitmaps->value->type == QTYPE_QSTRING &&
+ strcmp(bitmaps->value->u.local, name) == 0) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static void collect_all_bitmaps(BlockDriverState *bs,
+ BlockDirtyBitmapOrStrList **bitmaps)
+{
+ GLOBAL_STATE_CODE();
+ GRAPH_RDLOCK_GUARD_MAINLOOP();
+
+ for (; bs; bs = bdrv_filter_or_cow_bs(bs)) {
+ for (BdrvDirtyBitmap *bm = bdrv_dirty_bitmap_first(bs); bm;
+ bm = bdrv_dirty_bitmap_next(bm)) {
+ const char *name = bdrv_dirty_bitmap_name(bm);
+ BlockDirtyBitmapOrStr *el;
+
+ if (is_duplicate_bitmap(*bitmaps, name)) {
+ continue;
+ }
+ el = g_new(BlockDirtyBitmapOrStr, 1);
+ *el = (BlockDirtyBitmapOrStr) {
+ .type = QTYPE_QSTRING,
+ .u.local = g_strdup(name),
+ };
+ QAPI_LIST_PREPEND(*bitmaps, el);
+ }
+ }
+}
+
int main(int argc, char **argv)
{
BlockBackend *blk;
@@ -553,6 +598,7 @@ int main(int argc, char **argv)
{ "offset", required_argument, NULL, 'o' },
{ "read-only", no_argument, NULL, 'r' },
{ "allocation-depth", no_argument, NULL, 'A' },
+ { "all-bitmaps", no_argument, NULL, QEMU_NBD_OPT_ALL_BITMAPS },
{ "bitmap", required_argument, NULL, 'B' },
{ "connect", required_argument, NULL, 'c' },
{ "disconnect", no_argument, NULL, 'd' },
@@ -602,6 +648,7 @@ int main(int argc, char **argv)
const char *export_description = NULL;
BlockDirtyBitmapOrStrList *bitmaps = NULL;
bool alloc_depth = false;
+ bool all_bitmaps = false;
const char *tlscredsid = NULL;
const char *tlshostname = NULL;
bool imageOpts = false;
@@ -725,6 +772,9 @@ int main(int argc, char **argv)
case 'A':
alloc_depth = true;
break;
+ case QEMU_NBD_OPT_ALL_BITMAPS:
+ all_bitmaps = true;
+ break;
case 'B':
{
BlockDirtyBitmapOrStr *el = g_new(BlockDirtyBitmapOrStr, 1);
@@ -837,7 +887,8 @@ int main(int argc, char **argv)
}
if (export_name || export_description || dev_offset ||
opts.device || disconnect || fmt || sn_id_or_name || bitmaps ||
- alloc_depth || seen_aio || seen_discard || seen_cache) {
+ all_bitmaps || alloc_depth || seen_aio || seen_discard ||
+ seen_cache) {
error_report("List mode is incompatible with per-device settings");
exit(EXIT_FAILURE);
}
@@ -1185,6 +1236,10 @@ int main(int argc, char **argv)
exit(EXIT_FAILURE);
}
+ if (all_bitmaps) {
+ collect_all_bitmaps(orig_bs, &bitmaps);
+ }
+
bs->detect_zeroes = detect_zeroes;
nbd_server_is_qemu_nbd(shared);
diff --git a/tests/qemu-iotests/tests/qemu-img-bitmaps b/tests/qemu-iotests/tests/qemu-img-bitmaps
index 979bc0d6c9c..5484fe6f424 100755
--- a/tests/qemu-iotests/tests/qemu-img-bitmaps
+++ b/tests/qemu-iotests/tests/qemu-img-bitmaps
@@ -131,6 +131,19 @@ $QEMU_IMG map --output=json --image-opts \
nbd_server_stop
+# Repeat with the --all-bitmaps option
+nbd_server_start_unix_socket -r -f qcow2 --all-bitmaps "$TEST_IMG"
+$QEMU_IMG map --output=json --image-opts \
+ "$IMG,x-dirty-bitmap=qemu:dirty-bitmap:b0" | _filter_qemu_img_map
+$QEMU_IMG map --output=json --image-opts \
+ "$IMG,x-dirty-bitmap=qemu:dirty-bitmap:b1" | _filter_qemu_img_map
+$QEMU_IMG map --output=json --image-opts \
+ "$IMG,x-dirty-bitmap=qemu:dirty-bitmap:b2" | _filter_qemu_img_map
+$QEMU_IMG map --output=json --image-opts \
+ "$IMG,x-dirty-bitmap=qemu:dirty-bitmap:b3" | _filter_qemu_img_map
+
+nbd_server_stop
+
echo
echo "=== Check handling of inconsistent bitmap ==="
echo
diff --git a/tests/qemu-iotests/tests/qemu-img-bitmaps.out b/tests/qemu-iotests/tests/qemu-img-bitmaps.out
index 99290d3ba5e..f2e97a090b0 100644
--- a/tests/qemu-iotests/tests/qemu-img-bitmaps.out
+++ b/tests/qemu-iotests/tests/qemu-img-bitmaps.out
@@ -103,6 +103,18 @@ Format specific information:
=== Check bitmap contents ===
+[{ "start": 0, "length": 3145728, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET},
+{ "start": 3145728, "length": 1048576, "depth": 0, "present": false, "zero": false, "data": false, "compressed": false},
+{ "start": 4194304, "length": 6291456, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET}]
+[{ "start": 0, "length": 1048576, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET},
+{ "start": 1048576, "length": 1048576, "depth": 0, "present": false, "zero": false, "data": false, "compressed": false},
+{ "start": 2097152, "length": 8388608, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET}]
+[{ "start": 0, "length": 2097152, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET},
+{ "start": 2097152, "length": 1048576, "depth": 0, "present": false, "zero": false, "data": false, "compressed": false},
+{ "start": 3145728, "length": 7340032, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET}]
+[{ "start": 0, "length": 2097152, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET},
+{ "start": 2097152, "length": 1048576, "depth": 0, "present": false, "zero": false, "data": false, "compressed": false},
+{ "start": 3145728, "length": 7340032, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET}]
[{ "start": 0, "length": 3145728, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET},
{ "start": 3145728, "length": 1048576, "depth": 0, "present": false, "zero": false, "data": false, "compressed": false},
{ "start": 4194304, "length": 6291456, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET}]
--
2.56.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH] qemu-nbd: Add --all-bitmaps option
2026-10-19 22:22 [PATCH] qemu-nbd: Add --all-bitmaps option Eric Blake
@ 2026-10-20 10:57 ` Denis V. Lunev
2026-10-30 11:01 ` Kevin Wolf
1 sibling, 0 replies; 3+ messages in thread
From: Denis V. Lunev @ 2026-10-20 10:57 UTC (permalink / raw)
To: Eric Blake, qemu-devel
Cc: qemu-block, Denis V. Lunev, Vladimir Sementsov-Ogievskiy,
Pierrick Bouvier, Kevin Wolf, Hanna Reitz
On 10/20/26 01:22, Eric Blake wrote:
> When exporting bitmaps over NBD, we previously required a user to pass
> one '-B name' per bitmap, which they would have to use 'qemu-img info'
> to learn the list of names to pass. More convenient is an option to
> export all possible bitmaps at once, as discussed here [1].
>
> Implementation-wise, mixing --all-bitmaps and -B is harmless (grabbing
> all bitmap names already requires crawling the backing chain and
> deduplicating, so either the -B name is already detected as a
> duplicate from adding the name again, or it is an invalid name that
> will still cause a later error about bitmap not found). I also tested
> that mixing -s and --all-bitmaps still works (the temporary overlay
> image to make -s work has no bitmaps of its own, so starting the crawl
> for bitmap names at the original bs is just fine).
>
> Also, now that parallels can have bitmaps (and not just qcow2), a
> slight doc wording change for -B is warranted.
>
> [1] https://lists.nongnu.org/archive/html/qemu-devel/2026-10/msg01234.html
>
> Signed-off-by: Eric Blake <eblake@redhat.com>
> CC: Denis V. Lunev <den@openvz.org>
> ---
> docs/tools/qemu-nbd.rst | 12 +++-
> qemu-nbd.c | 57 ++++++++++++++++++-
> tests/qemu-iotests/tests/qemu-img-bitmaps | 13 +++++
> tests/qemu-iotests/tests/qemu-img-bitmaps.out | 12 ++++
> 4 files changed, 90 insertions(+), 4 deletions(-)
>
> diff --git a/docs/tools/qemu-nbd.rst b/docs/tools/qemu-nbd.rst
> index 336b4aa46e7..a966c282be2 100644
> --- a/docs/tools/qemu-nbd.rst
> +++ b/docs/tools/qemu-nbd.rst
> @@ -83,9 +83,15 @@ driver options if :option:`--image-opts` is specified.
>
> .. option:: -B, --bitmap=NAME
>
> - If *filename* has a qcow2 persistent bitmap *NAME*, expose
> - that bitmap via the ``qemu:dirty-bitmap:NAME`` metadata context
> - accessible through NBD_OPT_SET_META_CONTEXT.
> + If *filename* has a persistent bitmap *NAME* (possibly via a backing
> + chain), expose that bitmap via the ``qemu:dirty-bitmap:NAME`` metadata
> + context accessible through NBD_OPT_SET_META_CONTEXT.
> +
> +.. option:: --all-bitmaps
> +
> + If *filename* has any persistent bitmaps (possibly via a backing
> + chain), expose one ``qemu:dirty-bitmap:NAME`` metadata context per
> + bitmap, accessible through NBD_OPT_SET_META_CONTEXT.
>
> .. option:: -s, --snapshot
>
> diff --git a/qemu-nbd.c b/qemu-nbd.c
> index fcca88932a3..fa28609d7dc 100644
> --- a/qemu-nbd.c
> +++ b/qemu-nbd.c
> @@ -28,6 +28,7 @@
> #include "system/runstate.h" /* for qemu_system_killed() prototype */
> #include "block/block_int.h"
> #include "block/nbd.h"
> +#include "block/dirty-bitmap.h"
> #include "qemu/main-loop.h"
> #include "qemu/module.h"
> #include "qemu/option.h"
> @@ -71,6 +72,7 @@
> #define QEMU_NBD_OPT_SELINUX_LABEL 266
> #define QEMU_NBD_OPT_TLSHOSTNAME 267
> #define QEMU_NBD_OPT_HANDSHAKE_LIMIT 268
> +#define QEMU_NBD_OPT_ALL_BITMAPS 269
>
> #define MBR_SIZE 512
>
> @@ -109,6 +111,7 @@ static void usage(const char *name)
> " -o, --offset=OFFSET offset into the image\n"
> " -A, --allocation-depth expose the allocation depth\n"
> " -B, --bitmap=NAME expose a persistent dirty bitmap\n"
> +" --all-bitmaps expose all persistent dirty bitmaps\n"
> "\n"
> "General purpose options:\n"
> " -L, --list list exports available from another NBD server\n"
> @@ -530,6 +533,48 @@ static void qemu_nbd_shutdown(void)
> bdrv_close_all();
> }
>
> +/* Helpers to implement --all-bitmaps option. */
> +static bool is_duplicate_bitmap(BlockDirtyBitmapOrStrList *bitmaps,
> + const char *name)
> +{
> + /* Treat an anonymous bitmap as a duplicate. */
> + if (!name) {
> + return true;
> + }
> + for (; bitmaps; bitmaps = bitmaps->next) {
> + if (bitmaps->value->type == QTYPE_QSTRING &&
> + strcmp(bitmaps->value->u.local, name) == 0) {
> + return true;
> + }
> + }
> + return false;
> +}
> +
> +static void collect_all_bitmaps(BlockDriverState *bs,
> + BlockDirtyBitmapOrStrList **bitmaps)
> +{
> + GLOBAL_STATE_CODE();
> + GRAPH_RDLOCK_GUARD_MAINLOOP();
> +
> + for (; bs; bs = bdrv_filter_or_cow_bs(bs)) {
> + for (BdrvDirtyBitmap *bm = bdrv_dirty_bitmap_first(bs); bm;
> + bm = bdrv_dirty_bitmap_next(bm)) {
> + const char *name = bdrv_dirty_bitmap_name(bm);
> + BlockDirtyBitmapOrStr *el;
> +
> + if (is_duplicate_bitmap(*bitmaps, name)) {
> + continue;
> + }
> + el = g_new(BlockDirtyBitmapOrStr, 1);
> + *el = (BlockDirtyBitmapOrStr) {
> + .type = QTYPE_QSTRING,
> + .u.local = g_strdup(name),
> + };
> + QAPI_LIST_PREPEND(*bitmaps, el);
> + }
> + }
> +}
> +
> int main(int argc, char **argv)
> {
> BlockBackend *blk;
> @@ -553,6 +598,7 @@ int main(int argc, char **argv)
> { "offset", required_argument, NULL, 'o' },
> { "read-only", no_argument, NULL, 'r' },
> { "allocation-depth", no_argument, NULL, 'A' },
> + { "all-bitmaps", no_argument, NULL, QEMU_NBD_OPT_ALL_BITMAPS },
> { "bitmap", required_argument, NULL, 'B' },
> { "connect", required_argument, NULL, 'c' },
> { "disconnect", no_argument, NULL, 'd' },
> @@ -602,6 +648,7 @@ int main(int argc, char **argv)
> const char *export_description = NULL;
> BlockDirtyBitmapOrStrList *bitmaps = NULL;
> bool alloc_depth = false;
> + bool all_bitmaps = false;
> const char *tlscredsid = NULL;
> const char *tlshostname = NULL;
> bool imageOpts = false;
> @@ -725,6 +772,9 @@ int main(int argc, char **argv)
> case 'A':
> alloc_depth = true;
> break;
> + case QEMU_NBD_OPT_ALL_BITMAPS:
> + all_bitmaps = true;
> + break;
> case 'B':
> {
> BlockDirtyBitmapOrStr *el = g_new(BlockDirtyBitmapOrStr, 1);
> @@ -837,7 +887,8 @@ int main(int argc, char **argv)
> }
> if (export_name || export_description || dev_offset ||
> opts.device || disconnect || fmt || sn_id_or_name || bitmaps ||
> - alloc_depth || seen_aio || seen_discard || seen_cache) {
> + all_bitmaps || alloc_depth || seen_aio || seen_discard ||
> + seen_cache) {
> error_report("List mode is incompatible with per-device settings");
> exit(EXIT_FAILURE);
> }
> @@ -1185,6 +1236,10 @@ int main(int argc, char **argv)
> exit(EXIT_FAILURE);
> }
>
> + if (all_bitmaps) {
> + collect_all_bitmaps(orig_bs, &bitmaps);
> + }
> +
> bs->detect_zeroes = detect_zeroes;
>
> nbd_server_is_qemu_nbd(shared);
> diff --git a/tests/qemu-iotests/tests/qemu-img-bitmaps b/tests/qemu-iotests/tests/qemu-img-bitmaps
> index 979bc0d6c9c..5484fe6f424 100755
> --- a/tests/qemu-iotests/tests/qemu-img-bitmaps
> +++ b/tests/qemu-iotests/tests/qemu-img-bitmaps
> @@ -131,6 +131,19 @@ $QEMU_IMG map --output=json --image-opts \
>
> nbd_server_stop
>
> +# Repeat with the --all-bitmaps option
> +nbd_server_start_unix_socket -r -f qcow2 --all-bitmaps "$TEST_IMG"
> +$QEMU_IMG map --output=json --image-opts \
> + "$IMG,x-dirty-bitmap=qemu:dirty-bitmap:b0" | _filter_qemu_img_map
> +$QEMU_IMG map --output=json --image-opts \
> + "$IMG,x-dirty-bitmap=qemu:dirty-bitmap:b1" | _filter_qemu_img_map
> +$QEMU_IMG map --output=json --image-opts \
> + "$IMG,x-dirty-bitmap=qemu:dirty-bitmap:b2" | _filter_qemu_img_map
> +$QEMU_IMG map --output=json --image-opts \
> + "$IMG,x-dirty-bitmap=qemu:dirty-bitmap:b3" | _filter_qemu_img_map
> +
> +nbd_server_stop
> +
> echo
> echo "=== Check handling of inconsistent bitmap ==="
> echo
> diff --git a/tests/qemu-iotests/tests/qemu-img-bitmaps.out b/tests/qemu-iotests/tests/qemu-img-bitmaps.out
> index 99290d3ba5e..f2e97a090b0 100644
> --- a/tests/qemu-iotests/tests/qemu-img-bitmaps.out
> +++ b/tests/qemu-iotests/tests/qemu-img-bitmaps.out
> @@ -103,6 +103,18 @@ Format specific information:
>
> === Check bitmap contents ===
>
> +[{ "start": 0, "length": 3145728, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET},
> +{ "start": 3145728, "length": 1048576, "depth": 0, "present": false, "zero": false, "data": false, "compressed": false},
> +{ "start": 4194304, "length": 6291456, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET}]
> +[{ "start": 0, "length": 1048576, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET},
> +{ "start": 1048576, "length": 1048576, "depth": 0, "present": false, "zero": false, "data": false, "compressed": false},
> +{ "start": 2097152, "length": 8388608, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET}]
> +[{ "start": 0, "length": 2097152, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET},
> +{ "start": 2097152, "length": 1048576, "depth": 0, "present": false, "zero": false, "data": false, "compressed": false},
> +{ "start": 3145728, "length": 7340032, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET}]
> +[{ "start": 0, "length": 2097152, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET},
> +{ "start": 2097152, "length": 1048576, "depth": 0, "present": false, "zero": false, "data": false, "compressed": false},
> +{ "start": 3145728, "length": 7340032, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET}]
> [{ "start": 0, "length": 3145728, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET},
> { "start": 3145728, "length": 1048576, "depth": 0, "present": false, "zero": false, "data": false, "compressed": false},
> { "start": 4194304, "length": 6291456, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET}]
Reviewed-by: Denis V. Lunev <den@openvz.org>
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] qemu-nbd: Add --all-bitmaps option
2026-10-19 22:22 [PATCH] qemu-nbd: Add --all-bitmaps option Eric Blake
2026-10-20 10:57 ` Denis V. Lunev
@ 2026-10-30 11:01 ` Kevin Wolf
1 sibling, 0 replies; 3+ messages in thread
From: Kevin Wolf @ 2026-10-30 11:01 UTC (permalink / raw)
To: Eric Blake
Cc: qemu-devel, qemu-block, Denis V. Lunev,
Vladimir Sementsov-Ogievskiy, Pierrick Bouvier, Hanna Reitz
Am 20.10.2026 um 00:22 hat Eric Blake geschrieben:
> When exporting bitmaps over NBD, we previously required a user to pass
> one '-B name' per bitmap, which they would have to use 'qemu-img info'
> to learn the list of names to pass. More convenient is an option to
> export all possible bitmaps at once, as discussed here [1].
>
> Implementation-wise, mixing --all-bitmaps and -B is harmless (grabbing
> all bitmap names already requires crawling the backing chain and
> deduplicating, so either the -B name is already detected as a
> duplicate from adding the name again, or it is an invalid name that
> will still cause a later error about bitmap not found). I also tested
> that mixing -s and --all-bitmaps still works (the temporary overlay
> image to make -s work has no bitmaps of its own, so starting the crawl
> for bitmap names at the original bs is just fine).
>
> Also, now that parallels can have bitmaps (and not just qcow2), a
> slight doc wording change for -B is warranted.
>
> [1] https://lists.nongnu.org/archive/html/qemu-devel/2026-10/msg01234.html
>
> Signed-off-by: Eric Blake <eblake@redhat.com>
> CC: Denis V. Lunev <den@openvz.org>
Thanks, applied to the block branch.
One thing I noticed is that you check for duplicates in the new
--all-bitmaps path, but in the existing -B path, nothing ever checks if
the user specified the same bitmap twice.
It seems to work fine even with adding the same bitmap twice, so I'm not
really sure if making things consistent would mean dropping the checks
for --all-bitmaps resulting in smaller code, or adding the check for -B
resulting in less surprising state. But I think there is room for a
cleanup patch on top of this.
Kevin
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-30 11:02 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-19 22:22 [PATCH] qemu-nbd: Add --all-bitmaps option Eric Blake
2026-10-20 10:57 ` Denis V. Lunev
2026-10-30 11:01 ` Kevin Wolf
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.