error: Drop bogus "use error_setg() instead" admonitions
[qemu/ar7.git] / tests / qemu-iotests / 060
blob74ad371885dc690f85c46590b5abc342ceec4e66
1 #!/bin/bash
3 # Test case for image corruption (overlapping data structures) in qcow2
5 # Copyright (C) 2013 Red Hat, Inc.
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 # creator
22 owner=mreitz@redhat.com
24 seq="$(basename $0)"
25 echo "QA output created by $seq"
27 here="$PWD"
28 status=1 # failure is the default!
30 _cleanup()
32 _cleanup_test_img
34 trap "_cleanup; exit \$status" 0 1 2 3 15
36 # Sometimes the error line might be dumped before/after an event
37 # randomly. Mask it out for specific test that may trigger this
38 # uncertainty for current test for now.
39 _filter_io_error()
41 sed '/Input\/output error/d'
44 # get standard environment, filters and checks
45 . ./common.rc
46 . ./common.filter
48 # This tests qocw2-specific low-level functionality
49 _supported_fmt qcow2
50 _supported_proto file
51 _supported_os Linux
53 rt_offset=65536 # 0x10000 (XXX: just an assumption)
54 rb_offset=131072 # 0x20000 (XXX: just an assumption)
55 l1_offset=196608 # 0x30000 (XXX: just an assumption)
56 l2_offset=262144 # 0x40000 (XXX: just an assumption)
57 l2_offset_after_snapshot=524288 # 0x80000 (XXX: just an assumption)
59 IMGOPTS="compat=1.1"
61 OPEN_RW="open -o overlap-check=all $TEST_IMG"
62 # Overlap checks are done before write operations only, therefore opening an
63 # image read-only makes the overlap-check option irrelevant
64 OPEN_RO="open -r $TEST_IMG"
66 echo
67 echo "=== Testing L2 reference into L1 ==="
68 echo
69 _make_test_img 64M
70 # Link first L1 entry (first L2 table) onto itself
71 # (Note the MSb in the L1 entry is set, ensuring the refcount is one - else any
72 # later write will result in a COW operation, effectively ruining this attempt
73 # on image corruption)
74 poke_file "$TEST_IMG" "$l1_offset" "\x80\x00\x00\x00\x00\x03\x00\x00"
75 _check_test_img
77 # The corrupt bit should not be set anyway
78 $PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
80 # Try to write something, thereby forcing the corrupt bit to be set
81 $QEMU_IO -c "$OPEN_RW" -c "write -P 0x2a 0 512" | _filter_qemu_io
83 # The corrupt bit must now be set
84 $PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
86 # This information should be available through qemu-img info
87 _img_info --format-specific
89 # Try to open the image R/W (which should fail)
90 $QEMU_IO -c "$OPEN_RW" -c "read 0 512" 2>&1 | _filter_qemu_io \
91 | _filter_testdir \
92 | _filter_imgfmt
94 # Try to open it RO (which should succeed)
95 $QEMU_IO -c "$OPEN_RO" -c "read 0 512" | _filter_qemu_io
97 # We could now try to fix the image, but this would probably fail (how should an
98 # L2 table linked onto the L1 table be fixed?)
100 echo
101 echo "=== Testing cluster data reference into refcount block ==="
102 echo
103 _make_test_img 64M
104 # Allocate L2 table
105 truncate -s "$(($l2_offset+65536))" "$TEST_IMG"
106 poke_file "$TEST_IMG" "$l1_offset" "\x80\x00\x00\x00\x00\x04\x00\x00"
107 # Mark cluster as used
108 poke_file "$TEST_IMG" "$(($rb_offset+8))" "\x00\x01"
109 # Redirect new data cluster onto refcount block
110 poke_file "$TEST_IMG" "$l2_offset" "\x80\x00\x00\x00\x00\x02\x00\x00"
111 _check_test_img
112 $PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
113 $QEMU_IO -c "$OPEN_RW" -c "write -P 0x2a 0 512" | _filter_qemu_io
114 $PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
116 # Try to fix it
117 _check_test_img -r all
119 # The corrupt bit should be cleared
120 $PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
122 # Look if it's really really fixed
123 $QEMU_IO -c "$OPEN_RW" -c "write -P 0x2a 0 512" | _filter_qemu_io
124 $PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
126 echo
127 echo "=== Testing cluster data reference into inactive L2 table ==="
128 echo
129 _make_test_img 64M
130 $QEMU_IO -c "$OPEN_RW" -c "write -P 1 0 512" | _filter_qemu_io
131 $QEMU_IMG snapshot -c foo "$TEST_IMG"
132 $QEMU_IO -c "$OPEN_RW" -c "write -P 2 0 512" | _filter_qemu_io
133 # The inactive L2 table remains at its old offset
134 poke_file "$TEST_IMG" "$l2_offset_after_snapshot" \
135 "\x80\x00\x00\x00\x00\x04\x00\x00"
136 _check_test_img
137 $PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
138 $QEMU_IO -c "$OPEN_RW" -c "write -P 3 0 512" | _filter_qemu_io
139 $PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
140 _check_test_img -r all
141 $PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
142 $QEMU_IO -c "$OPEN_RW" -c "write -P 4 0 512" | _filter_qemu_io
143 $PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
145 # Check data
146 $QEMU_IO -c "$OPEN_RO" -c "read -P 4 0 512" | _filter_qemu_io
147 $QEMU_IMG snapshot -a foo "$TEST_IMG"
148 _check_test_img
149 $QEMU_IO -c "$OPEN_RO" -c "read -P 1 0 512" | _filter_qemu_io
151 echo
152 echo "=== Testing overlap while COW is in flight ==="
153 echo
154 # compat=0.10 is required in order to make the following discard actually
155 # unallocate the sector rather than make it a zero sector - we want COW, after
156 # all.
157 IMGOPTS='compat=0.10' _make_test_img 1G
158 # Write two clusters, the second one enforces creation of an L2 table after
159 # the first data cluster.
160 $QEMU_IO -c 'write 0k 64k' -c 'write 512M 64k' "$TEST_IMG" | _filter_qemu_io
161 # Discard the first cluster. This cluster will soon enough be reallocated and
162 # used for COW.
163 $QEMU_IO -c 'discard 0k 64k' "$TEST_IMG" | _filter_qemu_io
164 # Now, corrupt the image by marking the second L2 table cluster as free.
165 poke_file "$TEST_IMG" '131084' "\x00\x00" # 0x2000c
166 # Start a write operation requiring COW on the image stopping it right before
167 # doing the read; then, trigger the corruption prevention by writing anything to
168 # any unallocated cluster, leading to an attempt to overwrite the second L2
169 # table. Finally, resume the COW write and see it fail (but not crash).
170 echo "open -o file.driver=blkdebug $TEST_IMG
171 break cow_read 0
172 aio_write 0k 1k
173 wait_break 0
174 write 64k 64k
175 resume 0" | $QEMU_IO | _filter_qemu_io
177 echo
178 echo "=== Testing unallocated image header ==="
179 echo
180 _make_test_img 64M
181 # Create L1/L2
182 $QEMU_IO -c "write 0 64k" "$TEST_IMG" | _filter_qemu_io
183 poke_file "$TEST_IMG" "$rb_offset" "\x00\x00"
184 $QEMU_IO -c "write 64k 64k" "$TEST_IMG" | _filter_qemu_io
186 echo
187 echo "=== Testing unaligned L1 entry ==="
188 echo
189 _make_test_img 64M
190 $QEMU_IO -c "write 0 64k" "$TEST_IMG" | _filter_qemu_io
191 # This will be masked with ~(512 - 1) = ~0x1ff, so whether the lower 9 bits are
192 # aligned or not does not matter
193 poke_file "$TEST_IMG" "$l1_offset" "\x80\x00\x00\x00\x00\x04\x2a\x00"
194 $QEMU_IO -c "read 0 64k" "$TEST_IMG" | _filter_qemu_io
196 # Test how well zero cluster expansion can cope with this
197 _make_test_img 64M
198 $QEMU_IO -c "write 0 64k" "$TEST_IMG" | _filter_qemu_io
199 poke_file "$TEST_IMG" "$l1_offset" "\x80\x00\x00\x00\x00\x04\x2a\x00"
200 $QEMU_IMG amend -o compat=0.10 "$TEST_IMG"
202 echo
203 echo "=== Testing unaligned L2 entry ==="
204 echo
205 _make_test_img 64M
206 $QEMU_IO -c "write 0 64k" "$TEST_IMG" | _filter_qemu_io
207 poke_file "$TEST_IMG" "$l2_offset" "\x80\x00\x00\x00\x00\x05\x2a\x00"
208 $QEMU_IO -c "read 0 64k" "$TEST_IMG" | _filter_qemu_io
210 echo
211 echo "=== Testing unaligned pre-allocated zero cluster ==="
212 echo
213 _make_test_img 64M
214 $QEMU_IO -c "write 0 64k" "$TEST_IMG" | _filter_qemu_io
215 poke_file "$TEST_IMG" "$l2_offset" "\x80\x00\x00\x00\x00\x05\x2a\x01"
216 # zero cluster expansion
217 $QEMU_IMG amend -o compat=0.10 "$TEST_IMG"
219 echo
220 echo "=== Testing unaligned reftable entry ==="
221 echo
222 _make_test_img 64M
223 poke_file "$TEST_IMG" "$rt_offset" "\x00\x00\x00\x00\x00\x02\x2a\x00"
224 $QEMU_IO -c "write 0 64k" "$TEST_IMG" | _filter_qemu_io
226 echo
227 echo "=== Testing non-fatal corruption on freeing ==="
228 echo
229 _make_test_img 64M
230 $QEMU_IO -c "write 0 64k" "$TEST_IMG" | _filter_qemu_io
231 poke_file "$TEST_IMG" "$l2_offset" "\x80\x00\x00\x00\x00\x05\x2a\x00"
232 $QEMU_IO -c "discard 0 64k" "$TEST_IMG" | _filter_qemu_io
234 echo
235 echo "=== Testing read-only corruption report ==="
236 echo
237 _make_test_img 64M
238 $QEMU_IO -c "write 0 64k" "$TEST_IMG" | _filter_qemu_io
239 poke_file "$TEST_IMG" "$l2_offset" "\x80\x00\x00\x00\x00\x05\x2a\x00"
240 # Should only emit a single error message
241 $QEMU_IO -c "$OPEN_RO" -c "read 0 64k" -c "read 0 64k" | _filter_qemu_io
243 echo
244 echo "=== Testing non-fatal and then fatal corruption report ==="
245 echo
246 _make_test_img 64M
247 $QEMU_IO -c "write 0 128k" "$TEST_IMG" | _filter_qemu_io
248 poke_file "$TEST_IMG" "$l2_offset" "\x80\x00\x00\x00\x00\x05\x2a\x00"
249 poke_file "$TEST_IMG" "$(($l2_offset+8))" "\x80\x00\x00\x00\x00\x06\x2a\x00"
250 # Should emit two error messages
251 $QEMU_IO -c "discard 0 64k" -c "read 64k 64k" "$TEST_IMG" | _filter_qemu_io
253 echo
254 echo "=== Testing empty refcount table ==="
255 echo
256 _make_test_img 64M
257 poke_file "$TEST_IMG" "$rt_offset" "\x00\x00\x00\x00\x00\x00\x00\x00"
258 $QEMU_IO -c "write 0 64k" "$TEST_IMG" | _filter_qemu_io
259 # Repair the image
260 _check_test_img -r all
262 echo
263 echo "=== Testing empty refcount table with valid L1 and L2 tables ==="
264 echo
265 _make_test_img 64M
266 $QEMU_IO -c "write 0 64k" "$TEST_IMG" | _filter_qemu_io
267 poke_file "$TEST_IMG" "$rt_offset" "\x00\x00\x00\x00\x00\x00\x00\x00"
268 # Since the first data cluster is already allocated this triggers an
269 # allocation with an explicit offset (using qcow2_alloc_clusters_at())
270 # causing a refcount block to be allocated at offset 0
271 $QEMU_IO -c "write 0 128k" "$TEST_IMG" | _filter_qemu_io
272 # Repair the image
273 _check_test_img -r all
275 echo
276 echo "=== Testing empty refcount block ==="
277 echo
278 _make_test_img 64M
279 poke_file "$TEST_IMG" "$rb_offset" "\x00\x00\x00\x00\x00\x00\x00\x00"
280 $QEMU_IO -c "write 0 64k" "$TEST_IMG" | _filter_qemu_io
281 # Repair the image
282 _check_test_img -r all
284 echo
285 echo "=== Testing empty refcount block with compressed write ==="
286 echo
287 _make_test_img 64M
288 $QEMU_IO -c "write 64k 64k" "$TEST_IMG" | _filter_qemu_io
289 poke_file "$TEST_IMG" "$rb_offset" "\x00\x00\x00\x00\x00\x00\x00\x00"
290 # The previous write already allocated an L2 table, so now this new
291 # write will try to allocate a compressed data cluster at offset 0.
292 $QEMU_IO -c "write -c 0k 64k" "$TEST_IMG" | _filter_qemu_io
293 # Repair the image
294 _check_test_img -r all
296 echo
297 echo "=== Testing zero refcount table size ==="
298 echo
299 _make_test_img 64M
300 poke_file "$TEST_IMG" "56" "\x00\x00\x00\x00"
301 $QEMU_IO -c "write 0 64k" "$TEST_IMG" 2>&1 | _filter_testdir | _filter_imgfmt
302 # Repair the image
303 _check_test_img -r all
305 echo
306 echo "=== Testing incorrect refcount table offset ==="
307 echo
308 _make_test_img 64M
309 poke_file "$TEST_IMG" "48" "\x00\x00\x00\x00\x00\x00\x00\x00"
310 $QEMU_IO -c "write 0 64k" "$TEST_IMG" | _filter_qemu_io
312 echo
313 echo "=== Testing dirty corrupt image ==="
314 echo
316 _make_test_img 64M
318 # Let the refblock appear unaligned
319 poke_file "$TEST_IMG" "$rt_offset" "\x00\x00\x00\x00\xff\xff\x2a\x00"
320 # Mark the image dirty, thus forcing an automatic check when opening it
321 poke_file "$TEST_IMG" 72 "\x00\x00\x00\x00\x00\x00\x00\x01"
322 # Open the image (qemu should refuse to do so)
323 $QEMU_IO -c close "$TEST_IMG" 2>&1 | _filter_testdir | _filter_imgfmt
325 echo '--- Repairing ---'
327 # The actual repair should have happened (because of the dirty bit),
328 # but some cleanup may have failed (like freeing the old reftable)
329 # because the image was already marked corrupt by that point
330 _check_test_img -r all
332 echo
333 echo "=== Writing to an unaligned preallocated zero cluster ==="
334 echo
336 _make_test_img 64M
338 # Allocate the L2 table
339 $QEMU_IO -c "write 0 64k" -c "discard 0 64k" "$TEST_IMG" | _filter_qemu_io
340 # Pretend there is a preallocated zero cluster somewhere inside the
341 # image header
342 poke_file "$TEST_IMG" "$l2_offset" "\x80\x00\x00\x00\x00\x00\x2a\x01"
343 # Let's write to it!
344 $QEMU_IO -c "write 0 64k" "$TEST_IMG" | _filter_qemu_io
346 echo '--- Repairing ---'
347 _check_test_img -r all
349 echo
350 echo '=== Discarding with an unaligned refblock ==='
351 echo
353 _make_test_img 64M
355 $QEMU_IO -c "write 0 128k" "$TEST_IMG" | _filter_qemu_io
356 # Make our refblock unaligned
357 poke_file "$TEST_IMG" "$(($rt_offset))" "\x00\x00\x00\x00\x00\x00\x2a\x00"
358 # Now try to discard something that will be submitted as two requests
359 # (main part + tail)
360 $QEMU_IO -c "discard 0 65537" "$TEST_IMG"
362 echo '--- Repairing ---'
363 # Fails the first repair because the corruption prevents the check
364 # function from double-checking
365 # (Using -q for the first invocation, because otherwise the
366 # double-check error message appears above the summary for some
367 # reason -- so let's just hide the summary)
368 _check_test_img -q -r all
369 _check_test_img -r all
371 echo
372 echo "=== Discarding an out-of-bounds refblock ==="
373 echo
375 _make_test_img 64M
377 # Pretend there's a refblock really up high
378 poke_file "$TEST_IMG" "$(($rt_offset+8))" "\x00\xff\xff\xff\x00\x00\x00\x00"
379 # Let's try to shrink the qcow2 image so that the block driver tries
380 # to discard that refblock (and see what happens!)
381 $QEMU_IMG resize --shrink "$TEST_IMG" 32M
383 echo '--- Checking and retrying ---'
384 # Image should not be resized
385 _img_info | grep 'virtual size'
386 # But it should pass this check, because the "partial" resize has
387 # already overwritten refblocks past the end
388 _check_test_img -r all
389 # So let's try again
390 $QEMU_IMG resize --shrink "$TEST_IMG" 32M
391 _img_info | grep 'virtual size'
393 echo
394 echo "=== Discarding a non-covered in-bounds refblock ==="
395 echo
397 IMGOPTS='refcount_bits=1' _make_test_img 64M
399 # Pretend there's a refblock somewhere where there is no refblock to
400 # cover it (but the covering refblock has a valid index in the
401 # reftable)
402 # Every refblock covers 65536 * 8 * 65536 = 32 GB, so we have to point
403 # to 0x10_0000_0000 (64G) to point to the third refblock
404 poke_file "$TEST_IMG" "$(($rt_offset+8))" "\x00\x00\x00\x10\x00\x00\x00\x00"
405 $QEMU_IMG resize --shrink "$TEST_IMG" 32M
407 echo '--- Checking and retrying ---'
408 # Image should not be resized
409 _img_info | grep 'virtual size'
410 # But it should pass this check, because the "partial" resize has
411 # already overwritten refblocks past the end
412 _check_test_img -r all
413 # So let's try again
414 $QEMU_IMG resize --shrink "$TEST_IMG" 32M
415 _img_info | grep 'virtual size'
417 echo
418 echo "=== Discarding a refblock covered by an unaligned refblock ==="
419 echo
421 IMGOPTS='refcount_bits=1' _make_test_img 64M
423 # Same as above
424 poke_file "$TEST_IMG" "$(($rt_offset+8))" "\x00\x00\x00\x10\x00\x00\x00\x00"
425 # But now we actually "create" an unaligned third refblock
426 poke_file "$TEST_IMG" "$(($rt_offset+16))" "\x00\x00\x00\x00\x00\x00\x02\x00"
427 $QEMU_IMG resize --shrink "$TEST_IMG" 32M
429 echo '--- Repairing ---'
430 # Fails the first repair because the corruption prevents the check
431 # function from double-checking
432 # (Using -q for the first invocation, because otherwise the
433 # double-check error message appears above the summary for some
434 # reason -- so let's just hide the summary)
435 _check_test_img -q -r all
436 _check_test_img -r all
438 echo
439 echo "=== Testing the QEMU shutdown with a corrupted image ==="
440 echo
441 _make_test_img 64M
442 poke_file "$TEST_IMG" "$rt_offset" "\x00\x00\x00\x00\x00\x00\x00\x00"
443 echo "{'execute': 'qmp_capabilities'}
444 {'execute': 'human-monitor-command',
445 'arguments': {'command-line': 'qemu-io drive \"write 0 512\"'}}
446 {'execute': 'quit'}" \
447 | $QEMU -qmp stdio -nographic -nodefaults \
448 -drive if=none,node-name=drive,file="$TEST_IMG",driver=qcow2 \
449 | _filter_qmp | _filter_qemu_io
451 echo
452 echo "=== Testing incoming inactive corrupted image ==="
453 echo
455 _make_test_img 64M
456 # Create an unaligned L1 entry, so qemu will signal a corruption when
457 # reading from the covered area
458 poke_file "$TEST_IMG" "$l1_offset" "\x00\x00\x00\x00\x2a\x2a\x2a\x2a"
460 # Inactive images are effectively read-only images, so this should be a
461 # non-fatal corruption (which does not modify the image)
462 echo "{'execute': 'qmp_capabilities'}
463 {'execute': 'human-monitor-command',
464 'arguments': {'command-line': 'qemu-io drive \"read 0 512\"'}}
465 {'execute': 'quit'}" \
466 | $QEMU -qmp stdio -nographic -nodefaults \
467 -blockdev "{'node-name': 'drive',
468 'driver': 'qcow2',
469 'file': {
470 'driver': 'file',
471 'filename': '$TEST_IMG'
472 }}" \
473 -incoming exec:'cat /dev/null' \
474 2>&1 \
475 | _filter_qmp | _filter_qemu_io | _filter_io_error
477 echo
478 # Image should not have been marked corrupt
479 _img_info --format-specific | grep 'corrupt:'
481 # success, all done
482 echo "*** done"
483 rm -f $seq.full
484 status=0