| #!/usr/bin/env 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" |
| |
| status=1 # failure is the default! |
| |
| _cleanup() |
| { |
| rm -f nbd.sock |
| rm -f nbd-fault-injector.out |
| rm -f nbd-fault-injector.conf |
| } |
| trap "_cleanup; exit \$status" 0 1 2 3 15 |
| |
| # get standard environment, filters and checks |
| . ./common.rc |
| . ./common.filter |
| |
| _supported_fmt raw |
| _supported_proto nbd |
| _supported_os Linux |
| |
| check_disconnect() { |
| local event export_name=foo extra_args nbd_addr nbd_url proto when |
| |
| while true; do |
| case $1 in |
| --classic-negotiation) |
| shift |
| extra_args=--classic-negotiation |
| export_name= |
| ;; |
| --tcp) |
| shift |
| proto=tcp |
| ;; |
| --unix) |
| shift |
| proto=unix |
| ;; |
| *) |
| break |
| ;; |
| esac |
| done |
| |
| event=$1 |
| when=$2 |
| echo "=== Check disconnect $when $event ===" |
| echo |
| |
| cat > "$TEST_DIR/nbd-fault-injector.conf" <<EOF |
| [inject-error] |
| event=$event |
| when=$when |
| EOF |
| |
| if [ "$proto" = "tcp" ]; then |
| nbd_addr="127.0.0.1:0" |
| else |
| nbd_addr="$TEST_DIR/nbd.sock" |
| fi |
| |
| rm -f "$TEST_DIR/nbd.sock" |
| |
| echo > "$TEST_DIR/nbd-fault-injector.out" |
| $PYTHON nbd-fault-injector.py $extra_args "$nbd_addr" "$TEST_DIR/nbd-fault-injector.conf" >"$TEST_DIR/nbd-fault-injector.out" 2>&1 & |
| |
| # Wait for server to be ready |
| while ! grep -q 'Listening on ' "$TEST_DIR/nbd-fault-injector.out"; do |
| sleep 0.1 |
| done |
| |
| # Extract the final address (port number has now been assigned in tcp case) |
| nbd_addr=$(sed -n 's/^Listening on //p' \ |
| "$TEST_DIR/nbd-fault-injector.out") |
| |
| if [ "$proto" = "tcp" ]; then |
| nbd_url="nbd+tcp://$nbd_addr/$export_name" |
| else |
| nbd_url="nbd+unix:///$export_name?socket=$nbd_addr" |
| fi |
| |
| $QEMU_IO -c "read 0 512" "$nbd_url" 2>&1 | _filter_qemu_io | _filter_nbd |
| |
| echo |
| } |
| |
| for proto in tcp unix; do |
| for event in neg1 "export" neg2 request reply data; do |
| for when in before after; do |
| check_disconnect "--$proto" "$event" "$when" |
| done |
| |
| # Also inject short replies from the NBD server |
| case "$event" in |
| neg1) |
| for when in 8 16; do |
| check_disconnect "--$proto" "$event" "$when" |
| done |
| ;; |
| "export") |
| for when in 4 12 16; do |
| check_disconnect "--$proto" "$event" "$when" |
| done |
| ;; |
| neg2) |
| for when in 8 10; do |
| check_disconnect "--$proto" "$event" "$when" |
| done |
| ;; |
| reply) |
| for when in 4 8; do |
| check_disconnect "--$proto" "$event" "$when" |
| done |
| ;; |
| esac |
| done |
| |
| # Also check classic negotiation without export information |
| for when in before 8 16 24 28 after; do |
| check_disconnect "--$proto" --classic-negotiation "neg-classic" "$when" |
| done |
| done |
| |
| # success, all done |
| echo "*** done" |
| rm -f $seq.full |
| status=0 |