Merge remote-tracking branch 'remotes/nvme/tags/nvme-fixes-20210407-pull-request...
[qemu/ar7.git] / tests / qemu-iotests / 081
blob1ac66f197e46814285295818267df08546e75e2d
1 #!/usr/bin/env bash
2 # group: rw quick
4 # Test Quorum block driver
6 # Copyright (C) 2013 Nodalink, SARL.
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.
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.
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/>.
22 # creator
23 owner=benoit@irqsave.net
25 seq=`basename $0`
26 echo "QA output created by $seq"
28 status=1 # failure is the default!
30 _cleanup()
32 _rm_test_img "$TEST_DIR/1.raw"
33 _rm_test_img "$TEST_DIR/2.raw"
34 _rm_test_img "$TEST_DIR/3.raw"
36 trap "_cleanup; exit \$status" 0 1 2 3 15
38 # get standard environment, filters and checks
39 . ./common.rc
40 . ./common.filter
42 _supported_fmt raw
43 _supported_proto file
44 _supported_os Linux
45 _require_drivers quorum
46 _require_devices virtio-scsi
48 do_run_qemu()
50 echo Testing: "$@"
51 $QEMU -nographic -qmp stdio -serial none "$@"
52 echo
55 run_qemu()
57 do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_imgfmt | _filter_qemu \
58 | _filter_qmp | _filter_qemu_io \
59 | _filter_generated_node_ids
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"
70 echo
71 echo "== creating quorum files =="
73 size=10M
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
79 echo
80 echo "== writing images =="
82 $QEMU_IO -c "open -o $quorum" -c "write -P 0x32 0 $size" | _filter_qemu_io
84 echo
85 echo "== checking quorum write =="
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
91 echo
92 echo "== corrupting image =="
94 $QEMU_IO -c "write -P 0x42 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io
96 echo
97 echo "== checking quorum correction =="
99 $QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
101 echo
102 echo "== checking mixed reference/option specification =="
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"
116 { "execute": "blockdev-add",
117 "arguments": {
118 "driver": "quorum",
119 "node-name": "drive0-quorum",
120 "vote-threshold": 2,
121 "children": [
123 "driver": "$IMGFMT",
124 "file": {
125 "driver": "file",
126 "filename": "$TEST_DIR/1.raw"
129 "drive2",
131 "driver": "$IMGFMT",
132 "file": {
133 "driver": "file",
134 "filename": "$TEST_DIR/3.raw"
140 { "execute": "human-monitor-command",
141 "arguments": {
142 "command-line": 'qemu-io drive0-quorum "read -P 0x32 0 $size"'
145 { "execute": "quit" }
148 echo
149 echo "== using quorum rewrite corrupted mode =="
151 quorum="$quorum,file.rewrite-corrupted=on"
153 $QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
155 echo
156 echo "== checking that quorum has corrected the corrupted file =="
158 $QEMU_IO -c "read -P 0x32 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io
160 echo
161 echo "== using quorum rewrite corrupted mode without WRITE permission =="
163 # The same as above, but this time, do it on a quorum node whose only
164 # parent will not take the WRITE permission
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
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" }
202 "execute": "human-monitor-command",
203 "arguments": {
204 "command-line": 'qemu-io -d quorum-drive "read -P 0x32 0 $size"'
207 { "execute": "quit" }
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
213 echo
214 echo "== breaking quorum =="
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
219 echo
220 echo "== checking that quorum is broken =="
222 $QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
224 echo
225 echo "== checking the blkverify mode with broken content =="
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"
233 $QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
235 echo
236 echo "== writing the same data to both files =="
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
241 echo
242 echo "== checking the blkverify mode with valid content =="
244 $QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
246 echo
247 echo "== checking the blkverify mode with invalid settings =="
249 quorum="$quorum,file.children.2.file.filename=$TEST_DIR/3.raw"
250 quorum="$quorum,file.children.2.driver=raw"
252 $QEMU_IO -c "open -o $quorum" | _filter_qemu_io
254 echo
255 echo "== dynamically adding a child to a quorum =="
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": [
268 "driver": "$IMGFMT",
269 "file": {
270 "driver": "file",
271 "filename": "$TEST_DIR/1.raw"
275 "driver": "$IMGFMT",
276 "file": {
277 "driver": "file",
278 "filename": "$TEST_DIR/2.raw"
284 { "execute": "blockdev-add",
285 "arguments": {
286 "node-name": "drive3",
287 "driver": "$IMGFMT",
288 "file": {
289 "driver": "file",
290 "filename": "$TEST_DIR/2.raw"
294 { "execute": "x-blockdev-change",
295 "arguments": { "parent": "drive0-quorum",
296 "node": "drive3" } }
297 { "execute": "quit" }
299 done
301 echo
302 echo "== dynamically removing a child from a quorum =="
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": [
316 "driver": "$IMGFMT",
317 "file": {
318 "driver": "file",
319 "filename": "$TEST_DIR/1.raw"
323 "driver": "$IMGFMT",
324 "file": {
325 "driver": "file",
326 "filename": "$TEST_DIR/2.raw"
332 { "execute": "x-blockdev-change",
333 "arguments": { "parent": "drive0-quorum",
334 "child": "children.1" } }
335 { "execute": "quit" }
337 done
338 done
340 # success, all done
341 echo "*** done"
342 rm -f $seq.full
343 status=0