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