1#!/usr/bin/env bash 2# 3# qcow2 error path testing 4# 5# Copyright (C) 2010 Red Hat, Inc. 6# 7# This program is free software; you can redistribute it and/or modify 8# it under the terms of the GNU General Public License as published by 9# the Free Software Foundation; either version 2 of the License, or 10# (at your option) any later version. 11# 12# This program is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU General Public License for more details. 16# 17# You should have received a copy of the GNU General Public License 18# along with this program. If not, see <http://www.gnu.org/licenses/>. 19# 20 21# creator 22owner=kwolf@redhat.com 23 24seq=`basename $0` 25echo "QA output created by $seq" 26 27status=1 # failure is the default! 28 29_cleanup() 30{ 31 _cleanup_test_img 32 rm "$TEST_DIR/blkdebug.conf" 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. ./common.pattern 40 41# Currently only qcow2 supports rebasing 42_supported_fmt qcow2 43_supported_proto file 44_default_cache_mode writethrough 45_supported_cache_modes writethrough none 46# The refcount table tests expect a certain minimum width for refcount entries 47# (so that the refcount table actually needs to grow); that minimum is 16 bits, 48# being the default refcount entry width. 49# 32 and 64 bits do not work either, however, due to different leaked cluster 50# count on error. 51# Thus, the only remaining option is refcount_bits=16. 52# 53# As for data_file, none of the refcount tests can work for it. 54_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)' \ 55 data_file 56 57echo "Errors while writing 128 kB" 58echo 59 60CLUSTER_SIZE=1024 61 62BLKDBG_TEST_IMG="blkdebug:$TEST_DIR/blkdebug.conf:$TEST_IMG" 63 64for event in \ 65 l1_update \ 66 \ 67 l2_load \ 68 l2_update \ 69 l2_alloc_write \ 70 \ 71 write_aio \ 72 \ 73 refblock_load \ 74 refblock_update_part \ 75 refblock_alloc \ 76 \ 77 cluster_alloc \ 78 79do 80 81for errno in 5 28; do 82for imm in off; do 83for once in on off; do 84for vmstate in "" "-b"; do 85 86cat > "$TEST_DIR/blkdebug.conf" <<EOF 87[inject-error] 88event = "$event" 89errno = "$errno" 90immediately = "$imm" 91once ="$once" 92EOF 93 94_make_test_img 1G 95 96echo 97echo "Event: $event; errno: $errno; imm: $imm; once: $once; write $vmstate" 98 99# We want to catch a simple L2 update, not the allocation of the first L2 table 100if [ "$event" == "l2_update" ]; then 101 $QEMU_IO -c "write $vmstate 0 512" "$TEST_IMG" > /dev/null 2>&1 102fi 103 104$QEMU_IO -c "write $vmstate 0 128k " "$BLKDBG_TEST_IMG" | _filter_qemu_io 105 106# l2_load is not called on allocation, so issue a second write 107# Reads are another path to trigger l2_load, so do a read, too 108if [ "$event" == "l2_load" ]; then 109 $QEMU_IO -c "write $vmstate 0 128k " "$BLKDBG_TEST_IMG" | _filter_qemu_io 110 $QEMU_IO -c "read $vmstate 0 128k " "$BLKDBG_TEST_IMG" | _filter_qemu_io 111fi 112 113_check_test_img_ignore_leaks 2>&1 | grep -v "refcount=1 reference=0" 114 115done 116done 117done 118done 119done 120 121 122echo 123echo === Refcount table growth tests === 124echo 125CLUSTER_SIZE=512 126 127 128for event in \ 129 refblock_alloc_hookup \ 130 refblock_alloc_write \ 131 refblock_alloc_write_blocks \ 132 refblock_alloc_write_table \ 133 refblock_alloc_switch_table \ 134 135do 136 137# This one takes a while, so let's test only one error code (ENOSPC should 138# never be generated by qemu, so it's probably a good choice) 139for errno in 28; do 140for imm in off; do 141for once in on off; do 142for vmstate in "" "-b"; do 143 144cat > "$TEST_DIR/blkdebug.conf" <<EOF 145[inject-error] 146event = "$event" 147errno = "$errno" 148immediately = "$imm" 149once = "$once" 150EOF 151 152_make_test_img 1G 153 154echo 155echo "Event: $event; errno: $errno; imm: $imm; once: $once; write $vmstate" 156$QEMU_IO -c "write $vmstate 0 64M" "$BLKDBG_TEST_IMG" | _filter_qemu_io 157 158_check_test_img_ignore_leaks 2>&1 | grep -v "refcount=1 reference=0" 159 160done 161done 162done 163done 164done 165 166echo 167echo === L1 growth tests === 168echo 169CLUSTER_SIZE=1024 170 171 172for event in \ 173 l1_grow_alloc_table \ 174 l1_grow_write_table \ 175 l1_grow_activate_table \ 176 177do 178 179for errno in 5 28; do 180for imm in off; do 181for once in on off; do 182 183cat > "$TEST_DIR/blkdebug.conf" <<EOF 184[inject-error] 185event = "$event" 186errno = "$errno" 187immediately = "$imm" 188once = "$once" 189EOF 190 191_make_test_img 1G 192 193echo 194echo "Event: $event; errno: $errno; imm: $imm; once: $once" 195$QEMU_IO -c "write -b 0 64k" "$BLKDBG_TEST_IMG" | _filter_qemu_io 196 197_check_test_img_ignore_leaks 2>&1 | grep -v "refcount=1 reference=0" 198 199done 200done 201done 202done 203 204echo 205echo === Avoid cluster leaks after temporary failure === 206echo 207 208cat > "$TEST_DIR/blkdebug.conf" <<EOF 209[inject-error] 210event = "write_aio" 211errno = "5" 212once = "on" 213EOF 214 215# After the failed first write, do a second write so that the updated refcount 216# block is actually written back 217_make_test_img 64M 218$QEMU_IO -c "write 0 1M" -c "write 0 1M" "$BLKDBG_TEST_IMG" | _filter_qemu_io 219_check_test_img 220 221echo 222echo === Avoid freeing preallocated zero clusters on failure === 223echo 224 225cat > "$TEST_DIR/blkdebug.conf" <<EOF 226[inject-error] 227event = "write_aio" 228errno = "5" 229once = "on" 230EOF 231 232_make_test_img $CLUSTER_SIZE 233# Create a preallocated zero cluster 234$QEMU_IO -c "write 0 $CLUSTER_SIZE" -c "write -z 0 $CLUSTER_SIZE" "$TEST_IMG" \ 235 | _filter_qemu_io 236# Try to overwrite it (prompting an I/O error from blkdebug), thus 237# triggering the alloc abort code 238$QEMU_IO -c "write 0 $CLUSTER_SIZE" "$BLKDBG_TEST_IMG" | _filter_qemu_io 239 240_check_test_img 241 242# success, all done 243echo "*** done" 244rm -f $seq.full 245status=0 246