1*dc668dedSStefan Hajnoczi#!/bin/bash 2*dc668dedSStefan Hajnoczi# 3*dc668dedSStefan Hajnoczi# Test NBD client unexpected disconnect 4*dc668dedSStefan Hajnoczi# 5*dc668dedSStefan Hajnoczi# Copyright Red Hat, Inc. 2014 6*dc668dedSStefan Hajnoczi# 7*dc668dedSStefan Hajnoczi# This program is free software; you can redistribute it and/or modify 8*dc668dedSStefan Hajnoczi# it under the terms of the GNU General Public License as published by 9*dc668dedSStefan Hajnoczi# the Free Software Foundation; either version 2 of the License, or 10*dc668dedSStefan Hajnoczi# (at your option) any later version. 11*dc668dedSStefan Hajnoczi# 12*dc668dedSStefan Hajnoczi# This program is distributed in the hope that it will be useful, 13*dc668dedSStefan Hajnoczi# but WITHOUT ANY WARRANTY; without even the implied warranty of 14*dc668dedSStefan Hajnoczi# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*dc668dedSStefan Hajnoczi# GNU General Public License for more details. 16*dc668dedSStefan Hajnoczi# 17*dc668dedSStefan Hajnoczi# You should have received a copy of the GNU General Public License 18*dc668dedSStefan Hajnoczi# along with this program. If not, see <http://www.gnu.org/licenses/>. 19*dc668dedSStefan Hajnoczi# 20*dc668dedSStefan Hajnoczi 21*dc668dedSStefan Hajnoczi# creator 22*dc668dedSStefan Hajnocziowner=stefanha@redhat.com 23*dc668dedSStefan Hajnoczi 24*dc668dedSStefan Hajnocziseq=`basename $0` 25*dc668dedSStefan Hajnocziecho "QA output created by $seq" 26*dc668dedSStefan Hajnoczi 27*dc668dedSStefan Hajnoczihere=`pwd` 28*dc668dedSStefan Hajnoczitmp=/tmp/$$ 29*dc668dedSStefan Hajnoczistatus=1 # failure is the default! 30*dc668dedSStefan Hajnoczi 31*dc668dedSStefan Hajnoczi# get standard environment, filters and checks 32*dc668dedSStefan Hajnoczi. ./common.rc 33*dc668dedSStefan Hajnoczi. ./common.filter 34*dc668dedSStefan Hajnoczi 35*dc668dedSStefan Hajnoczi_supported_fmt generic 36*dc668dedSStefan Hajnoczi_supported_proto nbd 37*dc668dedSStefan Hajnoczi_supported_os Linux 38*dc668dedSStefan Hajnoczi 39*dc668dedSStefan Hajnoczi# Pick a TCP port based on our pid. This way multiple instances of this test 40*dc668dedSStefan Hajnoczi# can run in parallel without conflicting. 41*dc668dedSStefan Hajnoczichoose_tcp_port() { 42*dc668dedSStefan Hajnoczi echo $((($$ % 31744) + 1024)) # 1024 <= port < 32768 43*dc668dedSStefan Hajnoczi} 44*dc668dedSStefan Hajnoczi 45*dc668dedSStefan Hajnocziwait_for_tcp_port() { 46*dc668dedSStefan Hajnoczi while ! (netstat --tcp --listening --numeric | \ 47*dc668dedSStefan Hajnoczi grep "$1.*0.0.0.0:\*.*LISTEN") 2>&1 >/dev/null; do 48*dc668dedSStefan Hajnoczi sleep 0.1 49*dc668dedSStefan Hajnoczi done 50*dc668dedSStefan Hajnoczi} 51*dc668dedSStefan Hajnoczi 52*dc668dedSStefan Hajnoczifilter_nbd() { 53*dc668dedSStefan Hajnoczi # nbd.c error messages contain function names and line numbers that are prone 54*dc668dedSStefan Hajnoczi # to change. Message ordering depends on timing between send and receive 55*dc668dedSStefan Hajnoczi # callbacks sometimes, making them unreliable. 56*dc668dedSStefan Hajnoczi # 57*dc668dedSStefan Hajnoczi # Filter out the TCP port number since this changes between runs. 58*dc668dedSStefan Hajnoczi sed -e 's#^nbd.c:.*##g' \ 59*dc668dedSStefan Hajnoczi -e 's#nbd:127.0.0.1:[^:]*:#nbd:127.0.0.1:PORT:#g' 60*dc668dedSStefan Hajnoczi} 61*dc668dedSStefan Hajnoczi 62*dc668dedSStefan Hajnoczicheck_disconnect() { 63*dc668dedSStefan Hajnoczi event=$1 64*dc668dedSStefan Hajnoczi when=$2 65*dc668dedSStefan Hajnoczi negotiation=$3 66*dc668dedSStefan Hajnoczi echo "=== Check disconnect $when $event ===" 67*dc668dedSStefan Hajnoczi echo 68*dc668dedSStefan Hajnoczi 69*dc668dedSStefan Hajnoczi port=$(choose_tcp_port) 70*dc668dedSStefan Hajnoczi 71*dc668dedSStefan Hajnoczi cat > "$TEST_DIR/nbd-fault-injector.conf" <<EOF 72*dc668dedSStefan Hajnoczi[inject-error] 73*dc668dedSStefan Hajnoczievent=$event 74*dc668dedSStefan Hajnocziwhen=$when 75*dc668dedSStefan HajnocziEOF 76*dc668dedSStefan Hajnoczi 77*dc668dedSStefan Hajnoczi if [ "$negotiation" = "--classic-negotiation" ]; then 78*dc668dedSStefan Hajnoczi extra_args=--classic-negotiation 79*dc668dedSStefan Hajnoczi nbd_url="nbd:127.0.0.1:$port" 80*dc668dedSStefan Hajnoczi else 81*dc668dedSStefan Hajnoczi nbd_url="nbd:127.0.0.1:$port:exportname=foo" 82*dc668dedSStefan Hajnoczi fi 83*dc668dedSStefan Hajnoczi 84*dc668dedSStefan Hajnoczi ./nbd-fault-injector.py $extra_args "127.0.0.1:$port" "$TEST_DIR/nbd-fault-injector.conf" 2>&1 >/dev/null & 85*dc668dedSStefan Hajnoczi wait_for_tcp_port "127.0.0.1:$port" 86*dc668dedSStefan Hajnoczi $QEMU_IO -c "read 0 512" "$nbd_url" 2>&1 | _filter_qemu_io | filter_nbd 87*dc668dedSStefan Hajnoczi 88*dc668dedSStefan Hajnoczi echo 89*dc668dedSStefan Hajnoczi} 90*dc668dedSStefan Hajnoczi 91*dc668dedSStefan Hajnoczifor event in neg1 "export" neg2 request reply data; do 92*dc668dedSStefan Hajnoczi for when in before after; do 93*dc668dedSStefan Hajnoczi check_disconnect "$event" "$when" 94*dc668dedSStefan Hajnoczi done 95*dc668dedSStefan Hajnoczi 96*dc668dedSStefan Hajnoczi # Also inject short replies from the NBD server 97*dc668dedSStefan Hajnoczi case "$event" in 98*dc668dedSStefan Hajnoczi neg1) 99*dc668dedSStefan Hajnoczi for when in 8 16; do 100*dc668dedSStefan Hajnoczi check_disconnect "$event" "$when" 101*dc668dedSStefan Hajnoczi done 102*dc668dedSStefan Hajnoczi ;; 103*dc668dedSStefan Hajnoczi "export") 104*dc668dedSStefan Hajnoczi for when in 4 12 16; do 105*dc668dedSStefan Hajnoczi check_disconnect "$event" "$when" 106*dc668dedSStefan Hajnoczi done 107*dc668dedSStefan Hajnoczi ;; 108*dc668dedSStefan Hajnoczi neg2) 109*dc668dedSStefan Hajnoczi for when in 8 10; do 110*dc668dedSStefan Hajnoczi check_disconnect "$event" "$when" 111*dc668dedSStefan Hajnoczi done 112*dc668dedSStefan Hajnoczi ;; 113*dc668dedSStefan Hajnoczi reply) 114*dc668dedSStefan Hajnoczi for when in 4 8; do 115*dc668dedSStefan Hajnoczi check_disconnect "$event" "$when" 116*dc668dedSStefan Hajnoczi done 117*dc668dedSStefan Hajnoczi ;; 118*dc668dedSStefan Hajnoczi esac 119*dc668dedSStefan Hajnoczidone 120*dc668dedSStefan Hajnoczi 121*dc668dedSStefan Hajnoczi# Also check classic negotiation without export information 122*dc668dedSStefan Hajnoczifor when in before 8 16 24 28 after; do 123*dc668dedSStefan Hajnoczi check_disconnect "neg-classic" "$when" --classic-negotiation 124*dc668dedSStefan Hajnoczidone 125*dc668dedSStefan Hajnoczi 126*dc668dedSStefan Hajnoczi# success, all done 127*dc668dedSStefan Hajnocziecho "*** done" 128*dc668dedSStefan Hajnoczirm -f $seq.full 129*dc668dedSStefan Hajnoczistatus=0 130