qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

081 (10027B)


      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