111a82d14SPhilippe Mathieu-Daudé#!/usr/bin/env bash 2*9dd003a9SVladimir Sementsov-Ogievskiy# group: rw quick 3c7fc5bc2SBenoît Canet# 4c7fc5bc2SBenoît Canet# Test Quorum block driver 5c7fc5bc2SBenoît Canet# 6c7fc5bc2SBenoît Canet# Copyright (C) 2013 Nodalink, SARL. 7c7fc5bc2SBenoît Canet# 8c7fc5bc2SBenoît Canet# This program is free software; you can redistribute it and/or modify 9c7fc5bc2SBenoît Canet# it under the terms of the GNU General Public License as published by 10c7fc5bc2SBenoît Canet# the Free Software Foundation; either version 2 of the License, or 11c7fc5bc2SBenoît Canet# (at your option) any later version. 12c7fc5bc2SBenoît Canet# 13c7fc5bc2SBenoît Canet# This program is distributed in the hope that it will be useful, 14c7fc5bc2SBenoît Canet# but WITHOUT ANY WARRANTY; without even the implied warranty of 15c7fc5bc2SBenoît Canet# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16c7fc5bc2SBenoît Canet# GNU General Public License for more details. 17c7fc5bc2SBenoît Canet# 18c7fc5bc2SBenoît Canet# You should have received a copy of the GNU General Public License 19c7fc5bc2SBenoît Canet# along with this program. If not, see <http://www.gnu.org/licenses/>. 20c7fc5bc2SBenoît Canet# 21c7fc5bc2SBenoît Canet 22c7fc5bc2SBenoît Canet# creator 23c7fc5bc2SBenoît Canetowner=benoit@irqsave.net 24c7fc5bc2SBenoît Canet 25c7fc5bc2SBenoît Canetseq=`basename $0` 26c7fc5bc2SBenoît Canetecho "QA output created by $seq" 27c7fc5bc2SBenoît Canet 28c7fc5bc2SBenoît Canetstatus=1 # failure is the default! 29c7fc5bc2SBenoît Canet 30c7fc5bc2SBenoît Canet_cleanup() 31c7fc5bc2SBenoît Canet{ 32f91ecbd7SMax Reitz _rm_test_img "$TEST_DIR/1.raw" 33f91ecbd7SMax Reitz _rm_test_img "$TEST_DIR/2.raw" 34f91ecbd7SMax Reitz _rm_test_img "$TEST_DIR/3.raw" 35c7fc5bc2SBenoît Canet} 36c7fc5bc2SBenoît Canettrap "_cleanup; exit \$status" 0 1 2 3 15 37c7fc5bc2SBenoît Canet 38c7fc5bc2SBenoît Canet# get standard environment, filters and checks 39c7fc5bc2SBenoît Canet. ./common.rc 40c7fc5bc2SBenoît Canet. ./common.filter 41c7fc5bc2SBenoît Canet 42c7fc5bc2SBenoît Canet_supported_fmt raw 43c5f7c0afSPeter Lieven_supported_proto file 44c7fc5bc2SBenoît Canet_supported_os Linux 4521b43d00SThomas Huth_require_drivers quorum 46c61c644fSMax Reitz_require_devices virtio-scsi 47c7fc5bc2SBenoît Canet 488cedcffdSEric Blakedo_run_qemu() 496141f3bdSMax Reitz{ 5055f2c014SMax Reitz echo Testing: "$@" 516141f3bdSMax Reitz $QEMU -nographic -qmp stdio -serial none "$@" 526141f3bdSMax Reitz echo 536141f3bdSMax Reitz} 546141f3bdSMax Reitz 558cedcffdSEric Blakerun_qemu() 566141f3bdSMax Reitz{ 5755f2c014SMax Reitz do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_imgfmt | _filter_qemu \ 5855f2c014SMax Reitz | _filter_qmp | _filter_qemu_io \ 5955f2c014SMax Reitz | _filter_generated_node_ids 606141f3bdSMax Reitz} 616141f3bdSMax Reitz 628f9e835fSKevin Wolfquorum="driver=raw,file.driver=quorum,file.vote-threshold=2" 638f9e835fSKevin Wolfquorum="$quorum,file.children.0.file.filename=$TEST_DIR/1.raw" 64c7fc5bc2SBenoît Canetquorum="$quorum,file.children.1.file.filename=$TEST_DIR/2.raw" 658f9e835fSKevin Wolfquorum="$quorum,file.children.2.file.filename=$TEST_DIR/3.raw" 668f9e835fSKevin Wolfquorum="$quorum,file.children.0.driver=raw" 678f9e835fSKevin Wolfquorum="$quorum,file.children.1.driver=raw" 688f9e835fSKevin Wolfquorum="$quorum,file.children.2.driver=raw" 69c7fc5bc2SBenoît Canet 70c7fc5bc2SBenoît Canetecho 71c7fc5bc2SBenoît Canetecho "== creating quorum files ==" 72c7fc5bc2SBenoît Canet 73c7fc5bc2SBenoît Canetsize=10M 74c7fc5bc2SBenoît Canet 75c7fc5bc2SBenoît CanetTEST_IMG="$TEST_DIR/1.raw" _make_test_img $size 76c7fc5bc2SBenoît CanetTEST_IMG="$TEST_DIR/2.raw" _make_test_img $size 77c7fc5bc2SBenoît CanetTEST_IMG="$TEST_DIR/3.raw" _make_test_img $size 78c7fc5bc2SBenoît Canet 79c7fc5bc2SBenoît Canetecho 80c7fc5bc2SBenoît Canetecho "== writing images ==" 81c7fc5bc2SBenoît Canet 82c7fc5bc2SBenoît Canet$QEMU_IO -c "open -o $quorum" -c "write -P 0x32 0 $size" | _filter_qemu_io 83c7fc5bc2SBenoît Canet 84c7fc5bc2SBenoît Canetecho 85c7fc5bc2SBenoît Canetecho "== checking quorum write ==" 86c7fc5bc2SBenoît Canet 87c7fc5bc2SBenoît Canet$QEMU_IO -c "read -P 0x32 0 $size" "$TEST_DIR/1.raw" | _filter_qemu_io 88c7fc5bc2SBenoît Canet$QEMU_IO -c "read -P 0x32 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io 89c7fc5bc2SBenoît Canet$QEMU_IO -c "read -P 0x32 0 $size" "$TEST_DIR/3.raw" | _filter_qemu_io 90c7fc5bc2SBenoît Canet 91c7fc5bc2SBenoît Canetecho 92c7fc5bc2SBenoît Canetecho "== corrupting image ==" 93c7fc5bc2SBenoît Canet 94c7fc5bc2SBenoît Canet$QEMU_IO -c "write -P 0x42 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io 95c7fc5bc2SBenoît Canet 96c7fc5bc2SBenoît Canetecho 97c7fc5bc2SBenoît Canetecho "== checking quorum correction ==" 98c7fc5bc2SBenoît Canet 99c7fc5bc2SBenoît Canet$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io 100c7fc5bc2SBenoît Canet 101c7fc5bc2SBenoît Canetecho 1026141f3bdSMax Reitzecho "== checking mixed reference/option specification ==" 1036141f3bdSMax Reitz 1048e9e6530SMax Reitzrun_qemu <<EOF 1056141f3bdSMax Reitz{ "execute": "qmp_capabilities" } 1066141f3bdSMax Reitz{ "execute": "blockdev-add", 1076141f3bdSMax Reitz "arguments": { 1088e9e6530SMax Reitz "node-name": "drive2", 1098e9e6530SMax Reitz "driver": "$IMGFMT", 1108e9e6530SMax Reitz "file": { 1118e9e6530SMax Reitz "driver": "file", 1128e9e6530SMax Reitz "filename": "$TEST_DIR/2.raw" 1138e9e6530SMax Reitz } 1148e9e6530SMax Reitz } 1158e9e6530SMax Reitz} 1168e9e6530SMax Reitz{ "execute": "blockdev-add", 1178e9e6530SMax Reitz "arguments": { 1186141f3bdSMax Reitz "driver": "quorum", 11926d5fa10SKevin Wolf "node-name": "drive0-quorum", 1206141f3bdSMax Reitz "vote-threshold": 2, 1216141f3bdSMax Reitz "children": [ 1226141f3bdSMax Reitz { 1238e9e6530SMax Reitz "driver": "$IMGFMT", 1246141f3bdSMax Reitz "file": { 1256141f3bdSMax Reitz "driver": "file", 1266141f3bdSMax Reitz "filename": "$TEST_DIR/1.raw" 1276141f3bdSMax Reitz } 1286141f3bdSMax Reitz }, 1296141f3bdSMax Reitz "drive2", 1306141f3bdSMax Reitz { 1318e9e6530SMax Reitz "driver": "$IMGFMT", 1326141f3bdSMax Reitz "file": { 1336141f3bdSMax Reitz "driver": "file", 1346141f3bdSMax Reitz "filename": "$TEST_DIR/3.raw" 1356141f3bdSMax Reitz } 1366141f3bdSMax Reitz } 1376141f3bdSMax Reitz ] 1386141f3bdSMax Reitz } 1396141f3bdSMax Reitz} 1406141f3bdSMax Reitz{ "execute": "human-monitor-command", 1416141f3bdSMax Reitz "arguments": { 1426141f3bdSMax Reitz "command-line": 'qemu-io drive0-quorum "read -P 0x32 0 $size"' 1436141f3bdSMax Reitz } 1446141f3bdSMax Reitz} 1456141f3bdSMax Reitz{ "execute": "quit" } 1466141f3bdSMax ReitzEOF 1476141f3bdSMax Reitz 1486141f3bdSMax Reitzecho 149cf29a570SBenoît Canetecho "== using quorum rewrite corrupted mode ==" 150cf29a570SBenoît Canet 151cf29a570SBenoît Canetquorum="$quorum,file.rewrite-corrupted=on" 152cf29a570SBenoît Canet 153cf29a570SBenoît Canet$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io 154cf29a570SBenoît Canet 155cf29a570SBenoît Canetecho 156cf29a570SBenoît Canetecho "== checking that quorum has corrected the corrupted file ==" 157cf29a570SBenoît Canet 158cf29a570SBenoît Canet$QEMU_IO -c "read -P 0x32 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io 159cf29a570SBenoît Canet 160cf29a570SBenoît Canetecho 161c61c644fSMax Reitzecho "== using quorum rewrite corrupted mode without WRITE permission ==" 162c61c644fSMax Reitz 163c61c644fSMax Reitz# The same as above, but this time, do it on a quorum node whose only 164c61c644fSMax Reitz# parent will not take the WRITE permission 165c61c644fSMax Reitz 166c61c644fSMax Reitzecho '-- corrupting --' 167c61c644fSMax Reitz# Only corrupt a portion: The guest device (scsi-hd on virtio-scsi) 168c61c644fSMax Reitz# will read some data (looking for a partition table to guess the 169c61c644fSMax Reitz# disk's geometry), which would trigger a quorum mismatch if the 170c61c644fSMax Reitz# beginning of the image was corrupted. The subsequent 171c61c644fSMax Reitz# QUORUM_REPORT_BAD event would be suppressed (because at that point, 172c61c644fSMax Reitz# there cannot have been a qmp_capabilities on the monitor). Because 173c61c644fSMax Reitz# that event is rate-limited, the next QUORUM_REPORT_BAD that happens 174c61c644fSMax Reitz# thanks to our qemu-io read (which should trigger a mismatch) would 175c61c644fSMax Reitz# then be delayed past the VM quit and not appear in the output. 176c61c644fSMax Reitz# So we keep the first 1M intact to see a QUORUM_REPORT_BAD resulting 177c61c644fSMax Reitz# from the qemu-io invocation. 178c61c644fSMax Reitz$QEMU_IO -c "write -P 0x42 1M 1M" "$TEST_DIR/2.raw" | _filter_qemu_io 179c61c644fSMax Reitz 180c61c644fSMax Reitz# Fix the corruption (on a read-only quorum node, i.e. without taking 181c61c644fSMax Reitz# the WRITE permission on it -- its child nodes need to be R/W OTOH, 182c61c644fSMax Reitz# so that rewrite-corrupted works) 183c61c644fSMax Reitzecho 184c61c644fSMax Reitzecho '-- running quorum --' 185c61c644fSMax Reitzrun_qemu \ 186c61c644fSMax Reitz -blockdev file,node-name=file1,filename="$TEST_DIR/1.raw" \ 187c61c644fSMax Reitz -blockdev file,node-name=file2,filename="$TEST_DIR/2.raw" \ 188c61c644fSMax Reitz -blockdev file,node-name=file3,filename="$TEST_DIR/3.raw" \ 189c61c644fSMax Reitz -blockdev '{ 190c61c644fSMax Reitz "driver": "quorum", 191c61c644fSMax Reitz "node-name": "quorum", 192c61c644fSMax Reitz "read-only": true, 193c61c644fSMax Reitz "vote-threshold": 2, 194c61c644fSMax Reitz "rewrite-corrupted": true, 195c61c644fSMax Reitz "children": [ "file1", "file2", "file3" ] 196c61c644fSMax Reitz }' \ 197c61c644fSMax Reitz -device virtio-scsi,id=scsi \ 198c61c644fSMax Reitz -device scsi-hd,id=quorum-drive,bus=scsi.0,drive=quorum \ 199c61c644fSMax Reitz <<EOF 200c61c644fSMax Reitz{ "execute": "qmp_capabilities" } 201c61c644fSMax Reitz{ 202c61c644fSMax Reitz "execute": "human-monitor-command", 203c61c644fSMax Reitz "arguments": { 204c61c644fSMax Reitz "command-line": 'qemu-io -d quorum-drive "read -P 0x32 0 $size"' 205c61c644fSMax Reitz } 206c61c644fSMax Reitz} 207c61c644fSMax Reitz{ "execute": "quit" } 208c61c644fSMax ReitzEOF 209c61c644fSMax Reitz 210c61c644fSMax Reitzecho '-- checking that the image has been corrected --' 211c61c644fSMax Reitz$QEMU_IO -c "read -P 0x32 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io 212c61c644fSMax Reitz 213c61c644fSMax Reitzecho 214c7fc5bc2SBenoît Canetecho "== breaking quorum ==" 215c7fc5bc2SBenoît Canet 216c7fc5bc2SBenoît Canet$QEMU_IO -c "write -P 0x41 0 $size" "$TEST_DIR/1.raw" | _filter_qemu_io 217cf29a570SBenoît Canet$QEMU_IO -c "write -P 0x42 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io 218cf29a570SBenoît Canet 219c7fc5bc2SBenoît Canetecho 220c7fc5bc2SBenoît Canetecho "== checking that quorum is broken ==" 221c7fc5bc2SBenoît Canet 222c7fc5bc2SBenoît Canet$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io 223c7fc5bc2SBenoît Canet 22482c4c859SAlberto Garciaecho 22582c4c859SAlberto Garciaecho "== checking the blkverify mode with broken content ==" 22682c4c859SAlberto Garcia 22782c4c859SAlberto Garciaquorum="driver=raw,file.driver=quorum,file.vote-threshold=2,file.blkverify=on" 22882c4c859SAlberto Garciaquorum="$quorum,file.children.0.file.filename=$TEST_DIR/1.raw" 22982c4c859SAlberto Garciaquorum="$quorum,file.children.1.file.filename=$TEST_DIR/2.raw" 23082c4c859SAlberto Garciaquorum="$quorum,file.children.0.driver=raw" 23182c4c859SAlberto Garciaquorum="$quorum,file.children.1.driver=raw" 23282c4c859SAlberto Garcia 23382c4c859SAlberto Garcia$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io 23482c4c859SAlberto Garcia 23582c4c859SAlberto Garciaecho 23682c4c859SAlberto Garciaecho "== writing the same data to both files ==" 23782c4c859SAlberto Garcia 23882c4c859SAlberto Garcia$QEMU_IO -c "write -P 0x32 0 $size" "$TEST_DIR/1.raw" | _filter_qemu_io 23982c4c859SAlberto Garcia$QEMU_IO -c "write -P 0x32 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io 24082c4c859SAlberto Garcia 24182c4c859SAlberto Garciaecho 24282c4c859SAlberto Garciaecho "== checking the blkverify mode with valid content ==" 24382c4c859SAlberto Garcia 24482c4c859SAlberto Garcia$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io 24582c4c859SAlberto Garcia 24682c4c859SAlberto Garciaecho 24782c4c859SAlberto Garciaecho "== checking the blkverify mode with invalid settings ==" 24882c4c859SAlberto Garcia 24982c4c859SAlberto Garciaquorum="$quorum,file.children.2.file.filename=$TEST_DIR/3.raw" 25082c4c859SAlberto Garciaquorum="$quorum,file.children.2.driver=raw" 25182c4c859SAlberto Garcia 25282c4c859SAlberto Garcia$QEMU_IO -c "open -o $quorum" | _filter_qemu_io 25382c4c859SAlberto Garcia 25404f600efSAlberto Garciaecho 25504f600efSAlberto Garciaecho "== dynamically adding a child to a quorum ==" 25604f600efSAlberto Garcia 25704f600efSAlberto Garciafor verify in false true; do 25804f600efSAlberto Garcia run_qemu <<EOF 25904f600efSAlberto Garcia { "execute": "qmp_capabilities" } 26004f600efSAlberto Garcia { "execute": "blockdev-add", 26104f600efSAlberto Garcia "arguments": { 26204f600efSAlberto Garcia "driver": "quorum", 26304f600efSAlberto Garcia "node-name": "drive0-quorum", 26404f600efSAlberto Garcia "vote-threshold": 2, 26504f600efSAlberto Garcia "blkverify": ${verify}, 26604f600efSAlberto Garcia "children": [ 26704f600efSAlberto Garcia { 26804f600efSAlberto Garcia "driver": "$IMGFMT", 26904f600efSAlberto Garcia "file": { 27004f600efSAlberto Garcia "driver": "file", 27104f600efSAlberto Garcia "filename": "$TEST_DIR/1.raw" 27204f600efSAlberto Garcia } 27304f600efSAlberto Garcia }, 27404f600efSAlberto Garcia { 27504f600efSAlberto Garcia "driver": "$IMGFMT", 27604f600efSAlberto Garcia "file": { 27704f600efSAlberto Garcia "driver": "file", 27804f600efSAlberto Garcia "filename": "$TEST_DIR/2.raw" 27904f600efSAlberto Garcia } 28004f600efSAlberto Garcia } 28104f600efSAlberto Garcia ] 28204f600efSAlberto Garcia } 28304f600efSAlberto Garcia } 28404f600efSAlberto Garcia { "execute": "blockdev-add", 28504f600efSAlberto Garcia "arguments": { 28604f600efSAlberto Garcia "node-name": "drive3", 28704f600efSAlberto Garcia "driver": "$IMGFMT", 28804f600efSAlberto Garcia "file": { 28904f600efSAlberto Garcia "driver": "file", 29004f600efSAlberto Garcia "filename": "$TEST_DIR/2.raw" 29104f600efSAlberto Garcia } 29204f600efSAlberto Garcia } 29304f600efSAlberto Garcia } 29404f600efSAlberto Garcia { "execute": "x-blockdev-change", 29504f600efSAlberto Garcia "arguments": { "parent": "drive0-quorum", 29604f600efSAlberto Garcia "node": "drive3" } } 29704f600efSAlberto Garcia { "execute": "quit" } 29804f600efSAlberto GarciaEOF 29904f600efSAlberto Garciadone 30004f600efSAlberto Garcia 30104f600efSAlberto Garciaecho 30204f600efSAlberto Garciaecho "== dynamically removing a child from a quorum ==" 30304f600efSAlberto Garcia 30404f600efSAlberto Garciafor verify in false true; do 30504f600efSAlberto Garcia for vote_threshold in 1 2; do 30604f600efSAlberto Garcia run_qemu <<EOF 30704f600efSAlberto Garcia { "execute": "qmp_capabilities" } 30804f600efSAlberto Garcia { "execute": "blockdev-add", 30904f600efSAlberto Garcia "arguments": { 31004f600efSAlberto Garcia "driver": "quorum", 31104f600efSAlberto Garcia "node-name": "drive0-quorum", 31204f600efSAlberto Garcia "vote-threshold": ${vote_threshold}, 31304f600efSAlberto Garcia "blkverify": ${verify}, 31404f600efSAlberto Garcia "children": [ 31504f600efSAlberto Garcia { 31604f600efSAlberto Garcia "driver": "$IMGFMT", 31704f600efSAlberto Garcia "file": { 31804f600efSAlberto Garcia "driver": "file", 31904f600efSAlberto Garcia "filename": "$TEST_DIR/1.raw" 32004f600efSAlberto Garcia } 32104f600efSAlberto Garcia }, 32204f600efSAlberto Garcia { 32304f600efSAlberto Garcia "driver": "$IMGFMT", 32404f600efSAlberto Garcia "file": { 32504f600efSAlberto Garcia "driver": "file", 32604f600efSAlberto Garcia "filename": "$TEST_DIR/2.raw" 32704f600efSAlberto Garcia } 32804f600efSAlberto Garcia } 32904f600efSAlberto Garcia ] 33004f600efSAlberto Garcia } 33104f600efSAlberto Garcia } 33204f600efSAlberto Garcia { "execute": "x-blockdev-change", 33304f600efSAlberto Garcia "arguments": { "parent": "drive0-quorum", 33404f600efSAlberto Garcia "child": "children.1" } } 33504f600efSAlberto Garcia { "execute": "quit" } 33604f600efSAlberto GarciaEOF 33704f600efSAlberto Garcia done 33804f600efSAlberto Garciadone 33904f600efSAlberto Garcia 340c7fc5bc2SBenoît Canet# success, all done 341c7fc5bc2SBenoît Canetecho "*** done" 342c7fc5bc2SBenoît Canetrm -f $seq.full 343c7fc5bc2SBenoît Canetstatus=0 344