mirror of
https://gitlab.com/qemu-project/qemu.git
synced 2026-10-28 14:04:39 +08:00
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 <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>
This commit is contained in:
1 parent
c6c8bdc21a
commit
901ac73874
2 files changed
+9
-2
No files matched your search
+7
-1
@@ -2245,7 +2245,7 @@ static int img_convert(const img_cmd_t *ccmd, int argc, char **argv)
|
|||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
bool writethrough, src_writethrough, image_opts = false,
|
bool writethrough, src_writethrough, image_opts = false,
|
||||||
skip_create = false, progress = false, tgt_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 force_share = false;
|
||||||
bool explict_min_sparse = false;
|
bool explict_min_sparse = false;
|
||||||
bool bitmaps = 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);
|
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:
|
out:
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
qemu_progress_print(100, 0);
|
qemu_progress_print(100, 0);
|
||||||
|
|||||||
@@ -267,9 +267,10 @@ qemu-img convert exited with status 0
|
|||||||
|
|
||||||
=== failing flush after convert with 'writeback' cache mode ===
|
=== 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 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 L2 table cache: Input/output error
|
||||||
qemu-img: Failed to flush the refcount block 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: 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
|
*** done
|
||||||
Reference in new issue
Block a user