OSDN Git Service

Updated the FSF address to <https://www.gnu.org/licenses/>
[qmiga/qemu.git] / tests / qemu-iotests / 081
1 #!/usr/bin/env bash
2 # group: rw quick
3 #
4 # Test Quorum block driver
5 #
6 # Copyright (C) 2013 Nodalink, SARL.
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
23 owner=benoit@irqsave.net
24
25 seq=`basename $0`
26 echo "QA output created by $seq"
27
28 status=1        # failure is the default!
29
30 _cleanup()
31 {
32     _rm_test_img "$TEST_DIR/1.raw"
33     _rm_test_img "$TEST_DIR/2.raw"
34     _rm_test_img "$TEST_DIR/3.raw"
35 }
36 trap "_cleanup; exit \$status" 0 1 2 3 15
37
38 # get standard environment, filters and checks
39 . ./common.rc
40 . ./common.filter
41
42 _supported_fmt raw
43 _supported_proto file
44 _supported_os Linux
45 _require_drivers quorum
46 _require_devices virtio-scsi
47
48 do_run_qemu()
49 {
50     echo Testing: "$@"
51     $QEMU -nographic -qmp stdio -serial none "$@"
52     echo
53 }
54
55 run_qemu()
56 {
57     do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_imgfmt | _filter_qemu \
58                           | _filter_qmp | _filter_qemu_io \
59                           | _filter_generated_node_ids
60 }
61
62 quorum="driver=raw,file.driver=quorum,file.vote-threshold=2"
63 quorum="$quorum,file.children.0.file.filename=$TEST_DIR/1.raw"
64 quorum="$quorum,file.children.1.file.filename=$TEST_DIR/2.raw"
65 quorum="$quorum,file.children.2.file.filename=$TEST_DIR/3.raw"
66 quorum="$quorum,file.children.0.driver=raw"
67 quorum="$quorum,file.children.1.driver=raw"
68 quorum="$quorum,file.children.2.driver=raw"
69
70 echo
71 echo "== creating quorum files =="
72
73 size=10M
74
75 TEST_IMG="$TEST_DIR/1.raw" _make_test_img $size
76 TEST_IMG="$TEST_DIR/2.raw" _make_test_img $size
77 TEST_IMG="$TEST_DIR/3.raw" _make_test_img $size
78
79 echo
80 echo "== writing images =="
81
82 $QEMU_IO -c "open -o $quorum" -c "write -P 0x32 0 $size" | _filter_qemu_io
83
84 echo
85 echo "== checking quorum write =="
86
87 $QEMU_IO -c "read -P 0x32 0 $size" "$TEST_DIR/1.raw" | _filter_qemu_io
88 $QEMU_IO -c "read -P 0x32 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io
89 $QEMU_IO -c "read -P 0x32 0 $size" "$TEST_DIR/3.raw" | _filter_qemu_io
90
91 echo
92 echo "== corrupting image =="
93
94 $QEMU_IO -c "write -P 0x42 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io
95
96 echo
97 echo "== checking quorum correction =="
98
99 $QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
100
101 echo
102 echo "== checking mixed reference/option specification =="
103
104 run_qemu <<EOF
105 { "execute": "qmp_capabilities" }
106 { "execute": "blockdev-add",
107     "arguments": {
108         "node-name": "drive2",
109         "driver": "$IMGFMT",
110         "file": {
111             "driver": "file",
112             "filename": "$TEST_DIR/2.raw"
113         }
114     }
115 }
116 { "execute": "blockdev-add",
117     "arguments": {
118         "driver": "quorum",
119         "node-name": "drive0-quorum",
120         "vote-threshold": 2,
121         "children": [
122             {
123                 "driver": "$IMGFMT",
124                 "file": {
125                     "driver": "file",
126                     "filename": "$TEST_DIR/1.raw"
127                 }
128             },
129             "drive2",
130             {
131                 "driver": "$IMGFMT",
132                 "file": {
133                     "driver": "file",
134                     "filename": "$TEST_DIR/3.raw"
135                 }
136             }
137         ]
138     }
139 }
140 { "execute": "human-monitor-command",
141     "arguments": {
142         "command-line": 'qemu-io drive0-quorum "read -P 0x32 0 $size"'
143     }
144 }
145 { "execute": "quit" }
146 EOF
147
148 echo
149 echo "== using quorum rewrite corrupted mode =="
150
151 quorum="$quorum,file.rewrite-corrupted=on"
152
153 $QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
154
155 echo
156 echo "== checking that quorum has corrected the corrupted file =="
157
158 $QEMU_IO -c "read -P 0x32 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io
159
160 echo
161 echo "== using quorum rewrite corrupted mode without WRITE permission =="
162
163 # The same as above, but this time, do it on a quorum node whose only
164 # parent will not take the WRITE permission
165
166 echo '-- corrupting --'
167 # Only corrupt a portion: The guest device (scsi-hd on virtio-scsi)
168 # will read some data (looking for a partition table to guess the
169 # disk's geometry), which would trigger a quorum mismatch if the
170 # beginning of the image was corrupted.  The subsequent
171 # QUORUM_REPORT_BAD event would be suppressed (because at that point,
172 # there cannot have been a qmp_capabilities on the monitor).  Because
173 # that event is rate-limited, the next QUORUM_REPORT_BAD that happens
174 # thanks to our qemu-io read (which should trigger a mismatch) would
175 # then be delayed past the VM quit and not appear in the output.
176 # So we keep the first 1M intact to see a QUORUM_REPORT_BAD resulting
177 # from the qemu-io invocation.
178 $QEMU_IO -c "write -P 0x42 1M 1M" "$TEST_DIR/2.raw" | _filter_qemu_io
179
180 # Fix the corruption (on a read-only quorum node, i.e. without taking
181 # the WRITE permission on it -- its child nodes need to be R/W OTOH,
182 # so that rewrite-corrupted works)
183 echo
184 echo '-- running quorum --'
185 run_qemu \
186     -blockdev file,node-name=file1,filename="$TEST_DIR/1.raw" \
187     -blockdev file,node-name=file2,filename="$TEST_DIR/2.raw" \
188     -blockdev file,node-name=file3,filename="$TEST_DIR/3.raw" \
189     -blockdev '{
190         "driver": "quorum",
191         "node-name": "quorum",
192         "read-only": true,
193         "vote-threshold": 2,
194         "rewrite-corrupted": true,
195         "children": [ "file1", "file2", "file3" ]
196     }' \
197     -device virtio-scsi,id=scsi \
198     -device scsi-hd,id=quorum-drive,bus=scsi.0,drive=quorum \
199     <<EOF
200 { "execute": "qmp_capabilities" }
201 {
202     "execute": "human-monitor-command",
203     "arguments": {
204         "command-line": 'qemu-io -d quorum-drive "read -P 0x32 0 $size"'
205     }
206 }
207 { "execute": "quit" }
208 EOF
209
210 echo '-- checking that the image has been corrected --'
211 $QEMU_IO -c "read -P 0x32 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io
212
213 echo
214 echo "== breaking quorum =="
215
216 $QEMU_IO -c "write -P 0x41 0 $size" "$TEST_DIR/1.raw" | _filter_qemu_io
217 $QEMU_IO -c "write -P 0x42 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io
218
219 echo
220 echo "== checking that quorum is broken =="
221
222 $QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
223
224 echo
225 echo "== checking the blkverify mode with broken content =="
226
227 quorum="driver=raw,file.driver=quorum,file.vote-threshold=2,file.blkverify=on"
228 quorum="$quorum,file.children.0.file.filename=$TEST_DIR/1.raw"
229 quorum="$quorum,file.children.1.file.filename=$TEST_DIR/2.raw"
230 quorum="$quorum,file.children.0.driver=raw"
231 quorum="$quorum,file.children.1.driver=raw"
232
233 $QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
234
235 echo
236 echo "== writing the same data to both files =="
237
238 $QEMU_IO -c "write -P 0x32 0 $size" "$TEST_DIR/1.raw" | _filter_qemu_io
239 $QEMU_IO -c "write -P 0x32 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io
240
241 echo
242 echo "== checking the blkverify mode with valid content =="
243
244 $QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
245
246 echo
247 echo "== checking the blkverify mode with invalid settings =="
248
249 quorum="$quorum,file.children.2.file.filename=$TEST_DIR/3.raw"
250 quorum="$quorum,file.children.2.driver=raw"
251
252 $QEMU_IO -c "open -o $quorum" | _filter_qemu_io
253
254 echo
255 echo "== dynamically adding a child to a quorum =="
256
257 for verify in false true; do
258     run_qemu <<EOF
259     { "execute": "qmp_capabilities" }
260     { "execute": "blockdev-add",
261         "arguments": {
262             "driver": "quorum",
263             "node-name": "drive0-quorum",
264             "vote-threshold": 2,
265             "blkverify": ${verify},
266             "children": [
267                 {
268                     "driver": "$IMGFMT",
269                     "file": {
270                         "driver": "file",
271                         "filename": "$TEST_DIR/1.raw"
272                     }
273                 },
274                 {
275                     "driver": "$IMGFMT",
276                     "file": {
277                         "driver": "file",
278                         "filename": "$TEST_DIR/2.raw"
279                     }
280                 }
281             ]
282         }
283     }
284     { "execute": "blockdev-add",
285         "arguments": {
286             "node-name": "drive3",
287             "driver": "$IMGFMT",
288             "file": {
289                 "driver": "file",
290                 "filename": "$TEST_DIR/2.raw"
291             }
292         }
293     }
294     { "execute": "x-blockdev-change",
295       "arguments": { "parent": "drive0-quorum",
296                      "node": "drive3" } }
297     { "execute": "quit" }
298 EOF
299 done
300
301 echo
302 echo "== dynamically removing a child from a quorum =="
303
304 for verify in false true; do
305     for vote_threshold in 1 2; do
306         run_qemu <<EOF
307         { "execute": "qmp_capabilities" }
308         { "execute": "blockdev-add",
309             "arguments": {
310                 "driver": "quorum",
311                 "node-name": "drive0-quorum",
312                 "vote-threshold": ${vote_threshold},
313                 "blkverify": ${verify},
314                 "children": [
315                     {
316                         "driver": "$IMGFMT",
317                         "file": {
318                             "driver": "file",
319                             "filename": "$TEST_DIR/1.raw"
320                         }
321                     },
322                     {
323                         "driver": "$IMGFMT",
324                         "file": {
325                             "driver": "file",
326                             "filename": "$TEST_DIR/2.raw"
327                         }
328                     }
329                 ]
330             }
331         }
332         { "execute": "x-blockdev-change",
333           "arguments": { "parent": "drive0-quorum",
334                          "child": "children.1" } }
335         { "execute": "quit" }
336 EOF
337     done
338 done
339
340 # success, all done
341 echo "*** done"
342 rm -f $seq.full
343 status=0