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