1#!/usr/bin/env bash 2# 3# Test NBD client unexpected disconnect 4# 5# Copyright Red Hat, Inc. 2014 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=stefanha@redhat.com 23 24seq=`basename $0` 25echo "QA output created by $seq" 26 27status=1 # failure is the default! 28 29_cleanup() 30{ 31 rm -f nbd.sock 32 rm -f nbd-fault-injector.out 33 rm -f nbd-fault-injector.conf 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 nbd 43_supported_os Linux 44 45check_disconnect() { 46 local event export_name=foo extra_args nbd_addr nbd_url proto when 47 48 while true; do 49 case $1 in 50 --classic-negotiation) 51 shift 52 extra_args=--classic-negotiation 53 export_name= 54 ;; 55 --tcp) 56 shift 57 proto=tcp 58 ;; 59 --unix) 60 shift 61 proto=unix 62 ;; 63 *) 64 break 65 ;; 66 esac 67 done 68 69 event=$1 70 when=$2 71 echo "=== Check disconnect $when $event ===" 72 echo 73 74 cat > "$TEST_DIR/nbd-fault-injector.conf" <<EOF 75[inject-error] 76event=$event 77when=$when 78EOF 79 80 if [ "$proto" = "tcp" ]; then 81 nbd_addr="127.0.0.1:0" 82 else 83 nbd_addr="$TEST_DIR/nbd.sock" 84 fi 85 86 rm -f "$TEST_DIR/nbd.sock" 87 88 echo > "$TEST_DIR/nbd-fault-injector.out" 89 $PYTHON nbd-fault-injector.py $extra_args "$nbd_addr" "$TEST_DIR/nbd-fault-injector.conf" >"$TEST_DIR/nbd-fault-injector.out" 2>&1 & 90 91 # Wait for server to be ready 92 while ! grep -q 'Listening on ' "$TEST_DIR/nbd-fault-injector.out"; do 93 sleep 0.1 94 done 95 96 # Extract the final address (port number has now been assigned in tcp case) 97 nbd_addr=$(sed -n 's/^Listening on //p' \ 98 "$TEST_DIR/nbd-fault-injector.out") 99 100 if [ "$proto" = "tcp" ]; then 101 nbd_url="nbd+tcp://$nbd_addr/$export_name" 102 else 103 nbd_url="nbd+unix:///$export_name?socket=$nbd_addr" 104 fi 105 106 $QEMU_IO -c "read 0 512" "$nbd_url" 2>&1 | _filter_qemu_io | _filter_nbd 107 108 echo 109} 110 111for proto in tcp unix; do 112 for event in neg1 "export" neg2 request reply data; do 113 for when in before after; do 114 check_disconnect "--$proto" "$event" "$when" 115 done 116 117 # Also inject short replies from the NBD server 118 case "$event" in 119 neg1) 120 for when in 8 16; do 121 check_disconnect "--$proto" "$event" "$when" 122 done 123 ;; 124 "export") 125 for when in 4 12 16; do 126 check_disconnect "--$proto" "$event" "$when" 127 done 128 ;; 129 neg2) 130 for when in 8 10; do 131 check_disconnect "--$proto" "$event" "$when" 132 done 133 ;; 134 reply) 135 for when in 4 8; do 136 check_disconnect "--$proto" "$event" "$when" 137 done 138 ;; 139 esac 140 done 141 142 # Also check classic negotiation without export information 143 for when in before 8 16 24 28 after; do 144 check_disconnect "--$proto" --classic-negotiation "neg-classic" "$when" 145 done 146done 147 148# success, all done 149echo "*** done" 150rm -f $seq.full 151status=0 152