1#!/usr/bin/env bash 2# group: rw auto aio quick 3# 4# Test concurrent cluster allocations 5# 6# Copyright (C) 2012 Red Hat, Inc. 7# 8# This program is free software; you can redistribute it and/or modify 9# it under the terms of the GNU General Public License as published by 10# the Free Software Foundation; either version 2 of the License, or 11# (at your option) any later version. 12# 13# This program is distributed in the hope that it will be useful, 14# but WITHOUT ANY WARRANTY; without even the implied warranty of 15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16# GNU General Public License for more details. 17# 18# You should have received a copy of the GNU General Public License 19# along with this program. If not, see <http://www.gnu.org/licenses/>. 20# 21 22# creator 23owner=kwolf@redhat.com 24 25seq=`basename $0` 26echo "QA output created by $seq" 27 28status=1 # failure is the default! 29 30_cleanup() 31{ 32 _cleanup_test_img 33} 34trap "_cleanup; exit \$status" 0 1 2 3 15 35 36# get standard environment, filters and checks 37. ./common.rc 38. ./common.filter 39 40_supported_fmt qcow2 41_supported_proto file fuse 42# data_file does not support compressed clusters 43_unsupported_imgopts data_file 44 45CLUSTER_SIZE=64k 46size=128M 47 48echo 49echo "== creating backing file for COW tests ==" 50 51TEST_IMG_SAVE=$TEST_IMG 52TEST_IMG="$TEST_IMG.base" 53_make_test_img $size 54 55backing_io() 56{ 57 local offset=$1 58 local sectors=$2 59 local op=$3 60 local pattern=0 61 local cur_sec=0 62 63 for ((i=0;i<=$((sectors - 1));i++)); do 64 cur_sec=$((offset / 65536 + i)) 65 pattern=$(( ( (cur_sec % 128) + (cur_sec / 128)) % 128 )) 66 67 echo "$op -P $pattern $((cur_sec * 64))k 64k" 68 done 69} 70 71backing_io 0 32 write | $QEMU_IO "$TEST_IMG" | _filter_qemu_io 72 73TEST_IMG=$TEST_IMG_SAVE 74_make_test_img -b "$TEST_IMG.base" -F $IMGFMT 6G 75 76echo 77echo "== Some concurrent requests touching the same cluster ==" 78 79overlay_io() 80{ 81# Allocate middle of cluster 1, then write to somewhere before and after it 82cat <<EOF 83break write_aio A 84aio_write -P 10 0x18000 0x2000 85wait_break A 86 87aio_write -P 11 0x12000 0x2000 88aio_write -P 12 0x1c000 0x2000 89 90resume A 91aio_flush 92EOF 93 94# Sequential write case: Alloc middle of cluster 2, then write overlapping 95# to next cluster 96cat <<EOF 97break write_aio A 98aio_write -P 20 0x28000 0x2000 99wait_break A 100aio_write -P 21 0x2a000 0x10000 101resume A 102aio_flush 103EOF 104 105# The same with a gap between both requests 106cat <<EOF 107break write_aio A 108aio_write -P 40 0x48000 0x2000 109wait_break A 110aio_write -P 41 0x4c000 0x10000 111resume A 112aio_flush 113EOF 114 115# Sequential write, but the next cluster is already allocated 116cat <<EOF 117write -P 70 0x76000 0x8000 118aio_flush 119break write_aio A 120aio_write -P 60 0x66000 0x2000 121wait_break A 122aio_write -P 61 0x6a000 0xe000 123resume A 124aio_flush 125EOF 126 127# Sequential write, but the next cluster is already allocated 128# and phyiscally in the right position 129cat <<EOF 130write -P 89 0x80000 0x1000 131write -P 90 0x96000 0x8000 132aio_flush 133discard 0x80000 0x10000 134aio_flush 135break write_aio A 136aio_write -P 80 0x86000 0x2000 137wait_break A 138aio_write -P 81 0x8a000 0xe000 139resume A 140aio_flush 141EOF 142 143# Sequential write, and the next cluster is compressed 144cat <<EOF 145write -P 109 0xa0000 0x1000 146write -c -P 110 0xb0000 0x10000 147aio_flush 148discard 0xa0000 0x10000 149aio_flush 150break write_aio A 151aio_write -P 100 0xa6000 0x2000 152wait_break A 153aio_write -P 101 0xaa000 0xe000 154resume A 155aio_flush 156EOF 157 158# Reverse sequential write 159cat <<EOF 160break write_aio A 161aio_write -P 121 0xdc000 0x2000 162wait_break A 163aio_write -P 120 0xc4000 0x18000 164resume A 165aio_flush 166EOF 167 168# Reverse sequential write with a gap 169cat <<EOF 170break write_aio A 171aio_write -P 141 0xfc000 0x2000 172wait_break A 173aio_write -P 140 0xe4000 0x14000 174resume A 175aio_flush 176EOF 177 178# Allocate an area in the middle and then overwrite with a larger request 179cat <<EOF 180break write_aio A 181aio_write -P 161 0x10c000 0x8000 182wait_break A 183aio_write -P 160 0x104000 0x18000 184resume A 185aio_flush 186EOF 187} 188 189overlay_io | $QEMU_IO blkdebug::"$TEST_IMG" | _filter_qemu_io |\ 190 sed -e 's/[0-9]*\/[0-9]* bytes at offset [0-9]*/XXX\/XXX bytes at offset XXX/g' \ 191 -e 's/^[0-9]* KiB/XXX KiB/g' 192 193echo 194echo "== Verify image content ==" 195 196verify_io() 197{ 198 if ($QEMU_IMG info -U -f "$IMGFMT" "$TEST_IMG" | grep "compat: 0.10" > /dev/null); then 199 # In v2 images clusters are not discarded when there is a backing file. 200 # Keep the variable empty so that the previous value can be used as 201 # the default below 202 discarded= 203 else 204 # Discarded clusters are zeroed for v3 or later 205 discarded=0 206 fi 207 208 echo read -P 0 0 0x10000 209 210 echo read -P 1 0x10000 0x2000 211 echo read -P 11 0x12000 0x2000 212 echo read -P 1 0x14000 0x4000 213 echo read -P 10 0x18000 0x2000 214 echo read -P 1 0x1a000 0x2000 215 echo read -P 12 0x1c000 0x2000 216 echo read -P 1 0x1e000 0x2000 217 218 echo read -P 2 0x20000 0x8000 219 echo read -P 20 0x28000 0x2000 220 echo read -P 21 0x2a000 0x10000 221 echo read -P 3 0x3a000 0x6000 222 223 echo read -P 4 0x40000 0x8000 224 echo read -P 40 0x48000 0x2000 225 echo read -P 4 0x4a000 0x2000 226 echo read -P 41 0x4c000 0x10000 227 echo read -P 5 0x5c000 0x4000 228 229 echo read -P 6 0x60000 0x6000 230 echo read -P 60 0x66000 0x2000 231 echo read -P 6 0x68000 0x2000 232 echo read -P 61 0x6a000 0xe000 233 echo read -P 70 0x78000 0x6000 234 echo read -P 7 0x7e000 0x2000 235 236 echo read -P ${discarded:-89} 0x80000 0x1000 237 echo read -P ${discarded:-8} 0x81000 0x5000 238 echo read -P 80 0x86000 0x2000 239 echo read -P ${discarded:-8} 0x88000 0x2000 240 echo read -P 81 0x8a000 0xe000 241 echo read -P 90 0x98000 0x6000 242 echo read -P 9 0x9e000 0x2000 243 244 echo read -P ${discarded:-109} 0xa0000 0x1000 245 echo read -P ${discarded:-10} 0xa1000 0x5000 246 echo read -P 100 0xa6000 0x2000 247 echo read -P ${discarded:-10} 0xa8000 0x2000 248 echo read -P 101 0xaa000 0xe000 249 echo read -P 110 0xb8000 0x8000 250 251 echo read -P 12 0xc0000 0x4000 252 echo read -P 120 0xc4000 0x18000 253 echo read -P 121 0xdc000 0x2000 254 echo read -P 13 0xde000 0x2000 255 256 echo read -P 14 0xe0000 0x4000 257 echo read -P 140 0xe4000 0x14000 258 echo read -P 15 0xf8000 0x4000 259 echo read -P 141 0xfc000 0x2000 260 echo read -P 15 0xfe000 0x2000 261 262 echo read -P 16 0x100000 0x4000 263 echo read -P 160 0x104000 0x8000 264 # Undefined content for 0x10c000 0x8000 265 echo read -P 160 0x114000 0x8000 266 echo read -P 17 0x11c000 0x4000 267} 268 269verify_io | $QEMU_IO "$TEST_IMG" | _filter_qemu_io 270 271_check_test_img 272 273# success, all done 274echo "*** done" 275rm -f $seq.full 276status=0 277