* [PULL 01/15] maint: Update eblake's staging repo
2026-10-08 13:11 [PULL 00/15] NBD patches through 2026-10-08 Eric Blake
@ 2026-10-08 13:11 ` Eric Blake
2026-10-08 13:11 ` [PULL 02/15] qemu-nbd: Support -s and -l at the same time Eric Blake
` (13 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Eric Blake @ 2026-10-08 13:11 UTC (permalink / raw)
To: qemu-devel; +Cc: Markus Armbruster
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 <eblake@redhat.com>
Message-ID: <20261007122951.1935165-2-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
---
MAINTAINERS | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 1312bbd1bd8..518f5ee6115 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3365,7 +3365,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
@@ -4364,7 +4364,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
--
2.56.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PULL 02/15] qemu-nbd: Support -s and -l at the same time
2026-10-08 13:11 [PULL 00/15] NBD patches through 2026-10-08 Eric Blake
2026-10-08 13:11 ` [PULL 01/15] maint: Update eblake's staging repo Eric Blake
@ 2026-10-08 13:11 ` Eric Blake
2026-10-09 10:40 ` Richard Henderson
2026-10-08 13:11 ` [PULL 03/15] iotests: add test cases for failing flush after qemu-img convert Eric Blake
` (12 subsequent siblings)
14 siblings, 1 reply; 18+ messages in thread
From: Eric Blake @ 2026-10-08 13:11 UTC (permalink / raw)
To: qemu-devel
Cc: Vladimir Sementsov-Ogievskiy, Pierrick Bouvier, Kevin Wolf,
Hanna Reitz, open list:Network Block Dev...
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 <eblake@redhat.com>
Message-ID: <20260408021636.794794-2-eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
[eblake: improve test with Vladimir's suggestions]
Signed-off-by: Eric Blake <eblake@redhat.com>
---
docs/tools/qemu-nbd.rst | 7 +-
qemu-nbd.c | 20 ++++-
tests/qemu-iotests/tests/qemu-nbd-snapshots | 81 +++++++++++++++++++
.../qemu-iotests/tests/qemu-nbd-snapshots.out | 39 +++++++++
4 files changed, 141 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 f82ea5fd77b..336b4aa46e7 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 ed5895861bb..128486a0ec2 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,17 @@ int main(int argc, char **argv)
blk_set_enable_write_cache(blk, !writethrough);
+ orig_bs = bs;
+ if (flags & BDRV_O_SNAPSHOT) {
+ 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 00000000000..ce62e97877b
--- /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 00000000000..47289c30f1d
--- /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
--
2.56.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PULL 02/15] qemu-nbd: Support -s and -l at the same time
2026-10-08 13:11 ` [PULL 02/15] qemu-nbd: Support -s and -l at the same time Eric Blake
@ 2026-10-09 10:40 ` Richard Henderson
2026-10-13 15:00 ` Eric Blake
0 siblings, 1 reply; 18+ messages in thread
From: Richard Henderson @ 2026-10-09 10:40 UTC (permalink / raw)
To: Eric Blake, qemu-devel
Cc: Vladimir Sementsov-Ogievskiy, Pierrick Bouvier, Kevin Wolf,
Hanna Reitz, open list:Network Block Dev...
On 10/8/26 15:11, Eric Blake wrote:
> @@ -1155,13 +1165,17 @@ int main(int argc, char **argv)
>
> blk_set_enable_write_cache(blk, !writethrough);
>
> + orig_bs = bs;
> + if (flags & BDRV_O_SNAPSHOT) {
> + orig_bs = bs->backing->bs;
> + }
tsan complains:
../qemu-nbd.c:1170:23: error: reading variable 'backing' requires
holding mutex 'graph_lock' [-Werror,-Wthread-safety-analysis]
https://gitlab.com/qemu-project/qemu/-/jobs/17055360066
r~
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PULL 02/15] qemu-nbd: Support -s and -l at the same time
2026-10-09 10:40 ` Richard Henderson
@ 2026-10-13 15:00 ` Eric Blake
0 siblings, 0 replies; 18+ messages in thread
From: Eric Blake @ 2026-10-13 15:00 UTC (permalink / raw)
To: Richard Henderson
Cc: qemu-devel, Vladimir Sementsov-Ogievskiy, Pierrick Bouvier,
Kevin Wolf, Hanna Reitz, open list:Network Block Dev...
On Fri, Oct 09, 2026 at 12:40:59PM +0200, Richard Henderson wrote:
> On 10/8/26 15:11, Eric Blake wrote:
> > @@ -1155,13 +1165,17 @@ int main(int argc, char **argv)
> >
> > blk_set_enable_write_cache(blk, !writethrough);
> >
> > + orig_bs = bs;
> > + if (flags & BDRV_O_SNAPSHOT) {
> > + orig_bs = bs->backing->bs;
> > + }
>
> tsan complains:
>
> ../qemu-nbd.c:1170:23: error: reading variable 'backing' requires holding
> mutex 'graph_lock' [-Werror,-Wthread-safety-analysis]
>
> https://gitlab.com/qemu-project/qemu/-/jobs/17055360066
Thanks for the heads up. I got a TSAN build working on my environment,
fixed up the problem, and posted a v2 pull request.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc.
Virtualization: qemu.org | libguestfs.org
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PULL 03/15] iotests: add test cases for failing flush after qemu-img convert
2026-10-08 13:11 [PULL 00/15] NBD patches through 2026-10-08 Eric Blake
2026-10-08 13:11 ` [PULL 01/15] maint: Update eblake's staging repo Eric Blake
2026-10-08 13:11 ` [PULL 02/15] qemu-nbd: Support -s and -l at the same time Eric Blake
@ 2026-10-08 13:11 ` Eric Blake
2026-10-08 13:11 ` [PULL 04/15] iotests.py: add filter_qemu() Eric Blake
` (11 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Eric Blake @ 2026-10-08 13:11 UTC (permalink / raw)
To: qemu-devel
Cc: Fiona Ebner, Kevin Wolf, Hanna Reitz, open list:Block layer core
From: Fiona Ebner <f.ebner@proxmox.com>
In preparation to add more checks in the following commits and show
how the behavior changes.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Message-ID: <20260930132140.2342574-2-f.ebner@proxmox.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
---
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 be0f6b79e5d..488649f1bd0 100755
--- a/tests/qemu-iotests/122
+++ b/tests/qemu-iotests/122
@@ -334,6 +334,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 6a1aa3fe2b9..f3e28f33bc2 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
--
2.56.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PULL 04/15] iotests.py: add filter_qemu()
2026-10-08 13:11 [PULL 00/15] NBD patches through 2026-10-08 Eric Blake
` (2 preceding siblings ...)
2026-10-08 13:11 ` [PULL 03/15] iotests: add test cases for failing flush after qemu-img convert Eric Blake
@ 2026-10-08 13:11 ` Eric Blake
2026-10-08 13:11 ` [PULL 05/15] block: report flush error during bdrv_close() Eric Blake
` (10 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Eric Blake @ 2026-10-08 13:11 UTC (permalink / raw)
To: qemu-devel
Cc: Fiona Ebner, Kevin Wolf, Hanna Reitz, open list:Block layer core
From: Fiona Ebner <f.ebner@proxmox.com>
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 <f.ebner@proxmox.com>
Message-ID: <20260930132140.2342574-3-f.ebner@proxmox.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
---
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 7d5a77a85e5..642a160bb28 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)
--
2.56.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PULL 05/15] block: report flush error during bdrv_close()
2026-10-08 13:11 [PULL 00/15] NBD patches through 2026-10-08 Eric Blake
` (3 preceding siblings ...)
2026-10-08 13:11 ` [PULL 04/15] iotests.py: add filter_qemu() Eric Blake
@ 2026-10-08 13:11 ` Eric Blake
2026-10-08 13:11 ` [PULL 06/15] qemu-img: convert: flush target image after copying Eric Blake
` (9 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Eric Blake @ 2026-10-08 13:11 UTC (permalink / raw)
To: qemu-devel
Cc: Fiona Ebner, Kevin Wolf, Hanna Reitz, open list:Block layer core
From: Fiona Ebner <f.ebner@proxmox.com>
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 <f.ebner@proxmox.com>
Message-ID: <20260930132140.2342574-4-f.ebner@proxmox.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
---
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 f0a6042e616..c05ad01f25c 100644
--- a/block.c
+++ b/block.c
@@ -5162,12 +5162,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 d37e266dade..88cb4dd934e 100755
--- a/tests/qemu-iotests/026
+++ b/tests/qemu-iotests/026
@@ -103,13 +103,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"
@@ -155,7 +155,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"
@@ -194,7 +194,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 b998a9ac83d..47bd88b1d3c 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 83c4ce6314c..8237b325ea5 100755
--- a/tests/qemu-iotests/071
+++ b/tests/qemu-iotests/071
@@ -54,7 +54,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 f2d015d8cca..a69e6f7e501 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 b20c21faf6a..3b2b27c5fec 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 6c73dd0977f..912b0290af0 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 488649f1bd0..9da1246f097 100755
--- a/tests/qemu-iotests/122
+++ b/tests/qemu-iotests/122
@@ -357,15 +357,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 f3e28f33bc2..84283f24343 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 2a98ad58f5d..ef32f8ec036 100755
--- a/tests/qemu-iotests/244
+++ b/tests/qemu-iotests/244
@@ -264,7 +264,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 c5e62146c93..81463d6f0ec 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 0d970c102f6..3885b741d99 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 bf8c0018ba5..748ea3079c0 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 d76278b576c..73583dec169 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 4a5241e5d40..894b232b4a4 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
--
2.56.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PULL 06/15] qemu-img: convert: flush target image after copying
2026-10-08 13:11 [PULL 00/15] NBD patches through 2026-10-08 Eric Blake
` (4 preceding siblings ...)
2026-10-08 13:11 ` [PULL 05/15] block: report flush error during bdrv_close() Eric Blake
@ 2026-10-08 13:11 ` Eric Blake
2026-10-08 13:11 ` [PULL 07/15] nbd/client-connection: Fix client returning a closed channel Eric Blake
` (8 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Eric Blake @ 2026-10-08 13:11 UTC (permalink / raw)
To: qemu-devel
Cc: Fiona Ebner, Kevin Wolf, Hanna Reitz, open list:Block layer core
From: Fiona Ebner <f.ebner@proxmox.com>
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 <f.ebner@proxmox.com>
Message-ID: <20260930132140.2342574-5-f.ebner@proxmox.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
---
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 2f63d311413..edf75e43aba 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 84283f24343..38794f96ac2 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
--
2.56.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PULL 07/15] nbd/client-connection: Fix client returning a closed channel
2026-10-08 13:11 [PULL 00/15] NBD patches through 2026-10-08 Eric Blake
` (5 preceding siblings ...)
2026-10-08 13:11 ` [PULL 06/15] qemu-img: convert: flush target image after copying Eric Blake
@ 2026-10-08 13:11 ` Eric Blake
2026-10-08 13:11 ` [PULL 08/15] iotests: Add coverage for NBD connect thread start delay Eric Blake
` (7 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Eric Blake @ 2026-10-08 13:11 UTC (permalink / raw)
To: qemu-devel
Cc: Guillaume Vincke, Vladimir Sementsov-Ogievskiy,
open list:Network Block Dev...
From: Guillaume Vincke <guillaume.vincke@ovhcloud.com>
When a server closes the connection after a successful handshake but
before running any operations, the channel returned by
nbd_co_establish_connection() is the closed one and the connect thread
is not started.
When configured with reconnect-delay=0 (the default), this situation
generates at least two IO errors. The first one happens when trying to
issue an operation to the closed socket. The connect thread will be
started on the next request, which may happen long after, and will
create the second error as nbd_co_establish_connection() returns a NULL
channel.
Peeking the channel to detect FIN or RST avoids the first IO error and
does not delay the starting of the connect thread.
Signed-off-by: Guillaume Vincke <guillaume.vincke@ovhcloud.com>
Message-ID: <20260925155346.357703-2-guillaume.vincke@ovhcloud.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
[eblake: minor formatting changes]
Signed-off-by: Eric Blake <eblake@redhat.com>
---
nbd/client-connection.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/nbd/client-connection.c b/nbd/client-connection.c
index 6a4f0807170..aec62934d1a 100644
--- a/nbd/client-connection.c
+++ b/nbd/client-connection.c
@@ -274,6 +274,23 @@ void nbd_client_connection_release(NBDClientConnection *conn)
}
}
+/* Only true when the peer closed the channel. Does not detect if dead. */
+static bool nbd_channel_is_closed(QIOChannel *ioc)
+{
+ char data;
+ struct iovec iov = { .iov_base = &data, .iov_len = 1 };
+ ssize_t len = -1;
+
+ if (!qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_READ_MSG_PEEK)) {
+ return false;
+ }
+
+ len = qio_channel_readv_full(
+ ioc, &iov, 1, NULL, NULL, QIO_CHANNEL_READ_FLAG_MSG_PEEK, NULL);
+
+ return len == 0 || (len < 0 && len != QIO_CHANNEL_ERR_BLOCK);
+}
+
/*
* Get a new connection in context of @conn:
* if the thread is running, wait for completion
@@ -295,6 +312,7 @@ nbd_co_establish_connection(NBDClientConnection *conn, NBDExportInfo *info,
bool blocking, Error **errp)
{
QemuThread thread;
+ QIOChannel *ioc;
if (conn->do_negotiation) {
assert(info);
@@ -308,6 +326,20 @@ nbd_co_establish_connection(NBDClientConnection *conn, NBDExportInfo *info,
assert(!conn->wait_co);
if (!conn->running) {
+ if (conn->sioc) {
+ /* discard if the socket got closed by its peer */
+ ioc = QIO_CHANNEL(conn->sioc);
+ if (!qio_channel_set_blocking(ioc, false, NULL) ||
+ nbd_channel_is_closed(ioc)) {
+
+ qio_channel_close(ioc, NULL);
+ object_unref(OBJECT(conn->sioc));
+ conn->sioc = NULL;
+ object_unref(OBJECT(conn->ioc));
+ conn->ioc = NULL;
+ }
+ }
+
if (conn->sioc) {
/* Previous attempt finally succeeded in background */
if (conn->do_negotiation) {
--
2.56.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PULL 08/15] iotests: Add coverage for NBD connect thread start delay
2026-10-08 13:11 [PULL 00/15] NBD patches through 2026-10-08 Eric Blake
` (6 preceding siblings ...)
2026-10-08 13:11 ` [PULL 07/15] nbd/client-connection: Fix client returning a closed channel Eric Blake
@ 2026-10-08 13:11 ` Eric Blake
2026-10-08 13:11 ` [PULL 09/15] migration: add QEMU_COUNTED_STRING_SIZE for counted string buffers Eric Blake
` (6 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Eric Blake @ 2026-10-08 13:11 UTC (permalink / raw)
To: qemu-devel
Cc: Guillaume Vincke, Vladimir Sementsov-Ogievskiy, Kevin Wolf,
Hanna Reitz, open list:Network Block Dev...
From: Guillaume Vincke <guillaume.vincke@ovhcloud.com>
Test the connect thread starting condition with reconnect-delay=0 when
the server disconnects after a successful handshake but before running
operations. Prior to the change to nbd_co_establish_connection(), this
test would demonstrate two I/O errors. The tests 264 and 277 covering
reconnection do not use reconnect-delay=0 so this case is not exercised.
Add a test that provokes multiple errors in order to put an NBD client
in the above-mentioned situation and shows that the first operation
starts the connect thread and leads to successful subsequent I/O.
Signed-off-by: Guillaume Vincke <guillaume.vincke@ovhcloud.com>
Message-ID: <20260925155346.357703-3-guillaume.vincke@ovhcloud.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Tested-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
---
tests/qemu-iotests/tests/nbd-stale-connection | 62 +++++++++++++++++++
.../tests/nbd-stale-connection.out | 17 +++++
2 files changed, 79 insertions(+)
create mode 100755 tests/qemu-iotests/tests/nbd-stale-connection
create mode 100644 tests/qemu-iotests/tests/nbd-stale-connection.out
diff --git a/tests/qemu-iotests/tests/nbd-stale-connection b/tests/qemu-iotests/tests/nbd-stale-connection
new file mode 100755
index 00000000000..6f6fb6ef1b8
--- /dev/null
+++ b/tests/qemu-iotests/tests/nbd-stale-connection
@@ -0,0 +1,62 @@
+#!/usr/bin/env python3
+# group: quick
+#
+# Test the NBD client stale channel discard
+#
+# Copyright (C) 2026 OVHcloud
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import time
+import iotests
+from iotests import qemu_nbd_popen, qemu_img_create, file_path, log
+
+
+# estimated duration required by the connect thread to reach a running server
+MAX_NBD_HANDSHAKE_DURATION = 0.5
+# sleep duration of the connection retry in nbd client
+CONNECT_RETRY_DELAY = 1
+
+iotests.script_initialize()
+nbd_sock = file_path('nbd-sock', base_dir=iotests.sock_dir)
+disk = file_path('disk')
+qemu_img_create('-f', iotests.imgfmt, disk, '1M')
+
+with iotests.VM() as vm:
+
+ vm.launch()
+
+ with qemu_nbd_popen('-k', nbd_sock, '-f', iotests.imgfmt, disk):
+ vm.cmd('blockdev-add', {
+ 'driver': 'nbd',
+ 'node-name': 'nbd0',
+ 'server': {'type': 'unix', 'path': nbd_sock},
+ })
+ iotests.log('=== NBD Device connected ===')
+ log(vm.qmp('x-qemu-io', device='nbd0', command='write -P 0x5a 0 64k'))
+
+ iotests.log('=== NBD server down. Detect the break and start the connect '
+ 'thread ===')
+ # client was in CONNECTED state a new operation updates to CONNECTING
+ log(vm.qmp('x-qemu-io', device='nbd0', command='write -P 0x5a 0 64k'))
+ # in CONNECTING, the operation starts the connect thread
+ log(vm.qmp('x-qemu-io', device='nbd0', command='write -P 0x5a 0 64k'))
+
+ with qemu_nbd_popen('-k', nbd_sock, '-f', iotests.imgfmt, disk):
+ iotests.log('=== NBD server up. Wait for the connect thread to park '
+ 'the channel ===')
+ # wait for the connect thread to get a new channel and stop
+ time.sleep(CONNECT_RETRY_DELAY + MAX_NBD_HANDSHAKE_DURATION)
+
+ iotests.log('=== NBD server down. The parked channel is closed ===')
+
+ with qemu_nbd_popen('-k', nbd_sock, '-f', iotests.imgfmt, disk):
+ iotests.log('=== NBD server up. Restart the connect thread ===')
+ # operation will determine that the channel got closed and restart the
+ # connect thread
+ log(vm.qmp('x-qemu-io', device='nbd0', command='write -P 0x5a 0 64k'))
+ # Wait for it to succeed
+ iotests.log('=== Wait for the connect thread to park the new channel. '
+ 'Subsequent operations are successful ===')
+ time.sleep(MAX_NBD_HANDSHAKE_DURATION)
+ log(vm.qmp('x-qemu-io', device='nbd0', command='write -P 0x5a 0 64k'))
diff --git a/tests/qemu-iotests/tests/nbd-stale-connection.out b/tests/qemu-iotests/tests/nbd-stale-connection.out
new file mode 100644
index 00000000000..50f80e23058
--- /dev/null
+++ b/tests/qemu-iotests/tests/nbd-stale-connection.out
@@ -0,0 +1,17 @@
+Start NBD server
+=== NBD Device connected ===
+{"return": {}}
+Kill NBD server
+=== NBD server down. Detect the break and start the connect thread ===
+{"error": {"class": "GenericError", "desc": "write failed: Input/output error"}}
+{"error": {"class": "GenericError", "desc": "write failed: Input/output error"}}
+Start NBD server
+=== NBD server up. Wait for the connect thread to park the channel ===
+Kill NBD server
+=== NBD server down. The parked channel is closed ===
+Start NBD server
+=== NBD server up. Restart the connect thread ===
+{"error": {"class": "GenericError", "desc": "write failed: Input/output error"}}
+=== Wait for the connect thread to park the new channel. Subsequent operations are successful ===
+{"return": {}}
+Kill NBD server
--
2.56.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PULL 09/15] migration: add QEMU_COUNTED_STRING_SIZE for counted string buffers
2026-10-08 13:11 [PULL 00/15] NBD patches through 2026-10-08 Eric Blake
` (7 preceding siblings ...)
2026-10-08 13:11 ` [PULL 08/15] iotests: Add coverage for NBD connect thread start delay Eric Blake
@ 2026-10-08 13:11 ` Eric Blake
2026-10-08 13:11 ` [PULL 10/15] migration/block-dirty-bitmap: fix postcopy abort with bitmaps on several nodes Eric Blake
` (5 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Eric Blake @ 2026-10-08 13:11 UTC (permalink / raw)
To: qemu-devel
Cc: Denis V. Lunev, Peter Xu, Fabiano Rosas,
Vladimir Sementsov-Ogievskiy, qemu-stable, John Snow,
open list:Dirty Bitmaps
From: "Denis V. Lunev" <den@openvz.org>
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 <eblake@redhat.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
Cc: Peter Xu <peterx@redhat.com>
Cc: Fabiano Rosas <farosas@suse.de>
Cc: Eric Blake <eblake@redhat.com>
Cc: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Cc: qemu-stable@nongnu.org
Message-ID: <20261006170738.453977-2-den@openvz.org>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
---
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 adec5abc071..2a073bed299 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 1b8f39c12bb..1386f436355 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 7735e618549..df3f96fb240 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);
}
--
2.56.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PULL 10/15] migration/block-dirty-bitmap: fix postcopy abort with bitmaps on several nodes
2026-10-08 13:11 [PULL 00/15] NBD patches through 2026-10-08 Eric Blake
` (8 preceding siblings ...)
2026-10-08 13:11 ` [PULL 09/15] migration: add QEMU_COUNTED_STRING_SIZE for counted string buffers Eric Blake
@ 2026-10-08 13:11 ` Eric Blake
2026-10-08 13:11 ` [PULL 11/15] iotests/migrate-bitmaps-postcopy-test: add a bitmap on a second node Eric Blake
` (4 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Eric Blake @ 2026-10-08 13:11 UTC (permalink / raw)
To: qemu-devel
Cc: Denis V. Lunev, Peter Xu, Fabiano Rosas,
Vladimir Sementsov-Ogievskiy, qemu-stable, John Snow,
open list:Dirty Bitmaps
From: "Denis V. Lunev" <den@openvz.org>
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 <den@openvz.org>
Cc: Peter Xu <peterx@redhat.com>
Cc: Fabiano Rosas <farosas@suse.de>
Cc: Eric Blake <eblake@redhat.com>
Cc: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Cc: qemu-stable@nongnu.org
Message-ID: <20261006170738.453977-3-den@openvz.org>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
---
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 1386f436355..35623379eb6 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
--
2.56.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PULL 11/15] iotests/migrate-bitmaps-postcopy-test: add a bitmap on a second node
2026-10-08 13:11 [PULL 00/15] NBD patches through 2026-10-08 Eric Blake
` (9 preceding siblings ...)
2026-10-08 13:11 ` [PULL 10/15] migration/block-dirty-bitmap: fix postcopy abort with bitmaps on several nodes Eric Blake
@ 2026-10-08 13:11 ` Eric Blake
2026-10-08 13:11 ` [PULL 12/15] iotests/nbd-in-qcow2-chain: use default machine Eric Blake
` (3 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Eric Blake @ 2026-10-08 13:11 UTC (permalink / raw)
To: qemu-devel
Cc: Denis V. Lunev, Peter Xu, Fabiano Rosas,
Vladimir Sementsov-Ogievskiy, Kevin Wolf, Hanna Reitz,
open list:Block layer core
From: "Denis V. Lunev" <den@openvz.org>
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 <den@openvz.org>
Tested-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Cc: Peter Xu <peterx@redhat.com>
Cc: Fabiano Rosas <farosas@suse.de>
Cc: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Message-ID: <20261006170738.453977-4-den@openvz.org>
[eblake: squash in fix to pass even after aborted run left behind stale fifo]
Signed-off-by: Eric Blake <eblake@redhat.com>
---
.../tests/migrate-bitmaps-postcopy-test | 21 +++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test b/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test
index b2b37ada4b2..bada325e017 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,25 @@ 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')
+ # 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 +138,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 +230,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
--
2.56.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PULL 12/15] iotests/nbd-in-qcow2-chain: use default machine
2026-10-08 13:11 [PULL 00/15] NBD patches through 2026-10-08 Eric Blake
` (10 preceding siblings ...)
2026-10-08 13:11 ` [PULL 11/15] iotests/migrate-bitmaps-postcopy-test: add a bitmap on a second node Eric Blake
@ 2026-10-08 13:11 ` Eric Blake
2026-10-08 13:11 ` [PULL 13/15] iotests/nbd-tls-iothread: skip on non-x86 hardware Eric Blake
` (2 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Eric Blake @ 2026-10-08 13:11 UTC (permalink / raw)
To: qemu-devel
Cc: Eric Farman, Vladimir Sementsov-Ogievskiy, Kevin Wolf,
Hanna Reitz, open list:Network Block Dev...
From: Eric Farman <farman@linux.ibm.com>
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 <farman@linux.ibm.com>
Message-ID: <20260925194409.716498-2-farman@linux.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
---
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 455ddfa86fe..e35f072eba4 100755
--- a/tests/qemu-iotests/tests/nbd-in-qcow2-chain
+++ b/tests/qemu-iotests/tests/nbd-in-qcow2-chain
@@ -43,7 +43,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",
--
2.56.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PULL 13/15] iotests/nbd-tls-iothread: skip on non-x86 hardware
2026-10-08 13:11 [PULL 00/15] NBD patches through 2026-10-08 Eric Blake
` (11 preceding siblings ...)
2026-10-08 13:11 ` [PULL 12/15] iotests/nbd-in-qcow2-chain: use default machine Eric Blake
@ 2026-10-08 13:11 ` Eric Blake
2026-10-08 13:11 ` [PULL 14/15] iotests/fuse-truncate: skip if FUSE is not usable Eric Blake
2026-10-08 13:11 ` [PULL 15/15] iotests/iothreads-nbd-export: Skip on s390 Eric Blake
14 siblings, 0 replies; 18+ messages in thread
From: Eric Blake @ 2026-10-08 13:11 UTC (permalink / raw)
To: qemu-devel
Cc: Eric Farman, Vladimir Sementsov-Ogievskiy, Kevin Wolf,
Hanna Reitz, open list:Network Block Dev...
From: Eric Farman <farman@linux.ibm.com>
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 <farman@linux.ibm.com>
Message-ID: <20260925194409.716498-3-farman@linux.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
---
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 a2fb07206e5..4326e2d3e5c 100755
--- a/tests/qemu-iotests/tests/nbd-tls-iothread
+++ b/tests/qemu-iotests/tests/nbd-tls-iothread
@@ -47,6 +47,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
--
2.56.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PULL 14/15] iotests/fuse-truncate: skip if FUSE is not usable
2026-10-08 13:11 [PULL 00/15] NBD patches through 2026-10-08 Eric Blake
` (12 preceding siblings ...)
2026-10-08 13:11 ` [PULL 13/15] iotests/nbd-tls-iothread: skip on non-x86 hardware Eric Blake
@ 2026-10-08 13:11 ` Eric Blake
2026-10-08 13:11 ` [PULL 15/15] iotests/iothreads-nbd-export: Skip on s390 Eric Blake
14 siblings, 0 replies; 18+ messages in thread
From: Eric Blake @ 2026-10-08 13:11 UTC (permalink / raw)
To: qemu-devel
Cc: Eric Farman, Kevin Wolf, Hanna Reitz, open list:Block layer core
From: Eric Farman <farman@linux.ibm.com>
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 <farman@linux.ibm.com>
Message-ID: <20260925194409.716498-4-farman@linux.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
---
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 7eee35111c8..f3d2f1866c8 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:
--
2.56.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PULL 15/15] iotests/iothreads-nbd-export: Skip on s390
2026-10-08 13:11 [PULL 00/15] NBD patches through 2026-10-08 Eric Blake
` (13 preceding siblings ...)
2026-10-08 13:11 ` [PULL 14/15] iotests/fuse-truncate: skip if FUSE is not usable Eric Blake
@ 2026-10-08 13:11 ` Eric Blake
14 siblings, 0 replies; 18+ messages in thread
From: Eric Blake @ 2026-10-08 13:11 UTC (permalink / raw)
To: qemu-devel
Cc: Eric Farman, Vladimir Sementsov-Ogievskiy, Kevin Wolf,
Hanna Reitz, Cornelia Huck, Matthew Rosato,
open list:Network Block Dev..., open list:S390 general arch...
From: Eric Farman <farman@linux.ibm.com>
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 <farman@linux.ibm.com>
Message-ID: <20260925194409.716498-6-farman@linux.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
---
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 037260729c7..72493ad2279 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:
--
2.56.0
^ permalink raw reply related [flat|nested] 18+ messages in thread