Whamcloud - gitweb
LU-14627 lnet: Ensure ref taken when queueing for discovery
[fs/lustre-release.git] / lustre / tests / sanity-lnet.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10 # bug number for skipped test:
11 ALWAYS_EXCEPT="$SANITY_LNET_EXCEPT "
12 [ "$SLOW" = "no" ] && EXCEPT_SLOW=""
13 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
14
15 LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
16
17 . $LUSTRE/tests/test-framework.sh
18 CLEANUP=${CLEANUP:-:}
19 SETUP=${SETUP:-:}
20 init_test_env $@
21 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
22 init_logging
23
24 build_test_filter
25
26 [[ -z $LNETCTL ]] && skip "Need lnetctl"
27
28 load_lnet() {
29         load_module ../libcfs/libcfs/libcfs
30         # Prevent local MODOPTS_LIBCFS being passed as part of environment
31         # variable to remote nodes
32         unset MODOPTS_LIBCFS
33
34         set_default_debug
35         load_module ../lnet/lnet/lnet "$@"
36
37         LNDPATH=${LNDPATH:-"../lnet/klnds"}
38         if [ -z "$LNETLND" ]; then
39                 case $NETTYPE in
40                 o2ib*)  LNETLND="o2iblnd/ko2iblnd" ;;
41                 tcp*)   LNETLND="socklnd/ksocklnd" ;;
42                 *)      local lnd="${NETTYPE%%[0-9]}lnd"
43                         [ -f "$LNDPATH/$lnd/k$lnd.ko" ] &&
44                                 LNETLND="$lnd/k$lnd" ||
45                                 LNETLND="socklnd/ksocklnd"
46                 esac
47         fi
48         load_module ../lnet/klnds/$LNETLND
49 }
50
51 cleanup_lnet() {
52         echo "Cleaning up LNet"
53         lsmod | grep -q lnet &&
54                 $LNETCTL lnet unconfigure 2>/dev/null
55         unload_modules
56 }
57
58 TESTNS='test_ns'
59 RUN_NS="ip netns exec $TESTNS"
60 FAKE_IF="test1pg"
61 FAKE_IP="10.1.2.3"
62
63 setup_netns() {
64         cleanup_netns
65
66         ip netns add $TESTNS
67         ip link add 'test1pl' type veth peer name $FAKE_IF netns $TESTNS
68         ip link set 'test1pl' up
69         $RUN_NS ip addr add "${FAKE_IP}/31" dev $FAKE_IF
70         $RUN_NS ip link set $FAKE_IF up
71 }
72
73 cleanup_netns() {
74         (ip netns list | grep -q $TESTNS) && ip netns del $TESTNS
75         if ip link show test1pl >/dev/null 2>&1; then
76                 ip link del test1pl
77         fi
78 }
79
80 cleanupall -f
81
82 setup_netns
83 load_lnet
84
85 test_1() {
86         $LNETCTL lnet configure
87 }
88 run_test 1 "configure lnet with lnetctl"
89
90
91 ### load lnet in default namespace, configure in target namespace
92
93 test_2() {
94         cleanup_lnet || exit 1
95         load_lnet "networks=\"\""
96         $RUN_NS $LNETCTL lnet configure --all || exit 1
97         $LNETCTL net show --net tcp | grep -q "nid: ${FAKE_IP}@tcp$"
98 }
99 run_test 2 "load lnet w/o module option, configure in a non-default namespace"
100
101 test_3() {
102         cleanup_lnet || exit 1
103         load_lnet "networks=tcp($FAKE_IF)"
104         $RUN_NS $LNETCTL lnet configure --all || exit 1
105         $LNETCTL net show --net tcp | grep -q "nid: ${FAKE_IP}@tcp$"
106 }
107 run_test 3 "load lnet using networks module options in a non-default namespace"
108
109 test_4() {
110         cleanup_lnet || exit 1
111         load_lnet "networks=\"\" ip2nets=\"tcp0($FAKE_IF) ${FAKE_IP}\""
112         $RUN_NS $LNETCTL lnet configure --all || exit 1
113         $LNETCTL net show | grep -q "nid: ${FAKE_IP}@tcp$"
114 }
115 run_test 4 "load lnet using ip2nets in a non-default namespace"
116
117
118 ### Add the interfaces in the target namespace
119
120 test_5() {
121         cleanup_lnet || exit 1
122         load_lnet
123         $LNETCTL lnet configure || exit 1
124         $RUN_NS $LNETCTL net add --net tcp0 --if $FAKE_IF
125 }
126 run_test 5 "add a network using an interface in the non-default namespace"
127
128 test_212() {
129         local rnodes=$(remote_nodes_list)
130         [[ -z $rnodes ]] && skip "Need at least 1 remote node"
131
132         cleanup_lnet || error "Failed to cleanup before test execution"
133
134         # Loading modules should configure LNet with the appropriate
135         # test-framework configuration
136         load_modules || error "Failed to load modules"
137
138         local my_nid=$($LCTL list_nids | head -n 1)
139         [[ -z $my_nid ]] &&
140                 error "Failed to get primary NID for local host $HOSTNAME"
141
142         local rnode=$(awk '{print $1}' <<<$rnodes)
143         local rnodenids=$(do_node $rnode $LCTL list_nids | xargs echo)
144         local rloaded=false
145
146         if [[ -z $rnodenids ]]; then
147                 do_rpc_nodes $rnode load_modules_local
148                 rloaded=true
149                 rnodenids=$(do_node $rnode $LCTL list_nids | xargs echo)
150         fi
151
152         local rnodepnid=$(awk '{print $1}' <<< $rnodenids)
153
154         [[ -z $rnodepnid ]] &&
155                 error "Failed to get primary NID for remote host $rnode"
156
157         log "Initial discovery"
158         $LNETCTL discover --force $rnodepnid ||
159                 error "Failed to discover $rnodepnid"
160
161         do_node $rnode "$LNETCTL discover --force $my_nid" ||
162                 error "$rnode failed to discover $my_nid"
163
164         log "Fail local discover ping to set LNET_PEER_REDISCOVER flag"
165         $LCTL net_drop_add -s "*@$NETTYPE" -d "*@$NETTYPE" -r 1 -e local_error
166         $LNETCTL discover --force $rnodepnid &&
167                 error "Discovery should have failed"
168         $LCTL net_drop_del -a
169
170         local nid
171         for nid in $rnodenids; do
172                 # We need GET (PING) delay just long enough so we can trigger
173                 # discovery on the remote peer
174                 $LCTL net_delay_add -s "*@$NETTYPE" -d $nid -r 1 -m GET -l 3
175                 $LCTL net_drop_add -s "*@$NETTYPE" -d $nid -r 1 -m GET -e local_error
176                 # We need PUT (PUSH) delay just long enough so we can process
177                 # the PING failure
178                 $LCTL net_delay_add -s "*@$NETTYPE" -d $nid -r 1 -m PUT -l 6
179         done
180
181         log "Force $HOSTNAME to discover $rnodepnid (in background)"
182         # We want to get a PING sent that we know will eventually fail.
183         # The delay rules we added will ensure the ping is not sent until
184         # the PUSH is also in flight (see below), and the drop rule ensures that
185         # when the PING is eventually sent it will error out
186         $LNETCTL discover --force $rnodepnid &
187         local pid1=$!
188
189         # We want a discovery PUSH from rnode to put rnode back on our
190         # discovery queue. This should cause us to try and send a PUSH to rnode
191         # while the PING is still outstanding.
192         log "Force $rnode to discover $my_nid"
193         do_node $rnode $LNETCTL discover --force $my_nid
194
195         # At this point we'll have both PING_SENT and PUSH_SENT set for the
196         # rnode peer. Wait for the PING to error out which should terminate the
197         # discovery process that we backgrounded.
198         log "Wait for $pid1"
199         wait $pid1
200         log "Finished wait on $pid1"
201
202         # The PING send failure clears the PING_SENT flag and puts the peer back
203         # on the discovery queue. When discovery thread processes the peer it
204         # will mistakenly clear the PUSH_SENT flag (and set PUSH_FAILED).
205         # Discovery will then complete for this peer even though we have an
206         # outstanding PUSH.
207         # When PUSH is actually unlinked it will be forced back onto the
208         # discovery queue, but we no longer have a ref on the peer. When
209         # discovery completes again, we'll trip the ASSERT in
210         # lnet_destroy_peer_locked()
211
212         # Delete the delay rules to send the PUSH
213         $LCTL net_delay_del -a
214         # Delete the drop rules
215         $LCTL net_drop_del -a
216
217         unload_modules ||
218                 error "Failed to unload modules"
219         if $rloaded; then
220                 do_rpc_nodes $rnode unload_modules_local ||
221                         error "Failed to unload modules on $rnode"
222         fi
223
224         return 0
225 }
226 run_test 212 "Check discovery refcount loss bug (LU-14627)"
227
228
229 cleanup_netns
230 cleanup_lnet
231 exit_status