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