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