From b8c0e25800b49de98fd3d81cc2e48bcaf2d1e430 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Wed, 7 Oct 2026 07:26:06 -0500 Subject: [PATCH 01/13] maint: Update eblake's staging repo repo.or.cz is struggling with geofencing restrictions and frequent service degredation from AI bot overloads; time to update my staging repo to something with a bit more accessibility and uptime. Signed-off-by: Eric Blake Message-ID: <20261007122951.1935165-2-eblake@redhat.com> Reviewed-by: Markus Armbruster --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 22caaee967..33b4f7c259 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3393,7 +3393,7 @@ F: migration/block-dirty-bitmap.c F: util/hbitmap.c F: tests/unit/test-hbitmap.c F: docs/interop/bitmaps.rst -T: git https://repo.or.cz/qemu/ericb.git bitmaps +T: git https://gitlab.com/ebblake/qemu.git bitmaps T: git https://gitlab.com/vsementsov/qemu.git block Character device backends @@ -4392,7 +4392,7 @@ F: blockdev-nbd.c F: docs/interop/nbd.rst F: docs/tools/qemu-nbd.rst F: tests/qemu-iotests/tests/*nbd* -T: git https://repo.or.cz/qemu/ericb.git nbd +T: git https://gitlab.com/ebblake/qemu.git nbd T: git https://gitlab.com/vsementsov/qemu.git block NFS From 67a2606004afdea1b5bab2386ff7cf87c3cca526 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Tue, 7 Apr 2026 21:16:33 -0500 Subject: [PATCH 02/13] qemu-nbd: Support -s and -l at the same time qemu-nbd already has the ability to wrap a read-write layer on top of the export of a read-only image (-s) and the ability to export an internal snapshot rather than the main image in a qcow2 file (-l SNAPID). But it gave a confusing error message when trying to mix the two, because the snapshot overlay created first no longer has access to the internal snapshots of the image being wrapped. WIth a bit of finesse, this useful scenario is now supported. https://gitlab.com/qemu-project/qemu/-/work_items/159 Signed-off-by: Eric Blake Message-ID: <20260408021636.794794-2-eblake@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy [eblake: improve test with Vladimir's suggestions, add lock to satisfy TSAN] Signed-off-by: Eric Blake --- docs/tools/qemu-nbd.rst | 7 +- qemu-nbd.c | 22 ++++- tests/qemu-iotests/tests/qemu-nbd-snapshots | 81 +++++++++++++++++++ .../qemu-iotests/tests/qemu-nbd-snapshots.out | 39 +++++++++ 4 files changed, 143 insertions(+), 6 deletions(-) create mode 100755 tests/qemu-iotests/tests/qemu-nbd-snapshots create mode 100644 tests/qemu-iotests/tests/qemu-nbd-snapshots.out diff --git a/docs/tools/qemu-nbd.rst b/docs/tools/qemu-nbd.rst index f82ea5fd77..336b4aa46e 100644 --- a/docs/tools/qemu-nbd.rst +++ b/docs/tools/qemu-nbd.rst @@ -95,9 +95,10 @@ driver options if :option:`--image-opts` is specified. .. option:: -l, --load-snapshot=SNAPSHOT_PARAM - Load an internal snapshot inside *filename* and export it - as an read-only device, SNAPSHOT_PARAM format is - ``snapshot.id=[ID],snapshot.name=[NAME]`` or ``[ID_OR_NAME]`` + Load an internal snapshot inside *filename* and export it. + SNAPSHOT_PARAM format is ``snapshot.id=[ID],snapshot.name=[NAME]`` + or ``[ID_OR_NAME]``. The export is read-only unless ``-s`` is also + in use. .. option:: --cache=CACHE diff --git a/qemu-nbd.c b/qemu-nbd.c index ed5895861b..fcca88932a 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -534,6 +534,7 @@ int main(int argc, char **argv) { BlockBackend *blk; BlockDriverState *bs; + BlockDriverState *orig_bs; uint64_t dev_offset = 0; bool readonly = false; bool disconnect = false; @@ -716,7 +717,7 @@ int main(int argc, char **argv) } else { sn_id_or_name = optarg; } - /* fall through */ + break; case 'r': readonly = true; flags &= ~BDRV_O_RDWR; @@ -1110,6 +1111,15 @@ int main(int argc, char **argv) bdrv_init(); atexit(qemu_nbd_shutdown); + /* + * -s and -l can be used together to create read-write wrapper + * around an internal snapshot. Otherwise, -l in isolation implies + * read-only. + */ + if ((sn_opts || sn_id_or_name) && (flags & BDRV_O_SNAPSHOT) == 0) { + readonly = true; + flags &= ~BDRV_O_RDWR; + } opts.srcpath = argv[optind]; if (imageOpts) { QemuOpts *o; @@ -1155,13 +1165,19 @@ int main(int argc, char **argv) blk_set_enable_write_cache(blk, !writethrough); + orig_bs = bs; + if (flags & BDRV_O_SNAPSHOT) { + WITH_GRAPH_RDLOCK_GUARD() { + orig_bs = bs->backing->bs; + } + } if (sn_opts) { - ret = bdrv_snapshot_load_tmp(bs, + ret = bdrv_snapshot_load_tmp(orig_bs, qemu_opt_get(sn_opts, SNAPSHOT_OPT_ID), qemu_opt_get(sn_opts, SNAPSHOT_OPT_NAME), &local_err); } else if (sn_id_or_name) { - ret = bdrv_snapshot_load_tmp_by_id_or_name(bs, sn_id_or_name, + ret = bdrv_snapshot_load_tmp_by_id_or_name(orig_bs, sn_id_or_name, &local_err); } if (ret < 0) { diff --git a/tests/qemu-iotests/tests/qemu-nbd-snapshots b/tests/qemu-iotests/tests/qemu-nbd-snapshots new file mode 100755 index 0000000000..ce62e97877 --- /dev/null +++ b/tests/qemu-iotests/tests/qemu-nbd-snapshots @@ -0,0 +1,81 @@ +#!/usr/bin/env bash +# group: rw quick +# +# Test qemu-nbd snapshot handling +# +# Copyright (C) Red Hat, Inc. +# +# SPDX-License-Identifier: GPL-2.0-or-later + +seq="$(basename $0)" +echo "QA output created by $seq" + +status=1 # failure is the default! + +_cleanup() +{ + _cleanup_test_img + nbd_server_stop +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +cd .. +. ./common.rc +. ./common.filter +. ./common.nbd + +_supported_fmt qcow2 +_supported_proto file +_supported_os Linux +_require_command QEMU_NBD + +echo +echo "=== Initial image setup ===" +echo + +# Create qcow2 image with one internal snapshot +_make_test_img 10M +$QEMU_IO -c 'w -P 1 3M 1M' -f $IMGFMT "$TEST_IMG" | _filter_qemu_io +$QEMU_IMG snapshot -c snap -f $IMGFMT "$TEST_IMG" | _filter_qemu_img +$QEMU_IO -c 'w -P 2 3M 1M' -f $IMGFMT "$TEST_IMG" | _filter_qemu_io + +echo +echo "=== Main image in snapshot mode ===" +echo + +nbd_server_start_unix_socket -s -f qcow2 "$TEST_IMG" +$QEMU_IO -c 'r -P 2 3M 1M' -c 'w -P 3 3M 1M' -c 'r -P 3 3M 1M' -f raw \ + nbd:unix:$nbd_unix_socket | _filter_qemu_io +nbd_server_stop + +echo +echo "=== Read-only snapshot access ===" +echo + +nbd_server_start_unix_socket -l snap -f qcow2 "$TEST_IMG" +$QEMU_IO -r -c 'r -P 1 3M 1M' -f raw \ + nbd:unix:$nbd_unix_socket | _filter_qemu_io +$QEMU_IO -c 'r -P 1 3M 1M' -f raw \ + nbd:unix:$nbd_unix_socket 2>&1 | _filter_qemu_io | _filter_testdir +nbd_server_stop + +echo +echo "=== Combine -s and -l for read-write internal snapshot access ===" +echo + +nbd_server_start_unix_socket -s -l snap -f qcow2 "$TEST_IMG" +$QEMU_IO -c 'r -P 1 3M 1M' -c 'w -P 3 3M 1M' -c 'r -P 3 3M 1M' -f raw \ + nbd:unix:$nbd_unix_socket | _filter_qemu_io +nbd_server_stop + +echo +echo "=== Check that original image is unchanged ===" +echo + +$QEMU_IO -c 'r -P 2 3M 1M' -f $IMGFMT "$TEST_IMG" | _filter_qemu_io + +# success, all done +echo '*** done' +rm -f $seq.full +status=0 diff --git a/tests/qemu-iotests/tests/qemu-nbd-snapshots.out b/tests/qemu-iotests/tests/qemu-nbd-snapshots.out new file mode 100644 index 0000000000..47289c30f1 --- /dev/null +++ b/tests/qemu-iotests/tests/qemu-nbd-snapshots.out @@ -0,0 +1,39 @@ +QA output created by qemu-nbd-snapshots + +=== Initial image setup === + +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=10485760 +wrote 1048576/1048576 bytes at offset 3145728 +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 1048576/1048576 bytes at offset 3145728 +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +=== Main image in snapshot mode === + +read 1048576/1048576 bytes at offset 3145728 +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 1048576/1048576 bytes at offset 3145728 +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 1048576/1048576 bytes at offset 3145728 +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +=== Read-only snapshot access === + +read 1048576/1048576 bytes at offset 3145728 +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-io: can't open device nbd:unix:SOCK_DIR/qemu-nbd.sock: Could not open image: Permission denied + +=== Combine -s and -l for read-write internal snapshot access === + +read 1048576/1048576 bytes at offset 3145728 +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 1048576/1048576 bytes at offset 3145728 +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 1048576/1048576 bytes at offset 3145728 +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +=== Check that original image is unchanged === + +read 1048576/1048576 bytes at offset 3145728 +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +*** done From 90b5f6ca171dcc7673c95e31f2a270b64608bb70 Mon Sep 17 00:00:00 2001 From: Fiona Ebner Date: Wed, 30 Sep 2026 15:19:22 +0200 Subject: [PATCH 03/13] iotests: add test cases for failing flush after qemu-img convert In preparation to add more checks in the following commits and show how the behavior changes. Signed-off-by: Fiona Ebner Message-ID: <20260930132140.2342574-2-f.ebner@proxmox.com> Reviewed-by: Eric Blake Signed-off-by: Eric Blake --- tests/qemu-iotests/122 | 33 +++++++++++++++++++++++++++++++++ tests/qemu-iotests/122.out | 14 ++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/tests/qemu-iotests/122 b/tests/qemu-iotests/122 index 7f84188f51..6eafbec0e2 100755 --- a/tests/qemu-iotests/122 +++ b/tests/qemu-iotests/122 @@ -332,6 +332,39 @@ echo $QEMU_IMG convert -O $IMGFMT -o preallocation=metadata -n \ "$TEST_IMG" "$TEST_IMG".orig && echo "unexpected success" +echo +echo "=== failing flush after convert with default ('unsafe') cache mode ===" +echo + +TEST_IMG="$TEST_IMG".orig _make_test_img 1M +TEST_IMG="$TEST_IMG" _make_test_img 1M + +$QEMU_IO -c "write -P 42 0 1M" "$TEST_IMG".orig | _filter_qemu_io + +target_fails_flush="json:{ + 'driver': '$IMGFMT', + 'file': { + 'driver': 'blkdebug', + 'inject-error': [{ + 'event': 'flush_to_disk' + }], + 'image': { + 'driver': 'file', + 'filename': '$TEST_IMG' + } + } +}" + +$QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n "$TEST_IMG".orig "$target_fails_flush" +echo "qemu-img convert exited with status $?" + +echo +echo "=== failing flush after convert with 'writeback' cache mode ===" +echo + +$QEMU_IMG convert -t writeback -f $IMGFMT -O $IMGFMT -n "$TEST_IMG".orig "$target_fails_flush" +echo "qemu-img convert exited with status $?" + # success, all done echo '*** done' rm -f $seq.full diff --git a/tests/qemu-iotests/122.out b/tests/qemu-iotests/122.out index 6a1aa3fe2b..f3e28f33bc 100644 --- a/tests/qemu-iotests/122.out +++ b/tests/qemu-iotests/122.out @@ -256,4 +256,18 @@ Formatting 'TEST_DIR/t.IMGFMT.orig', fmt=IMGFMT size=67108864 === -n incompatible with -o === qemu-img: -o has no effect when skipping image creation + +=== failing flush after convert with default ('unsafe') cache mode === + +Formatting 'TEST_DIR/t.IMGFMT.orig', fmt=IMGFMT size=1048576 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 +wrote 1048576/1048576 bytes at offset 0 +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-img convert exited with status 0 + +=== failing flush after convert with 'writeback' cache mode === + +qemu-img: Failed to flush the L2 table cache: Input/output error +qemu-img: Failed to flush the refcount block cache: Input/output error +qemu-img convert exited with status 0 *** done From 9d2cdc4d3b716cf5c19af522237e8d3597d079c2 Mon Sep 17 00:00:00 2001 From: Fiona Ebner Date: Wed, 30 Sep 2026 15:19:23 +0200 Subject: [PATCH 04/13] iotests.py: add filter_qemu() Add a filter_qemu() helper function for replacing the QEMU program name with 'QEMU_PROG' in test's log messages. Signed-off-by: Fiona Ebner Message-ID: <20260930132140.2342574-3-f.ebner@proxmox.com> Reviewed-by: Eric Blake Signed-off-by: Eric Blake --- tests/qemu-iotests/iotests.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index 7d5a77a85e..642a160bb2 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -596,6 +596,10 @@ def filter_qemu_io(msg): return qemu_io_re.sub("X ops; XX:XX:XX.X " "(XXX YYY/sec and XXX ops/sec)", msg) +qemu_re = re.compile(r"%s" % os.path.basename(qemu_prog)) +def filter_qemu(msg): + return qemu_re.sub("QEMU_PROG", msg) + chown_re = re.compile(r"chown [0-9]+:[0-9]+") def filter_chown(msg): return chown_re.sub("chown UID:GID", msg) From c6c8bdc21af335ad72c899609d24844415a5af81 Mon Sep 17 00:00:00 2001 From: Fiona Ebner Date: Wed, 30 Sep 2026 15:19:24 +0200 Subject: [PATCH 05/13] block: report flush error during bdrv_close() Flush during bdrv_close() was introduced back in 2012 in commit 80ccf93b88 ("qemu-img: let 'qemu-img convert' flush data"). However, a failing flush was quietly ignored [0]. Report the error instead, since this could mean that the image contents are not as expected. Adapt the iotests accordingly. For all tests except '080' and 'qsd-migrate' the failures come from blkdebug configurations. For '080', the failures are also directly expected, because of invalid L1 table size and offset. For the 'qsd-migrate' test, the error happens, because the QSD node which is attached via NBD to the source VM was inactivated. [0]: Note that the errors reported for qcow2 come from qcow2_inactivate() which is only called as part of bs->drv->bdrv_close() after bdrv_flush(). In particular, adding > 'once': 'on' to the blkdebug driver in the relevant test case in the 122 iotest shows that the failure can be silent in case of qcow2 too. Signed-off-by: Fiona Ebner Message-ID: <20260930132140.2342574-4-f.ebner@proxmox.com> Reviewed-by: Eric Blake Signed-off-by: Eric Blake --- block.c | 13 +++- tests/qemu-iotests/026 | 10 +-- tests/qemu-iotests/026.out | 84 ++++++++++++++++++++++ tests/qemu-iotests/071 | 2 +- tests/qemu-iotests/071.out | 2 + tests/qemu-iotests/080.out | 2 + tests/qemu-iotests/098.out | 4 ++ tests/qemu-iotests/122 | 8 +-- tests/qemu-iotests/122.out | 2 + tests/qemu-iotests/244 | 2 +- tests/qemu-iotests/244.out | 1 + tests/qemu-iotests/tests/file-io-error | 2 +- tests/qemu-iotests/tests/file-io-error.out | 2 + tests/qemu-iotests/tests/qsd-migrate | 5 +- tests/qemu-iotests/tests/qsd-migrate.out | 1 + 15 files changed, 125 insertions(+), 15 deletions(-) diff --git a/block.c b/block.c index e39f15816a..e72268db8d 100644 --- a/block.c +++ b/block.c @@ -5174,12 +5174,23 @@ static void GRAPH_UNLOCKED bdrv_close(BlockDriverState *bs) { BdrvAioNotifier *ban, *ban_next; BdrvChild *child, *next; + int ret; GLOBAL_STATE_CODE(); assert(!bs->refcnt); bdrv_drained_begin(bs); /* complete I/O */ - bdrv_flush(bs); + ret = bdrv_flush(bs); + if (ret < 0) { + const char *name; + if (bs->filename[0]) { + name = bs->filename; + } else { + name = bdrv_get_node_name(bs); + } + error_report("Failed flush for '%s' during close: %s", name, + strerror(-ret)); + } bdrv_drain(bs); /* in case flush left pending I/O */ if (bs->drv) { diff --git a/tests/qemu-iotests/026 b/tests/qemu-iotests/026 index f43a2bd55b..4fd319232a 100755 --- a/tests/qemu-iotests/026 +++ b/tests/qemu-iotests/026 @@ -101,13 +101,13 @@ if [ "$event" == "l2_update" ]; then $QEMU_IO -c "write $vmstate 0 512" "$TEST_IMG" > /dev/null 2>&1 fi -$QEMU_IO -c "write $vmstate 0 128k " "$BLKDBG_TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "write $vmstate 0 128k " "$BLKDBG_TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir # l2_load is not called on allocation, so issue a second write # Reads are another path to trigger l2_load, so do a read, too if [ "$event" == "l2_load" ]; then - $QEMU_IO -c "write $vmstate 0 128k " "$BLKDBG_TEST_IMG" | _filter_qemu_io - $QEMU_IO -c "read $vmstate 0 128k " "$BLKDBG_TEST_IMG" | _filter_qemu_io + $QEMU_IO -c "write $vmstate 0 128k " "$BLKDBG_TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir + $QEMU_IO -c "read $vmstate 0 128k " "$BLKDBG_TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir fi _check_test_img_ignore_leaks 2>&1 | grep -v "refcount=1 reference=0" @@ -153,7 +153,7 @@ _make_test_img 1G echo echo "Event: $event; errno: $errno; imm: $imm; once: $once; write $vmstate" -$QEMU_IO -c "write $vmstate 0 64M" "$BLKDBG_TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "write $vmstate 0 64M" "$BLKDBG_TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir _check_test_img_ignore_leaks 2>&1 | grep -v "refcount=1 reference=0" @@ -192,7 +192,7 @@ _make_test_img 1G echo echo "Event: $event; errno: $errno; imm: $imm; once: $once" -$QEMU_IO -c "write -b 0 64k" "$BLKDBG_TEST_IMG" | _filter_qemu_io +$QEMU_IO -c "write -b 0 64k" "$BLKDBG_TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir _check_test_img_ignore_leaks 2>&1 | grep -v "refcount=1 reference=0" diff --git a/tests/qemu-iotests/026.out b/tests/qemu-iotests/026.out index b998a9ac83..47bd88b1d3 100644 --- a/tests/qemu-iotests/026.out +++ b/tests/qemu-iotests/026.out @@ -15,15 +15,19 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: l1_update; errno: 5; imm: off; once: off; write qemu-io: write failed: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error qemu-io: Failed to flush the L2 table cache: Input/output error qemu-io: Failed to flush the refcount block cache: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: l1_update; errno: 5; imm: off; once: off; write -b qemu-io: write failed: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error qemu-io: Failed to flush the L2 table cache: Input/output error qemu-io: Failed to flush the refcount block cache: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 @@ -39,15 +43,19 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: l1_update; errno: 28; imm: off; once: off; write qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: l1_update; errno: 28; imm: off; once: off; write -b qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 @@ -127,15 +135,19 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: l2_update; errno: 5; imm: off; once: off; write qemu-io: write failed: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error qemu-io: Failed to flush the L2 table cache: Input/output error qemu-io: Failed to flush the refcount block cache: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: l2_update; errno: 5; imm: off; once: off; write -b qemu-io: write failed: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error qemu-io: Failed to flush the L2 table cache: Input/output error qemu-io: Failed to flush the refcount block cache: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 @@ -151,15 +163,19 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: l2_update; errno: 28; imm: off; once: off; write qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: l2_update; errno: 28; imm: off; once: off; write -b qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 @@ -175,15 +191,19 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: l2_alloc_write; errno: 5; imm: off; once: off; write qemu-io: write failed: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error qemu-io: Failed to flush the L2 table cache: Input/output error qemu-io: Failed to flush the refcount block cache: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: l2_alloc_write; errno: 5; imm: off; once: off; write -b qemu-io: write failed: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error qemu-io: Failed to flush the L2 table cache: Input/output error qemu-io: Failed to flush the refcount block cache: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 @@ -199,15 +219,19 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: l2_alloc_write; errno: 28; imm: off; once: off; write qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: l2_alloc_write; errno: 28; imm: off; once: off; write -b qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 @@ -223,15 +247,19 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: write_aio; errno: 5; imm: off; once: off; write qemu-io: write failed: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error qemu-io: Failed to flush the L2 table cache: Input/output error qemu-io: Failed to flush the refcount block cache: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: write_aio; errno: 5; imm: off; once: off; write -b qemu-io: write failed: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error qemu-io: Failed to flush the L2 table cache: Input/output error qemu-io: Failed to flush the refcount block cache: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 @@ -247,15 +275,19 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: write_aio; errno: 28; imm: off; once: off; write qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: write_aio; errno: 28; imm: off; once: off; write -b qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 @@ -271,15 +303,19 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: refblock_load; errno: 5; imm: off; once: off; write qemu-io: write failed: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error qemu-io: Failed to flush the L2 table cache: Input/output error qemu-io: Failed to flush the refcount block cache: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: refblock_load; errno: 5; imm: off; once: off; write -b qemu-io: write failed: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error qemu-io: Failed to flush the L2 table cache: Input/output error qemu-io: Failed to flush the refcount block cache: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 @@ -295,15 +331,19 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: refblock_load; errno: 28; imm: off; once: off; write qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: refblock_load; errno: 28; imm: off; once: off; write -b qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 @@ -319,15 +359,19 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: refblock_update_part; errno: 5; imm: off; once: off; write qemu-io: write failed: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error qemu-io: Failed to flush the L2 table cache: Input/output error qemu-io: Failed to flush the refcount block cache: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: refblock_update_part; errno: 5; imm: off; once: off; write -b qemu-io: write failed: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error qemu-io: Failed to flush the L2 table cache: Input/output error qemu-io: Failed to flush the refcount block cache: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 @@ -343,15 +387,19 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: refblock_update_part; errno: 28; imm: off; once: off; write qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: refblock_update_part; errno: 28; imm: off; once: off; write -b qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 @@ -367,15 +415,19 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: refblock_alloc; errno: 5; imm: off; once: off; write qemu-io: write failed: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error qemu-io: Failed to flush the L2 table cache: Input/output error qemu-io: Failed to flush the refcount block cache: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: refblock_alloc; errno: 5; imm: off; once: off; write -b qemu-io: write failed: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error qemu-io: Failed to flush the L2 table cache: Input/output error qemu-io: Failed to flush the refcount block cache: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 @@ -391,15 +443,19 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: refblock_alloc; errno: 28; imm: off; once: off; write qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: refblock_alloc; errno: 28; imm: off; once: off; write -b qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 @@ -458,15 +514,19 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: refblock_alloc_hookup; errno: 28; imm: off; once: off; write qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: refblock_alloc_hookup; errno: 28; imm: off; once: off; write -b qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 @@ -482,15 +542,19 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: refblock_alloc_write; errno: 28; imm: off; once: off; write qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: refblock_alloc_write; errno: 28; imm: off; once: off; write -b qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 @@ -506,15 +570,19 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: off; write qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: off; write -b qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 @@ -530,15 +598,19 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: refblock_alloc_write_table; errno: 28; imm: off; once: off; write qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: refblock_alloc_write_table; errno: 28; imm: off; once: off; write -b qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 @@ -554,15 +626,19 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: refblock_alloc_switch_table; errno: 28; imm: off; once: off; write qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: refblock_alloc_switch_table; errno: 28; imm: off; once: off; write -b qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. === L1 growth tests === @@ -596,8 +672,10 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: l1_grow_write_table; errno: 5; imm: off; once: off qemu-io: write failed: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error qemu-io: Failed to flush the L2 table cache: Input/output error qemu-io: Failed to flush the refcount block cache: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 @@ -608,8 +686,10 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: l1_grow_write_table; errno: 28; imm: off; once: off qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 @@ -620,8 +700,10 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: l1_grow_activate_table; errno: 5; imm: off; once: off qemu-io: write failed: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error qemu-io: Failed to flush the L2 table cache: Input/output error qemu-io: Failed to flush the refcount block cache: Input/output error +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: Input/output error No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 @@ -632,8 +714,10 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Event: l1_grow_activate_table; errno: 28; imm: off; once: off qemu-io: write failed: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device qemu-io: Failed to flush the L2 table cache: No space left on device qemu-io: Failed to flush the refcount block cache: No space left on device +qemu-io: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.qcow2' during close: No space left on device No errors were found on the image. === Avoid cluster leaks after temporary failure === diff --git a/tests/qemu-iotests/071 b/tests/qemu-iotests/071 index fc4eba8e18..f9e8574aec 100755 --- a/tests/qemu-iotests/071 +++ b/tests/qemu-iotests/071 @@ -52,7 +52,7 @@ do_run_qemu() run_qemu() { - do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_qmp | _filter_qemu_io + do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_qmp | _filter_qemu_io | _filter_json_filename } IMG_SIZE=64M diff --git a/tests/qemu-iotests/071.out b/tests/qemu-iotests/071.out index f2d015d8cc..a69e6f7e50 100644 --- a/tests/qemu-iotests/071.out +++ b/tests/qemu-iotests/071.out @@ -83,8 +83,10 @@ wrote 512/512 bytes at offset 0 {"return": ""} {"return": "Error: read failed: Input/output error\r\n"} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} +QEMU_PROG: Failed flush for 'json:{ /* filtered */ }' during close: Input/output error QEMU_PROG: Failed to flush the L2 table cache: Input/output error QEMU_PROG: Failed to flush the refcount block cache: Input/output error +QEMU_PROG: Failed flush for 'json:{ /* filtered */ }' during close: Input/output error {"return": {}} *** done diff --git a/tests/qemu-iotests/080.out b/tests/qemu-iotests/080.out index b20c21faf6..3b2b27c5fe 100644 --- a/tests/qemu-iotests/080.out +++ b/tests/qemu-iotests/080.out @@ -67,6 +67,7 @@ qemu-img: Failed to load snapshot: Snapshot L1 table offset invalid qemu-img: Snapshot L1 table offset invalid qemu-img: Failed to turn zero into data clusters: Invalid argument qemu-io: write failed: Invalid argument +qemu-io: Failed flush for 'TEST_DIR/t.qcow2' during close: Invalid argument qemu-io: Failed to flush the refcount block cache: Invalid argument qemu-img: Snapshot L1 table offset invalid qemu-img: Could not apply snapshot 'test': Failed to load snapshot: Invalid argument @@ -90,6 +91,7 @@ qemu-img: Failed to load snapshot: Snapshot L1 table too large qemu-img: Snapshot L1 table too large qemu-img: Failed to turn zero into data clusters: File too large qemu-io: write failed: File too large +qemu-io: Failed flush for 'TEST_DIR/t.qcow2' during close: File too large qemu-io: Failed to flush the refcount block cache: File too large qemu-img: Snapshot L1 table too large qemu-img: Could not apply snapshot 'test': Failed to load snapshot: File too large diff --git a/tests/qemu-iotests/098.out b/tests/qemu-iotests/098.out index 6c73dd0977..912b0290af 100644 --- a/tests/qemu-iotests/098.out +++ b/tests/qemu-iotests/098.out @@ -6,6 +6,7 @@ Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=IMGFMT wrote 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-img: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT' during close: Input/output error qemu-img: Failed to empty blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error No errors were found on the image. @@ -15,6 +16,7 @@ Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=IMGFMT wrote 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-img: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT' during close: Input/output error qemu-img: Failed to empty blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error Leaked cluster 4 refcount=1 reference=0 Leaked cluster 5 refcount=1 reference=0 @@ -28,6 +30,7 @@ Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=IMGFMT wrote 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-img: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT' during close: Input/output error qemu-img: Failed to empty blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error ERROR cluster 0 refcount=0 reference=1 ERROR cluster 1 refcount=0 reference=1 @@ -42,6 +45,7 @@ Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=IMGFMT wrote 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-img: Failed flush for 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT' during close: Input/output error qemu-img: Failed to empty blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error ERROR cluster 0 refcount=0 reference=1 ERROR cluster 1 refcount=0 reference=1 diff --git a/tests/qemu-iotests/122 b/tests/qemu-iotests/122 index 6eafbec0e2..6570df76b6 100755 --- a/tests/qemu-iotests/122 +++ b/tests/qemu-iotests/122 @@ -355,15 +355,15 @@ target_fails_flush="json:{ } }" -$QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n "$TEST_IMG".orig "$target_fails_flush" -echo "qemu-img convert exited with status $?" +$QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n "$TEST_IMG".orig "$target_fails_flush" 2>&1 | _filter_json_filename +echo "qemu-img convert exited with status ${PIPESTATUS[0]}" echo echo "=== failing flush after convert with 'writeback' cache mode ===" echo -$QEMU_IMG convert -t writeback -f $IMGFMT -O $IMGFMT -n "$TEST_IMG".orig "$target_fails_flush" -echo "qemu-img convert exited with status $?" +$QEMU_IMG convert -t writeback -f $IMGFMT -O $IMGFMT -n "$TEST_IMG".orig "$target_fails_flush" 2>&1 | _filter_json_filename +echo "qemu-img convert exited with status ${PIPESTATUS[0]}" # success, all done echo '*** done' diff --git a/tests/qemu-iotests/122.out b/tests/qemu-iotests/122.out index f3e28f33bc..84283f2434 100644 --- a/tests/qemu-iotests/122.out +++ b/tests/qemu-iotests/122.out @@ -267,7 +267,9 @@ qemu-img convert exited with status 0 === failing flush after convert with 'writeback' cache mode === +qemu-img: Failed flush for 'json:{ /* filtered */ }' during close: Input/output error qemu-img: Failed to flush the L2 table cache: Input/output error qemu-img: Failed to flush the refcount block cache: Input/output error +qemu-img: Failed flush for 'json:{ /* filtered */ }' during close: Input/output error qemu-img convert exited with status 0 *** done diff --git a/tests/qemu-iotests/244 b/tests/qemu-iotests/244 index a8af524c12..334e1c2b8d 100755 --- a/tests/qemu-iotests/244 +++ b/tests/qemu-iotests/244 @@ -262,7 +262,7 @@ $QEMU_IO -c 'write 0 512' -c flush \ } } }" \ - | _filter_qemu_io + 2>&1 | _filter_qemu_io | _filter_generated_node_ids result=${PIPESTATUS[0]} echo diff --git a/tests/qemu-iotests/244.out b/tests/qemu-iotests/244.out index c5e62146c9..81463d6f0e 100644 --- a/tests/qemu-iotests/244.out +++ b/tests/qemu-iotests/244.out @@ -134,6 +134,7 @@ Images are identical. === Flushing should flush the data file === +qemu-io: Failed flush for 'NODE_NAME' during close: Input/output error wrote 512/512 bytes at offset 0 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) diff --git a/tests/qemu-iotests/tests/file-io-error b/tests/qemu-iotests/tests/file-io-error index 0d970c102f..3885b741d9 100755 --- a/tests/qemu-iotests/tests/file-io-error +++ b/tests/qemu-iotests/tests/file-io-error @@ -94,7 +94,7 @@ echo "$output" echo # This should fail, but gracefully, i.e. just print an I/O error, not crash. -$QEMU_IO -f file -c 'write 0 64M' "$TEST_DIR/fuse-export" | _filter_qemu_io +$QEMU_IO -f file -c 'write 0 64M' "$TEST_DIR/fuse-export" 2>&1 | _filter_qemu_io | _filter_testdir echo capture_events=BLOCK_EXPORT_DELETED _send_qemu_cmd $QEMU_HANDLE \ diff --git a/tests/qemu-iotests/tests/file-io-error.out b/tests/qemu-iotests/tests/file-io-error.out index bf8c0018ba..748ea3079c 100644 --- a/tests/qemu-iotests/tests/file-io-error.out +++ b/tests/qemu-iotests/tests/file-io-error.out @@ -22,6 +22,7 @@ QA output created by file-io-error {"return": {}} qemu-io: write failed: Input/output error +qemu-io: Failed flush for 'TEST_DIR/fuse-export' during close: Input/output error {'execute': 'block-export-del', 'arguments': {'id': 'exp0'}} @@ -29,5 +30,6 @@ qemu-io: write failed: Input/output error {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "exp0"}} {'execute': 'blockdev-del', 'arguments': {'node-name': 'node0'}} +QEMU_PROG: Failed flush for 'node0' during close: Input/output error {"return": {}} *** done diff --git a/tests/qemu-iotests/tests/qsd-migrate b/tests/qemu-iotests/tests/qsd-migrate index d76278b576..73583dec16 100755 --- a/tests/qemu-iotests/tests/qsd-migrate +++ b/tests/qemu-iotests/tests/qsd-migrate @@ -20,7 +20,7 @@ import iotests -from iotests import filter_qemu_io, filter_qtest +from iotests import filter_qemu, filter_qemu_io, filter_qtest iotests.script_initialize(supported_fmts=['qcow2', 'qed', 'raw'], supported_protocols=['file'], @@ -126,11 +126,12 @@ with iotests.FilePath('disk.img') as path, \ iotests.log('\nDone') + # NOTE: Flush during close fails here, since the QSD node was inactivated. vm_src.shutdown() iotests.log('\n--- vm_src log ---') log = vm_src.get_log() if log: - iotests.log(log, [filter_qtest, filter_qemu_io]) + iotests.log(log, [filter_qtest, filter_qemu_io, filter_qemu]) qsd_src.stop() vm_dst.shutdown() diff --git a/tests/qemu-iotests/tests/qsd-migrate.out b/tests/qemu-iotests/tests/qsd-migrate.out index 4a5241e5d4..894b232b4a 100644 --- a/tests/qemu-iotests/tests/qsd-migrate.out +++ b/tests/qemu-iotests/tests/qsd-migrate.out @@ -47,6 +47,7 @@ read 4096/4096 bytes at offset 0 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) read 4096/4096 bytes at offset 0 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +QEMU_PROG: Failed flush for 'disk' during close: Operation not permitted --- vm_dst log --- read 4096/4096 bytes at offset 0 From 901ac73874c2129a17b6e54482aee800a0f9b2d2 Mon Sep 17 00:00:00 2001 From: Fiona Ebner Date: Wed, 30 Sep 2026 15:19:25 +0200 Subject: [PATCH 06/13] qemu-img: convert: flush target image after copying With 'qemu-img convert', when using a cache mode with 'cache.no-flush = off', the expectation is that the data is flushed to the disk, which happens since commit 80ccf93b88 ("qemu-img: let 'qemu-img convert' flush data"). This expectation also encompasses that failure to do so is properly reported, so ensure that 'qemu-img convert' exits with a non-zero status code when the target image cannot be flushed. In particular, the reproducer below [0], based on a report by Ing. Alfonso Kuen Arroyo [1], would result in > rc=0 > Content mismatch at offset XYZ! before this change, and in > rc=1 > Content mismatch at offset XYZ! after this change. Note that this change does not affect the (default) 'unsafe' cache mode, because bdrv_co_flush() still skips flush to disk for that cache mode. [0]: > #!/bin/bash -x > dd if=/dev/urandom of=src.raw bs=1M count=500 > truncate -s 500M dst.img > LOOP=$(losetup --find --show dst.img) > SIZE=$(blockdev --getsz $LOOP) > dd if=/dev/zero of=$LOOP bs=1M count=500 conv=fsync status=none > sync > echo 3 > /proc/sys/vm/drop_caches > dmsetup create flk --table "0 $SIZE flakey $LOOP 0 5 5" > qemu-img convert -t writeback -p -r 100M -f raw -O raw src.raw /dev/mapper/flk > echo rc=$? > sleep 5 > dmsetup remove flk > qemu-img compare src.raw $LOOP > losetup -d $LOOP > rm src.raw dst.img [1]: https://lore.proxmox.com/pve-devel/178961792132.43804.17173233935297903311@idkmanager.com/ Signed-off-by: Fiona Ebner Message-ID: <20260930132140.2342574-5-f.ebner@proxmox.com> Reviewed-by: Eric Blake Signed-off-by: Eric Blake --- qemu-img.c | 8 +++++++- tests/qemu-iotests/122.out | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/qemu-img.c b/qemu-img.c index 2f63d31141..edf75e43ab 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -2245,7 +2245,7 @@ static int img_convert(const img_cmd_t *ccmd, int argc, char **argv) Error *local_err = NULL; bool writethrough, src_writethrough, image_opts = false, skip_create = false, progress = false, tgt_image_opts = false; - int64_t ret = -EINVAL; + int64_t ret = -EINVAL, ret2; bool force_share = false; bool explict_min_sparse = false; bool bitmaps = false; @@ -2872,6 +2872,12 @@ static int img_convert(const img_cmd_t *ccmd, int argc, char **argv) ret = convert_copy_bitmaps(blk_bs(s.src[0]), out_bs, skip_broken); } + ret2 = blk_flush(s.target); + if (ret2 < 0) { + error_report("Failed to flush target image: %s", strerror(-ret2)); + ret = ret != 0 ? ret : ret2; + } + out: if (!ret) { qemu_progress_print(100, 0); diff --git a/tests/qemu-iotests/122.out b/tests/qemu-iotests/122.out index 84283f2434..38794f96ac 100644 --- a/tests/qemu-iotests/122.out +++ b/tests/qemu-iotests/122.out @@ -267,9 +267,10 @@ qemu-img convert exited with status 0 === failing flush after convert with 'writeback' cache mode === +qemu-img: Failed to flush target image: Input/output error qemu-img: Failed flush for 'json:{ /* filtered */ }' during close: Input/output error qemu-img: Failed to flush the L2 table cache: Input/output error qemu-img: Failed to flush the refcount block cache: Input/output error qemu-img: Failed flush for 'json:{ /* filtered */ }' during close: Input/output error -qemu-img convert exited with status 0 +qemu-img convert exited with status 1 *** done From 319cd41f110ada2cbb7dd17700893327a3cb925e Mon Sep 17 00:00:00 2001 From: "Denis V. Lunev" Date: Tue, 6 Oct 2026 19:07:36 +0200 Subject: [PATCH 07/13] migration: add QEMU_COUNTED_STRING_SIZE for counted string buffers A counted string carries its length in one byte, so the buffer that qemu_get_counted_string() fills must hold 256 bytes. The dirty bitmap load state spells that size as a bare 256 for both of its alias buffers. Name it next to the qemu_get_counted_string() prototype and use it there, in the length assert of qemu_put_counted_string() and in DBMLoadState. Suggested-by: Eric Blake Signed-off-by: Denis V. Lunev Cc: Peter Xu Cc: Fabiano Rosas Cc: Eric Blake Cc: Vladimir Sementsov-Ogievskiy Cc: qemu-stable@nongnu.org Message-ID: <20261006170738.453977-2-den@openvz.org> Reviewed-by: Eric Blake Signed-off-by: Eric Blake --- include/migration/qemu-file-types.h | 6 +++++- migration/block-dirty-bitmap.c | 4 ++-- migration/qemu-file.c | 5 +++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/include/migration/qemu-file-types.h b/include/migration/qemu-file-types.h index adec5abc07..2a073bed29 100644 --- a/include/migration/qemu-file-types.h +++ b/include/migration/qemu-file-types.h @@ -163,7 +163,11 @@ static inline void qemu_get_sbe64s(QEMUFile *f, int64_t *pv) qemu_get_be64s(f, (uint64_t *)pv); } -size_t coroutine_mixed_fn qemu_get_counted_string(QEMUFile *f, char buf[256]); +/* Buffer size for a string whose length is sent as a single byte */ +#define QEMU_COUNTED_STRING_SIZE 256 + +size_t coroutine_mixed_fn +qemu_get_counted_string(QEMUFile *f, char buf[QEMU_COUNTED_STRING_SIZE]); void qemu_put_counted_string(QEMUFile *f, const char *name); diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c index 1b8f39c12b..1386f43635 100644 --- a/migration/block-dirty-bitmap.c +++ b/migration/block-dirty-bitmap.c @@ -145,8 +145,8 @@ typedef struct LoadBitmapState { /* State of the dirty bitmap migration (DBM) during load process */ typedef struct DBMLoadState { uint32_t flags; - char node_alias[256]; - char bitmap_alias[256]; + char node_alias[QEMU_COUNTED_STRING_SIZE]; + char bitmap_alias[QEMU_COUNTED_STRING_SIZE]; char bitmap_name[BDRV_BITMAP_MAX_NAME_SIZE + 1]; BlockDriverState *bs; BdrvDirtyBitmap *bitmap; diff --git a/migration/qemu-file.c b/migration/qemu-file.c index 7735e61854..df3f96fb24 100644 --- a/migration/qemu-file.c +++ b/migration/qemu-file.c @@ -829,7 +829,8 @@ uint64_t qemu_get_be64(QEMUFile *f) * else 0 * (Note a 0 length string will return 0 either way) */ -size_t coroutine_mixed_fn qemu_get_counted_string(QEMUFile *f, char buf[256]) +size_t coroutine_mixed_fn +qemu_get_counted_string(QEMUFile *f, char buf[QEMU_COUNTED_STRING_SIZE]) { size_t len = qemu_get_byte(f); size_t res = qemu_get_buffer(f, (uint8_t *)buf, len); @@ -847,7 +848,7 @@ void qemu_put_counted_string(QEMUFile *f, const char *str) { size_t len = strlen(str); - assert(len < 256); + assert(len < QEMU_COUNTED_STRING_SIZE); qemu_put_byte(f, len); qemu_put_buffer(f, (const uint8_t *)str, len); } From 4d11088a088d0915196e38b3e69df12d4f06fdb5 Mon Sep 17 00:00:00 2001 From: "Denis V. Lunev" Date: Tue, 6 Oct 2026 19:07:37 +0200 Subject: [PATCH 08/13] migration/block-dirty-bitmap: fix postcopy abort with bitmaps on several nodes With dirty bitmaps on more than one node, the source switches nodes during the postcopy bulk phase and sends the node name again. The destination reads those chunks in the postcopy listen thread, which does not hold the BQL, and resolves the name through bdrv_lookup_bs(): qemu-system-x86_64: ../block.c:6400: bdrv_lookup_bs: Assertion `qemu_in_main_thread()' failed. The bdrv_find_dirty_bitmap() call right after it needs the BQL or the dirty bitmap lock as well. Taking the BQL there would deadlock: the listen thread holds s->lock, and dirty_bitmap_mig_before_vm_start() takes s->lock with the BQL held. Every node and bitmap that a non-START chunk refers to was set up by a START chunk, and those are loaded under the BQL during setup. Record the node alias there, and resolve all other chunks against s->bitmaps instead of the block graph. Bitmaps on a single node never resend the node name after setup, which is why migrate-bitmaps-postcopy-test does not catch this. Fixes: f791bf7f93f2 ("assertions for block global state API") Signed-off-by: Denis V. Lunev Cc: Peter Xu Cc: Fabiano Rosas Cc: Eric Blake Cc: Vladimir Sementsov-Ogievskiy Cc: qemu-stable@nongnu.org Message-ID: <20261006170738.453977-3-den@openvz.org> Reviewed-by: Eric Blake Signed-off-by: Eric Blake --- migration/block-dirty-bitmap.c | 58 +++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c index 1386f43635..35623379eb 100644 --- a/migration/block-dirty-bitmap.c +++ b/migration/block-dirty-bitmap.c @@ -140,6 +140,7 @@ typedef struct LoadBitmapState { BdrvDirtyBitmap *bitmap; bool migrated; bool enabled; + char node_alias[QEMU_COUNTED_STRING_SIZE]; } LoadBitmapState; /* State of the dirty bitmap migration (DBM) during load process */ @@ -859,6 +860,7 @@ static int dirty_bitmap_load_start(QEMUFile *f, DBMLoadState *s) } b = g_new(LoadBitmapState, 1); + g_strlcpy(b->node_alias, s->node_alias, sizeof(b->node_alias)); b->bs = s->bs; b->bitmap = s->bitmap; b->migrated = false; @@ -1056,6 +1058,53 @@ static int dirty_bitmap_load_bits(QEMUFile *f, DBMLoadState *s) return 0; } +/* + * Only START chunks are guaranteed to be loaded under the BQL; the rest may + * come from the postcopy listen thread and must not touch the block graph. + */ +static BlockDriverState *dirty_bitmap_load_find_bs(DBMLoadState *s, + const char *device, + const char *node_name, + Error **errp) +{ + GSList *item; + + if (s->flags & DIRTY_BITMAP_MIG_FLAG_START) { + return bdrv_lookup_bs(device, node_name, errp); + } + + for (item = s->bitmaps; item; item = g_slist_next(item)) { + LoadBitmapState *b = item->data; + + if (!strcmp(b->node_alias, s->node_alias)) { + return b->bs; + } + } + + error_setg(errp, "no migrated bitmaps on node alias '%s'", s->node_alias); + return NULL; +} + +static BdrvDirtyBitmap *dirty_bitmap_load_find_bitmap(DBMLoadState *s) +{ + GSList *item; + + if (s->flags & DIRTY_BITMAP_MIG_FLAG_START) { + return bdrv_find_dirty_bitmap(s->bs, s->bitmap_name); + } + + for (item = s->bitmaps; item; item = g_slist_next(item)) { + LoadBitmapState *b = item->data; + + if (b->bs == s->bs && + !strcmp(bdrv_dirty_bitmap_name(b->bitmap), s->bitmap_name)) { + return b->bitmap; + } + } + + return NULL; +} + static int dirty_bitmap_load_header(QEMUFile *f, DBMLoadState *s, GHashTable *alias_map) { @@ -1084,11 +1133,12 @@ static int dirty_bitmap_load_header(QEMUFile *f, DBMLoadState *s, s->bs = NULL; } else { bitmap_alias_map = amin->subtree; - s->bs = bdrv_lookup_bs(NULL, amin->string, &local_err); + s->bs = dirty_bitmap_load_find_bs(s, NULL, amin->string, + &local_err); } } else { - s->bs = bdrv_lookup_bs(s->node_alias, s->node_alias, - &local_err); + s->bs = dirty_bitmap_load_find_bs(s, s->node_alias, + s->node_alias, &local_err); } if (!s->bs) { error_report_err(local_err); @@ -1139,7 +1189,7 @@ static int dirty_bitmap_load_header(QEMUFile *f, DBMLoadState *s, if (!s->cancelled) { g_strlcpy(s->bitmap_name, bitmap_name, sizeof(s->bitmap_name)); - s->bitmap = bdrv_find_dirty_bitmap(s->bs, s->bitmap_name); + s->bitmap = dirty_bitmap_load_find_bitmap(s); /* * bitmap may be NULL here, it wouldn't be an error if it is the From faa80b9847b9f326d7570c512d52e0a22a5bd5b3 Mon Sep 17 00:00:00 2001 From: "Denis V. Lunev" Date: Tue, 6 Oct 2026 19:07:38 +0200 Subject: [PATCH 09/13] iotests/migrate-bitmaps-postcopy-test: add a bitmap on a second node All bitmaps in the test live on drive0, so the source never switches nodes after setup and the destination never resolves a node name from the postcopy listen thread. Add a second drive with one bitmap and check that it arrives intact. Signed-off-by: Denis V. Lunev Tested-by: Eric Blake Reviewed-by: Eric Blake Cc: Peter Xu Cc: Fabiano Rosas Cc: Vladimir Sementsov-Ogievskiy Message-ID: <20261006170738.453977-4-den@openvz.org> [eblake: squash in fix to pass even after aborted run left behind stale fifo, and to avoid check-python-minreqs lint failure] Signed-off-by: Eric Blake --- .../tests/migrate-bitmaps-postcopy-test | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test b/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test index b2b37ada4b..53f7dafc79 100755 --- a/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test +++ b/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test @@ -27,6 +27,8 @@ debug = False disk_a = os.path.join(iotests.test_dir, 'disk_a') disk_b = os.path.join(iotests.test_dir, 'disk_b') +disk_a1 = os.path.join(iotests.test_dir, 'disk_a1') +disk_b1 = os.path.join(iotests.test_dir, 'disk_b1') size = '256G' fifo = os.path.join(iotests.test_dir, 'mig_fifo') @@ -97,16 +99,26 @@ class TestDirtyBitmapPostcopyMigration(iotests.QMPTestCase): self.vm_b.shutdown() os.remove(disk_a) os.remove(disk_b) + os.remove(disk_a1) + os.remove(disk_b1) os.remove(fifo) def setUp(self): + if os.path.exists(fifo): + os.remove(fifo) os.mkfifo(fifo) qemu_img('create', '-f', iotests.imgfmt, disk_a, size) qemu_img('create', '-f', iotests.imgfmt, disk_b, size) + qemu_img('create', '-f', iotests.imgfmt, disk_a1, '1G') + qemu_img('create', '-f', iotests.imgfmt, disk_b1, '1G') self.vm_a = iotests.VM(path_suffix='a').add_drive(disk_a, 'discard=unmap') self.vm_b = iotests.VM(path_suffix='b').add_drive(disk_b, 'discard=unmap') + self.drive1_sha256 = "" + # A bitmap on a second node makes postcopy switch nodes after setup + self.vm_a.add_drive(disk_a1) + self.vm_b.add_drive(disk_b1) self.vm_b.add_incoming("exec: cat '" + fifo + "'") self.vm_a.launch() self.vm_b.launch() @@ -127,6 +139,13 @@ class TestDirtyBitmapPostcopyMigration(iotests.QMPTestCase): node='drive0', name='bitmap0') empty_sha256 = result['return']['sha256'] + self.vm_a.cmd('block-dirty-bitmap-add', node='drive1', + name='bitmap0', granularity=granularity) + self.vm_a.hmp_qemu_io('drive1', 'write 0 64k') + result = self.vm_a.qmp('x-debug-block-dirty-bitmap-sha256', + node='drive1', name='bitmap0') + self.drive1_sha256 = result['return']['sha256'] + apply_discards(self.vm_a, discards1) result = self.vm_a.qmp('x-debug-block-dirty-bitmap-sha256', @@ -212,6 +231,9 @@ class TestDirtyBitmapPostcopyMigration(iotests.QMPTestCase): # check that bitmaps are migrated and persistence works check_bitmaps(self.vm_b, nb_bitmaps) + result = self.vm_b.qmp('x-debug-block-dirty-bitmap-sha256', + node='drive1', name='bitmap0') + self.assert_qmp(result, 'return/sha256', self.drive1_sha256) self.vm_b.shutdown() # recreate vm_b, so there is no incoming option, which prevents # loading bitmaps from disk From 491b16721044353b980aa562cd163c6d51eac19a Mon Sep 17 00:00:00 2001 From: Eric Farman Date: Fri, 25 Sep 2026 21:44:05 +0200 Subject: [PATCH 10/13] iotests/nbd-in-qcow2-chain: use default machine Some of the NBD tests explicitly specify `-machine q35` which won't work when running against, say, qemu-system-s390x. The nbd-in-qcow2-chain test runs fine with the default machine on a z16 host, so allow it to run in other configurations. Fixes: 24fd6d75b3 ("iotests: Add coverage of recent NBD qio deadlock fix") Signed-off-by: Eric Farman Message-ID: <20260925194409.716498-2-farman@linux.ibm.com> Reviewed-by: Eric Blake Signed-off-by: Eric Blake --- tests/qemu-iotests/tests/nbd-in-qcow2-chain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/qemu-iotests/tests/nbd-in-qcow2-chain b/tests/qemu-iotests/tests/nbd-in-qcow2-chain index 9a977e5a1b..5c929e42f9 100755 --- a/tests/qemu-iotests/tests/nbd-in-qcow2-chain +++ b/tests/qemu-iotests/tests/nbd-in-qcow2-chain @@ -41,7 +41,7 @@ TEST_IMG="$TEST_IMG.base" _make_test_img $size echo echo "=== Starting QEMU and exposing base image ===" -_launch_qemu -machine q35 +_launch_qemu h1=$QEMU_HANDLE _send_qemu_cmd $QEMU_HANDLE '{"execute": "qmp_capabilities"}' 'return' _send_qemu_cmd $QEMU_HANDLE '{"execute": "blockdev-add", From f9a75891db4550f3176178d539a9c5b0b3c8e445 Mon Sep 17 00:00:00 2001 From: Eric Farman Date: Fri, 25 Sep 2026 21:44:06 +0200 Subject: [PATCH 11/13] iotests/nbd-tls-iothread: skip on non-x86 hardware Like nbd-in-qcow2-chain, this test assumes a q35 machine is present, which might not be available on other hosts. Unlike that test, simply allowing it to run with the default machine still throws an errors. Fence this to PC-only machines for now. Signed-off-by: Eric Farman Message-ID: <20260925194409.716498-3-farman@linux.ibm.com> Reviewed-by: Eric Blake Signed-off-by: Eric Blake --- tests/qemu-iotests/tests/nbd-tls-iothread | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/qemu-iotests/tests/nbd-tls-iothread b/tests/qemu-iotests/tests/nbd-tls-iothread index 6cf52a0aa9..a3b8f38284 100755 --- a/tests/qemu-iotests/tests/nbd-tls-iothread +++ b/tests/qemu-iotests/tests/nbd-tls-iothread @@ -45,6 +45,10 @@ cd .. _supported_fmt qcow2 # Hardcoded to qcow2 command line and QMP below _supported_proto file +if [ "$QEMU_DEFAULT_MACHINE" != "pc" ]; then + _notrun "Requires a PC machine" +fi + # pick_unused_port # # Picks and returns an "unused" port, setting the global variable From 14e22f67ed0b6dd6abde1fb9443d9d28fc78e1ca Mon Sep 17 00:00:00 2001 From: Eric Farman Date: Fri, 25 Sep 2026 21:44:07 +0200 Subject: [PATCH 12/13] iotests/fuse-truncate: skip if FUSE is not usable Commit 951227d3755 ("iotests: skip FUSE tests when FUSE is not usable") reworked some of the fuse-related tests to skip where needed, but the new test fuse-truncate raced with that and missed out on the same treatment. Add that same python-esque skip logic to this test. Fixes: 7d06bbb2d9 ("iotests: test O_TRUNC behavior for fuse exports") Signed-off-by: Eric Farman Message-ID: <20260925194409.716498-4-farman@linux.ibm.com> Reviewed-by: Eric Blake Signed-off-by: Eric Blake --- tests/qemu-iotests/tests/fuse-truncate | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/qemu-iotests/tests/fuse-truncate b/tests/qemu-iotests/tests/fuse-truncate index 7eee35111c..f3d2f1866c 100755 --- a/tests/qemu-iotests/tests/fuse-truncate +++ b/tests/qemu-iotests/tests/fuse-truncate @@ -32,9 +32,12 @@ def check_fuse_support(): test_qsd.stop() os.remove(fuse_mount_point) if 'error' in res: - assert (res['error']['desc'] == - "Parameter 'type' does not accept value 'fuse'") - iotests.notrun('No FUSE support') + desc = res['error']['desc'] + if desc == "Parameter 'type' does not accept value 'fuse'": + iotests.notrun('No FUSE support') + if 'Failed to mount FUSE session' in desc: + iotests.notrun('FUSE not usable in this environment') + assert False, desc def check_sudo_support(): try: From 137374d861a3507e18d9154c5266e20c92371e20 Mon Sep 17 00:00:00 2001 From: Eric Farman Date: Fri, 25 Sep 2026 21:44:09 +0200 Subject: [PATCH 13/13] iotests/iothreads-nbd-export: Skip on s390 Running this test on s390 causes long python exception tracebacks at the beginning of the system_reset loop. The problem appears to be the same one described by commit ad302b21aab6, in that QEMU will exit on s390 without any kernel or boot disk. In other tests, this is addressed by adding -no-shutdown to the command line, and that does create a clean failure instead of a long line of python exceptions: --- /home/farman/git/qemu/tests/qemu-iotests/tests/iothreads-nbd-export.out +++ /home/farman/git/qemu/build/scratch/qcow2-file-iothreads-nbd-export/iothreads-nbd-export.out.bad @@ -16,4 +16,4 @@ {"return": {}} {"return": {}} Checking that it is still alive... -{"return": {"running": true, "status": "running"}} +{"return": {"running": false, "status": "prelaunch"}} Failures: iothreads-nbd-export Failed 1 of 1 iotests ...but obviously this isn't still a successful test, since it is expected that the guest will be still be usable after the reset loop. So, barring a solution to that, just skip this test on s390. Signed-off-by: Eric Farman Message-ID: <20260925194409.716498-6-farman@linux.ibm.com> Reviewed-by: Eric Blake Signed-off-by: Eric Blake --- tests/qemu-iotests/tests/iothreads-nbd-export | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/qemu-iotests/tests/iothreads-nbd-export b/tests/qemu-iotests/tests/iothreads-nbd-export index 037260729c..72493ad227 100755 --- a/tests/qemu-iotests/tests/iothreads-nbd-export +++ b/tests/qemu-iotests/tests/iothreads-nbd-export @@ -25,6 +25,11 @@ import iotests iotests.script_initialize(supported_fmts=['qcow2'], supported_platforms=['linux']) +# QEMU on s390 will exit without any sort of backing disk, +# so the reset loop requested by this test will fail. +if iotests.qemu_default_machine == 's390-ccw-virtio': + iotests.notrun('Cannot run test on s390') + with iotests.FilePath('disk1.img') as path, \ iotests.FilePath('nbd.sock', base_dir=iotests.sock_dir) as nbd_sock, \ qemu.machine.QEMUMachine(iotests.qemu_prog) as vm: