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 968*87fe52ceSAndrey Drobyshev# Check that rebase with compression works correctly with images containing 969*87fe52ceSAndrey Drobyshev# subclusters. When compression is enabled and we allocate a new 970*87fe52ceSAndrey Drobyshev# subcluster within the target (overlay) image, we expect the entire cluster 971*87fe52ceSAndrey Drobyshev# containing that subcluster to become compressed. 972*87fe52ceSAndrey Drobyshev# 973*87fe52ceSAndrey Drobyshev# Here we expect 1st and 3rd clusters of the top (overlay) image to become 974*87fe52ceSAndrey Drobyshev# compressed after the rebase, while cluster 2 to remain unallocated and 975*87fe52ceSAndrey Drobyshev# be read from the base (new backing) image. 976*87fe52ceSAndrey Drobyshev# 977*87fe52ceSAndrey Drobyshev# Base (new backing): |-- -- .. -- --|11 11 .. 11 11|-- -- .. -- --| 978*87fe52ceSAndrey Drobyshev# Mid (old backing): |-- -- .. -- 22|-- -- .. -- --|33 -- .. -- --| 979*87fe52ceSAndrey Drobyshev# Top: |-- -- .. -- --|-- -- -- -- --|-- -- .. -- --| 980*87fe52ceSAndrey Drobyshev 981*87fe52ceSAndrey Drobyshevecho 982*87fe52ceSAndrey Drobyshevecho "### Rebase with compression for images with subclusters ###" 983*87fe52ceSAndrey Drobyshevecho 984*87fe52ceSAndrey Drobyshev 985*87fe52ceSAndrey Drobyshevecho "# create backing chain" 986*87fe52ceSAndrey Drobyshevecho 987*87fe52ceSAndrey Drobyshev 988*87fe52ceSAndrey DrobyshevTEST_IMG="$TEST_IMG.base" _make_test_img -o cluster_size=1M,extended_l2=on 3M 989*87fe52ceSAndrey DrobyshevTEST_IMG="$TEST_IMG.mid" _make_test_img -o cluster_size=1M,extended_l2=on \ 990*87fe52ceSAndrey Drobyshev -b "$TEST_IMG.base" -F qcow2 3M 991*87fe52ceSAndrey DrobyshevTEST_IMG="$TEST_IMG.top" _make_test_img -o cluster_size=1M,extended_l2=on \ 992*87fe52ceSAndrey Drobyshev -b "$TEST_IMG.mid" -F qcow2 3M 993*87fe52ceSAndrey Drobyshev 994*87fe52ceSAndrey Drobyshevecho 995*87fe52ceSAndrey Drobyshevecho "# fill old and new backing with data" 996*87fe52ceSAndrey Drobyshevecho 997*87fe52ceSAndrey Drobyshev 998*87fe52ceSAndrey Drobyshev$QEMU_IO -c "write -P 0x11 1M 1M" "$TEST_IMG.base" | _filter_qemu_io 999*87fe52ceSAndrey Drobyshev$QEMU_IO -c "write -P 0x22 $(( 31 * 32 ))k 32k" \ 1000*87fe52ceSAndrey Drobyshev -c "write -P 0x33 $(( 64 * 32 ))k 32k" \ 1001*87fe52ceSAndrey Drobyshev "$TEST_IMG.mid" | _filter_qemu_io 1002*87fe52ceSAndrey Drobyshev 1003*87fe52ceSAndrey Drobyshevecho 1004*87fe52ceSAndrey Drobyshevecho "# rebase topmost image onto the new backing, with compression" 1005*87fe52ceSAndrey Drobyshevecho 1006*87fe52ceSAndrey Drobyshev 1007*87fe52ceSAndrey Drobyshev$QEMU_IMG rebase -c -b "$TEST_IMG.base" -F qcow2 "$TEST_IMG.top" 1008*87fe52ceSAndrey Drobyshev 1009*87fe52ceSAndrey Drobyshevecho "# verify that the 1st and 3rd clusters've become compressed" 1010*87fe52ceSAndrey Drobyshevecho 1011*87fe52ceSAndrey Drobyshev 1012*87fe52ceSAndrey Drobyshev$QEMU_IMG map --output=json "$TEST_IMG.top" | _filter_testdir 1013*87fe52ceSAndrey Drobyshev 1014*87fe52ceSAndrey Drobyshevecho 1015*87fe52ceSAndrey Drobyshevecho "# verify that data is read the same before and after rebase" 1016*87fe52ceSAndrey Drobyshevecho 1017*87fe52ceSAndrey Drobyshev 1018*87fe52ceSAndrey Drobyshev$QEMU_IO -c "read -P 0x22 $(( 31 * 32 ))k 32k" \ 1019*87fe52ceSAndrey Drobyshev -c "read -P 0x11 1M 1M" \ 1020*87fe52ceSAndrey Drobyshev -c "read -P 0x33 $(( 64 * 32 ))k 32k" \ 1021*87fe52ceSAndrey Drobyshev "$TEST_IMG.top" | _filter_qemu_io 1022*87fe52ceSAndrey Drobyshev 1023*87fe52ceSAndrey Drobyshevecho 1024*87fe52ceSAndrey Drobyshevecho "# verify image bitmap" 1025*87fe52ceSAndrey Drobyshevecho 1026*87fe52ceSAndrey Drobyshev 1027*87fe52ceSAndrey Drobyshev# For compressed clusters bitmap is always 0. For unallocated cluster 1028*87fe52ceSAndrey Drobyshev# there should be no entry at all, thus bitmap is also 0. 1029*87fe52ceSAndrey DrobyshevTEST_IMG="$TEST_IMG.top" alloc="" zero="" _verify_l2_bitmap 0 1030*87fe52ceSAndrey DrobyshevTEST_IMG="$TEST_IMG.top" alloc="" zero="" _verify_l2_bitmap 1 1031*87fe52ceSAndrey DrobyshevTEST_IMG="$TEST_IMG.top" alloc="" zero="" _verify_l2_bitmap 2 1032*87fe52ceSAndrey Drobyshev 1033a5d3cfa2SAlberto Garcia# success, all done 1034a5d3cfa2SAlberto Garciaecho "*** done" 1035a5d3cfa2SAlberto Garciarm -f $seq.full 1036a5d3cfa2SAlberto Garciastatus=0 1037