On 2014-11-17 at 11:38, Max Reitz wrote:
On 2014-11-17 at 09:34, Max Reitz wrote:
On 2014-11-15 at 15:50, Eric Blake wrote:
On 11/14/2014 06:06 AM, Max Reitz wrote:
Add a test for conversion between different refcount widths and errors
specific to certain widths (i.e. snapshots with refcount_width=1).
Signed-off-by: Max Reitz <mre...@redhat.com>
---
tests/qemu-iotests/112 | 252
+++++++++++++++++++++++++++++++++++++++++++++
tests/qemu-iotests/112.out | 131 +++++++++++++++++++++++
tests/qemu-iotests/group | 1 +
3 files changed, 384 insertions(+)
create mode 100755 tests/qemu-iotests/112
create mode 100644 tests/qemu-iotests/112.out
+echo
+echo '=== Testing too many references for check ==='
+echo
+
+IMGOPTS="$IMGOPTS,refcount_width=1" _make_test_img 64M
+print_refcount_width
+
+# This cluster should be created at 0x50000
+$QEMU_IO -c 'write 0 64k' "$TEST_IMG" | _filter_qemu_io
+# Now make the second L2 entry (the L2 table should be at 0x40000)
point to that
+# cluster, so we have two references
+poke_file "$TEST_IMG" $((0x40008)) "\x80\x00\x00\x00\x00\x05\x00\x00"
+
+# This should say "please use amend"
+_check_test_img -r all
+
+# So we do that
+$QEMU_IMG amend -o refcount_width=2 "$TEST_IMG"
+print_refcount_width
+
+# And try again
+_check_test_img -r all
I think this section also deserves a test that fuzzes an image with
width=64 to intentionally set the most significant bit of one of the
refcounts, and make sure that we gracefully diagnose it as invalid.
+
+echo
+echo '=== Multiple walks necessary during amend ==='
+echo
+
+IMGOPTS="$IMGOPTS,refcount_width=1,cluster_size=512"
_make_test_img 64k
+
+# Cluster 0 is the image header, clusters 1 to 4 are used by the
L1 table, a
+# single L2 table, the reftable and a single refblock. This
creates 58 data
+# clusters (actually, the L2 table is created here, too), so in
total there are
+# then 63 used clusters in the image. With a refcount width of 64,
one refblock
+# describes 64 clusters (512 bytes / 64 bits/entry = 64 entries),
so this will
+# make the first target refblock have exactly one free entry.
+$QEMU_IO -c "write 0 $((58 * 512))" "$TEST_IMG" | _filter_qemu_io
+
+# Now change the refcount width; since the first target refblock
has exactly one
+# free entry, that entry will be used to store its own reference.
No other
+# refblocks are needed, so then the new reftable will be
allocated; since the
+# first target refblock is completely filled up, this will require
a new
+# refblock which is why the refcount width changing function will
need to run
+# through everything one more time until the allocations are stable.
+$QEMU_IMG amend -o refcount_width=64 "$TEST_IMG"
+print_refcount_width
Umm, that sounds backwards from what you document. It's a good test of
the _new_ reftable needing a second round of allocations. So keep it
with corrected comments. But I think you _intended_ to write a test
that starts with a refcount_width=64 image and resize to a
refcount_width=1, where the _old_ reftable then suffers a reallocation
as part of allocating refblocks for the new table.
That's what you intended, but that's harder to test, so I settled for
this (and the comments are appropriate (note that "target refblock"
refers to the refblocks after amendment); note that this does indeed
fail with v1 of this series.
It may even help if
you add a tracepoint for every iteration through the walk function
callback, to prove we are indeed executing it 3 times instead of the
usual 2, for these test cases.
That's a good idea! I thought about adding some info, but totally
forgot about trace points.
...On second thought, trace doesn't work so well with qemu-img. My
best bet would be blkdebug, but that seems kind of ugly to me...
Problem "solved": If there will be more walks than originally thought
(3+1 instead of 2+1), progress will regress at one point. I'll just grep
for that point and that should be enough (progress jumping from 66.67 %
to 50.00 %).
Max