xref: /qemu/tests/qemu-iotests/026 (revision 2e8f72ac)
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