1#!/usr/bin/env bash 2# 3# Test Quorum block driver 4# 5# Copyright (C) 2013 Nodalink, SARL. 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=benoit@irqsave.net 23 24seq=`basename $0` 25echo "QA output created by $seq" 26 27status=1 # failure is the default! 28 29_cleanup() 30{ 31 _rm_test_img "$TEST_DIR/1.raw" 32 _rm_test_img "$TEST_DIR/2.raw" 33 _rm_test_img "$TEST_DIR/3.raw" 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 41_supported_fmt raw 42_supported_proto file 43_supported_os Linux 44_require_drivers quorum 45 46do_run_qemu() 47{ 48 echo Testing: "$@" 49 $QEMU -nographic -qmp stdio -serial none "$@" 50 echo 51} 52 53run_qemu() 54{ 55 do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_imgfmt | _filter_qemu \ 56 | _filter_qmp | _filter_qemu_io \ 57 | _filter_generated_node_ids 58} 59 60quorum="driver=raw,file.driver=quorum,file.vote-threshold=2" 61quorum="$quorum,file.children.0.file.filename=$TEST_DIR/1.raw" 62quorum="$quorum,file.children.1.file.filename=$TEST_DIR/2.raw" 63quorum="$quorum,file.children.2.file.filename=$TEST_DIR/3.raw" 64quorum="$quorum,file.children.0.driver=raw" 65quorum="$quorum,file.children.1.driver=raw" 66quorum="$quorum,file.children.2.driver=raw" 67 68echo 69echo "== creating quorum files ==" 70 71size=10M 72 73TEST_IMG="$TEST_DIR/1.raw" _make_test_img $size 74TEST_IMG="$TEST_DIR/2.raw" _make_test_img $size 75TEST_IMG="$TEST_DIR/3.raw" _make_test_img $size 76 77echo 78echo "== writing images ==" 79 80$QEMU_IO -c "open -o $quorum" -c "write -P 0x32 0 $size" | _filter_qemu_io 81 82echo 83echo "== checking quorum write ==" 84 85$QEMU_IO -c "read -P 0x32 0 $size" "$TEST_DIR/1.raw" | _filter_qemu_io 86$QEMU_IO -c "read -P 0x32 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io 87$QEMU_IO -c "read -P 0x32 0 $size" "$TEST_DIR/3.raw" | _filter_qemu_io 88 89echo 90echo "== corrupting image ==" 91 92$QEMU_IO -c "write -P 0x42 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io 93 94echo 95echo "== checking quorum correction ==" 96 97$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io 98 99echo 100echo "== checking mixed reference/option specification ==" 101 102run_qemu <<EOF 103{ "execute": "qmp_capabilities" } 104{ "execute": "blockdev-add", 105 "arguments": { 106 "node-name": "drive2", 107 "driver": "$IMGFMT", 108 "file": { 109 "driver": "file", 110 "filename": "$TEST_DIR/2.raw" 111 } 112 } 113} 114{ "execute": "blockdev-add", 115 "arguments": { 116 "driver": "quorum", 117 "node-name": "drive0-quorum", 118 "vote-threshold": 2, 119 "children": [ 120 { 121 "driver": "$IMGFMT", 122 "file": { 123 "driver": "file", 124 "filename": "$TEST_DIR/1.raw" 125 } 126 }, 127 "drive2", 128 { 129 "driver": "$IMGFMT", 130 "file": { 131 "driver": "file", 132 "filename": "$TEST_DIR/3.raw" 133 } 134 } 135 ] 136 } 137} 138{ "execute": "human-monitor-command", 139 "arguments": { 140 "command-line": 'qemu-io drive0-quorum "read -P 0x32 0 $size"' 141 } 142} 143{ "execute": "quit" } 144EOF 145 146echo 147echo "== using quorum rewrite corrupted mode ==" 148 149quorum="$quorum,file.rewrite-corrupted=on" 150 151$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io 152 153echo 154echo "== checking that quorum has corrected the corrupted file ==" 155 156$QEMU_IO -c "read -P 0x32 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io 157 158echo 159echo "== breaking quorum ==" 160 161$QEMU_IO -c "write -P 0x41 0 $size" "$TEST_DIR/1.raw" | _filter_qemu_io 162$QEMU_IO -c "write -P 0x42 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io 163 164echo 165echo "== checking that quorum is broken ==" 166 167$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io 168 169echo 170echo "== checking the blkverify mode with broken content ==" 171 172quorum="driver=raw,file.driver=quorum,file.vote-threshold=2,file.blkverify=on" 173quorum="$quorum,file.children.0.file.filename=$TEST_DIR/1.raw" 174quorum="$quorum,file.children.1.file.filename=$TEST_DIR/2.raw" 175quorum="$quorum,file.children.0.driver=raw" 176quorum="$quorum,file.children.1.driver=raw" 177 178$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io 179 180echo 181echo "== writing the same data to both files ==" 182 183$QEMU_IO -c "write -P 0x32 0 $size" "$TEST_DIR/1.raw" | _filter_qemu_io 184$QEMU_IO -c "write -P 0x32 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io 185 186echo 187echo "== checking the blkverify mode with valid content ==" 188 189$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io 190 191echo 192echo "== checking the blkverify mode with invalid settings ==" 193 194quorum="$quorum,file.children.2.file.filename=$TEST_DIR/3.raw" 195quorum="$quorum,file.children.2.driver=raw" 196 197$QEMU_IO -c "open -o $quorum" | _filter_qemu_io 198 199echo 200echo "== dynamically adding a child to a quorum ==" 201 202for verify in false true; do 203 run_qemu <<EOF 204 { "execute": "qmp_capabilities" } 205 { "execute": "blockdev-add", 206 "arguments": { 207 "driver": "quorum", 208 "node-name": "drive0-quorum", 209 "vote-threshold": 2, 210 "blkverify": ${verify}, 211 "children": [ 212 { 213 "driver": "$IMGFMT", 214 "file": { 215 "driver": "file", 216 "filename": "$TEST_DIR/1.raw" 217 } 218 }, 219 { 220 "driver": "$IMGFMT", 221 "file": { 222 "driver": "file", 223 "filename": "$TEST_DIR/2.raw" 224 } 225 } 226 ] 227 } 228 } 229 { "execute": "blockdev-add", 230 "arguments": { 231 "node-name": "drive3", 232 "driver": "$IMGFMT", 233 "file": { 234 "driver": "file", 235 "filename": "$TEST_DIR/2.raw" 236 } 237 } 238 } 239 { "execute": "x-blockdev-change", 240 "arguments": { "parent": "drive0-quorum", 241 "node": "drive3" } } 242 { "execute": "quit" } 243EOF 244done 245 246echo 247echo "== dynamically removing a child from a quorum ==" 248 249for verify in false true; do 250 for vote_threshold in 1 2; do 251 run_qemu <<EOF 252 { "execute": "qmp_capabilities" } 253 { "execute": "blockdev-add", 254 "arguments": { 255 "driver": "quorum", 256 "node-name": "drive0-quorum", 257 "vote-threshold": ${vote_threshold}, 258 "blkverify": ${verify}, 259 "children": [ 260 { 261 "driver": "$IMGFMT", 262 "file": { 263 "driver": "file", 264 "filename": "$TEST_DIR/1.raw" 265 } 266 }, 267 { 268 "driver": "$IMGFMT", 269 "file": { 270 "driver": "file", 271 "filename": "$TEST_DIR/2.raw" 272 } 273 } 274 ] 275 } 276 } 277 { "execute": "x-blockdev-change", 278 "arguments": { "parent": "drive0-quorum", 279 "child": "children.1" } } 280 { "execute": "quit" } 281EOF 282 done 283done 284 285# success, all done 286echo "*** done" 287rm -f $seq.full 288status=0 289