1#!/bin/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 27here=`pwd` 28status=1 # failure is the default! 29 30_cleanup() 31{ 32 rm -f nbd.sock 33 rm -f nbd-fault-injector.out 34 rm -f nbd-fault-injector.conf 35} 36trap "_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 generic 43_supported_proto nbd 44_supported_os Linux 45 46check_disconnect() { 47 local event export_name=foo extra_args nbd_addr nbd_url proto when 48 49 while true; do 50 case $1 in 51 --classic-negotiation) 52 shift 53 extra_args=--classic-negotiation 54 export_name= 55 ;; 56 --tcp) 57 shift 58 proto=tcp 59 ;; 60 --unix) 61 shift 62 proto=unix 63 ;; 64 *) 65 break 66 ;; 67 esac 68 done 69 70 event=$1 71 when=$2 72 echo "=== Check disconnect $when $event ===" 73 echo 74 75 cat > "$TEST_DIR/nbd-fault-injector.conf" <<EOF 76[inject-error] 77event=$event 78when=$when 79EOF 80 81 if [ "$proto" = "tcp" ]; then 82 nbd_addr="127.0.0.1:0" 83 else 84 nbd_addr="$TEST_DIR/nbd.sock" 85 fi 86 87 rm -f "$TEST_DIR/nbd.sock" 88 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 's/Listening on \(.*\)$/\1/' "$TEST_DIR/nbd-fault-injector.out") 98 99 if [ "$proto" = "tcp" ]; then 100 nbd_url="nbd+tcp://$nbd_addr/$export_name" 101 else 102 nbd_url="nbd+unix:///$export_name?socket=$nbd_addr" 103 fi 104 105 $QEMU_IO -c "read 0 512" "$nbd_url" 2>&1 | _filter_qemu_io | _filter_nbd 106 107 echo 108} 109 110for proto in tcp unix; do 111 for event in neg1 "export" neg2 request reply data; do 112 for when in before after; do 113 check_disconnect "--$proto" "$event" "$when" 114 done 115 116 # Also inject short replies from the NBD server 117 case "$event" in 118 neg1) 119 for when in 8 16; do 120 check_disconnect "--$proto" "$event" "$when" 121 done 122 ;; 123 "export") 124 for when in 4 12 16; do 125 check_disconnect "--$proto" "$event" "$when" 126 done 127 ;; 128 neg2) 129 for when in 8 10; do 130 check_disconnect "--$proto" "$event" "$when" 131 done 132 ;; 133 reply) 134 for when in 4 8; do 135 check_disconnect "--$proto" "$event" "$when" 136 done 137 ;; 138 esac 139 done 140 141 # Also check classic negotiation without export information 142 for when in before 8 16 24 28 after; do 143 check_disconnect "--$proto" --classic-negotiation "neg-classic" "$when" 144 done 145done 146 147# success, all done 148echo "*** done" 149rm -f $seq.full 150status=0 151