[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-stable] [PATCH 017/156] qcow2: Flush metadata during read-only reo
From: |
Michael Roth |
Subject: |
[Qemu-stable] [PATCH 017/156] qcow2: Flush metadata during read-only reopen |
Date: |
Tue, 8 Jul 2014 12:16:48 -0500 |
From: Kevin Wolf <address@hidden>
If lazy refcounts are enabled for a backing file, committing to this
backing file may leave it in a dirty state even if the commit succeeds.
The reason is that the bdrv_flush() call in bdrv_commit() doesn't flush
refcount updates with lazy refcounts enabled, and qcow2_reopen_prepare()
doesn't take care to flush metadata.
In order to fix this, this patch also fixes qcow2_mark_clean(), which
contains another ineffective bdrv_flush() call beause lazy refcounts are
disabled only afterwards. All existing callers of qcow2_mark_clean()
either don't modify refcounts or already flush manually, so that this
fixes only a latent, but not yet actually triggerable bug.
Another instance of the same problem is live snapshots. Again, a real
corruption is prevented by an explicit flush for non-read-only images in
external_snapshot_prepare(), but images using lazy refcounts stay dirty.
Cc: address@hidden
Signed-off-by: Kevin Wolf <address@hidden>
Reviewed-by: Stefan Hajnoczi <address@hidden>
(cherry picked from commit 4c2e5f8f46a17966dc45b5a3e07b97434c0eabdf)
Signed-off-by: Michael Roth <address@hidden>
---
block/qcow2.c | 25 +++++++++++++++++++++----
tests/qemu-iotests/039 | 20 ++++++++++++++++++++
tests/qemu-iotests/039.out | 11 +++++++++++
3 files changed, 52 insertions(+), 4 deletions(-)
diff --git a/block/qcow2.c b/block/qcow2.c
index 6e5d98d..b43c7d0 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -269,12 +269,15 @@ static int qcow2_mark_clean(BlockDriverState *bs)
BDRVQcowState *s = bs->opaque;
if (s->incompatible_features & QCOW2_INCOMPAT_DIRTY) {
- int ret = bdrv_flush(bs);
+ int ret;
+
+ s->incompatible_features &= ~QCOW2_INCOMPAT_DIRTY;
+
+ ret = bdrv_flush(bs);
if (ret < 0) {
return ret;
}
- s->incompatible_features &= ~QCOW2_INCOMPAT_DIRTY;
return qcow2_update_header(bs);
}
return 0;
@@ -792,11 +795,25 @@ static int qcow2_set_key(BlockDriverState *bs, const char
*key)
return 0;
}
-/* We have nothing to do for QCOW2 reopen, stubs just return
- * success */
+/* We have no actual commit/abort logic for qcow2, but we need to write out any
+ * unwritten data if we reopen read-only. */
static int qcow2_reopen_prepare(BDRVReopenState *state,
BlockReopenQueue *queue, Error **errp)
{
+ int ret;
+
+ if ((state->flags & BDRV_O_RDWR) == 0) {
+ ret = bdrv_flush(state->bs);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = qcow2_mark_clean(state->bs);
+ if (ret < 0) {
+ return ret;
+ }
+ }
+
return 0;
}
diff --git a/tests/qemu-iotests/039 b/tests/qemu-iotests/039
index 8bade92..cc4fad8 100755
--- a/tests/qemu-iotests/039
+++ b/tests/qemu-iotests/039
@@ -130,6 +130,26 @@ ulimit -c "$old_ulimit"
./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
_check_test_img
+echo
+echo "== Committing to a backing file with lazy_refcounts=on =="
+
+IMGOPTS="compat=1.1,lazy_refcounts=on"
+TEST_IMG="$TEST_IMG".base _make_test_img $size
+
+IMGOPTS="compat=1.1,lazy_refcounts=on,backing_file=$TEST_IMG.base"
+_make_test_img $size
+
+$QEMU_IO -c "write 0 512" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IMG commit "$TEST_IMG"
+
+# The dirty bit must not be set
+./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+./qcow2.py "$TEST_IMG".base dump-header | grep incompatible_features
+
+_check_test_img
+TEST_IMG="$TEST_IMG".base _check_test_img
+
+
# success, all done
echo "*** done"
rm -f $seq.full
diff --git a/tests/qemu-iotests/039.out b/tests/qemu-iotests/039.out
index 077fa64..fb31ae0 100644
--- a/tests/qemu-iotests/039.out
+++ b/tests/qemu-iotests/039.out
@@ -54,4 +54,15 @@ wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
incompatible_features 0x0
No errors were found on the image.
+
+== Committing to a backing file with lazy_refcounts=on ==
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
backing_file='TEST_DIR/t.IMGFMT.base'
+wrote 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Image committed.
+incompatible_features 0x0
+incompatible_features 0x0
+No errors were found on the image.
+No errors were found on the image.
*** done
--
1.9.1
- [Qemu-stable] [PATCH 010/156] tests: Fix 'make test' for i686 hosts (build regression), (continued)
- [Qemu-stable] [PATCH 010/156] tests: Fix 'make test' for i686 hosts (build regression), Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 008/156] qom: Avoid leaking str and bool properties on failure, Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 009/156] tap: avoid deadlocking rx, Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 066/156] virtio: allow mapping up to max queue size, Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 019/156] ide: Correct improper smart self test counter reset in ide core., Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 083/156] vpc: Validate block size (CVE-2014-0142), Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 111/156] qcow2: Fix copy_sectors() with VM state, Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 103/156] dmg: prevent out-of-bounds array access on terminator, Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 149/156] nbd: Don't validate from and len in NBD_CMD_DISC., Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 058/156] stellaris_enet: block migration, Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 017/156] qcow2: Flush metadata during read-only reopen,
Michael Roth <=
- [Qemu-stable] [PATCH 057/156] virtio: validate config_len on load, Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 106/156] dmg: sanitize chunk length and sectorcount (CVE-2014-0145), Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 082/156] vpc/vhd: add bounds check for max_table_entries and block_size (CVE-2014-0144), Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 135/156] aio: fix qemu_bh_schedule() bh->ctx race condition, Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 105/156] dmg: use appropriate types when reading chunks, Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 070/156] qemu-iotests: add cloop input validation tests, Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 067/156] migration: remove duplicate code, Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 012/156] mirror: fix throttling delay calculation, Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 078/156] bochs: Use unsigned variables for offsets and sizes (CVE-2014-0147), Michael Roth, 2014/07/08
- [Qemu-stable] [PATCH 014/156] virtio-net: Do not filter VLANs without F_CTRL_VLAN, Michael Roth, 2014/07/08