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