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/>.
23 owner
=benoit@irqsave.net
26 echo "QA output created by $seq"
28 status
=1 # failure is the default!
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
45 _require_drivers quorum
46 _require_devices virtio-scsi
51 $QEMU -nographic -qmp stdio
-serial none
"$@"
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"
71 echo "== creating quorum files =="
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
80 echo "== writing images =="
82 $QEMU_IO -c "open -o $quorum" -c "write -P 0x32 0 $size" | _filter_qemu_io
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
92 echo "== corrupting image =="
94 $QEMU_IO -c "write -P 0x42 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io
97 echo "== checking quorum correction =="
99 $QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
102 echo "== checking mixed reference/option specification =="
105 { "execute": "qmp_capabilities" }
106 { "execute": "blockdev-add",
108 "node-name": "drive2",
112 "filename": "$TEST_DIR/2.raw"
116 { "execute": "blockdev-add",
119 "node-name": "drive0-quorum",
126 "filename": "$TEST_DIR/1.raw"
134 "filename": "$TEST_DIR/3.raw"
140 { "execute": "human-monitor-command",
142 "command-line": 'qemu-io drive0-quorum "read -P 0x32 0 $size"'
145 { "execute": "quit" }
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
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
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)
184 echo '-- running quorum --'
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" \
191 "node-name": "quorum",
194 "rewrite-corrupted": true,
195 "children": [ "file1", "file2", "file3" ]
197 -device virtio-scsi
,id
=scsi \
198 -device scsi-hd
,id
=quorum-drive
,bus
=scsi
.0,drive
=quorum \
200 { "execute": "qmp_capabilities" }
202 "execute": "human-monitor-command",
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
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
220 echo "== checking that quorum is broken =="
222 $QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
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
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
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
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
255 echo "== dynamically adding a child to a quorum =="
257 for verify
in false true
; do
259 { "execute": "qmp_capabilities" }
260 { "execute": "blockdev-add",
263 "node-name": "drive0-quorum",
265 "blkverify": ${verify},
271 "filename": "$TEST_DIR/1.raw"
278 "filename": "$TEST_DIR/2.raw"
284 { "execute": "blockdev-add",
286 "node-name": "drive3",
290 "filename": "$TEST_DIR/2.raw"
294 { "execute": "x-blockdev-change",
295 "arguments": { "parent": "drive0-quorum",
297 { "execute": "quit" }
302 echo "== dynamically removing a child from a quorum =="
304 for verify
in false true
; do
305 for vote_threshold
in 1 2; do
307 { "execute": "qmp_capabilities" }
308 { "execute": "blockdev-add",
311 "node-name": "drive0-quorum",
312 "vote-threshold": ${vote_threshold},
313 "blkverify": ${verify},
319 "filename": "$TEST_DIR/1.raw"
326 "filename": "$TEST_DIR/2.raw"
332 { "execute": "x-blockdev-change",
333 "arguments": { "parent": "drive0-quorum",
334 "child": "children.1" } }
335 { "execute": "quit" }