summaryrefslogtreecommitdiff
path: root/tests/qemu-iotests/083
blob: f764534782a01eb547b60d6d6970602e901f354f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#!/bin/bash
#
# Test NBD client unexpected disconnect
#
# Copyright Red Hat, Inc. 2014
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

# creator
owner=stefanha@redhat.com

seq=`basename $0`
echo "QA output created by $seq"

here=`pwd`
tmp=/tmp/$$
status=1	# failure is the default!

# get standard environment, filters and checks
. ./common.rc
. ./common.filter

_supported_fmt generic
_supported_proto nbd
_supported_os Linux

# Pick a TCP port based on our pid.  This way multiple instances of this test
# can run in parallel without conflicting.
choose_tcp_port() {
	echo $((($$ % 31744) + 1024)) # 1024 <= port < 32768
}

wait_for_tcp_port() {
	while ! (netstat --tcp --listening --numeric | \
		 grep "$1.*0.0.0.0:\*.*LISTEN") 2>&1 >/dev/null; do
		sleep 0.1
	done
}

filter_nbd() {
	# nbd.c error messages contain function names and line numbers that are prone
	# to change.  Message ordering depends on timing between send and receive
	# callbacks sometimes, making them unreliable.
	#
	# Filter out the TCP port number since this changes between runs.
	sed -e 's#^nbd.c:.*##g' \
	    -e 's#nbd:127.0.0.1:[^:]*:#nbd:127.0.0.1:PORT:#g'
}

check_disconnect() {
	event=$1
	when=$2
	negotiation=$3
	echo "=== Check disconnect $when $event ==="
	echo

	port=$(choose_tcp_port)

	cat > "$TEST_DIR/nbd-fault-injector.conf" <<EOF
[inject-error]
event=$event
when=$when
EOF

	if [ "$negotiation" = "--classic-negotiation" ]; then
		extra_args=--classic-negotiation
		nbd_url="nbd:127.0.0.1:$port"
	else
		nbd_url="nbd:127.0.0.1:$port:exportname=foo"
	fi

	./nbd-fault-injector.py $extra_args "127.0.0.1:$port" "$TEST_DIR/nbd-fault-injector.conf" 2>&1 >/dev/null &
	wait_for_tcp_port "127.0.0.1:$port"
	$QEMU_IO -c "read 0 512" "$nbd_url" 2>&1 | _filter_qemu_io | filter_nbd

	echo
}

for event in neg1 "export" neg2 request reply data; do
	for when in before after; do
		check_disconnect "$event" "$when"
	done

	# Also inject short replies from the NBD server
	case "$event" in
	neg1)
		for when in 8 16; do
			check_disconnect "$event" "$when"
		done
		;;
	"export")
		for when in 4 12 16; do
			check_disconnect "$event" "$when"
		done
		;;
	neg2)
		for when in 8 10; do
			check_disconnect "$event" "$when"
		done
		;;
	reply)
		for when in 4 8; do
			check_disconnect "$event" "$when"
		done
		;;
	esac
done

# Also check classic negotiation without export information
for when in before 8 16 24 28 after; do
	check_disconnect "neg-classic" "$when" --classic-negotiation
done

# success, all done
echo "*** done"
rm -f $seq.full
status=0