1#!/usr/bin/env bash 2# group: rw 3# 4# Test NBD client unexpected disconnect 5# 6# Copyright Red Hat, Inc. 2014 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 23owner=stefanha@redhat.com 24 25seq=`basename $0` 26echo "QA output created by $seq" 27 28status=1 # failure is the default! 29 30_cleanup() 31{ 32 rm -f "$SOCK_DIR/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 raw 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="$SOCK_DIR/nbd.sock" 85 fi 86 87 rm -f "$SOCK_DIR/nbd.sock" 88 89 echo > "$TEST_DIR/nbd-fault-injector.out" 90 $PYTHON nbd-fault-injector.py $extra_args "$nbd_addr" "$TEST_DIR/nbd-fault-injector.conf" >"$TEST_DIR/nbd-fault-injector.out" 2>&1 & 91 92 # Wait for server to be ready 93 while ! grep -q 'Listening on ' "$TEST_DIR/nbd-fault-injector.out"; do 94 sleep 0.1 95 done 96 97 # Extract the final address (port number has now been assigned in tcp case) 98 nbd_addr=$(sed -n 's/^Listening on //p' \ 99 "$TEST_DIR/nbd-fault-injector.out") 100 101 if [ "$proto" = "tcp" ]; then 102 nbd_url="nbd+tcp://$nbd_addr/$export_name" 103 else 104 nbd_url="nbd+unix:///$export_name?socket=$nbd_addr" 105 fi 106 107 $QEMU_IO -c "read 0 512" "$nbd_url" 2>&1 | _filter_qemu_io | _filter_nbd 108 109 echo 110} 111 112for proto in tcp unix; do 113 for event in neg1 "export" neg2 request reply data; do 114 for when in before after; do 115 check_disconnect "--$proto" "$event" "$when" 116 done 117 118 # Also inject short replies from the NBD server 119 case "$event" in 120 neg1) 121 for when in 8 16; do 122 check_disconnect "--$proto" "$event" "$when" 123 done 124 ;; 125 "export") 126 for when in 4 12 16; do 127 check_disconnect "--$proto" "$event" "$when" 128 done 129 ;; 130 neg2) 131 for when in 8 10; do 132 check_disconnect "--$proto" "$event" "$when" 133 done 134 ;; 135 reply) 136 for when in 4 8; do 137 check_disconnect "--$proto" "$event" "$when" 138 done 139 ;; 140 esac 141 done 142 143 # Also check classic negotiation without export information 144 for when in before 8 16 24 28 after; do 145 check_disconnect "--$proto" --classic-negotiation "neg-classic" "$when" 146 done 147done 148 149# success, all done 150echo "*** done" 151rm -f $seq.full 152status=0 153