1#!/usr/bin/env bash 2# group: rw blkdbg 3# 4# qcow2 error path testing 5# 6# Copyright (C) 2010 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 rm "$TEST_DIR/blkdebug.conf" 34 rm -f "$TEST_IMG.data_file" 35} 36trap "_cleanup; exit \$status" 0 1 2 3 15 37 38# get standard environment, filters and checks 39. ./common.rc 40. ./common.filter 41. ./common.pattern 42 43# Currently only qcow2 supports rebasing 44_supported_fmt qcow2 45_supported_proto file fuse 46_default_cache_mode writethrough 47_supported_cache_modes writethrough none 48# The refcount table tests expect a certain minimum width for refcount entries 49# (so that the refcount table actually needs to grow); that minimum is 16 bits, 50# being the default refcount entry width. 51# 32 and 64 bits do not work either, however, due to different leaked cluster 52# count on error. 53# Thus, the only remaining option is refcount_bits=16. 54# 55# As for data_file, none of the refcount tests can work for it. 56_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)' \ 57 data_file 58 59echo "Errors while writing 128 kB" 60echo 61 62CLUSTER_SIZE=1024 63 64BLKDBG_TEST_IMG="blkdebug:$TEST_DIR/blkdebug.conf:$TEST_IMG" 65 66for event in \ 67 l1_update \ 68 \ 69 l2_load \ 70 l2_update \ 71 l2_alloc_write \ 72 \ 73 write_aio \ 74 \ 75 refblock_load \ 76 refblock_update_part \ 77 refblock_alloc \ 78 \ 79 cluster_alloc \ 80 81do 82 83for errno in 5 28; do 84for imm in off; do 85for once in on off; do 86for vmstate in "" "-b"; do 87 88cat > "$TEST_DIR/blkdebug.conf" <<EOF 89[inject-error] 90event = "$event" 91errno = "$errno" 92immediately = "$imm" 93once ="$once" 94EOF 95 96_make_test_img 1G 97 98echo 99echo "Event: $event; errno: $errno; imm: $imm; once: $once; write $vmstate" 100 101# We want to catch a simple L2 update, not the allocation of the first L2 table 102if [ "$event" == "l2_update" ]; then 103 $QEMU_IO -c "write $vmstate 0 512" "$TEST_IMG" > /dev/null 2>&1 104fi 105 106$QEMU_IO -c "write $vmstate 0 128k " "$BLKDBG_TEST_IMG" | _filter_qemu_io 107 108# l2_load is not called on allocation, so issue a second write 109# Reads are another path to trigger l2_load, so do a read, too 110if [ "$event" == "l2_load" ]; then 111 $QEMU_IO -c "write $vmstate 0 128k " "$BLKDBG_TEST_IMG" | _filter_qemu_io 112 $QEMU_IO -c "read $vmstate 0 128k " "$BLKDBG_TEST_IMG" | _filter_qemu_io 113fi 114 115_check_test_img_ignore_leaks 2>&1 | grep -v "refcount=1 reference=0" 116 117done 118done 119done 120done 121done 122 123 124echo 125echo === Refcount table growth tests === 126echo 127CLUSTER_SIZE=512 128 129 130for event in \ 131 refblock_alloc_hookup \ 132 refblock_alloc_write \ 133 refblock_alloc_write_blocks \ 134 refblock_alloc_write_table \ 135 refblock_alloc_switch_table \ 136 137do 138 139# This one takes a while, so let's test only one error code (ENOSPC should 140# never be generated by qemu, so it's probably a good choice) 141for errno in 28; do 142for imm in off; do 143for once in on off; do 144for vmstate in "" "-b"; do 145 146cat > "$TEST_DIR/blkdebug.conf" <<EOF 147[inject-error] 148event = "$event" 149errno = "$errno" 150immediately = "$imm" 151once = "$once" 152EOF 153 154_make_test_img 1G 155 156echo 157echo "Event: $event; errno: $errno; imm: $imm; once: $once; write $vmstate" 158$QEMU_IO -c "write $vmstate 0 64M" "$BLKDBG_TEST_IMG" | _filter_qemu_io 159 160_check_test_img_ignore_leaks 2>&1 | grep -v "refcount=1 reference=0" 161 162done 163done 164done 165done 166done 167 168echo 169echo === L1 growth tests === 170echo 171CLUSTER_SIZE=1024 172 173 174for event in \ 175 l1_grow_alloc_table \ 176 l1_grow_write_table \ 177 l1_grow_activate_table \ 178 179do 180 181for errno in 5 28; do 182for imm in off; do 183for once in on off; do 184 185cat > "$TEST_DIR/blkdebug.conf" <<EOF 186[inject-error] 187event = "$event" 188errno = "$errno" 189immediately = "$imm" 190once = "$once" 191EOF 192 193_make_test_img 1G 194 195echo 196echo "Event: $event; errno: $errno; imm: $imm; once: $once" 197$QEMU_IO -c "write -b 0 64k" "$BLKDBG_TEST_IMG" | _filter_qemu_io 198 199_check_test_img_ignore_leaks 2>&1 | grep -v "refcount=1 reference=0" 200 201done 202done 203done 204done 205 206echo 207echo === Avoid cluster leaks after temporary failure === 208echo 209 210cat > "$TEST_DIR/blkdebug.conf" <<EOF 211[inject-error] 212event = "write_aio" 213errno = "5" 214once = "on" 215EOF 216 217# After the failed first write, do a second write so that the updated refcount 218# block is actually written back 219_make_test_img 64M 220$QEMU_IO -c "write 0 1M" -c "write 0 1M" "$BLKDBG_TEST_IMG" | _filter_qemu_io 221_check_test_img 222 223echo 224echo === Avoid freeing preallocated zero clusters on failure === 225echo 226 227cat > "$TEST_DIR/blkdebug.conf" <<EOF 228[inject-error] 229event = "write_aio" 230errno = "5" 231once = "on" 232EOF 233 234_make_test_img $CLUSTER_SIZE 235# Create a preallocated zero cluster 236$QEMU_IO -c "write 0 $CLUSTER_SIZE" -c "write -z 0 $CLUSTER_SIZE" "$TEST_IMG" \ 237 | _filter_qemu_io 238# Try to overwrite it (prompting an I/O error from blkdebug), thus 239# triggering the alloc abort code 240$QEMU_IO -c "write 0 $CLUSTER_SIZE" "$BLKDBG_TEST_IMG" | _filter_qemu_io 241 242_check_test_img 243 244# success, all done 245echo "*** done" 246rm -f $seq.full 247status=0 248