xref: /openbmc/qemu/tests/qemu-iotests/271 (revision 3539d84d)
1#!/usr/bin/env bash
2# group: rw auto
3#
4# Test qcow2 images with extended L2 entries
5#
6# Copyright (C) 2019-2020 Igalia, S.L.
7# Author: Alberto Garcia <berto@igalia.com>
8#
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation; either version 2 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program.  If not, see <http://www.gnu.org/licenses/>.
21#
22
23# creator
24owner=berto@igalia.com
25
26seq="$(basename $0)"
27echo "QA output created by $seq"
28
29here="$PWD"
30status=1	# failure is the default!
31
32_cleanup()
33{
34        _cleanup_test_img
35        rm -f "$TEST_IMG.raw"
36}
37trap "_cleanup; exit \$status" 0 1 2 3 15
38
39# get standard environment, filters and checks
40. ./common.rc
41. ./common.filter
42
43_supported_fmt qcow2
44_supported_proto file nfs
45_supported_os Linux
46_unsupported_imgopts extended_l2 compat=0.10 cluster_size data_file refcount_bits=1[^0-9]
47
48l2_offset=$((0x40000))
49
50_verify_img()
51{
52    $QEMU_IMG compare "$TEST_IMG" "$TEST_IMG.raw" | grep -v 'Images are identical'
53    $QEMU_IMG check "$TEST_IMG" | _filter_qemu_img_check | \
54        grep -v 'No errors were found on the image'
55}
56
57# Compare the bitmap of an extended L2 entry against an expected value
58_verify_l2_bitmap()
59{
60    entry_no="$1"            # L2 entry number, starting from 0
61    expected_alloc="$alloc"  # Space-separated list of allocated subcluster indexes
62    expected_zero="$zero"    # Space-separated list of zero subcluster indexes
63
64    offset=$(($l2_offset + $entry_no * 16))
65    entry=$(peek_file_be "$TEST_IMG" $offset 8)
66    offset=$(($offset + 8))
67    bitmap=$(peek_file_be "$TEST_IMG" $offset 8)
68
69    expected_bitmap=0
70    for bit in $expected_alloc; do
71        expected_bitmap=$(($expected_bitmap | (1 << $bit)))
72    done
73    for bit in $expected_zero; do
74        expected_bitmap=$(($expected_bitmap | (1 << (32 + $bit))))
75    done
76    printf -v expected_bitmap "%u" $expected_bitmap # Convert to unsigned
77
78    printf "L2 entry #%d: 0x%016x %016x\n" "$entry_no" "$entry" "$bitmap"
79    if [ "$bitmap" != "$expected_bitmap" ]; then
80        printf "ERROR: expecting bitmap       0x%016x\n" "$expected_bitmap"
81    fi
82}
83
84# This should be called as _run_test c=XXX sc=XXX off=XXX len=XXX cmd=XXX
85# c:   cluster number (0 if unset)
86# sc:  subcluster number inside cluster @c (0 if unset)
87# off: offset inside subcluster @sc, in kilobytes (0 if unset)
88# len: request length, passed directly to qemu-io (e.g: 256, 4k, 1M, ...)
89# cmd: the command to pass to qemu-io, must be one of
90#      write    -> write
91#      zero     -> write -z
92#      unmap    -> write -z -u
93#      compress -> write -c
94#      discard  -> discard
95_run_test()
96{
97    unset c sc off len cmd
98    for var in "$@"; do eval "$var"; done
99    case "${cmd:-write}" in
100        zero)
101            cmd="write -q -z";;
102        unmap)
103            cmd="write -q -z -u";;
104        compress)
105            pat=$((${pat:-0} + 1))
106            cmd="write -q -c -P ${pat}";;
107        write)
108            pat=$((${pat:-0} + 1))
109            cmd="write -q -P ${pat}";;
110        discard)
111            cmd="discard -q";;
112        *)
113            echo "Unknown option $cmd"
114            exit 1;;
115    esac
116    c="${c:-0}"
117    sc="${sc:-0}"
118    off="${off:-0}"
119    offset="$(($c * 64 + $sc * 2 + $off))"
120    [ "$offset" != 0 ] && offset="${offset}k"
121    cmd="$cmd ${offset} ${len}"
122    raw_cmd=$(echo $cmd | sed s/-c//) # Raw images don't support -c
123    echo $cmd | sed 's/-P [0-9][0-9]\?/-P PATTERN/'
124    $QEMU_IO -c "$cmd" "$TEST_IMG" | _filter_qemu_io
125    $QEMU_IO -c "$raw_cmd" -f raw "$TEST_IMG.raw" | _filter_qemu_io
126    _verify_img
127    _verify_l2_bitmap "$c"
128}
129
130_reset_img()
131{
132    size="$1"
133    $QEMU_IMG create -f raw "$TEST_IMG.raw" "$size" | _filter_img_create
134    if [ "$use_backing_file" = "yes" ]; then
135        $QEMU_IMG create -f raw "$TEST_IMG.base" "$size" | _filter_img_create
136        $QEMU_IO -c "write -q -P 0xFF 0 $size" -f raw "$TEST_IMG.base" | _filter_qemu_io
137        $QEMU_IO -c "write -q -P 0xFF 0 $size" -f raw "$TEST_IMG.raw" | _filter_qemu_io
138        _make_test_img -o extended_l2=on -F raw -b "$TEST_IMG.base" "$size"
139    else
140        _make_test_img -o extended_l2=on "$size"
141    fi
142}
143
144############################################################
145############################################################
146############################################################
147
148# Test that writing to an image with subclusters produces the expected
149# results, in images with and without backing files
150for use_backing_file in yes no; do
151    echo
152    echo "### Standard write tests (backing file: $use_backing_file) ###"
153    echo
154    _reset_img 1M
155    ### Write subcluster #0 (beginning of subcluster) ###
156    alloc="0"; zero=""
157    _run_test sc=0 len=1k
158
159    ### Write subcluster #1 (middle of subcluster) ###
160    alloc="0 1"; zero=""
161    _run_test sc=1 off=1 len=512
162
163    ### Write subcluster #2 (end of subcluster) ###
164    alloc="0 1 2"; zero=""
165    _run_test sc=2 off=1 len=1k
166
167    ### Write subcluster #3 (full subcluster) ###
168    alloc="0 1 2 3"; zero=""
169    _run_test sc=3 len=2k
170
171    ### Write subclusters #4-6 (full subclusters) ###
172    alloc="$(seq 0 6)"; zero=""
173    _run_test sc=4 len=6k
174
175    ### Write subclusters #7-9 (partial subclusters) ###
176    alloc="$(seq 0 9)"; zero=""
177    _run_test sc=7 off=1 len=4k
178
179    ### Write subcluster #16 (partial subcluster) ###
180    alloc="$(seq 0 9) 16"; zero=""
181    _run_test sc=16 len=1k
182
183    ### Write subcluster #31-#33 (cluster overlap) ###
184    alloc="$(seq 0 9) 16 31"; zero=""
185    _run_test sc=31 off=1 len=4k
186    alloc="0 1" ; zero=""
187    _verify_l2_bitmap 1
188
189    ### Zero subcluster #1
190    alloc="0 $(seq 2 9) 16 31"; zero="1"
191    _run_test sc=1 len=2k cmd=zero
192
193    ### Zero cluster #0
194    alloc=""; zero="$(seq 0 31)"
195    _run_test sc=0 len=64k cmd=zero
196
197    ### Fill cluster #0 with data
198    alloc="$(seq 0 31)"; zero=""
199    _run_test sc=0 len=64k
200
201    ### Zero and unmap half of cluster #0 (this won't unmap it)
202    alloc="$(seq 16 31)"; zero="$(seq 0 15)"
203    _run_test sc=0 len=32k cmd=unmap
204
205    ### Zero and unmap cluster #0
206    alloc=""; zero="$(seq 0 31)"
207    _run_test sc=0 len=64k cmd=unmap
208
209    ### Write subcluster #1 (middle of subcluster)
210    alloc="1"; zero="0 $(seq 2 31)"
211    _run_test sc=1 off=1 len=512
212
213    ### Fill cluster #0 with data
214    alloc="$(seq 0 31)"; zero=""
215    _run_test sc=0 len=64k
216
217    ### Discard cluster #0
218    alloc=""; zero="$(seq 0 31)"
219    _run_test sc=0 len=64k cmd=discard
220
221    ### Write compressed data to cluster #0
222    alloc=""; zero=""
223    _run_test sc=0 len=64k cmd=compress
224
225    ### Write subcluster #1 (middle of subcluster)
226    alloc="$(seq 0 31)"; zero=""
227    _run_test sc=1 off=1 len=512
228done
229
230############################################################
231############################################################
232############################################################
233
234# calculate_l2_meta() checks if none of the clusters affected by a
235# write operation need COW or changes to their L2 metadata and simply
236# returns when they don't. This is a test for that optimization.
237# Here clusters #0-#3 are overwritten but only #1 and #2 need changes.
238echo
239echo '### Overwriting several clusters without COW ###'
240echo
241use_backing_file="no" _reset_img 1M
242# Write cluster #0, subclusters #12-#31
243alloc="$(seq 12 31)"; zero=""
244_run_test sc=12 len=40k
245
246# Write cluster #1, subcluster #13
247alloc="13"; zero=""
248_run_test c=1 sc=13 len=2k
249
250# Zeroize cluster #2, subcluster #14
251alloc="14"; zero=""
252_run_test c=2 sc=14 len=2k
253alloc=""; zero="14"
254_run_test c=2 sc=14 len=2k cmd=zero
255
256# Write cluster #3, subclusters #0-#16
257alloc="$(seq 0 16)"; zero=""
258_run_test c=3 sc=0 len=34k
259
260# Write from cluster #0, subcluster #12 to cluster #3, subcluster #11
261alloc="$(seq 12 31)"; zero=""
262_run_test sc=12 len=192k
263alloc="$(seq 0 31)"; zero=""
264_verify_l2_bitmap 1
265_verify_l2_bitmap 2
266
267alloc="$(seq 0 16)"; zero=""
268_verify_l2_bitmap 3
269
270############################################################
271############################################################
272############################################################
273
274# Test different patterns of writing zeroes
275for use_backing_file in yes no; do
276    echo
277    echo "### Writing zeroes 1: unallocated clusters (backing file: $use_backing_file) ###"
278    echo
279    # Note that the image size is not a multiple of the cluster size
280    _reset_img 2083k
281
282    # Cluster-aligned request from clusters #0 to #2
283    alloc=""; zero="$(seq 0 31)"
284    _run_test c=0 sc=0 len=192k cmd=zero
285    _verify_l2_bitmap 1
286    _verify_l2_bitmap 2
287
288    # Subcluster-aligned request from clusters #3 to #5
289    alloc=""; zero="$(seq 16 31)"
290    _run_test c=3 sc=16 len=128k cmd=zero
291    alloc=""; zero="$(seq 0 31)"
292    _verify_l2_bitmap 4
293    alloc=""; zero="$(seq 0 15)"
294    _verify_l2_bitmap 5
295
296    # Unaligned request from clusters #6 to #8
297    if [ "$use_backing_file" = "yes" ]; then
298        alloc="15"; zero="$(seq 16 31)" # copy-on-write happening here
299    else
300        alloc=""; zero="$(seq 15 31)"
301    fi
302    _run_test c=6 sc=15 off=1 len=128k cmd=zero
303    alloc=""; zero="$(seq 0 31)"
304    _verify_l2_bitmap 7
305    if [ "$use_backing_file" = "yes" ]; then
306        alloc="15"; zero="$(seq 0 14)" # copy-on-write happening here
307    else
308        alloc=""; zero="$(seq 0 15)"
309    fi
310    _verify_l2_bitmap 8
311
312    echo
313    echo "### Writing zeroes 2: allocated clusters (backing file: $use_backing_file) ###"
314    echo
315    alloc="$(seq 0 31)"; zero=""
316    _run_test c=9 sc=0 len=576k
317    _verify_l2_bitmap 10
318    _verify_l2_bitmap 11
319    _verify_l2_bitmap 12
320    _verify_l2_bitmap 13
321    _verify_l2_bitmap 14
322    _verify_l2_bitmap 15
323    _verify_l2_bitmap 16
324    _verify_l2_bitmap 17
325
326    # Cluster-aligned request from clusters #9 to #11
327    alloc=""; zero="$(seq 0 31)"
328    _run_test c=9 sc=0 len=192k cmd=zero
329    _verify_l2_bitmap 10
330    _verify_l2_bitmap 11
331
332    # Subcluster-aligned request from clusters #12 to #14
333    alloc="$(seq 0 15)"; zero="$(seq 16 31)"
334    _run_test c=12 sc=16 len=128k cmd=zero
335    alloc=""; zero="$(seq 0 31)"
336    _verify_l2_bitmap 13
337    alloc="$(seq 16 31)"; zero="$(seq 0 15)"
338    _verify_l2_bitmap 14
339
340    # Unaligned request from clusters #15 to #17
341    alloc="$(seq 0 15)"; zero="$(seq 16 31)"
342    _run_test c=15 sc=15 off=1 len=128k cmd=zero
343    alloc=""; zero="$(seq 0 31)"
344    _verify_l2_bitmap 16
345    alloc="$(seq 15 31)"; zero="$(seq 0 14)"
346    _verify_l2_bitmap 17
347
348    echo
349    echo "### Writing zeroes 3: compressed clusters (backing file: $use_backing_file) ###"
350    echo
351    alloc=""; zero=""
352    for c in $(seq 18 28); do
353        _run_test c=$c sc=0 len=64k cmd=compress
354    done
355
356    # Cluster-aligned request from clusters #18 to #20
357    alloc=""; zero="$(seq 0 31)"
358    _run_test c=18 sc=0 len=192k cmd=zero
359    _verify_l2_bitmap 19
360    _verify_l2_bitmap 20
361
362    # Subcluster-aligned request from clusters #21 to #23.
363    # We cannot partially zero a compressed cluster so the code
364    # returns -ENOTSUP, which means copy-on-write of the compressed
365    # data and fill the rest with actual zeroes on disk.
366    # TODO: cluster #22 should use the 'all zeroes' bits.
367    alloc="$(seq 0 31)"; zero=""
368    _run_test c=21 sc=16 len=128k cmd=zero
369    _verify_l2_bitmap 22
370    _verify_l2_bitmap 23
371
372    # Unaligned request from clusters #24 to #26
373    # In this case QEMU internally sends a 1k request followed by a
374    # subcluster-aligned 128k request. The first request decompresses
375    # cluster #24, but that's not enough to perform the second request
376    # efficiently because it partially writes to cluster #26 (which is
377    # compressed) so we hit the same problem as before.
378    alloc="$(seq 0 31)"; zero=""
379    _run_test c=24 sc=15 off=1 len=129k cmd=zero
380    _verify_l2_bitmap 25
381    _verify_l2_bitmap 26
382
383    # Unaligned request from clusters #27 to #29
384    # Similar to the previous case, but this time the tail of the
385    # request does not correspond to a compressed cluster, so it can
386    # be zeroed efficiently.
387    # Note that the very last subcluster is partially written, so if
388    # there's a backing file we need to perform cow.
389    alloc="$(seq 0 15)"; zero="$(seq 16 31)"
390    _run_test c=27 sc=15 off=1 len=128k cmd=zero
391    alloc=""; zero="$(seq 0 31)"
392    _verify_l2_bitmap 28
393    if [ "$use_backing_file" = "yes" ]; then
394        alloc="15"; zero="$(seq 0 14)" # copy-on-write happening here
395    else
396        alloc=""; zero="$(seq 0 15)"
397    fi
398    _verify_l2_bitmap 29
399
400    echo
401    echo "### Writing zeroes 4: other tests (backing file: $use_backing_file) ###"
402    echo
403    # Unaligned request in the middle of cluster #30.
404    # If there's a backing file we need to allocate and do
405    # copy-on-write on the partially zeroed subclusters.
406    # If not we can set the 'all zeroes' bit on them.
407    if [ "$use_backing_file" = "yes" ]; then
408        alloc="15 19"; zero="$(seq 16 18)" # copy-on-write happening here
409    else
410        alloc=""; zero="$(seq 15 19)"
411    fi
412    _run_test c=30 sc=15 off=1 len=8k cmd=zero
413
414    # Fill the last cluster with zeroes, up to the end of the image
415    # (the image size is not a multiple of the cluster or subcluster size).
416    alloc=""; zero="$(seq 0 17)"
417    _run_test c=32 sc=0 len=35k cmd=zero
418done
419
420############################################################
421############################################################
422############################################################
423
424# Zero + unmap
425for use_backing_file in yes no; do
426    echo
427    echo "### Zero + unmap 1: allocated clusters (backing file: $use_backing_file) ###"
428    echo
429    # Note that the image size is not a multiple of the cluster size
430    _reset_img 2083k
431    alloc="$(seq 0 31)"; zero=""
432    _run_test c=9 sc=0 len=576k
433    _verify_l2_bitmap 10
434    _verify_l2_bitmap 11
435    _verify_l2_bitmap 12
436    _verify_l2_bitmap 13
437    _verify_l2_bitmap 14
438    _verify_l2_bitmap 15
439    _verify_l2_bitmap 16
440    _verify_l2_bitmap 17
441
442    # Cluster-aligned request from clusters #9 to #11
443    alloc=""; zero="$(seq 0 31)"
444    _run_test c=9 sc=0 len=192k cmd=unmap
445    _verify_l2_bitmap 10
446    _verify_l2_bitmap 11
447
448    # Subcluster-aligned request from clusters #12 to #14
449    alloc="$(seq 0 15)"; zero="$(seq 16 31)"
450    _run_test c=12 sc=16 len=128k cmd=unmap
451    alloc=""; zero="$(seq 0 31)"
452    _verify_l2_bitmap 13
453    alloc="$(seq 16 31)"; zero="$(seq 0 15)"
454    _verify_l2_bitmap 14
455
456    # Unaligned request from clusters #15 to #17
457    alloc="$(seq 0 15)"; zero="$(seq 16 31)"
458    _run_test c=15 sc=15 off=1 len=128k cmd=unmap
459    alloc=""; zero="$(seq 0 31)"
460    _verify_l2_bitmap 16
461    alloc="$(seq 15 31)"; zero="$(seq 0 14)"
462    _verify_l2_bitmap 17
463
464    echo
465    echo "### Zero + unmap 2: compressed clusters (backing file: $use_backing_file) ###"
466    echo
467    alloc=""; zero=""
468    for c in $(seq 18 28); do
469        _run_test c=$c sc=0 len=64k cmd=compress
470    done
471
472    # Cluster-aligned request from clusters #18 to #20
473    alloc=""; zero="$(seq 0 31)"
474    _run_test c=18 sc=0 len=192k cmd=unmap
475    _verify_l2_bitmap 19
476    _verify_l2_bitmap 20
477
478    # Subcluster-aligned request from clusters #21 to #23.
479    # We cannot partially zero a compressed cluster so the code
480    # returns -ENOTSUP, which means copy-on-write of the compressed
481    # data and fill the rest with actual zeroes on disk.
482    # TODO: cluster #22 should use the 'all zeroes' bits.
483    alloc="$(seq 0 31)"; zero=""
484    _run_test c=21 sc=16 len=128k cmd=unmap
485    _verify_l2_bitmap 22
486    _verify_l2_bitmap 23
487
488    # Unaligned request from clusters #24 to #26
489    # In this case QEMU internally sends a 1k request followed by a
490    # subcluster-aligned 128k request. The first request decompresses
491    # cluster #24, but that's not enough to perform the second request
492    # efficiently because it partially writes to cluster #26 (which is
493    # compressed) so we hit the same problem as before.
494    alloc="$(seq 0 31)"; zero=""
495    _run_test c=24 sc=15 off=1 len=129k cmd=unmap
496    _verify_l2_bitmap 25
497    _verify_l2_bitmap 26
498
499    # Unaligned request from clusters #27 to #29
500    # Similar to the previous case, but this time the tail of the
501    # request does not correspond to a compressed cluster, so it can
502    # be zeroed efficiently.
503    # Note that the very last subcluster is partially written, so if
504    # there's a backing file we need to perform cow.
505    alloc="$(seq 0 15)"; zero="$(seq 16 31)"
506    _run_test c=27 sc=15 off=1 len=128k cmd=unmap
507    alloc=""; zero="$(seq 0 31)"
508    _verify_l2_bitmap 28
509    if [ "$use_backing_file" = "yes" ]; then
510        alloc="15"; zero="$(seq 0 14)" # copy-on-write happening here
511    else
512        alloc=""; zero="$(seq 0 15)"
513    fi
514    _verify_l2_bitmap 29
515done
516
517############################################################
518############################################################
519############################################################
520
521# Test qcow2_cluster_discard() with full and normal discards
522for use_backing_file in yes no; do
523    echo
524    echo "### Discarding clusters with non-zero bitmaps (backing file: $use_backing_file) ###"
525    echo
526    if [ "$use_backing_file" = "yes" ]; then
527        _make_test_img -o extended_l2=on -F raw -b "$TEST_IMG.base" 1M
528    else
529        _make_test_img -o extended_l2=on 1M
530    fi
531    # Write clusters #0-#2 and then discard them
532    $QEMU_IO -c 'write -q 0 128k' "$TEST_IMG"
533    $QEMU_IO -c 'discard -q 0 128k' "$TEST_IMG"
534    # 'qemu-io discard' doesn't do a full discard, it zeroizes the
535    # cluster, so both clusters have all zero bits set now
536    alloc=""; zero="$(seq 0 31)"
537    _verify_l2_bitmap 0
538    _verify_l2_bitmap 1
539    # Now mark the 2nd half of the subclusters from cluster #0 as unallocated
540    poke_file "$TEST_IMG" $(($l2_offset+8)) "\x00\x00"
541    # Discard cluster #0 again to see how the zero bits have changed
542    $QEMU_IO -c 'discard -q 0 64k' "$TEST_IMG"
543    # And do a full discard of cluster #1 by shrinking and growing the image
544    $QEMU_IMG resize --shrink "$TEST_IMG" 64k
545    $QEMU_IMG resize "$TEST_IMG" 1M
546    # A normal discard sets all 'zero' bits only if the image has a
547    # backing file, otherwise it won't touch them.
548    if [ "$use_backing_file" = "yes" ]; then
549        alloc=""; zero="$(seq 0 31)"
550    else
551        alloc=""; zero="$(seq 0 15)"
552    fi
553    _verify_l2_bitmap 0
554    # A full discard should clear the L2 entry completely. However
555    # when growing an image with a backing file the new clusters are
556    # zeroized to hide the stale data from the backing file
557    if [ "$use_backing_file" = "yes" ]; then
558        alloc=""; zero="$(seq 0 31)"
559    else
560        alloc=""; zero=""
561    fi
562    _verify_l2_bitmap 1
563done
564
565############################################################
566############################################################
567############################################################
568
569# Test that corrupted L2 entries are detected in both read and write
570# operations
571for corruption_test_cmd in read write; do
572    echo
573    echo "### Corrupted L2 entries - $corruption_test_cmd test (allocated) ###"
574    echo
575    echo "# 'cluster is zero' bit set on the standard cluster descriptor"
576    echo
577    # We actually don't consider this a corrupted image.
578    # The 'cluster is zero' bit is unused in extended L2 entries so
579    # QEMU ignores it.
580    # TODO: maybe treat the image as corrupted and make qemu-img check fix it?
581    _make_test_img -o extended_l2=on 1M
582    $QEMU_IO -c 'write -q -P 0x11 0 2k' "$TEST_IMG"
583    poke_file "$TEST_IMG" $(($l2_offset+7)) "\x01"
584    alloc="0"; zero=""
585    _verify_l2_bitmap 0
586    $QEMU_IO -c "$corruption_test_cmd -q -P 0x11 0 1k" "$TEST_IMG"
587    if [ "$corruption_test_cmd" = "write" ]; then
588        alloc="0"; zero=""
589    fi
590    _verify_l2_bitmap 0
591
592    echo
593    echo "# Both 'subcluster is zero' and 'subcluster is allocated' bits set"
594    echo
595    _make_test_img -o extended_l2=on 1M
596    # Write from the middle of cluster #0 to the middle of cluster #2
597    $QEMU_IO -c 'write -q 32k 128k' "$TEST_IMG"
598    # Corrupt the L2 entry from cluster #1
599    poke_file_be "$TEST_IMG" $(($l2_offset+24)) 4 1
600    alloc="$(seq 0 31)"; zero="0"
601    _verify_l2_bitmap 1
602    $QEMU_IO -c "$corruption_test_cmd 0 192k" "$TEST_IMG"
603
604    echo
605    echo "### Corrupted L2 entries - $corruption_test_cmd test (unallocated) ###"
606    echo
607    echo "# 'cluster is zero' bit set on the standard cluster descriptor"
608    echo
609    # We actually don't consider this a corrupted image.
610    # The 'cluster is zero' bit is unused in extended L2 entries so
611    # QEMU ignores it.
612    # TODO: maybe treat the image as corrupted and make qemu-img check fix it?
613    _make_test_img -o extended_l2=on 1M
614    # We want to modify the (empty) L2 entry from cluster #0,
615    # but we write to #4 in order to initialize the L2 table first
616    $QEMU_IO -c 'write -q 256k 1k' "$TEST_IMG"
617    poke_file "$TEST_IMG" $(($l2_offset+7)) "\x01"
618    alloc=""; zero=""
619    _verify_l2_bitmap 0
620    $QEMU_IO -c "$corruption_test_cmd -q 0 1k" "$TEST_IMG"
621    if [ "$corruption_test_cmd" = "write" ]; then
622        alloc="0"; zero=""
623    fi
624    _verify_l2_bitmap 0
625
626    echo
627    echo "# 'subcluster is allocated' bit set"
628    echo
629    _make_test_img -o extended_l2=on 1M
630    # We want to corrupt the (empty) L2 entry from cluster #0,
631    # but we write to #4 in order to initialize the L2 table first
632    $QEMU_IO -c 'write -q 256k 1k' "$TEST_IMG"
633    poke_file "$TEST_IMG" $(($l2_offset+15)) "\x01"
634    alloc="0"; zero=""
635    _verify_l2_bitmap 0
636    $QEMU_IO -c "$corruption_test_cmd 0 1k" "$TEST_IMG"
637
638    echo
639    echo "# Both 'subcluster is zero' and 'subcluster is allocated' bits set"
640    echo
641    _make_test_img -o extended_l2=on 1M
642    # We want to corrupt the (empty) L2 entry from cluster #1,
643    # but we write to #4 in order to initialize the L2 table first
644    $QEMU_IO -c 'write -q 256k 1k' "$TEST_IMG"
645    # Corrupt the L2 entry from cluster #1
646    poke_file_be "$TEST_IMG" $(($l2_offset+24)) 8 $(((1 << 32) | 1))
647    alloc="0"; zero="0"
648    _verify_l2_bitmap 1
649    $QEMU_IO -c "$corruption_test_cmd 0 192k" "$TEST_IMG"
650
651    echo
652    echo "### Compressed cluster with subcluster bitmap != 0 - $corruption_test_cmd test ###"
653    echo
654    # We actually don't consider this a corrupted image.
655    # The bitmap in compressed clusters is unused so QEMU should just ignore it.
656    _make_test_img -o extended_l2=on 1M
657    $QEMU_IO -c 'write -q -P 11 -c 0 64k' "$TEST_IMG"
658    # Change the L2 bitmap to allocate subcluster #31 and zeroize subcluster #0
659    poke_file "$TEST_IMG" $(($l2_offset+11)) "\x01\x80"
660    alloc="31"; zero="0"
661    _verify_l2_bitmap 0
662    $QEMU_IO -c "$corruption_test_cmd -P 11 0 64k" "$TEST_IMG" | _filter_qemu_io
663    # Writing allocates a new uncompressed cluster so we get a new bitmap
664    if [ "$corruption_test_cmd" = "write" ]; then
665        alloc="$(seq 0 31)"; zero=""
666    fi
667    _verify_l2_bitmap 0
668done
669
670############################################################
671############################################################
672############################################################
673
674echo
675echo "### Detect and repair unaligned clusters ###"
676echo
677# Create a backing file and fill it with data
678$QEMU_IMG create -f raw "$TEST_IMG.base" 128k | _filter_img_create
679$QEMU_IO -c "write -q -P 0xff 0 128k" -f raw "$TEST_IMG.base" | _filter_qemu_io
680
681echo "# Corrupted L2 entry, allocated subcluster #"
682# Create a new image, allocate a cluster and write some data to it
683_make_test_img -o extended_l2=on -F raw -b "$TEST_IMG.base"
684$QEMU_IO -c 'write -q -P 1 4k 2k' "$TEST_IMG"
685# Corrupt the L2 entry by making the offset unaligned
686poke_file "$TEST_IMG" "$(($l2_offset+6))" "\x02"
687# This cannot be repaired, qemu-img check will fail to fix it
688_check_test_img -r all
689# Attempting to read the image will still show that it's corrupted
690$QEMU_IO -c 'read -q 0 2k' "$TEST_IMG"
691
692echo "# Corrupted L2 entry, no allocated subclusters #"
693# Create a new image, allocate a cluster and zeroize subcluster #2
694_make_test_img -o extended_l2=on -F raw -b "$TEST_IMG.base"
695$QEMU_IO -c 'write -q -P 1 4k 2k' "$TEST_IMG"
696$QEMU_IO -c 'write -q -z   4k 2k' "$TEST_IMG"
697# Corrupt the L2 entry by making the offset unaligned
698poke_file "$TEST_IMG" "$(($l2_offset+6))" "\x02"
699# This time none of the subclusters are allocated so we can repair the image
700_check_test_img -r all
701# And the data can be read normally
702$QEMU_IO -c 'read -q -P 0xff  0   4k' "$TEST_IMG"
703$QEMU_IO -c 'read -q -P 0x00 4k   2k' "$TEST_IMG"
704$QEMU_IO -c 'read -q -P 0xff 6k 122k' "$TEST_IMG"
705
706############################################################
707############################################################
708############################################################
709
710echo
711echo "### Image creation options ###"
712echo
713echo "# cluster_size < 16k"
714_make_test_img -o extended_l2=on,cluster_size=8k 1M
715
716echo "# backing file and preallocation=metadata"
717# For preallocation with backing files, create a backing file first
718$QEMU_IMG create -f raw "$TEST_IMG.base" 1M | _filter_img_create
719$QEMU_IO -c "write -q -P 0xff 0 1M" -f raw "$TEST_IMG.base" | _filter_qemu_io
720
721_make_test_img -o extended_l2=on,preallocation=metadata -F raw -b "$TEST_IMG.base" 512k
722$QEMU_IMG resize "$TEST_IMG" 1M
723$QEMU_IO -c 'read -P 0xff    0 512k' "$TEST_IMG" | _filter_qemu_io
724$QEMU_IO -c 'read -P 0x00 512k 512k' "$TEST_IMG" | _filter_qemu_io
725$QEMU_IMG map "$TEST_IMG" | _filter_testdir
726
727echo "# backing file and preallocation=falloc"
728_make_test_img -o extended_l2=on,preallocation=falloc -F raw -b "$TEST_IMG.base" 512k
729$QEMU_IMG resize "$TEST_IMG" 1M
730$QEMU_IO -c 'read -P 0xff    0 512k' "$TEST_IMG" | _filter_qemu_io
731$QEMU_IO -c 'read -P 0x00 512k 512k' "$TEST_IMG" | _filter_qemu_io
732$QEMU_IMG map "$TEST_IMG" | _filter_testdir
733
734echo "# backing file and preallocation=full"
735_make_test_img -o extended_l2=on,preallocation=full -F raw -b "$TEST_IMG.base" 512k
736$QEMU_IMG resize "$TEST_IMG" 1M
737$QEMU_IO -c 'read -P 0xff    0 512k' "$TEST_IMG" | _filter_qemu_io
738$QEMU_IO -c 'read -P 0x00 512k 512k' "$TEST_IMG" | _filter_qemu_io
739$QEMU_IMG map "$TEST_IMG" | _filter_testdir
740
741echo
742echo "### Image resizing with preallocation and backing files ###"
743echo
744# In this case the new subclusters must have the 'all zeroes' bit set
745echo "# resize --preallocation=metadata"
746_make_test_img -o extended_l2=on -F raw -b "$TEST_IMG.base" 503k
747$QEMU_IMG resize --preallocation=metadata "$TEST_IMG" 1013k
748$QEMU_IO -c 'read -P 0xff    0 503k' "$TEST_IMG" | _filter_qemu_io
749$QEMU_IO -c 'read -P 0x00 503k 510k' "$TEST_IMG" | _filter_qemu_io
750
751# In this case and the next one the new subclusters must be allocated
752echo "# resize --preallocation=falloc"
753_make_test_img -o extended_l2=on -F raw -b "$TEST_IMG.base" 503k
754$QEMU_IMG resize --preallocation=falloc "$TEST_IMG" 1013k
755$QEMU_IO -c 'read -P 0xff    0 503k' "$TEST_IMG" | _filter_qemu_io
756$QEMU_IO -c 'read -P 0x00 503k 510k' "$TEST_IMG" | _filter_qemu_io
757
758echo "# resize --preallocation=full"
759_make_test_img -o extended_l2=on -F raw -b "$TEST_IMG.base" 503k
760$QEMU_IMG resize --preallocation=full "$TEST_IMG" 1013k
761$QEMU_IO -c 'read -P 0xff    0 503k' "$TEST_IMG" | _filter_qemu_io
762$QEMU_IO -c 'read -P 0x00 503k 510k' "$TEST_IMG" | _filter_qemu_io
763
764echo
765echo "### Image resizing with preallocation without backing files ###"
766echo
767# In this case the new subclusters must have the 'all zeroes' bit set
768echo "# resize --preallocation=metadata"
769_make_test_img -o extended_l2=on 503k
770$QEMU_IO -c 'write -P 0xff    0 503k' "$TEST_IMG" | _filter_qemu_io
771$QEMU_IMG resize --preallocation=metadata "$TEST_IMG" 1013k
772$QEMU_IO -c 'read -P 0xff    0 503k' "$TEST_IMG" | _filter_qemu_io
773$QEMU_IO -c 'read -P 0x00 503k 510k' "$TEST_IMG" | _filter_qemu_io
774
775# In this case and the next one the new subclusters must be allocated
776echo "# resize --preallocation=falloc"
777_make_test_img -o extended_l2=on 503k
778$QEMU_IO -c 'write -P 0xff    0 503k' "$TEST_IMG" | _filter_qemu_io
779$QEMU_IMG resize --preallocation=falloc "$TEST_IMG" 1013k
780$QEMU_IO -c 'read -P 0xff    0 503k' "$TEST_IMG" | _filter_qemu_io
781$QEMU_IO -c 'read -P 0x00 503k 510k' "$TEST_IMG" | _filter_qemu_io
782
783echo "# resize --preallocation=full"
784_make_test_img -o extended_l2=on 503k
785$QEMU_IO -c 'write -P 0xff    0 503k' "$TEST_IMG" | _filter_qemu_io
786$QEMU_IMG resize --preallocation=full "$TEST_IMG" 1013k
787$QEMU_IO -c 'read -P 0xff    0 503k' "$TEST_IMG" | _filter_qemu_io
788$QEMU_IO -c 'read -P 0x00 503k 510k' "$TEST_IMG" | _filter_qemu_io
789
790echo
791echo "### qemu-img measure ###"
792echo
793echo "# 512MB, extended_l2=off" # This needs one L2 table
794$QEMU_IMG measure --size 512M -O qcow2 -o extended_l2=off
795echo "# 512MB, extended_l2=on"  # This needs two L2 tables
796$QEMU_IMG measure --size 512M -O qcow2 -o extended_l2=on
797
798echo "# 16K clusters, 64GB, extended_l2=off" # This needs one full L1 table cluster
799$QEMU_IMG measure --size 64G -O qcow2 -o cluster_size=16k,extended_l2=off
800echo "# 16K clusters, 64GB, extended_l2=on"  # This needs two full L2 table clusters
801$QEMU_IMG measure --size 64G -O qcow2 -o cluster_size=16k,extended_l2=on
802
803echo "# 8k clusters" # This should fail
804$QEMU_IMG measure --size 1M -O qcow2 -o cluster_size=8k,extended_l2=on
805
806echo "# 1024 TB" # Maximum allowed size with extended_l2=on and 64K clusters
807$QEMU_IMG measure --size 1024T -O qcow2 -o extended_l2=on
808echo "# 1025 TB" # This should fail
809$QEMU_IMG measure --size 1025T -O qcow2 -o extended_l2=on
810
811echo
812echo "### qemu-img amend ###"
813echo
814_make_test_img -o extended_l2=on 1M
815$QEMU_IMG amend -o extended_l2=off "$TEST_IMG" && echo "Unexpected pass"
816
817_make_test_img -o extended_l2=off 1M
818$QEMU_IMG amend -o extended_l2=on "$TEST_IMG" && echo "Unexpected pass"
819
820echo
821echo "### Test copy-on-write on an image with snapshots ###"
822echo
823_make_test_img -o extended_l2=on 1M
824
825# For each cluster from #0 to #9 this loop zeroes subcluster #7
826# and allocates subclusters #13 and #18.
827alloc="13 18"; zero="7"
828for c in $(seq 0 9); do
829    $QEMU_IO -c "write -q -z $((64*$c+14))k 2k" \
830             -c "write -q -P $((0xd0+$c)) $((64*$c+26))k 2k" \
831             -c "write -q -P $((0xe0+$c)) $((64*$c+36))k 2k" "$TEST_IMG"
832    _verify_l2_bitmap "$c"
833done
834
835# Create a snapshot and set l2_offset to the new L2 table
836$QEMU_IMG snapshot -c snap1 "$TEST_IMG"
837l2_offset=$((0x110000))
838
839# Write different patterns to each one of the clusters
840# in order to see how copy-on-write behaves in each case.
841$QEMU_IO -c "write -q -P 0xf0 $((64*0+30))k 1k" \
842         -c "write -q -P 0xf1 $((64*1+20))k 1k" \
843         -c "write -q -P 0xf2 $((64*2+40))k 1k" \
844         -c "write -q -P 0xf3 $((64*3+26))k 1k" \
845         -c "write -q -P 0xf4 $((64*4+14))k 1k" \
846         -c "write -q -P 0xf5 $((64*5+1))k  1k" \
847         -c "write -q -z      $((64*6+30))k 3k" \
848         -c "write -q -z      $((64*7+26))k 2k" \
849         -c "write -q -z      $((64*8+26))k 1k" \
850         -c "write -q -z      $((64*9+12))k 1k" \
851         "$TEST_IMG"
852alloc="$(seq 13 18)"; zero="7" _verify_l2_bitmap 0
853alloc="$(seq 10 18)"; zero="7" _verify_l2_bitmap 1
854alloc="$(seq 13 20)"; zero="7" _verify_l2_bitmap 2
855alloc="$(seq 13 18)"; zero="7" _verify_l2_bitmap 3
856alloc="$(seq 7 18)";  zero=""  _verify_l2_bitmap 4
857alloc="$(seq 0 18)";  zero=""  _verify_l2_bitmap 5
858alloc="13 18";  zero="7 15 16" _verify_l2_bitmap 6
859alloc="18";        zero="7 13" _verify_l2_bitmap 7
860alloc="$(seq 13 18)"; zero="7" _verify_l2_bitmap 8
861alloc="13 18";      zero="6 7" _verify_l2_bitmap 9
862
863echo
864echo "### Test concurrent requests ###"
865echo
866
867_concurrent_io()
868{
869# Allocate three subclusters in the same cluster.
870# This works because handle_dependencies() checks whether the requests
871# allocate the same cluster, even if the COW regions don't overlap (in
872# this case they don't).
873cat <<EOF
874open -o driver=$IMGFMT blkdebug::$TEST_IMG
875break write_aio A
876aio_write -P 10 30k 2k
877wait_break A
878aio_write -P 11 20k 2k
879aio_write -P 12 40k 2k
880resume A
881aio_flush
882EOF
883}
884
885_concurrent_verify()
886{
887cat <<EOF
888open -o driver=$IMGFMT $TEST_IMG
889read -q -P 10 30k 2k
890read -q -P 11 20k 2k
891read -q -P 12 40k 2k
892EOF
893}
894
895_make_test_img -o extended_l2=on 1M
896_concurrent_io     | $QEMU_IO | _filter_qemu_io
897_concurrent_verify | $QEMU_IO | _filter_qemu_io
898
899# success, all done
900echo "*** done"
901rm -f $seq.full
902status=0
903