Whamcloud - gitweb
LU-17662 osd-zfs: Support for ZFS 2.2.3
[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
11 # bug number for skipped test:
12 ALWAYS_EXCEPT="$SANITY_LNET_EXCEPT 253 254"
13 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
14
15 [ "$SLOW" = "no" ] && EXCEPT_SLOW=""
16
17 LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
18
19 . $LUSTRE/tests/test-framework.sh
20 CLEANUP=${CLEANUP:-:}
21 SETUP=${SETUP:-:}
22 init_test_env "$@"
23 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
24 init_logging
25
26 [[ -z $LNETCTL ]] && skip "Need lnetctl"
27
28 restore_mounts=false
29
30 if is_mounted $MOUNT || is_mounted $MOUNT2; then
31         cleanupall || error "Failed cleanup prior to test execution"
32         restore_mounts=true
33 fi
34
35 cleanup_lnet() {
36         echo "Cleaning up LNet"
37         lsmod | grep -q lnet &&
38                 $LNETCTL lnet unconfigure 2>/dev/null
39         unload_modules
40 }
41
42 restore_modules=false
43 if module_loaded lnet ; then
44         cleanup_lnet || error "Failed to unload modules before test execution"
45         restore_modules=true
46 fi
47
48 cleanup_testsuite() {
49         trap "" EXIT
50         # Cleanup any tmp files created by the sub tests
51         rm -f $TMP/sanity-lnet-*.yaml $LNET_PARAMS_FILE
52         cleanup_netns
53         cleanup_lnet
54         if $restore_mounts; then
55                 setupall || error "Failed to setup Lustre after test execution"
56         elif $restore_modules; then
57                 load_modules ||
58                         error "Couldn't load modules after test execution"
59         fi
60         return 0
61 }
62
63 TESTNS='test_ns'
64 FAKE_IF="test1pg"
65 FAKE_IP="10.1.2.3"
66 FAKE_IP_ALIAS="10.1.2.31"
67 do_ns() {
68         echo "ip netns exec $TESTNS $*"
69         ip netns exec $TESTNS "$@"
70 }
71
72 setup_fakeif() {
73         local netns="$1"
74
75         local netns_arg=""
76         [[ -n $netns ]] &&
77                 netns_arg="netns $netns"
78
79         ip link add 'test1pl' type veth peer name $FAKE_IF $netns_arg
80         ip link set 'test1pl' up
81         if [[ -n $netns ]]; then
82                 do_ns ip addr add "${FAKE_IP}/31" dev $FAKE_IF
83                 do_ns ip link set $FAKE_IF up
84         else
85                 ip addr add "${FAKE_IP}/31" dev $FAKE_IF
86                 ip link set $FAKE_IF up
87         fi
88 }
89
90 cleanup_fakeif() {
91         ip link show test1pl >& /dev/null && ip link del test1pl || return 0
92 }
93
94 setup_netns() {
95         cleanup_netns
96
97         ip netns add $TESTNS
98         setup_fakeif $TESTNS
99 }
100
101 cleanup_netns() {
102         (ip netns list | grep -q $TESTNS) && ip netns del $TESTNS
103         cleanup_fakeif
104 }
105
106 configure_dlc() {
107         echo "Loading LNet and configuring DLC"
108         load_lnet || return $?
109         do_lnetctl lnet configure
110 }
111
112 GLOBAL_YAML_FILE=$TMP/sanity-lnet-global.yaml
113 define_global_yaml() {
114         $LNETCTL export --backup >${GLOBAL_YAML_FILE} ||
115                 error "Failed to export global yaml $?"
116 }
117
118 reinit_dlc() {
119         if lsmod | grep -q lnet; then
120                 do_lnetctl lnet unconfigure ||
121                         error "lnetctl lnet unconfigure failed $?"
122                 do_lnetctl lnet configure ||
123                         error "lnetctl lnet configure failed $?"
124         else
125                 configure_dlc || error "configure_dlc failed $?"
126         fi
127         define_global_yaml
128 }
129
130 append_global_yaml() {
131         [[ ! -e ${GLOBAL_YAML_FILE} ]] &&
132                 error "Missing global yaml at ${GLOBAL_YAML_FILE}"
133
134         cat ${GLOBAL_YAML_FILE} >> $TMP/sanity-lnet-$testnum-expected.yaml
135 }
136
137 create_base_yaml_file() {
138         append_global_yaml
139 }
140
141 compare_yaml_files() {
142         local expected="$TMP/sanity-lnet-$testnum-expected.yaml"
143         local actual="$TMP/sanity-lnet-$testnum-actual.yaml"
144         local rc=0
145         ! [[ -e $expected ]] && echo "$expected not found" && return 1
146         ! [[ -e $actual ]] && echo "$actual not found" && return 1
147         if [ verify_yaml_available ]; then
148                 verify_compare_yaml $actual $expected || rc=$?
149         else
150                 diff -upN ${actual} ${expected} || rc=$?
151         fi
152         echo "Expected:"
153         cat $expected
154         echo "Actual:"
155         cat $actual
156         return $rc
157 }
158
159 validate_nid() {
160         local nid="$1"
161         local net="${nid//*@/}"
162         local addr="${nid//@*/}"
163
164         local rc=1
165
166         local num_re='[0-9]+'
167
168         if [[ $net =~ (gni|kfi)[0-9]* ]]; then
169                 [[ $addr =~ ${num_re} ]] && rc=0
170         elif [[ $net =~ tcp[0-9]* ]]; then
171                 if ip_is_v4 "$addr" || ip_is_v6 "$addr"; then
172                         rc=0
173                 fi
174         elif [[ $net =~ o2ib[0-9]* ]]; then
175                 ip_is_v4 "$addr" && rc=0
176         else
177                 echo "Unrecognized net: \"$net\""
178         fi
179
180         if ((rc != 0)); then
181                 echo "Invalid nid: \"$nid\""
182         fi
183
184         return $rc
185 }
186
187 validate_nids() {
188         local yfile=$TMP/sanity-lnet-$testnum-actual.yaml
189         local primary_nids=$(awk '/-\s+primary nid:/{print $NF}' $yfile |
190                              xargs echo)
191         local secondary_nids=$(awk '/-\s+nid:/{print $NF}' $yfile | xargs echo)
192         local gateway_nids=$(awk '/gateway:/{print $NF}' $yfile | xargs echo)
193
194         local nid
195         for nid in $primary_nids $secondary_nids $gateway_nids; do
196                 validate_nid "$nid" || error "Bad NID \"${nid}\""
197         done
198         return 0
199 }
200
201 validate_peer_nids() {
202         local num_peers="$1"
203         local nids_per_peer="$2"
204
205         local expect_p="$num_peers"
206         # The primary nid also shows up in the list of secondary nids
207         local expect_s="$(($num_peers + $(($nids_per_peer*$num_peers))))"
208
209         local actual_p=$(awk '/-\s+primary nid:/{print $NF}' $TMP/sanity-lnet-$testnum-actual.yaml | wc -l)
210         local actual_s=$(awk '/-\s+nid:/{print $NF}' $TMP/sanity-lnet-$testnum-actual.yaml | wc -l)
211         if [[ $expect_p -ne $actual_p ]]; then
212                 compare_yaml_files
213                 error "Expected $expect_p but found $actual_p primary nids"
214         elif [[ $expect_s -ne $actual_s ]]; then
215                 compare_yaml_files
216                 error "Expected $expect_s but found $actual_s secondary nids"
217         fi
218         validate_nids
219 }
220
221 validate_gateway_nids() {
222         local expect_gw=$(grep -c -- 'gateway:' $TMP/sanity-lnet-$testnum-expected.yaml)
223         local actual_gw=$(grep -c -- 'gateway:' $TMP/sanity-lnet-$testnum-actual.yaml)
224
225         echo "expect_gw: $expect_gw actual_gw: $actual_gw"
226         if [[ $expect_gw -ne $actual_gw ]]; then
227                 compare_yaml_files
228                 error "Expected $expect_gw gateways but found $actual_gw gateways"
229         fi
230
231         local expect_gwnids=$(awk '/gateway:/{print $NF}' $TMP/sanity-lnet-$testnum-expected.yaml |
232                               xargs echo)
233         local nid
234
235         echo "expect_gwnids: $expect_gwnids"
236         for nid in ${expect_gwnids}; do
237                 if ! grep -q "gateway: ${nid}" $TMP/sanity-lnet-$testnum-actual.yaml; then
238                         compare_yaml_files
239                         error "${nid} not configured as gateway"
240                 fi
241         done
242
243         validate_nids
244 }
245
246 # TODO: Switch to ipcalc if/when we need more sophisticated validation
247 ip_is_v4() {
248         local ipv4_re='^([0-9]{1,3}\.){3,3}[0-9]{1,3}$'
249
250         if ! [[ $1 =~ $ipv4_re ]]; then
251                 return 1
252         fi
253
254         local quads=(${1//\./ })
255
256         (( ${#quads[@]} == 4)) || return 1
257
258         (( quads[0] < 256 && quads[1] < 256 &&
259            quads[2] < 256 && quads[3] < 256 )) || return 1
260
261         return 0
262 }
263
264 intf_has_ipv4() {
265         local addr=$(ip -o -4 a s "$1" | awk '{print $4}' | head -n 1 |
266                      sed 's,/[0-9]\+$,,')
267
268         ip_is_v4 "${addr}"
269 }
270
271 cleanupall -f
272 setup_netns || error "setup_netns failed with $?"
273
274 # Determine the local interface(s) used for LNet
275 load_lnet "config_on_load=1" || error "Failed to load modules"
276
277 do_lnetctl net show
278 ip a
279
280 INTERFACES=( $(lnet_if_list) )
281
282 if [[ -z ${INTERFACES[@]} ]]; then
283         error "Did not identify any LNet interfaces"
284 fi
285
286 if [[ $NETTYPE =~ (tcp|o2ib)[0-9]* ]]; then
287         if ! intf_has_ipv4 "${INTERFACES[0]}"; then
288                 always_except LU-5960 230
289                 always_except LU-9680 204
290                 always_except LU-9680 205
291                 always_except LU-9680 206
292                 always_except LU-9680 207
293                 always_except LU-9680 209
294                 always_except LU-9680 210
295                 always_except LU-9680 211
296                 always_except LU-9680 212
297                 always_except LU-9680 213
298                 always_except LU-9680 216
299                 always_except LU-9680 218
300                 always_except LU-9680 231
301                 always_except LU-9680 302
302                 always_except LU-9680 500
303                 always_except LU-14288 101
304                 always_except LU-14288 103
305                 always_except LU-17458 220
306                 always_except LU-17457 208
307                 always_except LU-17457 255
308                 always_except LU-17460 214
309         fi
310 fi
311
312 build_test_filter
313
314 cleanup_lnet || error "Failed to cleanup LNet"
315
316 stack_trap 'cleanup_testsuite' EXIT
317
318 test_0() {
319         configure_dlc || error "Failed to configure DLC rc = $?"
320         define_global_yaml
321         reinit_dlc || return $?
322         do_lnetctl import <  ${GLOBAL_YAML_FILE} || error "Import failed $?"
323         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
324         create_base_yaml_file
325         compare_yaml_files || error "Configuration changed after import"
326 }
327 run_test 0 "Export empty config, import the config, compare"
328
329 compare_peer_add() {
330         local prim_nid="${1:+--prim_nid $1}"
331         local nid="${2:+--nid $2}"
332
333         local actual="$TMP/sanity-lnet-$testnum-actual.yaml"
334
335         do_lnetctl peer add ${prim_nid} ${nid} || error "peer add failed $?"
336         $LNETCTL export --backup > $actual || error "export failed $?"
337         compare_yaml_files
338         return $?
339 }
340
341 test_1() {
342         reinit_dlc || return $?
343         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
344 peer:
345     - primary nid: 1.1.1.1@tcp
346       Multi-Rail: True
347       peer ni:
348         - nid: 1.1.1.1@tcp
349 EOF
350         append_global_yaml
351         compare_peer_add "1.1.1.1@tcp"
352 }
353 run_test 1 "Add peer with single nid (tcp)"
354
355 test_2() {
356         reinit_dlc || return $?
357         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
358 peer:
359     - primary nid: 2.2.2.2@o2ib
360       Multi-Rail: True
361       peer ni:
362         - nid: 2.2.2.2@o2ib
363 EOF
364         append_global_yaml
365         compare_peer_add "2.2.2.2@o2ib"
366 }
367 run_test 2 "Add peer with single nid (o2ib)"
368
369 test_3() {
370         reinit_dlc || return $?
371         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
372 peer:
373     - primary nid: 3.3.3.3@tcp
374       Multi-Rail: True
375       peer ni:
376         - nid: 3.3.3.3@tcp
377         - nid: 3.3.3.3@o2ib
378 EOF
379         append_global_yaml
380         compare_peer_add "3.3.3.3@tcp" "3.3.3.3@o2ib"
381 }
382 run_test 3 "Add peer with tcp primary o2ib secondary"
383
384 test_4() {
385         reinit_dlc || return $?
386         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
387 peer:
388     - primary nid: 4.4.4.4@tcp
389       Multi-Rail: True
390       peer ni:
391         - nid: 4.4.4.4@tcp
392         - nid: 4.4.4.1@tcp
393         - nid: 4.4.4.2@tcp
394         - nid: 4.4.4.3@tcp
395 EOF
396         append_global_yaml
397         echo "Add peer with nidrange (tcp)"
398         compare_peer_add "4.4.4.4@tcp" "4.4.4.[1-3]@tcp"
399
400         echo "Add peer with nidrange that overlaps primary nid (tcp)"
401         compare_peer_add "4.4.4.4@tcp" "4.4.4.[1-4]@tcp"
402 }
403 run_test 4 "Add peer with nidrange (tcp)"
404
405 test_5() {
406         reinit_dlc || return $?
407         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
408 peer:
409     - primary nid: 5.5.5.5@o2ib
410       Multi-Rail: True
411       peer ni:
412         - nid: 5.5.5.5@o2ib
413         - nid: 5.5.5.1@o2ib
414         - nid: 5.5.5.2@o2ib
415         - nid: 5.5.5.3@o2ib
416         - nid: 5.5.5.4@o2ib
417 EOF
418         append_global_yaml
419         echo "Add peer with nidrange (o2ib)"
420         compare_peer_add "5.5.5.5@o2ib" "5.5.5.[1-4]@o2ib"
421
422         echo "Add peer with nidranage that overlaps primary nid (o2ib)"
423         compare_peer_add "5.5.5.5@o2ib" "5.5.5.[1-4]@o2ib"
424
425         echo "Add peer with nidranage that contain , plus primary nid (o2ib)"
426         compare_peer_add "5.5.5.5@o2ib" "5.5.5.[1,2,3-4]@o2ib"
427 }
428 run_test 5 "Add peer with nidrange (o2ib)"
429
430 test_6() {
431         reinit_dlc || return $?
432         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
433 peer:
434     - primary nid: 6.6.6.6@tcp
435       Multi-Rail: True
436       peer ni:
437         - nid: 6.6.6.6@tcp
438         - nid: 6.6.6.0@tcp
439         - nid: 6.6.6.2@tcp
440         - nid: 6.6.6.4@tcp
441         - nid: 6.6.7.0@tcp
442         - nid: 6.6.7.2@tcp
443         - nid: 6.6.7.4@tcp
444         - nid: 6.6.1.0@o2ib
445         - nid: 6.6.1.3@o2ib
446         - nid: 6.6.1.6@o2ib
447         - nid: 6.6.3.0@o2ib
448         - nid: 6.6.3.3@o2ib
449         - nid: 6.6.3.6@o2ib
450         - nid: 6@gni
451         - nid: 10@gni
452         - nid: 6@kfi
453         - nid: 10@kfi
454 EOF
455         append_global_yaml
456
457         local nid_expr="6.6.[6-7].[0-4/2]@tcp"
458         nid_expr+=",6.6.[1-4/2].[0-6/3]@o2ib"
459         nid_expr+=",[6-12/4]@gni"
460         nid_expr+=",[6-12/4]@kfi"
461
462         compare_peer_add "6.6.6.6@tcp" "${nid_expr}"
463 }
464 run_test 6 "Add peer with multiple nidranges"
465
466 compare_peer_del() {
467         local prim_nid="${1:+--prim_nid $1}"
468         local nid="${2:+--nid $2}"
469
470         local actual="$TMP/sanity-lnet-$testnum-actual.yaml"
471
472         do_lnetctl peer del ${prim_nid} ${nid} || error "peer del failed $?"
473         $LNETCTL export --backup > $actual || error "export failed $?"
474         compare_yaml_files
475         return $?
476 }
477
478 test_7() {
479         reinit_dlc || return $?
480         create_base_yaml_file
481
482         echo "Delete peer with single nid (tcp)"
483         do_lnetctl peer add --prim_nid 7.7.7.7@tcp || error "Peer add failed $?"
484         compare_peer_del "7.7.7.7@tcp"
485
486         echo "Delete peer with single nid (o2ib)"
487         do_lnetctl peer add --prim_nid 7.7.7.7@o2ib || error "Peer add failed $?"
488         compare_peer_del "7.7.7.7@o2ib"
489
490         echo "Delete peer that has multiple nids (tcp)"
491         do_lnetctl peer add --prim_nid 7.7.7.7@tcp --nid 7.7.7.[8-12]@tcp ||
492                 error "Peer add failed $?"
493         compare_peer_del "7.7.7.7@tcp"
494
495         echo "Delete peer that has multiple nids (o2ib)"
496         do_lnetctl peer add --prim_nid 7.7.7.7@o2ib --nid 7.7.7.[8-12]@o2ib ||
497                 error "Peer add failed $?"
498         compare_peer_del "7.7.7.7@o2ib"
499
500         echo "Delete peer that has both tcp and o2ib nids"
501         do_lnetctl peer add --prim_nid 7.7.7.7@tcp \
502                 --nid 7.7.7.[9-12]@tcp,7.7.7.[13-15]@o2ib ||
503                 error "Peer add failed $?"
504         compare_peer_del "7.7.7.7@tcp"
505
506         echo "Delete peer with single nid (gni)"
507         do_lnetctl peer add --prim_nid 7@gni || error "Peer add failed $?"
508         compare_peer_del "7@gni"
509
510         echo "Delete peer that has multiple nids (gni)"
511         do_lnetctl peer add --prim_nid 7@gni --nid [8-12]@gni ||
512                 error "Peer add failed $?"
513         compare_peer_del "7@gni"
514
515         echo "Delete peer with single nid (kfi)"
516         do_lnetctl peer add --prim_nid 7@kfi || error "Peer add failed $?"
517         compare_peer_del "7@kfi"
518
519         echo "Delete peer that has multiple nids (kfi)"
520         do_lnetctl peer add --prim_nid 7@kfi --nid [8-12]@kfi ||
521                 error "Peer add failed $?"
522         compare_peer_del "7@kfi"
523
524         echo "Delete peer that has tcp, o2ib, gni and kfi nids"
525         do_lnetctl peer add --prim_nid 7@gni \
526                 --nid [8-12]@gni,7.7.7.[1-4]@tcp,7.7.7.[5-9]@o2ib,[1-5]@kfi ||
527                 error "Peer add failed $?"
528         compare_peer_del "7@gni"
529
530         echo "Delete peer that contains nid equal to primary nid"
531         do_lnetctl peer add --prim 1.1.1.1@tcp \
532                 --nid 1.1.1.1@tcp,2.2.2.2@tcp,3.3.3.3@tcp,4.4.4.4@tcp ||
533                 error "Peer add failed $?"
534         compare_peer_del "1.1.1.1@tcp" "1.1.1.1@tcp,2.2.2.2@tcp,3.3.3.3@tcp,4.4.4.4@tcp"
535 }
536 run_test 7 "Various peer delete tests"
537
538 test_8() {
539         reinit_dlc || return $?
540
541         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
542 peer:
543     - primary nid: 8.8.8.8@tcp
544       Multi-Rail: True
545       peer ni:
546         - nid: 8.8.8.8@tcp
547         - nid: 8.8.8.10@tcp
548         - nid: 8.8.8.11@tcp
549         - nid: 8.8.8.12@tcp
550         - nid: 8.8.8.14@tcp
551         - nid: 8.8.8.15@tcp
552 EOF
553         append_global_yaml
554
555         do_lnetctl peer add --prim_nid 8.8.8.8@tcp --nid 8.8.8.[10-15]@tcp ||
556                 error "Peer add failed $?"
557         compare_peer_del "8.8.8.8@tcp" "8.8.8.13@tcp"
558 }
559 run_test 8 "Delete single secondary nid from peer (tcp)"
560
561 test_9() {
562         reinit_dlc || return $?
563
564         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
565 peer:
566     - primary nid: 9.9.9.9@tcp
567       Multi-Rail: True
568       peer ni:
569         - nid: 9.9.9.9@tcp
570 EOF
571         append_global_yaml
572
573         do_lnetctl peer add --prim_nid 9.9.9.9@tcp \
574                 --nid 9.9.9.[11-16]@tcp || error "Peer add failed $?"
575         compare_peer_del "9.9.9.9@tcp" "9.9.9.[11-16]@tcp"
576 }
577 run_test 9 "Delete all secondary nids from peer (tcp)"
578
579 test_10() {
580         reinit_dlc || return $?
581
582         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
583 peer:
584     - primary nid: 10.10.10.10@tcp
585       Multi-Rail: True
586       peer ni:
587         - nid: 10.10.10.10@tcp
588         - nid: 10.10.10.12@tcp
589         - nid: 10.10.10.13@tcp
590         - nid: 10.10.10.15@tcp
591         - nid: 10.10.10.16@tcp
592 EOF
593         append_global_yaml
594         do_lnetctl peer add --prim_nid 10.10.10.10@tcp \
595                 --nid 10.10.10.[12-16]@tcp || error "Peer add failed $?"
596         compare_peer_del "10.10.10.10@tcp" "10.10.10.14@tcp"
597 }
598 run_test 10 "Delete single secondary nid from peer (o2ib)"
599
600 test_11() {
601         reinit_dlc || return $?
602
603         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
604 peer:
605     - primary nid: 11.11.11.11@tcp
606       Multi-Rail: True
607       peer ni:
608         - nid: 11.11.11.11@tcp
609 EOF
610         append_global_yaml
611         do_lnetctl peer add --prim_nid 11.11.11.11@tcp \
612                 --nid 11.11.11.[13-17]@tcp || error "Peer add failed $?"
613         compare_peer_del "11.11.11.11@tcp" "11.11.11.[13-17]@tcp"
614 }
615 run_test 11 "Delete all secondary nids from peer (o2ib)"
616
617 test_12() {
618         reinit_dlc || return $?
619
620         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
621 peer:
622     - primary nid: 12.12.12.12@o2ib
623       Multi-Rail: True
624       peer ni:
625         - nid: 12.12.12.12@o2ib
626         - nid: 13.13.13.13@o2ib
627         - nid: 14.13.13.13@o2ib
628         - nid: 14.15.13.13@o2ib
629         - nid: 15.17.1.5@tcp
630         - nid: 15.17.1.10@tcp
631         - nid: 15.17.1.20@tcp
632 EOF
633         append_global_yaml
634         do_lnetctl peer add --prim_nid 12.12.12.12@o2ib \
635                 --nid [13-14/1].[13-15/2].13.13@o2ib,[15-16/3].[17-19/4].[1].[5-20/5]@tcp ||
636                 error "Peer add failed $?"
637         compare_peer_del "12.12.12.12@o2ib" "13.15.13.13@o2ib,15.17.1.15@tcp"
638 }
639 run_test 12 "Delete a secondary nid from peer (tcp and o2ib)"
640
641 test_13() {
642         reinit_dlc || return $?
643
644         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
645 peer:
646     - primary nid: 13.13.13.13@o2ib
647       Multi-Rail: True
648       peer ni:
649         - nid: 13.13.13.13@o2ib
650 EOF
651         append_global_yaml
652         do_lnetctl peer add --prim_nid 13.13.13.13@o2ib \
653                 --nid [14-15].[1-2/1].[1].[100-254/10]@tcp,14.14.[254].14@o2ib ||
654                 error "Peer add failed $?"
655         compare_peer_del "13.13.13.13@o2ib" \
656                 "[14-15].[1-2/1].[1].[100-254/10]@tcp,14.14.[254].14@o2ib"
657 }
658 run_test 13 "Delete all secondary nids from peer (tcp and o2ib)"
659
660 create_nid() {
661         local num="$1"
662         local net="$2"
663
664         if [[ $net =~ gni* ]] || [[ $net =~ kfi* ]]; then
665                 echo "${num}@${net}"
666         else
667                 echo "${num}.${num}.${num}.${num}@${net}"
668         fi
669 }
670
671 create_mr_peer_yaml() {
672         local num_peers="$1"
673         local secondary_nids="$2"
674         local net="$3"
675
676         echo "Generating peer yaml for $num_peers peers with $secondary_nids secondary nids"
677         echo "peer:" >> $TMP/sanity-lnet-$testnum-expected.yaml
678         local i
679         local total_nids=$((num_peers + $((num_peers * secondary_nids))))
680         local created=0
681         local nidnum=1
682         while [[ $created -lt $num_peers ]]; do
683                 local primary=$(create_nid ${nidnum} ${net})
684         cat <<EOF >> $TMP/sanity-lnet-$testnum-expected.yaml
685     - primary nid: $primary
686       Multi-Rail: True
687       peer ni:
688         - nid: $primary
689 EOF
690                 local j
691                 local start=$((nidnum + 1))
692                 local end=$((nidnum + $secondary_nids))
693                 for j in $(seq ${start} ${end}); do
694                         local nid=$(create_nid $j ${net})
695                         echo "        - nid: $nid" >> $TMP/sanity-lnet-$testnum-expected.yaml
696                 done
697                 nidnum=$((end + 1))
698                 ((created++))
699         done
700 }
701
702 test_14() {
703         reinit_dlc || return $?
704
705         echo "Create single peer, single nid, using import"
706         create_mr_peer_yaml 1 0 tcp
707         do_lnetctl import < $TMP/sanity-lnet-$testnum-expected.yaml ||
708                 error "Import failed $?"
709         append_global_yaml
710         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
711         compare_yaml_files
712
713         echo "Delete single peer using import --del"
714         do_lnetctl import --del < $TMP/sanity-lnet-$testnum-expected.yaml ||
715                 error "Import failed $?"
716         rm -f $TMP/sanity-lnet-$testnum-expected.yaml
717         create_base_yaml_file
718         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
719         compare_yaml_files
720 }
721 run_test 14 "import peer create/delete with single nid"
722
723 test_15() {
724         reinit_dlc || return $?
725
726         echo "Create multiple peers, single nid per peer, using import"
727         create_mr_peer_yaml 5 0 o2ib
728         # The ordering of nids for this use-case is non-deterministic, so we
729         # we can't just diff the expected/actual output.
730         do_lnetctl import < $TMP/sanity-lnet-$testnum-expected.yaml ||
731                 error "Import failed $?"
732         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
733         validate_peer_nids 5 0
734
735         echo "Delete multiple peers, single nid per peer, using import --del"
736         do_lnetctl import --del < $TMP/sanity-lnet-$testnum-expected.yaml ||
737                 error "Import failed $?"
738         rm -f $TMP/sanity-lnet-$testnum-expected.yaml
739         create_base_yaml_file
740         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
741         compare_yaml_files
742 }
743 run_test 15 "import multi peer create/delete with single nid per peer"
744
745 test_16() {
746         reinit_dlc || return $?
747
748         echo "Create single peer, multiple nids, using import"
749         create_mr_peer_yaml 1 5 tcp
750         do_lnetctl import < $TMP/sanity-lnet-$testnum-expected.yaml ||
751                 error "Import failed $?"
752         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
753         validate_peer_nids 1 5
754
755         echo "Delete single peer, multiple nids, using import --del"
756         do_lnetctl import --del < $TMP/sanity-lnet-$testnum-expected.yaml ||
757                 error "Import failed $?"
758         rm -f $TMP/sanity-lnet-$testnum-expected.yaml
759         create_base_yaml_file
760         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
761         compare_yaml_files
762 }
763 run_test 16 "import peer create/delete with multiple nids"
764
765 test_17() {
766         reinit_dlc || return $?
767
768         echo "Create multiple peers, multiple nids per peer, using import"
769         create_mr_peer_yaml 5 7 o2ib
770         do_lnetctl import < $TMP/sanity-lnet-$testnum-expected.yaml ||
771                 error "Import failed $?"
772         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
773         validate_peer_nids 5 7
774
775         echo "Delete multiple peers, multiple nids per peer, using import --del"
776         do_lnetctl import --del < $TMP/sanity-lnet-$testnum-expected.yaml ||
777                 error "Import failed $?"
778         rm -f $TMP/sanity-lnet-$testnum-expected.yaml
779         create_base_yaml_file
780         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
781         compare_yaml_files
782 }
783 run_test 17 "import multi peer create/delete with multiple nids"
784
785 test_18a() {
786         reinit_dlc || return $?
787
788         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
789 peer:
790     - primary nid: 1.1.1.1@tcp
791       Multi-Rail: True
792       peer ni:
793         - nid: 1.1.1.1@tcp
794         - nid: 2.2.2.2@tcp
795         - nid: 4.4.4.4@tcp
796         - nid: 3.3.3.3@o2ib
797         - nid: 5@gni
798 EOF
799         echo "Import peer with 5 nids"
800         cat $TMP/sanity-lnet-$testnum-expected.yaml
801         do_lnetctl import < $TMP/sanity-lnet-$testnum-expected.yaml ||
802                 error "Import failed $?"
803         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
804 peer:
805     - primary nid: 1.1.1.1@tcp
806       Multi-Rail: True
807       peer ni:
808         - nid: 2.2.2.2@tcp
809         - nid: 3.3.3.3@o2ib
810         - nid: 5@gni
811 EOF
812         echo "Delete three of the nids"
813         cat $TMP/sanity-lnet-$testnum-expected.yaml
814         do_lnetctl import --del < $TMP/sanity-lnet-$testnum-expected.yaml
815         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
816 peer:
817     - primary nid: 1.1.1.1@tcp
818       Multi-Rail: True
819       peer ni:
820         - nid: 1.1.1.1@tcp
821         - nid: 4.4.4.4@tcp
822 EOF
823         echo "Check peer has expected nids remaining"
824         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
825         append_global_yaml
826         compare_yaml_files
827 }
828 run_test 18a "Delete a subset of nids from a single peer using import --del"
829
830 test_18b() {
831         reinit_dlc || return $?
832
833         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
834 peer:
835     - primary nid: 1.1.1.1@tcp
836       Multi-Rail: True
837       peer ni:
838         - nid: 1.1.1.1@tcp
839         - nid: 2.2.2.2@tcp
840         - nid: 4.4.4.4@tcp
841         - nid: 3.3.3.3@o2ib
842         - nid: 5@gni
843     - primary nid: 6.6.6.6@o2ib
844       Multi-Rail: True
845       peer ni:
846         - nid: 6.6.6.6@o2ib
847         - nid: 7.7.7.7@tcp
848         - nid: 8.8.8.8@tcp
849         - nid: 9.9.9.9@tcp
850         - nid: 10@gni
851 EOF
852         echo "Import two peers with 5 nids each"
853         cat $TMP/sanity-lnet-$testnum-expected.yaml
854         do_lnetctl import < $TMP/sanity-lnet-$testnum-expected.yaml ||
855                 error "Import failed $?"
856         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
857 peer:
858     - primary nid: 1.1.1.1@tcp
859       Multi-Rail: True
860       peer ni:
861         - nid: 2.2.2.2@tcp
862         - nid: 3.3.3.3@o2ib
863         - nid: 5@gni
864     - primary nid: 6.6.6.6@o2ib
865       Multi-Rail: True
866       peer ni:
867         - nid: 7.7.7.7@tcp
868         - nid: 8.8.8.8@tcp
869         - nid: 10@gni
870 EOF
871         echo "Delete three of the nids from each peer"
872         cat $TMP/sanity-lnet-$testnum-expected.yaml
873         do_lnetctl import --del < $TMP/sanity-lnet-$testnum-expected.yaml
874         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
875 peer:
876     - primary nid: 6.6.6.6@o2ib
877       Multi-Rail: True
878       peer ni:
879         - nid: 6.6.6.6@o2ib
880         - nid: 7.7.7.7@tcp
881     - primary nid: 1.1.1.1@tcp
882       Multi-Rail: True
883       peer ni:
884         - nid: 1.1.1.1@tcp
885         - nid: 4.4.4.4@tcp
886 EOF
887         append_global_yaml
888         echo "Check peers have expected nids remaining"
889         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
890         compare_yaml_files
891         validate_peer_nids 2 1
892 }
893 run_test 18b "Delete multiple nids from multiple peers using import --del"
894
895 test_19() {
896         reinit_dlc || return $?
897         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
898 peer:
899     - primary nid: 19@gni
900       Multi-Rail: True
901       peer ni:
902         - nid: 19@gni
903 EOF
904         append_global_yaml
905         compare_peer_add "19@gni"
906 }
907 run_test 19 "Add peer with single nid (gni)"
908
909 test_20() {
910         reinit_dlc || return $?
911         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
912 peer:
913     - primary nid: 20@gni
914       Multi-Rail: True
915       peer ni:
916         - nid: 20@gni
917         - nid: 20.20.20.20@tcp
918         - nid: 20.20.20.20@o2ib
919 EOF
920         append_global_yaml
921         compare_peer_add "20@gni" "20.20.20.20@tcp,20.20.20.20@o2ib"
922 }
923 run_test 20 "Add peer with gni primary and tcp, o2ib secondary"
924
925 test_21() {
926         reinit_dlc || return $?
927         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
928 peer:
929     - primary nid: 21@gni
930       Multi-Rail: True
931       peer ni:
932         - nid: 21@gni
933         - nid: 22@gni
934         - nid: 23@gni
935         - nid: 24@gni
936         - nid: 25@gni
937 EOF
938         append_global_yaml
939         echo "Add peer with nidrange (gni)"
940         compare_peer_add "21@gni" "[22-25]@gni" || error
941         echo "Add peer with nidrange that overlaps primary nid (gni)"
942         compare_peer_add "21@gni" "[21-25]@gni"
943 }
944 run_test 21 "Add peer with nidrange (gni)"
945
946 test_22() {
947         reinit_dlc || return $?
948         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
949 peer:
950     - primary nid: 22@gni
951       Multi-Rail: True
952       peer ni:
953         - nid: 22@gni
954         - nid: 24@gni
955         - nid: 25@gni
956         - nid: 27@gni
957         - nid: 28@gni
958         - nid: 29@gni
959 EOF
960         append_global_yaml
961         do_lnetctl peer add --prim_nid 22@gni --nid [24-29]@gni ||
962                 error "Peer add failed $?"
963         compare_peer_del "22@gni" "26@gni"
964 }
965 run_test 22 "Delete single secondary nid from peer (gni)"
966
967 test_23() {
968         reinit_dlc || return $?
969         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
970 peer:
971     - primary nid: 23@gni
972       Multi-Rail: True
973       peer ni:
974         - nid: 23@gni
975 EOF
976         append_global_yaml
977
978         do_lnetctl peer add --prim_nid 23@gni --nid [25-29]@gni ||
979                 error "Peer add failed $?"
980         compare_peer_del "23@gni" "[25-29]@gni"
981 }
982 run_test 23 "Delete all secondary nids from peer (gni)"
983
984 test_24() {
985         reinit_dlc || return $?
986         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
987 peer:
988     - primary nid: 24@gni
989       Multi-Rail: True
990       peer ni:
991         - nid: 24@gni
992         - nid: 11@gni
993         - nid: 13.13.13.13@o2ib
994         - nid: 14.13.13.13@o2ib
995         - nid: 14.15.13.13@o2ib
996         - nid: 15.17.1.5@tcp
997         - nid: 15.17.1.10@tcp
998         - nid: 15.17.1.20@tcp
999 EOF
1000         append_global_yaml
1001         do_lnetctl peer add --prim_nid 24@gni \
1002                 --nid [13-14/1].[13-15/2].13.13@o2ib,[15-16/3].[17-19/4].[1].[5-20/5]@tcp,[5-12/6]@gni ||
1003                 error "Peer add failed $?"
1004         compare_peer_del "24@gni" "5@gni,13.15.13.13@o2ib,15.17.1.15@tcp"
1005 }
1006 run_test 24 "Delete a secondary nid from peer (tcp, o2ib and gni)"
1007
1008 test_25() {
1009         reinit_dlc || return $?
1010         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
1011 peer:
1012     - primary nid: 25@gni
1013       Multi-Rail: True
1014       peer ni:
1015         - nid: 25@gni
1016 EOF
1017         append_global_yaml
1018         do_lnetctl peer add --prim_nid 25@gni \
1019                 --nid [26-27].[4-10/3].26.26@tcp,26.26.26.26@o2ib,[30-35]@gni ||
1020                 error "Peer add failed $?"
1021         compare_peer_del "25@gni" \
1022                 "[26-27].[4-10/3].26.26@tcp,26.26.26.26@o2ib,[30-35]@gni"
1023 }
1024 run_test 25 "Delete all secondary nids from peer (tcp, gni and o2ib)"
1025
1026 test_26() {
1027         reinit_dlc || return $?
1028
1029         do_lnetctl peer add --prim_nid 1.1.1.1@tcp --lock_prim ||
1030                 error "Peer add with --lock_prim option failed $?"
1031         local peer_state=$($LNETCTL peer show -v 4 --nid 1.1.1.1@tcp |
1032                 awk '/peer state/ {print $NF}')
1033         # This relies on the following peer state definition:
1034         # #define LNET_PEER_LOCK_PRIMARY          BIT(20)
1035         if ((!("$peer_state" & (1 << 20)))); then
1036                 error "Peer state does not have 'locked' bit set: $peer_state"
1037         fi
1038         do_lnetctl peer del --prim_nid 1.1.1.1@tcp ||
1039                 error "Peer del failed $?"
1040         $LNETCTL peer show --nid 1.1.1.1@tcp | grep -q 1.1.1.1@tcp ||
1041                 error "1.1.1.1@tcp is not listed"
1042         do_lnetctl peer del --prim_nid 1.1.1.1@tcp --force ||
1043                 error "Peer del --force failed $?"
1044         do_lnetctl peer show --nid 1.1.1.1@tcp &&
1045                 error "failed to delete 1.1.1.1@tcp"
1046
1047         return 0
1048 }
1049 run_test 26 "Delete peer with primary nid locked"
1050
1051 test_99a() {
1052         reinit_dlc || return $?
1053
1054         echo "Invalid prim_nid - peer add"
1055         do_lnetctl peer add --prim_nid foobar &&
1056                 error "Command should have failed"
1057
1058         echo "Invalid prim_nid - peer del"
1059         do_lnetctl peer del --prim_nid foobar &&
1060                 error "Command should have failed"
1061
1062         echo "Delete non-existing peer"
1063         do_lnetctl peer del --prim_nid 1.1.1.1@o2ib &&
1064                 error "Command should have failed"
1065
1066         echo "Don't provide mandatory argument for peer del"
1067         do_lnetctl peer del --nid 1.1.1.1@tcp &&
1068                 error "Command should have failed"
1069
1070         echo "Don't provide mandatory argument for peer add"
1071         do_lnetctl peer add --nid 1.1.1.1@tcp &&
1072                 error "Command should have failed"
1073
1074         echo "Don't provide mandatory arguments peer add"
1075         do_lnetctl peer add &&
1076                 error "Command should have failed"
1077
1078         echo "Invalid secondary nids"
1079         do_lnetctl peer add --prim_nid 1.1.1.1@tcp --nid foobar &&
1080                 error "Command should have failed"
1081
1082         echo "Exceed max nids per peer"
1083         do_lnetctl peer add --prim_nid 1.1.1.1@tcp --nid 1.1.1.[2-255]@tcp &&
1084                 error "Command should have failed"
1085
1086         echo "Invalid net type"
1087         do_lnetctl peer add --prim_nid 1@foo &&
1088                 error "Command should have failed"
1089
1090         echo "Invalid nid format"
1091         local invalid_nids="1@tcp 1@o2ib 1.1.1.1@gni"
1092
1093         local nid
1094         for nid in ${invalid_nids}; do
1095                 echo "Check invalid primary nid - '$nid'"
1096                 do_lnetctl peer add --prim_nid $nid &&
1097                         error "Command should have failed"
1098         done
1099
1100         local invalid_strs="[2-1]@gni [a-f/x]@gni 256.256.256.256@tcp"
1101         invalid_strs+=" 1.1.1.1.[2-5/f]@tcp 1.]2[.3.4@o2ib"
1102         invalid_strs+="1.[2-4,[5-6],7-8].1.1@tcp foobar"
1103
1104         local nidstr
1105         for nidstr in ${invalid_strs}; do
1106                 echo "Check invalid nidstring - '$nidstr'"
1107                 do_lnetctl peer add --prim_nid 1.1.1.1@tcp --nid $nidstr &&
1108                         error "Command should have failed"
1109         done
1110
1111         echo "Add non-local gateway"
1112         do_lnetctl route add --net tcp --gateway 1@gni &&
1113                 error "Command should have failed"
1114
1115         return 0
1116 }
1117 run_test 99a "Check various invalid inputs to lnetctl peer"
1118
1119 test_99b() {
1120         reinit_dlc || return $?
1121
1122         create_base_yaml_file
1123
1124         cat <<EOF > $TMP/sanity-lnet-$testnum-invalid.yaml
1125 peer:
1126     - primary nid: 99.99.99.99@tcp
1127       Multi-Rail: Foobar
1128       peer ni:
1129         - nid: 99.99.99.99@tcp
1130 EOF
1131         do_lnetctl import < $TMP/sanity-lnet-$testnum-invalid.yaml &&
1132                 error "import should have failed"
1133         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
1134         compare_yaml_files
1135 }
1136 run_test 99b "Invalid value for Multi-Rail in yaml import"
1137
1138 have_interface() {
1139         local if="$1"
1140         local ip=$(ip addr show dev $if | awk '/ inet /{print $2}')
1141         [[ -n $ip ]]
1142 }
1143
1144 add_net() {
1145         local net="$1"
1146         local if="$2"
1147
1148         do_lnetctl net add --net ${net} --if ${if} ||
1149                 error "Failed to add net ${net} on if ${if}"
1150 }
1151
1152 del_net() {
1153         local net="$1"
1154         local if="$2"
1155
1156         do_lnetctl net del --net ${net} --if ${if} ||
1157                 error "Failed to del net ${net} on if ${if}"
1158 }
1159
1160 compare_route_add() {
1161         local rnet="$1"
1162         local gw="$2"
1163
1164         local actual="$TMP/sanity-lnet-$testnum-actual.yaml"
1165
1166         do_lnetctl route add --net ${rnet} --gateway ${gw} ||
1167                 error "route add failed $?"
1168
1169         echo "$LNETCTL export --backup > $actual"
1170
1171         $LNETCTL export --backup > $actual ||
1172                 error "export failed $?"
1173
1174         validate_gateway_nids
1175         return $?
1176 }
1177
1178 append_net_tunables() {
1179         local net=${1:-tcp}
1180
1181         $LNETCTL net show -v --net ${net} | grep -v 'dev cpt' |
1182                 awk '/^\s+tunables:$/,/^\s+CPT:/' >> $TMP/sanity-lnet-$testnum-expected.yaml
1183 }
1184
1185 ROUTERS_REQUIRED=1
1186 ROUTERS=()
1187 declare -A ROUTER_INTERFACES
1188 RPEERS_REQUIRED=1
1189 RPEERS=()
1190 declare -A RPEER_INTERFACES
1191 init_router_test_vars() {
1192         local rnodes_required
1193         ((rnodes_required=ROUTERS_REQUIRED+RPEERS_REQUIRED))
1194         # all remote nodes, including some that may not be used
1195         local rnodes_all=( $(remote_nodes_list) )
1196         [[ -z $rnodes_all || "${#rnodes_all[@]}" -lt $rnodes_required ]] &&
1197                 skip "Need at least $rnodes_required remote nodes" \
1198                         "found \"${rnodes_all[@]}\""
1199
1200         ROUTERS=( "${rnodes_all[@]:0:${ROUTERS_REQUIRED}}" )
1201         RPEERS=( "${rnodes_all[@]:${ROUTERS_REQUIRED}:${RPEERS_REQUIRED}}" )
1202
1203         local rnodes=$(comma_list ${ROUTERS[@]} ${RPEERS[@]})
1204         local all_nodes=$(comma_list ${ROUTERS[@]} ${RPEERS[@]} $HOSTNAME)
1205
1206         do_nodes $rnodes $LUSTRE_RMMOD ||
1207                 error "failed to unload modules"
1208
1209         do_rpc_nodes $rnodes "load_lnet config_on_load=1" ||
1210                 error "Failed to load and configure LNet"
1211
1212         for router in ${ROUTERS[@]}; do
1213                 ROUTER_INTERFACES[$router]=$(do_rpc_nodes --quiet \
1214                                                 $router lnet_if_list)
1215         done
1216
1217         for rpeer in ${RPEERS[@]}; do
1218                 RPEER_INTERFACES[$rpeer]=$(do_rpc_nodes --quiet \
1219                                                 $rpeer lnet_if_list)
1220         done
1221
1222         do_nodes $all_nodes $LUSTRE_RMMOD ||
1223                 error "Failed to unload modules"
1224
1225         [[ ${#INTERFACES[@]} -eq 0 ]] &&
1226                 error "No interfaces configured for local host $HOSTNAME"
1227         for router in ${!ROUTER_INTERFACES[@]}; do
1228                 [[ -z "${ROUTER_INTERFACES[$router]}" ]] &&
1229                         error "No interfaces configured for router $router"
1230         done
1231         for rpeer in ${!RPEER_INTERFACES[@]}; do
1232                 [[ -z "${RPEER_INTERFACES[$rpeer]}" ]] &&
1233                         error "No interfaces configured for remote peer $rpeer"
1234         done
1235
1236         return 0
1237 }
1238
1239 do_net_add() {
1240         local node=$1
1241         local net=$2
1242         local if=$3
1243
1244         do_rpc_nodes $node "$LNETCTL net add --net $net --if $if" ||
1245                 error "add $net on interface $if on node $node failed rc=$?"
1246 }
1247
1248 do_route_add() {
1249         local node=$1
1250         local net=$2
1251         local gw=$3
1252
1253         do_node $node "$LNETCTL route add --net $net --gateway $gw" ||
1254                 error "route add to $net via $gw failed rc=$?"
1255 }
1256
1257 declare -A ROUTER_NIDS
1258 declare -A RPEER_NIDS
1259 LNIDS=()
1260 LOCAL_NET=${NETTYPE}
1261 REMOTE_NET=${NETTYPE}1
1262 setup_router_test() {
1263         local mod_opts="$@"
1264
1265         (( $MDS1_VERSION >= $(version_code 2.15.0) )) ||
1266                 skip "need at least 2.15.0 for load_lnet"
1267
1268         if [[ ${#RPEER_INTERFACES[@]} -eq 0 ]]; then
1269                 init_router_test_vars ||
1270                         return $?
1271         fi
1272
1273         local all_nodes=$(comma_list ${ROUTERS[@]} ${RPEERS[@]} $HOSTNAME)
1274
1275         do_nodes $all_nodes $LUSTRE_RMMOD ||
1276                 error "failed to unload modules"
1277
1278         mod_opts+=" alive_router_check_interval=5"
1279         mod_opts+=" router_ping_timeout=5"
1280         mod_opts+=" large_router_buffers=4"
1281         mod_opts+=" small_router_buffers=8"
1282         mod_opts+=" tiny_router_buffers=16"
1283         do_rpc_nodes $all_nodes load_lnet "${mod_opts}" ||
1284                 error "Failed to load lnet"
1285
1286         do_nodes $all_nodes "$LNETCTL lnet configure" ||
1287                 error "Failed to initialize DLC"
1288
1289         for router in ${!ROUTER_INTERFACES[@]}; do
1290                 local router_interfaces=( ${ROUTER_INTERFACES[$router]} )
1291
1292                 do_net_add $router $LOCAL_NET ${router_interfaces[0]} ||
1293                         return $?
1294                 do_net_add $router $REMOTE_NET ${router_interfaces[0]} ||
1295                         return $?
1296         done
1297
1298         for rpeer in ${!RPEER_INTERFACES[@]}; do
1299                 local rpeer_interfaces=( ${RPEER_INTERFACES[$rpeer]} )
1300
1301                 do_net_add $rpeer $REMOTE_NET ${rpeer_interfaces[0]} ||
1302                         return $?
1303         done
1304
1305         add_net $LOCAL_NET ${INTERFACES[0]} ||
1306                 return $?
1307
1308         for router in ${!ROUTER_INTERFACES[@]}; do
1309                 ROUTER_NIDS[$router]=$(do_node $router $LCTL list_nids
1310                                         2>/dev/null | xargs echo)
1311         done
1312
1313         for rpeer in ${!RPEER_INTERFACES[@]}; do
1314                 RPEER_NIDS[$rpeer]=$(do_node $rpeer $LCTL list_nids
1315                                         2>/dev/null | xargs echo)
1316         done
1317
1318         LNIDS=( $($LCTL list_nids 2>/dev/null | xargs echo) )
1319 }
1320
1321 do_route_del() {
1322         local node=$1
1323         local net=$2
1324         local gw=$3
1325
1326         do_nodesv $node \
1327         'output="$($LNETCTL route show --net $net --gateway $gw 2>/dev/null)"; \
1328                 if [[ "x${lnetctl_text}x" != "xx" ]]; then                     \
1329                                 $LNETCTL route del --net $net --gateway $gw;   \
1330                         else                                                   \
1331                                 exit 0;                                        \
1332                         fi'
1333 }
1334
1335 cleanup_router_test() {
1336         local all_nodes=$(comma_list $HOSTNAME ${ROUTERS[@]} ${RPEERS[@]})
1337
1338         for router in ${!ROUTER_NIDS[@]}; do
1339                 local router_nids=( ${ROUTER_NIDS[$router]} )
1340
1341                 do_route_del $HOSTNAME $REMOTE_NET ${router_nids[0]} ||
1342                         error "Failed to delete $HOSTNAME -> "\
1343                                 "$REMOTE_NET via ${router_nids[0]} route"
1344         done
1345
1346         for router in ${!ROUTER_INTERFACES[@]}; do
1347                 local router_nids=( ${ROUTER_NIDS[$router]} )
1348
1349                 do_route_del $rpeer $LOCAL_NET ${router_nids[1]} ||
1350                         error "Failed to delete $rpeer -> "\
1351                                 "$LOCAL_NET via ${router_nids[1]} route"
1352         done
1353
1354         do_nodes $all_nodes $LUSTRE_RMMOD ||
1355                 error "failed to unload modules"
1356
1357         return 0
1358 }
1359
1360 test_100() {
1361         define_global_yaml
1362         setup_router_test || return $?
1363         local router_nids=( ${ROUTER_NIDS[${ROUTERS[0]}]} )
1364
1365         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
1366 net:
1367     - net type: $LOCAL_NET
1368       local NI(s):
1369         - interfaces:
1370               0: ${INTERFACES[0]}
1371 EOF
1372         append_net_tunables $LOCAL_NET
1373         cat <<EOF >> $TMP/sanity-lnet-$testnum-expected.yaml
1374 route:
1375     - net: $REMOTE_NET
1376       gateway: ${router_nids[0]}
1377       hop: -1
1378       priority: 0
1379       health_sensitivity: 1
1380 peer:
1381     - primary nid: ${router_nids[0]}
1382       Multi-Rail: False
1383       peer ni:
1384         - nid: ${router_nids[0]}
1385 EOF
1386         append_global_yaml
1387         compare_route_add "$REMOTE_NET" "${router_nids[0]}"
1388         cleanup_router_test
1389 }
1390 run_test 100 "Add route with single gw"
1391
1392 ARR_IF0_IP=($(ip -o -4 a s ${INTERFACES[0]} |
1393             awk '{print $4}' | sed 's/\/.*//'))
1394 echo "Total IP for ${INTERFACES[0]} found [${#ARR_IF0_IP[@]}]"
1395 echo "Interface:IP are"
1396 for i in ${ARR_IF0_IP[@]}; do
1397         echo "${INTERFACES[0]}:$i"
1398 done
1399 IF0_IP=${ARR_IF0_IP[0]}
1400 IF0_NET=$(awk -F. '{print $1"."$2"."$3}'<<<"${IF0_IP}")
1401 IF0_HOSTNUM=$(awk -F. '{print $4}'<<<"${IF0_IP}")
1402 if (((IF0_HOSTNUM + 5) > 254)); then
1403         GW_HOSTNUM=1
1404 else
1405         GW_HOSTNUM=$((IF0_HOSTNUM + 1))
1406 fi
1407 GW_NID="${IF0_NET}.${GW_HOSTNUM}@${NETTYPE}"
1408 echo "Using GW_NID:$GW_NID"
1409
1410 test_101() {
1411         [[ -n $ARR_IF0_IP ]] || skip "Need IPv4 NIDs"
1412
1413         reinit_dlc || return $?
1414
1415         add_net "${NETTYPE}" "${INTERFACES[0]}"
1416
1417         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
1418 net:
1419     - net type: ${NETTYPE}
1420       local NI(s):
1421         - interfaces:
1422               0: ${INTERFACES[0]}
1423 EOF
1424         append_net_tunables ${NETTYPE}
1425
1426         echo "route:" >> $TMP/sanity-lnet-$testnum-expected.yaml
1427         for i in $(seq $GW_HOSTNUM $((GW_HOSTNUM + 4))); do
1428                 cat <<EOF >> $TMP/sanity-lnet-$testnum-expected.yaml
1429     - net: ${REMOTE_NET}
1430       gateway: ${IF0_NET}.${i}@${NETTYPE}
1431       hop: -1
1432       priority: 0
1433       health_sensitivity: 1
1434 EOF
1435         done
1436
1437         echo "peer:" >> $TMP/sanity-lnet-$testnum-expected.yaml
1438         for i in $(seq $GW_HOSTNUM $((GW_HOSTNUM + 4))); do
1439                 cat <<EOF >> $TMP/sanity-lnet-$testnum-expected.yaml
1440     - primary nid: ${IF0_NET}.${i}@${NETTYPE}
1441       Multi-Rail: False
1442       peer ni:
1443         - nid: ${IF0_NET}.${i}@${NETTYPE}
1444 EOF
1445         done
1446         append_global_yaml
1447
1448         local gw="${IF0_NET}.[$GW_HOSTNUM-$((GW_HOSTNUM + 4))]@${NETTYPE}"
1449
1450         compare_route_add "${REMOTE_NET}" "${gw}"
1451 }
1452 run_test 101 "Add route with multiple gw"
1453
1454 compare_route_del() {
1455         local rnet="$1"
1456         local gw="$2"
1457
1458         local actual="$TMP/sanity-lnet-$testnum-actual.yaml"
1459
1460         do_lnetctl route del --net ${rnet} --gateway ${gw} ||
1461                 error "route del failed $?"
1462         $LNETCTL export --backup > $actual ||
1463                 error "export failed $?"
1464         validate_gateway_nids
1465 }
1466
1467 test_102() {
1468         define_global_yaml
1469         setup_router_test || return $?
1470         local router_nids=( ${ROUTER_NIDS[${ROUTERS[0]}]} )
1471
1472         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-expected.yaml
1473
1474         do_lnetctl route add --net $REMOTE_NET --gateway ${router_nids[0]} ||
1475                 error "route add failed $?"
1476
1477         compare_route_del "$REMOTE_NET" "${router_nids[0]}"
1478         # Routes already deleted so don't call cleanup_router_test
1479 }
1480 run_test 102 "Delete route with single gw"
1481
1482 NUM_NID_EXPR='[103-120/4]'
1483 test_103() {
1484         [[ -n $ARR_IF0_IP ]] || skip "Need IPv4 NIDs"
1485
1486         reinit_dlc || return $?
1487         add_net "${NETTYPE}" "${INTERFACES[0]}"
1488         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-expected.yaml
1489
1490         local nid_expr
1491
1492         if [[ $NETTYPE =~ (tcp|o2ib)[0-9]* ]]; then
1493                 nid_expr="${IF0_NET}.[$GW_HOSTNUM-$((GW_HOSTNUM+5))/2]"
1494         else
1495                 nid_expr="${NUM_NID_EXPR}"
1496         fi
1497
1498         do_lnetctl route add --net ${NETTYPE}103 \
1499                 --gateway ${nid_expr}@${NETTYPE} ||
1500                 error "route add failed $?"
1501         compare_route_del "${NETTYPE}103" "${nid_expr}@${NETTYPE}"
1502 }
1503 run_test 103 "Delete route with multiple gw"
1504
1505 test_104() {
1506         local tyaml="$TMP/sanity-lnet-$testnum-expected.yaml"
1507
1508         reinit_dlc || return $?
1509
1510         # Default value is '3'
1511         local val=$($LNETCTL global show | awk '/response_tracking/{print $NF}')
1512         [[ $val -ne 3 ]] &&
1513                 error "Expect 3 found $val"
1514
1515         echo "Set < 0;  Should fail"
1516         do_lnetctl set response_tracking -1 &&
1517                 error "should have failed $?"
1518
1519         reinit_dlc || return $?
1520         cat <<EOF > $tyaml
1521 global:
1522     response_tracking: -10
1523 EOF
1524         do_lnetctl import < $tyaml &&
1525                 error "should have failed $?"
1526
1527         echo "Check valid values; Should succeed"
1528         local i
1529         for ((i = 0; i < 4; i++)); do
1530                 reinit_dlc || return $?
1531                 do_lnetctl set response_tracking $i ||
1532                         error "should have succeeded $?"
1533                 $LNETCTL global show | grep -q "response_tracking: $i" ||
1534                         error "Failed to set response_tracking to $i"
1535                 reinit_dlc || return $?
1536                 cat <<EOF > $tyaml
1537 global:
1538     response_tracking: $i
1539 EOF
1540                 do_lnetctl import < $tyaml ||
1541                         error "should have succeeded $?"
1542                 $LNETCTL global show | grep -q "response_tracking: $i" ||
1543                         error "Failed to set response_tracking to $i"
1544         done
1545
1546         reinit_dlc || return $?
1547         echo "Set > 3; Should fail"
1548         do_lnetctl set response_tracking 4 &&
1549                 error "should have failed $?"
1550
1551         reinit_dlc || return $?
1552         cat <<EOF > $tyaml
1553 global:
1554     response_tracking: 10
1555 EOF
1556         do_lnetctl import < $tyaml &&
1557                 error "should have failed $?"
1558         return 0
1559 }
1560 run_test 104 "Set/check response_tracking param"
1561
1562 test_105() {
1563         define_global_yaml
1564         setup_router_test || return $?
1565         local router_nids=( ${ROUTER_NIDS[${ROUTERS[0]}]} )
1566
1567         do_lnetctl route add --net $REMOTE_NET --gateway ${router_nids[0]} ||
1568                 error "route add failed $?"
1569         do_lnetctl peer add --prim ${router_nids[0]} &&
1570                 error "peer add should fail"
1571
1572         cleanup_router_test
1573 }
1574 run_test 105 "Adding duplicate GW peer should fail"
1575
1576 test_106() {
1577         define_global_yaml
1578         setup_router_test || return $?
1579         local router_nids=( ${ROUTER_NIDS[${ROUTERS[0]}]} )
1580
1581         do_lnetctl route add --net $REMOTE_NET --gateway ${router_nids[0]} ||
1582                 error "route add failed $?"
1583         do_lnetctl peer del --prim ${router_nids[0]} &&
1584                 error "peer del should fail"
1585
1586         cleanup_router_test
1587 }
1588 run_test 106 "Deleting GW peer should fail"
1589
1590 test_107() {
1591         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
1592
1593         cleanup_netns || error "Failed to cleanup netns before test execution"
1594         cleanup_lnet || error "Failed to unload modules before test execution"
1595
1596         setup_fakeif || error "Failed to add fake IF"
1597         have_interface "$FAKE_IF" ||
1598                 error "Expect $FAKE_IF configured but not found"
1599
1600         reinit_dlc || return $?
1601
1602         add_net "tcp" "${INTERFACES[0]}" || return $?
1603         add_net "tcp" "$FAKE_IF" || return $?
1604
1605         del_net "tcp" "$FAKE_IF" || return $?
1606
1607         cleanup_fakeif
1608         cleanup_lnet
1609         setup_netns
1610 }
1611 run_test 107 "Deleting extra interface doesn't crash node"
1612
1613 test_108() {
1614         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
1615
1616         cleanup_netns || error "Failed to cleanup netns before test execution"
1617         cleanup_lnet || error "Failed to unload modules before test execution"
1618
1619         setup_fakeif || error "Failed to add fake IF"
1620         have_interface "$FAKE_IF" ||
1621                 error "Expect $FAKE_IF configured but not found"
1622
1623         reinit_dlc || return $?
1624
1625         add_net "tcp" "${INTERFACES[0]}" || return $?
1626         $LNETCTL net show > $TMP/sanity-lnet-$testnum-expected.yaml
1627         add_net "tcp" "$FAKE_IF" || return $?
1628
1629         cat <<EOF >> $TMP/sanity-lnet-$testnum-expected.yaml
1630       -     nid: ${FAKE_IP}@tcp
1631             status: up
1632             interfaces:
1633                   0: ${FAKE_IF}
1634 EOF
1635         $LNETCTL net show > $TMP/sanity-lnet-$testnum-actual.yaml
1636         compare_yaml_files || error "not all interfaces were setup"
1637
1638         cleanup_fakeif
1639         cleanup_lnet
1640         setup_netns
1641
1642         return 0
1643 }
1644 run_test 108 "Check Multi-Rail setup"
1645
1646 test_109() {
1647         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
1648
1649         cleanup_netns || error "Failed to cleanup netns before test execution"
1650         cleanup_lnet || error "Failed to unload modules before test execution"
1651
1652         setup_fakeif || error "Failed to add fake IF"
1653         have_interface "$FAKE_IF" ||
1654                 error "Expect $FAKE_IF configured but not found"
1655
1656         FAKE_IF_ALIAS="${FAKE_IF}"
1657         FAKE_IF_ALIAS+=":0"
1658
1659         ifconfig "$FAKE_IF_ALIAS" "$FAKE_IP_ALIAS" up ||
1660                 error "Failed to add fake IF alias"
1661
1662         reinit_dlc || return $?
1663
1664         # add interface with longer name first
1665         add_net "tcp" "$FAKE_IF_ALIAS" || return $?
1666         add_net "tcp" "$FAKE_IF" || return $?
1667
1668         del_net "tcp" "$FAKE_IF" || return $?
1669         del_net "tcp" "$FAKE_IF_ALIAS" || return $?
1670
1671         # add interface with shorter name first
1672         add_net "tcp" "$FAKE_IF" || return $?
1673         add_net "tcp" "$FAKE_IF_ALIAS" || return $?
1674
1675         ifconfig "$FAKE_IF_ALIAS" "$FAKE_IP_ALIAS" down ||
1676                 error "Failed to clean up fake IF alias"
1677
1678         cleanup_fakeif
1679         cleanup_lnet
1680         setup_netns
1681 }
1682 run_test 109 "Add NI using a network interface alias (LU-16859)"
1683
1684 test_110() {
1685         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
1686
1687         cleanup_netns || error "Failed to cleanup netns before test execution"
1688         cleanup_lnet || error "Failed to unload modules before test execution"
1689
1690         configure_dlc || error "Failed to configure DLC rc = $?"
1691
1692         LOCAL_ADDR_LIST=$(local_addr_list)
1693         set -- $LOCAL_ADDR_LIST
1694         do_lnetctl net add --nid $2@tcp ||
1695                 error "Failed to add net tcp for IP $2@tcp"
1696
1697         $LNETCTL net show --net tcp | grep -q "nid: $2@tcp" ||
1698                 error "Failed to configure $2@tcp"
1699
1700         do_lnetctl net del --nid $2@tcp ||
1701                 error "Failed to del net tcp for IP $2@tcp"
1702
1703         $LNETCTL net show | grep -q "nid: $2@tcp"&&
1704                 error "$2@tcp should have been deleted"
1705
1706         cleanup_lnet
1707         setup_netns
1708 }
1709 run_test 110 "Add NI using a specific TCP / IP address"
1710
1711 test_111() {
1712         [[ $(uname -r | grep "3.10") ]] &&
1713                 skip "Unsupported on RHEL7"
1714
1715         reinit_dlc || return $?
1716         add_net "${NETTYPE}" "${INTERFACES[0]}"
1717
1718         for index in {2..500}
1719         do
1720                 do_lnetctl route add --net ${NETTYPE}${index} --gateway ${GW_NID}
1721         done
1722         do_lnetctl route show || return $?
1723 }
1724 run_test 111 "Test many routes"
1725
1726 test_200() {
1727         [[ ${NETTYPE} == tcp* ]] ||
1728                 skip "Need tcp NETTYPE"
1729         cleanup_lnet || exit 1
1730         load_lnet "networks=\"\""
1731         do_ns $LNETCTL lnet configure --all || exit 1
1732         $LNETCTL net show --net tcp | grep -q "nid: ${FAKE_IP}@tcp$"
1733 }
1734 run_test 200 "load lnet w/o module option, configure in a non-default namespace"
1735
1736 test_201() {
1737         [[ ${NETTYPE} == tcp* ]] ||
1738                 skip "Need tcp NETTYPE"
1739         cleanup_lnet || exit 1
1740         load_lnet "networks=tcp($FAKE_IF)"
1741         do_ns $LNETCTL lnet configure --all || exit 1
1742         $LNETCTL net show --net tcp | grep -q "nid: ${FAKE_IP}@tcp$"
1743 }
1744 run_test 201 "load lnet using networks module options in a non-default namespace"
1745
1746 test_202() {
1747         [[ ${NETTYPE} == tcp* ]] ||
1748                 skip "Need tcp NETTYPE"
1749         cleanup_lnet || exit 1
1750         load_lnet "networks=\"\" ip2nets=\"tcp0($FAKE_IF) ${FAKE_IP}\""
1751         do_ns $LNETCTL lnet configure --all || exit 1
1752         $LNETCTL net show | grep -q "nid: ${FAKE_IP}@tcp$"
1753 }
1754 run_test 202 "load lnet using ip2nets in a non-default namespace"
1755
1756
1757 ### Add the interfaces in the target namespace
1758
1759 test_203() {
1760         [[ ${NETTYPE} == tcp* ]] ||
1761                 skip "Need tcp NETTYPE"
1762         cleanup_lnet || exit 1
1763         load_lnet
1764         do_lnetctl lnet configure || exit 1
1765         do_ns $LNETCTL net add --net tcp0 --if $FAKE_IF
1766 }
1767 run_test 203 "add a network using an interface in the non-default namespace"
1768
1769 LNET_PARAMS_FILE="$TMP/$TESTSUITE.parameters"
1770 function save_lnet_params() {
1771         $LNETCTL global show | egrep -v '^global:$' |
1772                                sed 's/://' > $LNET_PARAMS_FILE
1773 }
1774
1775 function restore_lnet_params() {
1776         local param value
1777         while read param value; do
1778                 [[ $param == max_intf ]] && continue
1779                 [[ $param == lnd_timeout ]] && continue
1780                 $LNETCTL set ${param} ${value} ||
1781                         error "Failed to restore ${param} to ${value}"
1782         done < $LNET_PARAMS_FILE
1783 }
1784
1785 function lnet_health_pre() {
1786         save_lnet_params
1787
1788         # Lower transaction timeout to speed up test execution
1789         $LNETCTL set transaction_timeout 10 ||
1790                 error "Failed to set transaction_timeout $?"
1791
1792         RETRY_PARAM=$($LNETCTL global show | awk '/retry_count/{print $NF}')
1793         RSND_PRE=$($LNETCTL stats show | awk '/resend_count/{print $NF}')
1794         LO_HVAL_PRE=$($LNETCTL net show -v 2 | awk '/health value/{print $NF}' |
1795                       xargs echo | sed 's/ /+/g' | bc -l)
1796
1797         RMT_HVAL_PRE=$($LNETCTL peer show --nid ${RNIDS[0]} -v 2 2>/dev/null |
1798                        awk '/health value/{print $NF}' | xargs echo |
1799                        sed 's/ /+/g' | bc -l)
1800
1801         # Might not have any peers so initialize to zero.
1802         RMT_HVAL_PRE=${RMT_HVAL_PRE:-0}
1803
1804         return 0
1805 }
1806
1807 function lnet_health_post() {
1808         RSND_POST=$($LNETCTL stats show | awk '/resend_count/{print $NF}')
1809         LO_HVAL_POST=$($LNETCTL net show -v 2 |
1810                        awk '/health value/{print $NF}' |
1811                        xargs echo | sed 's/ /+/g' | bc -l)
1812
1813         RMT_HVAL_POST=$($LNETCTL peer show --nid ${RNIDS[0]} -v 2 2>/dev/null |
1814                         awk '/health value/{print $NF}' | xargs echo |
1815                         sed 's/ /+/g' | bc -l)
1816
1817         # Might not have any peers so initialize to zero.
1818         RMT_HVAL_POST=${RMT_HVAL_POST:-0}
1819
1820         ${VERBOSE} &&
1821         echo "Pre resends: $RSND_PRE" &&
1822         echo "Post resends: $RSND_POST" &&
1823         echo "Resends delta: $((RSND_POST - RSND_PRE))" &&
1824         echo "Pre local health: $LO_HVAL_PRE" &&
1825         echo "Post local health: $LO_HVAL_POST" &&
1826         echo "Pre remote health: $RMT_HVAL_PRE" &&
1827         echo "Post remote health: $RMT_HVAL_POST"
1828
1829         restore_lnet_params
1830
1831         do_lnetctl peer set --health 1000 --all
1832         do_lnetctl net set --health 1000 --all
1833
1834         return 0
1835 }
1836
1837 function check_no_resends() {
1838         echo "Check that no resends took place"
1839         [[ $RSND_POST -ne $RSND_PRE ]] &&
1840                 error "Found resends: $RSND_POST != $RSND_PRE"
1841
1842         return 0
1843 }
1844
1845 function check_resends() {
1846         local delta=$((RSND_POST - RSND_PRE))
1847
1848         echo "Check that $RETRY_PARAM resends took place"
1849         [[ $delta -ne $RETRY_PARAM ]] &&
1850                 error "Expected $RETRY_PARAM resends found $delta"
1851
1852         return 0
1853 }
1854
1855 function check_no_local_health() {
1856         echo "Check that local NI health is unchanged"
1857         [[ $LO_HVAL_POST -ne $LO_HVAL_PRE ]] &&
1858                 error "Local health changed: $LO_HVAL_POST != $LO_HVAL_PRE"
1859
1860         return 0
1861 }
1862
1863 function check_local_health() {
1864         echo "Check that local NI health has been changed"
1865         [[ $LO_HVAL_POST -eq $LO_HVAL_PRE ]] &&
1866                 error "Local health unchanged: $LO_HVAL_POST == $LO_HVAL_PRE"
1867
1868         return 0
1869 }
1870
1871 function check_no_remote_health() {
1872         echo "Check that remote NI health is unchanged"
1873         [[ $RMT_HVAL_POST -ne $RMT_HVAL_PRE ]] &&
1874                 error "Remote health changed: $RMT_HVAL_POST != $RMT_HVAL_PRE"
1875
1876         return 0
1877 }
1878
1879 function check_remote_health() {
1880         echo "Check that remote NI health has been changed"
1881         [[ $RMT_HVAL_POST -eq $RMT_HVAL_PRE ]] &&
1882                 error "Remote health unchanged: $RMT_HVAL_POST == $RMT_HVAL_PRE"
1883
1884         return 0
1885 }
1886
1887 RNODE=""
1888 RLOADED=false
1889 NET_DEL_ARGS=""
1890 RNIDS=( )
1891 LNIDS=( )
1892 setup_health_test() {
1893         local need_mr=$1
1894         local rc=0
1895
1896         [[ ${NETTYPE} == kfi* ]] && skip "kfi doesn't support drop rules"
1897
1898         local rnodes=$(remote_nodes_list)
1899         [[ -z $rnodes ]] && skip "Need at least 1 remote node"
1900
1901         cleanup_lnet || error "Failed to cleanup before test execution"
1902
1903         # Loading modules should configure LNet with the appropriate
1904         # test-framework configuration
1905         load_lnet "config_on_load=1" || error "Failed to load modules"
1906
1907         LNIDS=( $($LCTL list_nids | xargs echo) )
1908
1909         RNODE=$(awk '{print $1}' <<<$rnodes)
1910         RNIDS=( $(do_node $RNODE $LCTL list_nids | xargs echo) )
1911
1912         if [[ -z ${RNIDS[@]} ]]; then
1913                 do_rpc_nodes $RNODE load_lnet "config_on_load=1"
1914                 RLOADED=true
1915                 RNIDS=( $(do_node $RNODE $LCTL list_nids | xargs echo) )
1916         fi
1917
1918         [[ ${#LNIDS[@]} -lt 1 ]] &&
1919                 error "No NIDs configured for local host $HOSTNAME"
1920         [[ ${#RNIDS[@]} -lt 1 ]] &&
1921                 error "No NIDs configured for remote host $RNODE"
1922
1923         # Ensure all peer NIs are local (i.e. non-routed config)
1924         local rnid rnet lnid lnet
1925
1926         for rnid in ${RNIDS[@]}; do
1927                 rnet=${rnid##*@}
1928                 for lnid in ${LNIDS[@]}; do
1929                         lnet=${lnid##*@}
1930                         [[ ${lnet} == ${rnet} ]] &&
1931                                 break
1932                 done
1933                 [[ ${lnet} != ${rnet} ]] &&
1934                         skip "Need non-routed configuration"
1935         done
1936
1937         do_lnetctl discover ${RNIDS[0]} ||
1938                 error "Unable to discover ${RNIDS[0]}"
1939
1940         local mr=$($LNETCTL peer show --nid ${RNIDS[0]} |
1941                    awk '/Multi-Rail/{print $NF}')
1942
1943         if ${need_mr} && [[ $mr == False ]]; then
1944                 cleanup_health_test || return $?
1945                 skip "Need MR peer"
1946         fi
1947
1948         if ( ! ${need_mr} && [[ ${#RNIDS[@]} -gt 1 ]] ) ||
1949            ( ! ${need_mr} && [[ ${#LNIDS[@]} -gt 1 ]] ); then
1950                 cleanup_health_test || return $?
1951                 skip "Need SR peer"
1952         fi
1953
1954         if ${need_mr} && [[ ${#RNIDS[@]} -lt 2 ]]; then
1955                 # Add a second, reachable NID to rnode.
1956                 local net=${RNIDS[0]}
1957
1958                 net="${net//*@/}1"
1959
1960                 local if=$(do_rpc_nodes --quiet $RNODE lnet_if_list)
1961                 [[ -z $if ]] &&
1962                         error "Failed to determine interface for $RNODE"
1963
1964                 do_rpc_nodes $RNODE "$LNETCTL lnet configure"
1965                 do_rpc_nodes $RNODE "$LNETCTL net add --net $net --if $if" ||
1966                         rc=$?
1967                 if [[ $rc -ne 0 ]]; then
1968                         error "Failed to add interface to $RNODE rc=$?"
1969                 else
1970                         RNIDS[1]="${RNIDS[0]}1"
1971                         NET_DEL_ARGS="--net $net --if $if"
1972                 fi
1973         fi
1974
1975         if ${need_mr} && [[ ${#LNIDS[@]} -lt 2 ]]; then
1976                 local net=${LNIDS[0]}
1977                 net="${net//*@/}1"
1978
1979                 do_lnetctl lnet configure &&
1980                         do_lnetctl net add --net $net --if ${INTERFACES[0]} ||
1981                         rc=$?
1982                 if [[ $rc -ne 0 ]]; then
1983                         error "Failed to add interface rc=$?"
1984                 else
1985                         LNIDS[1]="${LNIDS[0]}1"
1986                 fi
1987         fi
1988
1989         $LNETCTL net show
1990
1991         $LNETCTL peer show -v 2 | egrep -e nid -e health
1992
1993         $LCTL set_param debug=+net
1994
1995         return 0
1996
1997 }
1998
1999 cleanup_health_test() {
2000         local rc=0
2001
2002         if [[ -n $NET_DEL_ARGS ]]; then
2003                 do_rpc_nodes $RNODE \
2004                         "$LNETCTL net del $NET_DEL_ARGS" ||
2005                         rc=$((rc + $?))
2006                 NET_DEL_ARGS=""
2007         fi
2008
2009         unload_modules || rc=$?
2010
2011         if $RLOADED; then
2012                 do_rpc_nodes $RNODE unload_modules_local ||
2013                         rc=$((rc + $?))
2014                 RLOADED=false
2015         fi
2016
2017         [[ $rc -ne 0 ]] &&
2018                 error "Failed cleanup"
2019
2020         return $rc
2021 }
2022
2023 add_health_test_drop_rules() {
2024         local args="-m GET -r 1 -e ${1}"
2025         local src dst
2026
2027         for src in "${LNIDS[@]}"; do
2028                 for dst in "${RNIDS[@]}" "${LNIDS[@]}"; do
2029                         $LCTL net_drop_add -s $src -d $dst ${args} ||
2030                                 error "Failed to add drop rule $src $dst $args"
2031                 done
2032         done
2033 }
2034
2035 do_lnet_health_ping_test() {
2036         local hstatus="$1"
2037
2038         echo "Simulate $hstatus"
2039
2040         lnet_health_pre || return $?
2041
2042         add_health_test_drop_rules ${hstatus}
2043         do_lnetctl ping ${RNIDS[0]} &&
2044                 error "Should have failed"
2045
2046         lnet_health_post
2047
2048         $LCTL net_drop_del -a
2049
2050         return 0
2051 }
2052
2053 # See lnet/lnet/lib-msg.c:lnet_health_check()
2054 LNET_LOCAL_RESEND_STATUSES="local_interrupt local_dropped local_aborted"
2055 LNET_LOCAL_RESEND_STATUSES+=" local_no_route local_timeout"
2056 LNET_LOCAL_NO_RESEND_STATUSES="local_error"
2057 test_204() {
2058         setup_health_test false || return $?
2059
2060         local hstatus
2061         for hstatus in ${LNET_LOCAL_RESEND_STATUSES} \
2062                        ${LNET_LOCAL_NO_RESEND_STATUSES}; do
2063                 do_lnet_health_ping_test "${hstatus}" || return $?
2064                 check_no_resends || return $?
2065                 check_no_local_health || return $?
2066         done
2067
2068         cleanup_health_test || return $?
2069
2070         return 0
2071 }
2072 run_test 204 "Check no health or resends for single-rail local failures"
2073
2074 test_205() {
2075         (( $MDS1_VERSION >= $(version_code 2.14.58) )) ||
2076                 skip "need at least 2.14.58"
2077
2078         setup_health_test true || return $?
2079
2080         local hstatus
2081         for hstatus in ${LNET_LOCAL_RESEND_STATUSES}; do
2082                 do_lnet_health_ping_test "${hstatus}" || return $?
2083                 check_resends || return $?
2084                 check_local_health || return $?
2085         done
2086
2087         for hstatus in ${LNET_LOCAL_NO_RESEND_STATUSES}; do
2088                 do_lnet_health_ping_test "${hstatus}" || return $?
2089                 check_no_resends || return $?
2090                 check_local_health || return $?
2091         done
2092
2093         cleanup_health_test || return $?
2094
2095         return 0
2096 }
2097 run_test 205 "Check health and resends for multi-rail local failures"
2098
2099 # See lnet/lnet/lib-msg.c:lnet_health_check()
2100 LNET_REMOTE_RESEND_STATUSES="remote_dropped"
2101 LNET_REMOTE_NO_RESEND_STATUSES="remote_error remote_timeout"
2102 test_206() {
2103         setup_health_test false || return $?
2104
2105         local hstatus
2106         for hstatus in ${LNET_REMOTE_RESEND_STATUSES} \
2107                        ${LNET_REMOTE_NO_RESEND_STATUSES}; do
2108                 do_lnet_health_ping_test "${hstatus}" || return $?
2109                 check_no_resends || return $?
2110                 check_no_local_health || return $?
2111                 check_no_remote_health || return $?
2112         done
2113
2114         cleanup_health_test || return $?
2115
2116         return 0
2117 }
2118 run_test 206 "Check no health or resends for single-rail remote failures"
2119
2120 test_207() {
2121         (( $MDS1_VERSION >= $(version_code 2.14.58) )) ||
2122                 skip "need at least 2.14.58"
2123
2124         setup_health_test true || return $?
2125
2126         local hstatus
2127         for hstatus in ${LNET_REMOTE_RESEND_STATUSES}; do
2128                 do_lnet_health_ping_test "${hstatus}" || return $?
2129                 check_resends || return $?
2130                 check_no_local_health || return $?
2131                 check_remote_health || return $?
2132                 do_lnetctl peer set --health 1000 --all ||
2133                         error "Unable to reset health rc=$?"
2134         done
2135         for hstatus in ${LNET_REMOTE_NO_RESEND_STATUSES}; do
2136                 do_lnet_health_ping_test "${hstatus}" || return $?
2137                 check_no_resends || return $?
2138                 check_no_local_health || return $?
2139                 check_remote_health || return $?
2140                 do_lnetctl peer set --health 1000 --all ||
2141                         error "Unable to reset health rc=$?"
2142         done
2143
2144         cleanup_health_test || return $?
2145
2146         return 0
2147 }
2148 run_test 207 "Check health and resends for multi-rail remote errors"
2149
2150 test_208_load_and_check_lnet() {
2151         local ip2nets="$1"
2152         local p_nid="$2"
2153         local s_nid="$3"
2154         local num_expected=1
2155
2156         load_lnet "networks=\"\" ip2nets=\"${ip2nets_str}\""
2157
2158         $LCTL net up ||
2159                 error "Failed to load LNet with ip2nets \"${ip2nets_str}\""
2160
2161         [[ -n $s_nid ]] &&
2162                 num_expected=2
2163
2164         declare -a nids
2165         nids=( $($LCTL list_nids) )
2166
2167         [[ ${#nids[@]} -ne ${num_expected} ]] &&
2168                 error "Expect ${num_expected} NIDs found ${#nids[@]}"
2169
2170         [[ ${nids[0]} == ${p_nid} ]] ||
2171                 error "Expect NID \"${p_nid}\" found \"${nids[0]}\""
2172
2173         [[ -n $s_nid ]] && [[ ${nids[1]} != ${s_nid} ]] &&
2174                 error "Expect second NID \"${s_nid}\" found \"${nids[1]}\""
2175
2176         $LCTL net down &>/dev/null
2177         cleanup_lnet
2178 }
2179
2180 test_208() {
2181         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
2182
2183         cleanup_netns || error "Failed to cleanup netns before test execution"
2184         cleanup_lnet || error "Failed to unload modules before test execution"
2185         setup_fakeif || error "Failed to add fake IF"
2186
2187         have_interface "$FAKE_IF" ||
2188                 error "Expect $FAKE_IF configured but not found"
2189
2190         local if0_ip=$(ip --oneline addr show dev ${INTERFACES[0]} |
2191                        awk '/inet /{print $4}' |
2192                        sed 's:/.*::')
2193         if0_ip=($(echo "${if0_ip[@]}" | tr ' ' '\n' | uniq | tr '\n' ' '))
2194         local ip2nets_str="tcp(${INTERFACES[0]}) $if0_ip"
2195
2196         echo "Configure single NID \"$ip2nets_str\""
2197         test_208_load_and_check_lnet "${ip2nets_str}" "${if0_ip}@tcp"
2198
2199         ip2nets_str="tcp(${INTERFACES[0]}) $if0_ip; tcp1($FAKE_IF) $FAKE_IP"
2200         echo "Configure two NIDs; two NETs \"$ip2nets_str\""
2201         test_208_load_and_check_lnet "${ip2nets_str}" "${if0_ip}@tcp" \
2202                                      "${FAKE_IP}@tcp1"
2203
2204         ip2nets_str="tcp(${INTERFACES[0]}) $if0_ip; tcp($FAKE_IF) $FAKE_IP"
2205         echo "Configure two NIDs; one NET \"$ip2nets_str\""
2206         test_208_load_and_check_lnet "${ip2nets_str}" "${if0_ip}@tcp" \
2207                                      "${FAKE_IP}@tcp"
2208         local addr1=( ${if0_ip//./ } )
2209         local addr2=( ${FAKE_IP//./ } )
2210         local range="[${addr1[0]},${addr2[0]}]"
2211
2212         local i
2213         for i in $(seq 1 3); do
2214                 range+=".[${addr1[$i]},${addr2[$i]}]"
2215         done
2216         ip2nets_str="tcp(${INTERFACES[0]},${FAKE_IF}) ${range}"
2217
2218         echo "Configured two NIDs; one NET alt syntax \"$ip2nets_str\""
2219         test_208_load_and_check_lnet "${ip2nets_str}" "${if0_ip}@tcp" \
2220                                      "${FAKE_IP}@tcp"
2221
2222         cleanup_fakeif
2223
2224         echo "alt syntax with missing IF \"$ip2nets_str\""
2225         load_lnet "networks=\"\" ip2nets=\"${ip2nets_str}\""
2226
2227         echo "$LCTL net up should fail"
2228         $LCTL net up &&
2229                 error "LNet bring up should have failed"
2230
2231         cleanup_lnet
2232 }
2233 run_test 208 "Test various kernel ip2nets configurations"
2234
2235 test_209() {
2236         (( $MDS1_VERSION >= $(version_code 2.14.58) )) ||
2237                 skip "need at least 2.14.58"
2238
2239         setup_health_test false || return $?
2240
2241         echo "Simulate network_timeout w/SR config"
2242         lnet_health_pre
2243
2244         add_health_test_drop_rules network_timeout
2245
2246         do_lnetctl discover ${RNIDS[0]} &&
2247                 error "Should have failed"
2248
2249         lnet_health_post
2250
2251         check_no_resends || return $?
2252         check_no_local_health || return $?
2253         check_no_remote_health || return $?
2254
2255         cleanup_health_test || return $?
2256
2257         setup_health_test true || return $?
2258
2259         echo "Simulate network_timeout w/MR config"
2260
2261         lnet_health_pre
2262
2263         add_health_test_drop_rules network_timeout
2264
2265         do_lnetctl discover ${RNIDS[0]} &&
2266                 error "Should have failed"
2267
2268         lnet_health_post
2269
2270         check_no_resends || return $?
2271         check_local_health || return $?
2272         check_remote_health || return $?
2273
2274         cleanup_health_test || return $?
2275
2276         return 0
2277 }
2278 run_test 209 "Check health, but not resends, for network timeout"
2279
2280 check_nid_in_recovq() {
2281         local queue="$1"
2282         local nid="$2"
2283         local expect="$3"
2284         local max_wait="${4:-10}"
2285         local rc=0
2286
2287         (($expect == 0)) &&
2288                 echo "$queue recovery queue should be empty" ||
2289                 echo "$queue recovery queue should have $nid"
2290
2291         wait_update $HOSTNAME \
2292                 "$LNETCTL debug recovery $queue | \
2293                  grep -wc \"nid-0: $nid\"" \
2294                 "$expect" "$max_wait"
2295         rc=$?
2296         do_lnetctl debug recovery $queue
2297         (($rc == 0)) ||
2298                 error "Expect $expect NIDs in recovery."
2299
2300         return 0
2301 }
2302
2303 # First ping is sent at time 0.
2304 # 2nd at 0 + 2^1 = 2
2305 # 3rd at 2 + 2^2 = 6
2306 # 4th at 6 + 2^3 = 14
2307 # 5th at 14 + 2^4 = 30
2308 # e.g. after 10 seconds we would expect 3 pings to have been sent, and the
2309 # NI will have been enqueued for the 4th ping.
2310
2311 # If the recovery limit is 10 seconds, then after the 4th ping is sent
2312 # we expect the peer NI to have aged out, so it will not actually be
2313 # queued for a 5th ping.
2314 # If max_recovery_ping_interval is set to 4 then:
2315 #  First ping is sent at time 0
2316 #  2nd at  0 + min(2^1, 4) = 2
2317 #  3rd at  2 + min(2^2, 4) = 6
2318 #  4th at  6 + min(2^3, 4) = 10
2319 #  5th at 10 + min(2^4, 4) = 14
2320 #  6th at 14 + min(2^5, 4) = 18
2321 #  7th at 18 + min(2^6, 4) = 22
2322 # e.g. after 4 seconds we would expect 2 pings to have been sent, and
2323 # after 13 seconds we would expect 4 pings to have been sent
2324 check_ping_count() {
2325         local queue="$1"
2326         local nid="$2"
2327         local expect="$3"
2328         local max_wait="$4"
2329
2330         echo "Check ping counts:"
2331
2332         local rc=0
2333         if [[ $queue == "ni" ]]; then
2334                 wait_update $HOSTNAME \
2335                         "$LNETCTL net show -v 2 | \
2336                          grep -e $nid -e ping_count | grep -wA1 $nid | \
2337                          awk '/ping_count/{print \\\$NF}'" "$expect" "$max_wait"
2338                 rc=$?
2339                 $LNETCTL net show -v 2 | grep -e $nid -e ping_count
2340         elif [[ $queue == peer_ni ]]; then
2341                 wait_update $HOSTNAME \
2342                         "$LNETCTL peer show -v 2 --nid $nid | \
2343                          grep -v primary | \
2344                          grep -e $nid -e ping_count | grep -wA1 $nid | \
2345                          awk '/ping_count/{print \\\$NF}'" "$expect" "$max_wait"
2346                 rc=$?
2347                 $LNETCTL peer show -v 2 --nid $nid | grep -v primary |
2348                         grep -e $nid -e ping_count
2349         else
2350                 error "Unrecognized queue \"$queue\""
2351                 return 1
2352         fi
2353
2354         ((rc == 0)) || error "Unexpected ping count"
2355
2356         return 0
2357 }
2358
2359 test_210() {
2360         [[ ${NETTYPE} == kfi* ]] && skip "kfi doesn't support drop rules"
2361
2362         reinit_dlc || return $?
2363         add_net "${NETTYPE}" "${INTERFACES[0]}" || return $?
2364         add_net "${NETTYPE}1" "${INTERFACES[0]}" || return $?
2365
2366         local prim_nid=$($LCTL list_nids | head -n 1)
2367
2368         do_lnetctl discover $prim_nid ||
2369                 error "failed to discover myself"
2370
2371         local default=$($LNETCTL global show |
2372                         awk '/recovery_limit/{print $NF}')
2373         # Set recovery limit to 10 seconds.
2374         do_lnetctl set recovery_limit 10 ||
2375                 error "failed to set recovery_limit"
2376
2377         $LCTL set_param debug=+net
2378         $LCTL net_drop_add -s *@${NETTYPE} -d *@${NETTYPE} -m GET -r 1 \
2379                 -e local_error ||
2380                 error "Failed to add drop rule"
2381         $LCTL net_drop_add -s *@${NETTYPE}1 -d *@${NETTYPE}1 -m GET -r 1 \
2382                 -e local_error ||
2383                 error "Failed to add drop rule"
2384         $LCTL net_drop_add -s *@${NETTYPE} -d *@${NETTYPE} -r 1 ||
2385                 error "Failed to add drop rule"
2386         $LCTL net_drop_add -s *@${NETTYPE}1 -d *@${NETTYPE}1 -r 1 ||
2387                 error "Failed to add drop rule"
2388         do_lnetctl net set --health 0 --nid $prim_nid
2389
2390         check_ping_count "ni" "$prim_nid" "2" "10"
2391         check_nid_in_recovq "-l" "$prim_nid" "1"
2392
2393         check_ping_count "ni" "$prim_nid" "3" "10"
2394         check_nid_in_recovq "-l" "$prim_nid" "1"
2395
2396         $LCTL net_drop_del -a
2397
2398         reinit_dlc || return $?
2399         add_net "${NETTYPE}" "${INTERFACES[0]}" || return $?
2400         add_net "${NETTYPE}1" "${INTERFACES[0]}" || return $?
2401
2402         local prim_nid=$($LCTL list_nids | head -n 1)
2403
2404         do_lnetctl discover $prim_nid ||
2405                 error "failed to discover myself"
2406
2407         do_lnetctl set recovery_limit $default ||
2408                 error "failed to set recovery_limit"
2409
2410         default=$($LNETCTL global show |
2411                   awk '/max_recovery_ping_interval/{print $NF}')
2412         do_lnetctl set max_recovery_ping_interval 4 ||
2413                 error "failed to set max_recovery_ping_interval"
2414
2415         $LCTL set_param debug=+net
2416         $LCTL net_drop_add -s *@${NETTYPE} -d *@${NETTYPE} -m GET -r 1 \
2417                 -e local_error ||
2418                 error "Failed to add drop rule"
2419         $LCTL net_drop_add -s *@${NETTYPE}1 -d *@${NETTYPE}1 -m GET -r 1 \
2420                 -e local_error ||
2421                 error "Failed to add drop rule"
2422         $LCTL net_drop_add -s *@${NETTYPE} -d *@${NETTYPE} -r 1 ||
2423                 error "Failed to add drop rule"
2424         $LCTL net_drop_add -s *@${NETTYPE}1 -d *@${NETTYPE}1 -r 1 ||
2425                 error "Failed to add drop rule"
2426         do_lnetctl net set --health 0 --nid $prim_nid
2427
2428         check_ping_count "ni" "$prim_nid" "2" "10"
2429         check_nid_in_recovq "-l" "$prim_nid" "1"
2430
2431         check_ping_count "ni" "$prim_nid" "4" "10"
2432         check_nid_in_recovq "-l" "$prim_nid" "1"
2433
2434         $LCTL net_drop_del -a
2435
2436         do_lnetctl set max_recovery_ping_interval $default ||
2437                 error "failed to set max_recovery_ping_interval"
2438
2439         return 0
2440 }
2441 run_test 210 "Local NI recovery checks"
2442
2443 test_211() {
2444         [[ ${NETTYPE} == kfi* ]] && skip "kfi doesn't support drop rules"
2445
2446         reinit_dlc || return $?
2447         add_net "${NETTYPE}" "${INTERFACES[0]}" || return $?
2448         add_net "${NETTYPE}1" "${INTERFACES[0]}" || return $?
2449
2450         local prim_nid=$($LCTL list_nids | head -n 1)
2451
2452         do_lnetctl discover $prim_nid ||
2453                 error "failed to discover myself"
2454
2455         local default=$($LNETCTL global show |
2456                         awk '/recovery_limit/{print $NF}')
2457         # Set recovery limit to 10 seconds.
2458         do_lnetctl set recovery_limit 10 ||
2459                 error "failed to set recovery_limit"
2460
2461         $LCTL net_drop_add -s *@${NETTYPE} -d *@${NETTYPE} -m GET -r 1 \
2462                 -e remote_error ||
2463                 error "Failed to add drop rule"
2464         $LCTL net_drop_add -s *@${NETTYPE}1 -d *@${NETTYPE}1 -m GET -r 1 \
2465                 -e remote_error ||
2466                 error "Failed to add drop rule"
2467         $LCTL net_drop_add -s *@${NETTYPE} -d *@${NETTYPE} -r 1 ||
2468                 error "Failed to add drop rule"
2469         $LCTL net_drop_add -s *@${NETTYPE}1 -d *@${NETTYPE}1 -r 1 ||
2470                 error "Failed to add drop rule"
2471
2472         # Set health to 0 on one interface. This forces it onto the recovery
2473         # queue.
2474         do_lnetctl peer set --nid $prim_nid --health 0
2475
2476         check_nid_in_recovq "-p" "$prim_nid" "1"
2477
2478         # The peer should age out in 10-20 seconds
2479         check_nid_in_recovq "-p" "$prim_nid" "0" "20"
2480         # Ping count should reset to 0 when peer ages out
2481         check_ping_count "peer_ni" "$prim_nid" "0"
2482
2483         $LCTL net_drop_del -a
2484
2485         # Set health to force it back onto the recovery queue. Set to 500 means
2486         # in ~5 seconds it should be back at maximum value.
2487         # NB: we reset the recovery limit to 0 (indefinite) so the peer NI is
2488         # eligible again
2489         do_lnetctl set recovery_limit 0 ||
2490                 error "failed to set recovery_limit"
2491
2492         do_lnetctl peer set --nid $prim_nid --health 500
2493
2494         check_nid_in_recovq "-p" "$prim_nid" "1"
2495         check_nid_in_recovq "-p" "$prim_nid" "0" "20"
2496
2497         reinit_dlc || return $?
2498         add_net "${NETTYPE}" "${INTERFACES[0]}" || return $?
2499         add_net "${NETTYPE}1" "${INTERFACES[0]}" || return $?
2500
2501         local prim_nid=$($LCTL list_nids | head -n 1)
2502
2503         do_lnetctl discover $prim_nid ||
2504                 error "failed to discover myself"
2505
2506         do_lnetctl set recovery_limit $default ||
2507                 error "failed to set recovery_limit"
2508
2509         default=$($LNETCTL global show |
2510                   awk '/max_recovery_ping_interval/{print $NF}')
2511         do_lnetctl set max_recovery_ping_interval 4 ||
2512                 error "failed to set max_recovery_ping_interval"
2513
2514         $LCTL net_drop_add -s *@${NETTYPE} -d *@${NETTYPE} -m GET -r 1 \
2515                 -e remote_error ||
2516                 error "Failed to add drop rule"
2517         $LCTL net_drop_add -s *@${NETTYPE}1 -d *@${NETTYPE}1 -m GET -r 1 \
2518                 -e remote_error ||
2519                 error "Failed to add drop rule"
2520         $LCTL net_drop_add -s *@${NETTYPE} -d *@${NETTYPE} -r 1 ||
2521                 error "Failed to add drop rule"
2522         $LCTL net_drop_add -s *@${NETTYPE}1 -d *@${NETTYPE}1 -r 1 ||
2523                 error "Failed to add drop rule"
2524
2525         # Set health to 0 on one interface. This forces it onto the recovery
2526         # queue.
2527         do_lnetctl peer set --nid $prim_nid --health 0
2528
2529         check_ping_count "peer_ni" "$prim_nid" "1" "4"
2530         check_nid_in_recovq "-p" "$prim_nid" "1"
2531
2532         # After we detect the 1st ping above, the 4th ping should be sent after
2533         # ~13 seconds
2534         check_ping_count "peer_ni" "$prim_nid" "4" "14"
2535         check_nid_in_recovq "-p" "$prim_nid" "1"
2536
2537         $LCTL net_drop_del -a
2538
2539         do_lnetctl set max_recovery_ping_interval $default ||
2540                 error "failed to set max_recovery_ping_interval"
2541
2542         return 0
2543 }
2544 run_test 211 "Remote NI recovery checks"
2545
2546 test_212() {
2547         [[ ${NETTYPE} == kfi* ]] && skip "kfi doesn't support drop rules"
2548
2549         local rnodes=$(remote_nodes_list)
2550         [[ -z $rnodes ]] && skip "Need at least 1 remote node"
2551
2552         cleanup_lnet || error "Failed to cleanup before test execution"
2553
2554         # Loading modules should configure LNet with the appropriate
2555         # test-framework configuration
2556         load_lnet "config_on_load=1" || error "Failed to load modules"
2557
2558         local my_nid=$($LCTL list_nids | head -n 1)
2559         [[ -z $my_nid ]] &&
2560                 error "Failed to get primary NID for local host $HOSTNAME"
2561
2562         local rnode=$(awk '{print $1}' <<<$rnodes)
2563         local rnodenids=$(do_node $rnode $LCTL list_nids | xargs echo)
2564         local rloaded=false
2565
2566         if [[ -z $rnodenids ]]; then
2567                 do_rpc_nodes $rnode load_lnet "config_on_load=1"
2568                 rloaded=true
2569                 rnodenids=$(do_node $rnode $LCTL list_nids | xargs echo)
2570         fi
2571
2572         local rnodepnid=$(awk '{print $1}' <<< $rnodenids)
2573
2574         [[ -z $rnodepnid ]] &&
2575                 error "Failed to get primary NID for remote host $rnode"
2576
2577         log "Initial discovery"
2578         do_lnetctl discover --force $rnodepnid ||
2579                 error "Failed to discover $rnodepnid"
2580
2581         do_node $rnode "$LNETCTL discover --force $my_nid" ||
2582                 error "$rnode failed to discover $my_nid"
2583
2584         log "Fail local discover ping to set LNET_PEER_REDISCOVER flag"
2585         $LCTL net_drop_add -s "*@$NETTYPE" -d "*@$NETTYPE" -r 1 \
2586                 -e local_error ||
2587                 error "Failed to add drop rule"
2588         do_lnetctl discover --force $rnodepnid &&
2589                 error "Discovery should have failed"
2590         $LCTL net_drop_del -a
2591
2592         local nid
2593         for nid in $rnodenids; do
2594                 # We need GET (PING) delay just long enough so we can trigger
2595                 # discovery on the remote peer
2596                 $LCTL net_delay_add -s "*@$NETTYPE" -d $nid -r 1 -m GET -l 3 ||
2597                         error "Failed to add delay rule"
2598                 $LCTL net_drop_add -s "*@$NETTYPE" -d $nid -r 1 -m GET \
2599                         -e local_error ||
2600                         error "Failed to add drop rule"
2601                 # We need PUT (PUSH) delay just long enough so we can process
2602                 # the PING failure
2603                 $LCTL net_delay_add -s "*@$NETTYPE" -d $nid -r 1 -m PUT -l 6 ||
2604                         error "Failed to add delay rule"
2605         done
2606
2607         log "Force $HOSTNAME to discover $rnodepnid (in background)"
2608         # We want to get a PING sent that we know will eventually fail.
2609         # The delay rules we added will ensure the ping is not sent until
2610         # the PUSH is also in flight (see below), and the drop rule ensures that
2611         # when the PING is eventually sent it will error out
2612         do_lnetctl discover --force $rnodepnid &
2613         local pid1=$!
2614
2615         # We want a discovery PUSH from rnode to put rnode back on our
2616         # discovery queue. This should cause us to try and send a PUSH to rnode
2617         # while the PING is still outstanding.
2618         log "Force $rnode to discover $my_nid"
2619         do_node $rnode $LNETCTL discover --force $my_nid
2620
2621         # At this point we'll have both PING_SENT and PUSH_SENT set for the
2622         # rnode peer. Wait for the PING to error out which should terminate the
2623         # discovery process that we backgrounded.
2624         log "Wait for $pid1"
2625         wait $pid1
2626         log "Finished wait on $pid1"
2627
2628         # The PING send failure clears the PING_SENT flag and puts the peer back
2629         # on the discovery queue. When discovery thread processes the peer it
2630         # will mistakenly clear the PUSH_SENT flag (and set PUSH_FAILED).
2631         # Discovery will then complete for this peer even though we have an
2632         # outstanding PUSH.
2633         # When PUSH is actually unlinked it will be forced back onto the
2634         # discovery queue, but we no longer have a ref on the peer. When
2635         # discovery completes again, we'll trip the ASSERT in
2636         # lnet_destroy_peer_locked()
2637
2638         # Delete the delay rules to send the PUSH
2639         $LCTL net_delay_del -a
2640         # Delete the drop rules
2641         $LCTL net_drop_del -a
2642
2643         unload_modules ||
2644                 error "Failed to unload modules"
2645         if $rloaded; then
2646                 do_rpc_nodes $rnode unload_modules_local ||
2647                         error "Failed to unload modules on $rnode"
2648         fi
2649
2650         return 0
2651 }
2652 run_test 212 "Check discovery refcount loss bug (LU-14627)"
2653
2654 test_213() {
2655         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
2656
2657         cleanup_netns || error "Failed to cleanup netns before test execution"
2658         cleanup_lnet || error "Failed to unload modules before test execution"
2659
2660         setup_fakeif || error "Failed to add fake IF"
2661         have_interface "$FAKE_IF" ||
2662                 error "Expect $FAKE_IF configured but not found"
2663
2664         reinit_dlc || return $?
2665
2666         add_net "tcp" "${INTERFACES[0]}" || return $?
2667         add_net "tcp" "$FAKE_IF" || return $?
2668
2669         local nid1=$(lctl list_nids | head -n 1)
2670         local nid2=$(lctl list_nids | tail --lines 1)
2671
2672         [[ $(lctl which_nid $nid1 $nid2) == $nid1 ]] ||
2673                 error "Expect nid1 \"$nid1\" to be preferred"
2674
2675         [[ $(lctl which_nid $nid2 $nid1) == $nid2 ]] ||
2676                 error "Expect nid2 \"$nid2\" to be preferred"
2677
2678         return 0
2679 }
2680 run_test 213 "Check LNetDist calculation for multiple local NIDs"
2681
2682 function check_ni_status() {
2683         local nid="$1"
2684         local expect="$2"
2685
2686         local status=$($LNETCTL net show |
2687                        grep -A 1 ${nid} |
2688                        awk '/status/{print $NF}')
2689
2690         echo "NI ${nid} expect status \"${expect}\" found \"${status}\""
2691         if [[ $status != $expect ]]; then
2692                 error "Error: Expect NI status \"$expect\" for NID \"$nid\" but found \"$status\""
2693         fi
2694
2695         return 0
2696 }
2697
2698 test_214() {
2699         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
2700
2701         cleanup_netns || error "Failed to cleanup netns before test execution"
2702         cleanup_lnet || error "Failed to unload modules before test execution"
2703
2704         setup_fakeif || error "Failed to add fake IF"
2705         have_interface "$FAKE_IF" ||
2706                 error "Expect $FAKE_IF configured but not found"
2707
2708         reinit_dlc || return $?
2709
2710         add_net "tcp" "${INTERFACES[0]}" || return $?
2711         add_net "tcp" "$FAKE_IF" || return $?
2712
2713         local nid1=$(lctl list_nids | head -n 1)
2714         local nid2=$(lctl list_nids | tail --lines 1)
2715
2716         check_ni_status "0@lo" up
2717         check_ni_status "$nid1" up
2718         check_ni_status "$nid2" up
2719
2720         do_lnetctl ping --source $nid2 $nid1 ||
2721                 error "$LNETCTL ping --source $nid2 $nid1 failed"
2722
2723         echo "Set $FAKE_IF down"
2724         echo "ip link set dev $FAKE_IF down"
2725         ip link set dev $FAKE_IF down
2726         check_ni_status "0@lo" up
2727         check_ni_status "$nid1" up
2728         check_ni_status "$nid2" down
2729 }
2730 run_test 214 "Check local NI status when link is downed"
2731
2732 get_ni_stat() {
2733         local nid=$1
2734         local stat=$2
2735
2736         $LNETCTL net show -v 2 |
2737                 egrep -e nid -e $stat |
2738                 grep -wA 1 $nid |
2739                 awk '/'$stat':/{print $NF}'
2740 }
2741
2742 ni_stats_pre() {
2743         local nidvar s
2744         for nidvar in nid1 nid2; do
2745                 for stat in send_count recv_count; do
2746                         s=$(get_ni_stat ${!nidvar} $stat)
2747                         eval ${nidvar}_pre_${stat}=$s
2748                 done
2749         done
2750 }
2751
2752 ni_stats_post() {
2753         local nidvar s
2754         for nidvar in nid1 nid2; do
2755                 for stat in send_count recv_count; do
2756                         s=$(get_ni_stat ${!nidvar} $stat)
2757                         eval ${nidvar}_post_${stat}=$s
2758                 done
2759         done
2760 }
2761
2762 ni_stat_changed() {
2763         local nidvar=$1
2764         local stat=$2
2765
2766         local pre post
2767         eval pre=\${${nidvar}_pre_${stat}}
2768         eval post=\${${nidvar}_post_${stat}}
2769
2770         echo "${!nidvar} pre ${stat} $pre post ${stat} $post"
2771
2772         [[ $pre -ne $post ]]
2773 }
2774
2775 test_215() {
2776         cleanup_netns || error "Failed to cleanup netns before test execution"
2777         cleanup_lnet || error "Failed to unload modules before test execution"
2778
2779         reinit_dlc || return $?
2780
2781         add_net "${NETTYPE}1" "${INTERFACES[0]}" || return $?
2782         add_net "${NETTYPE}2" "${INTERFACES[0]}" || return $?
2783
2784         local nid1=$($LCTL list_nids | head -n 1)
2785         local nid2=$($LCTL list_nids | tail --lines 1)
2786
2787         do_lnetctl peer add --prim $nid1 --nid $nid2 ||
2788                 error "Failed to add peer"
2789
2790         local npings=25
2791
2792         for nidvarA in nid1 nid2; do
2793                 src=${!nidvarA}
2794                 dst=${!nidvarA}
2795                 for nidvarB in nid1 nid2; do
2796                         [[ $nidvarA == $nidvarB ]] && continue
2797
2798                         ni_stats_pre
2799
2800                         echo "$LNETCTL ping $dst x $npings"
2801                         for i in $(seq 1 $npings); do
2802                                 $LNETCTL ping $dst &>/dev/null ||
2803                                         error "$LNETCTL ping $dst failed"
2804                         done
2805
2806                         ni_stats_post
2807
2808                         # No source specified, sends to either NID should cause
2809                         # counts to increase across both NIs
2810                         for nidvar in nid1 nid2; do
2811                                 for stat in send_count recv_count; do
2812                                         ni_stat_changed $nidvar $stat ||
2813                                                 error "$stat unchanged for ${!nidvar}"
2814                                 done
2815                         done
2816
2817                         ni_stats_pre
2818
2819                         echo "$LNETCTL ping --source $src $dst x $npings"
2820                         for i in $(seq 1 $npings); do
2821                                 $LNETCTL ping --source $src $dst &>/dev/null ||
2822                                         error "$LNETCTL ping --source $src $dst failed"
2823                         done
2824
2825                         ni_stats_post
2826
2827                         # src nid == dest nid means stats for the _other_ NI
2828                         # should be unchanged
2829                         for nidvar in nid1 nid2; do
2830                                 for stat in send_count recv_count; do
2831                                         if [[ ${!nidvar} == $src ]]; then
2832                                                 ni_stat_changed $nidvar $stat ||
2833                                                         error "$stat unchanged for ${!nidvar}"
2834                                         else
2835                                                 ni_stat_changed $nidvar $stat &&
2836                                                         error "$stat changed for ${!nidvar}"
2837                                         fi
2838                                 done
2839                         done
2840                 done
2841                 # Double number of pings for next iteration because the net
2842                 # sequence numbers will have diverged
2843                 npings=$(($npings * 2))
2844         done
2845
2846         # Ping from nid1 to nid2 should fail
2847         do_lnetctl ping --source $nid1 $nid2 &&
2848                 error "ping from $nid1 to $nid2 should fail"
2849
2850         # Ping from nid2 to nid1 should fail
2851         do_lnetctl ping --source $nid2 $nid1 &&
2852                 error "ping from $nid2 to $nid1 should fail"
2853
2854         return 0
2855 }
2856 run_test 215 "Test lnetctl ping --source option"
2857
2858 test_216() {
2859         [[ ${NETTYPE} == kfi* ]] && skip "kfi doesn't support drop rules"
2860
2861         local rc=0
2862
2863         reinit_dlc || return $?
2864
2865         add_net "${NETTYPE}" "${INTERFACES[0]}" || return $?
2866         add_net "${NETTYPE}1" "${INTERFACES[0]}" || return $?
2867
2868         local nids=( $($LCTL list_nids | xargs echo) )
2869
2870         do_lnetctl discover ${nids[0]} ||
2871                 error "Initial discovery failed"
2872
2873         do_lnetctl ping --source ${nids[0]} ${nids[0]} ||
2874                 error "Initial ping failed $?"
2875
2876         do_lnetctl ping --source ${nids[1]} ${nids[1]} ||
2877                 error "Initial ping failed $?"
2878
2879         local src dst
2880         for src in "${nids[@]}"; do
2881                 for dst in "${nids[@]}"; do
2882                         $LCTL net_drop_add -r 1 -s $src -d $dst \
2883                                 -e network_timeout ||
2884                                 error "Failed to add drop rule"
2885                 done
2886         done
2887
2888         do_lnetctl ping ${nids[0]} || rc=$?
2889
2890         $LCTL net_drop_del -a
2891
2892         [[ $rc -eq 0 ]] &&
2893                 error "expected ping to fail"
2894
2895         check_nid_in_recovq "-p" "${nids[0]}" "0"
2896         check_nid_in_recovq "-l" "${nids[0]}" "1"
2897
2898         return 0
2899 }
2900 run_test 216 "Failed send to peer NI owned by local host should not trigger peer NI recovery"
2901
2902 test_217() {
2903         reinit_dlc || return $?
2904
2905         [[ $($LNETCTL net show | grep -c nid) -ne 1 ]] &&
2906                 error "Unexpected number of NIs after initalizing DLC"
2907
2908         do_lnetctl discover 0@lo ||
2909                 error "Failed to discover 0@lo"
2910
2911         unload_modules
2912 }
2913 run_test 217 "Don't leak memory when discovering peer with nnis <= 1"
2914
2915 test_218() {
2916         [[ ${NETTYPE} == kfi* ]] && skip "kfi doesn't support drop rules"
2917
2918         reinit_dlc || return $?
2919
2920         [[ ${#INTERFACES[@]} -lt 2 ]] &&
2921                 skip "Need two LNet interfaces"
2922
2923         add_net "${NETTYPE}" "${INTERFACES[0]}" || return $?
2924
2925         local nid1=$($LCTL list_nids | head -n 1)
2926
2927         do_lnetctl ping $nid1 ||
2928                 error "ping failed"
2929
2930         add_net "${NETTYPE}" "${INTERFACES[1]}" || return $?
2931
2932         local nid2=$($LCTL list_nids | tail --lines 1)
2933
2934         do_lnetctl ping $nid2 ||
2935                 error "ping failed"
2936
2937         $LCTL net_drop_add -s $nid1 -d $nid1 -e local_error -r 1 ||
2938                 error "Failed to add drop rule"
2939
2940         do_lnetctl ping --source $nid1 $nid1 &&
2941                 error "ping should have failed"
2942
2943         local health_recovered
2944         local i
2945
2946         for i in $(seq 1 5); do
2947                 health_recovered=$($LNETCTL net show -v 2 |
2948                                    grep -c 'health value: 1000')
2949
2950                 if [[ $health_recovered -ne 2 ]]; then
2951                         echo "Wait 1 second for health to recover"
2952                         sleep 1
2953                 else
2954                         break
2955                 fi
2956         done
2957
2958         health_recovered=$($LNETCTL net show -v 2 |
2959                            grep -c 'health value: 1000')
2960
2961         $LCTL net_drop_del -a
2962
2963         [[ $health_recovered -ne 2 ]] &&
2964                 do_lnetctl net show -v 2 | egrep -e nid -e health &&
2965                 error "Health hasn't recovered"
2966
2967         return 0
2968 }
2969 run_test 218 "Local recovery pings should exercise all available paths"
2970
2971 test_219() {
2972         reinit_dlc || return $?
2973         add_net "${NETTYPE}" "${INTERFACES[0]}" || return $?
2974         add_net "${NETTYPE}1" "${INTERFACES[0]}" || return $?
2975
2976         local nid1=$(lctl list_nids | head -n 1)
2977         local nid2=$(lctl list_nids | tail --lines 1)
2978
2979         do_lnetctl ping $nid1 ||
2980                 error "Ping failed $?"
2981         do_lnetctl ping $nid2 ||
2982                 error "Ping failed $?"
2983
2984         do_lnetctl discover $nid2 ||
2985                 error "Discovery failed"
2986
2987         $LNETCTL peer show --nid $nid1 | grep -q $nid2 ||
2988                 error "$nid2 is not listed under $nid1"
2989 }
2990 run_test 219 "Consolidate peer entries"
2991
2992 # check that all routes are up
2993 check_route_aliveness() {
2994         local node="$1"
2995         local expected="$2"
2996
2997         local lctl_actual
2998         local lnetctl_actual
2999         local chk_intvl
3000         local i
3001
3002         chk_intvl=$(cat /sys/module/lnet/parameters/alive_router_check_interval)
3003
3004         lctl_actual=$(do_node $node $LCTL show_route |
3005                         awk '{print $7}' | sort -u | xargs)
3006         lnetctl_actual=$(do_node $node $LNETCTL route show -v |
3007                         awk '/state/{print $NF}' | sort -u | xargs)
3008
3009         for ((i = 0; i < $chk_intvl; i++)); do
3010                 if [[ $lctl_actual == $expected ]] &&
3011                    [[ $lnetctl_actual == $expected ]]; then
3012                         break
3013                 fi
3014
3015                 echo "wait 1s for route state change"
3016                 sleep 1
3017
3018                 lctl_actual=$(do_node $node $LCTL show_route |
3019                                 awk '{print $7}' | sort -u | xargs)
3020                 lnetctl_actual=$(do_node $node $LNETCTL route show -v |
3021                                 awk '/state/{print $NF}' | sort -u | xargs)
3022         done
3023
3024         [[ $lctl_actual != $expected ]] &&
3025                 error "Wanted \"$expected\" lctl found \"$lctl_actual\""
3026
3027         [[ $lnetctl_actual != $expected ]] &&
3028                 error "Wanted \"$expected\" lnetctl found \"$lnetctl_actual\""
3029
3030         return 0
3031 }
3032
3033 check_router_ni_status() {
3034         local router="$1"
3035         local expected_local="$2"
3036         local expected_remote="$3"
3037
3038         local actual_local
3039         local actual_remote
3040         local chk_intvl
3041         local timeout
3042         local i
3043
3044         chk_intvl=$(cat /sys/module/lnet/parameters/alive_router_check_interval)
3045         timeout=$(cat /sys/module/lnet/parameters/router_ping_timeout)
3046
3047         actual_local=$(do_node $router "$LNETCTL net show --net $LOCAL_NET" |
3048                        awk '/status/{print $NF}')
3049         actual_remote=$(do_node $router "$LNETCTL net show --net $REMOTE_NET" |
3050                         awk '/status/{print $NF}')
3051
3052         for ((i = 0; i < $((chk_intvl + timeout)); i++)); do
3053                 if [[ $actual_local == $expected_local ]] &&
3054                    [[ $actual_remote == $expected_remote ]]; then
3055                         break
3056                 fi
3057
3058                 echo "wait 1s for NI state change"
3059                 sleep 1
3060
3061                 actual_local=$(do_node $router \
3062                                "$LNETCTL net show --net $LOCAL_NET" |
3063                                 awk '/status/{print $NF}')
3064                 actual_remote=$(do_node $router \
3065                                 "$LNETCTL net show --net $REMOTE_NET" |
3066                                 awk '/status/{print $NF}')
3067         done
3068
3069         [[ $actual_local == $expected_local ]] ||
3070                 error "$LOCAL_NET should be $expected_local"
3071
3072         [[ $actual_remote == $expected_remote ]] ||
3073                 error "$REMOTE_NET should be $expected_remote"
3074
3075         return 0
3076 }
3077
3078
3079 do_basic_rtr_test() {
3080         for router in ${!ROUTER_INTERFACES[@]}; do
3081                 do_node $router "$LNETCTL set routing 1" ||
3082                         error "Unable to enable routing on $router"
3083         done
3084
3085         for router in ${!ROUTER_NIDS[@]}; do
3086                 local router_nids=( ${ROUTER_NIDS[$router]} )
3087
3088                 do_route_add $HOSTNAME $REMOTE_NET ${router_nids[0]} ||
3089                 error "Failed to add route $HOSTNAME -> "\
3090                         "$REMOTE_NET via ${router_nids[0]}"
3091         done
3092
3093         for router in ${!ROUTER_INTERFACES[@]}; do
3094                 local router_nids=( ${ROUTER_NIDS[$router]} )
3095
3096                 for rpeer in ${!RPEER_INTERFACES[@]}; do
3097                         do_route_add $rpeer $LOCAL_NET ${router_nids[1]} ||
3098                                 error "Failed to add route $rpeer -> "\
3099                                         "$LOCAL_NET via ${router_nids[1]}"
3100                 done
3101         done
3102
3103         check_route_aliveness "$HOSTNAME" "up" ||
3104                 return $?
3105
3106         for rpeer in ${RPEERS[@]}; do
3107                 check_route_aliveness "$rpeer" "up" ||
3108                         return $?
3109         done
3110
3111         for rpeer in ${!RPEER_NIDS[@]}; do
3112                 local rpeer_nids=( ${RPEER_NIDS[$rpeer]} )
3113
3114                 do_lnetctl ping ${rpeer_nids[0]} ||
3115                         error "Failed to ping ${rpeer_nids[0]}"
3116         done
3117
3118         for rpeer in ${RPEERS[@]}; do
3119                 do_node $rpeer "$LNETCTL ping ${LNIDS[0]}" ||
3120                         error "$rpeer failed to ping ${LNIDS[0]}"
3121         done
3122
3123         return 0
3124 }
3125
3126 test_220() {
3127         setup_router_test || return $?
3128
3129         do_basic_rtr_test || return $?
3130
3131         do_rpc_nodes $HOSTNAME,${RPEERS[0]} load_module \
3132                 ../lnet/selftest/lnet_selftest ||
3133                         error "Failed to load lnet-selftest module"
3134
3135         $LSTSH -H -t $HOSTNAME -f ${RPEERS[0]} -m rw -s 4k ||
3136                 error "lst failed"
3137
3138         $LSTSH -H -t $HOSTNAME -f ${RPEERS[0]} -m rw ||
3139                 error "lst failed"
3140
3141         cleanup_router_test || return $?
3142 }
3143 run_test 220 "Add routes w/default options - check aliveness"
3144
3145 test_221() {
3146         setup_router_test lnet_peer_discovery_disabled=1 || return $?
3147
3148         do_basic_rtr_test || return $?
3149
3150         cleanup_router_test || return $?
3151 }
3152 run_test 221 "Add routes w/DD disabled - check aliveness"
3153
3154 # assumes 1 router, 1 peer
3155 do_aarf_enabled_test() {
3156
3157         local router=${ROUTERS[0]}
3158         local router_nids=( ${ROUTER_NIDS[$router]} )
3159         local rpeer=${RPEERS[0]}
3160         local rpeer_nids=( ${RPEER_NIDS[$rpeer]} )
3161
3162         do_node $router "$LNETCTL set routing 1" ||
3163                 error "Unable to enable routing on $ROUTER"
3164
3165         check_router_ni_status $router "down" "down"
3166
3167         do_lnetctl ping ${rpeer_nids[0]} &&
3168                 error "Ping should fail"
3169
3170         do_node $rpeer "$LNETCTL ping ${LNIDS[0]}" &&
3171                 error "$rpeer ping should fail"
3172
3173         # Adding a route should cause the router's NI on LOCAL_NET to get up
3174         do_route_add $HOSTNAME $REMOTE_NET ${router_nids[0]} ||
3175                 return $?
3176
3177         check_router_ni_status $router "up" "down" ||
3178                 return $?
3179
3180         # But route should still be down because of avoid_asym_router_failure
3181         check_route_aliveness "$HOSTNAME" "down" ||
3182                 return $?
3183
3184         do_lnetctl ping ${rpeer_nids[0]} &&
3185                 error "Ping should fail"
3186
3187         do_node $rpeer "$LNETCTL ping ${LNIDS[0]}" &&
3188                 error "$rpeer ping should fail"
3189
3190         # Adding the symmetric route should cause the remote NI to go up and
3191         # routes to go up
3192         do_route_add $rpeer $LOCAL_NET ${router_nids[1]} ||
3193                 return $?
3194
3195         check_router_ni_status $router "up" "up" ||
3196                 return $?
3197
3198         check_route_aliveness "$HOSTNAME" "up" ||
3199                 return $?
3200
3201         check_route_aliveness "$rpeer" "up" ||
3202                 return $?
3203
3204         do_lnetctl ping ${rpeer_nids[0]} ||
3205                 error "Failed to ping ${rpeer_nids[0]}"
3206
3207         do_node $rpeer "$LNETCTL ping ${LNIDS[0]}" ||
3208                 error "$rpeer failed to ping ${LNIDS[0]}"
3209
3210         # Stop LNet on local host
3211         do_lnetctl lnet unconfigure ||
3212                 error "Failed to stop LNet rc=$?"
3213
3214         check_router_ni_status $router "down" "up" ||
3215                 return $?
3216
3217         check_route_aliveness "$rpeer" "down" ||
3218                 return $?
3219
3220         do_lnetctl ping ${rpeer_nids[0]} &&
3221                 error "Ping should fail"
3222
3223         do_node $rpeer "$LNETCTL ping ${LNIDS[0]}" &&
3224                 error "$rpeer ping should fail"
3225
3226         return 0
3227 }
3228
3229 test_222() {
3230         setup_router_test avoid_asym_router_failure=1 || return $?
3231
3232         do_aarf_enabled_test || return $?
3233
3234         cleanup_router_test || return $?
3235 }
3236 run_test 222 "Check avoid_asym_router_failure=1"
3237
3238 test_223() {
3239         local opts="avoid_asym_router_failure=1 lnet_peer_discovery_disabled=1"
3240
3241         setup_router_test $opts || return $?
3242
3243         do_aarf_enabled_test || return $?
3244
3245         cleanup_router_test || return $?
3246 }
3247 run_test 223 "Check avoid_asym_router_failure=1 w/DD disabled"
3248
3249 do_aarf_disabled_test() {
3250         local router=${ROUTERS[0]}
3251         local router_nids=( ${ROUTER_NIDS[$router]} )
3252         local rpeer=${RPEERS[0]}
3253         local rpeer_nids=( ${RPEER_NIDS[$rpeer]} )
3254
3255         do_node $router "$LNETCTL set routing 1" ||
3256                 error "Unable to enable routing on $router"
3257
3258         check_router_ni_status $router "down" "down"
3259
3260         do_route_add $HOSTNAME $REMOTE_NET ${router_nids[0]} ||
3261                 return $?
3262
3263         check_router_ni_status $router "up" "down" ||
3264                 return $?
3265
3266         check_route_aliveness "$HOSTNAME" "up" ||
3267                 return $?
3268
3269         do_route_add $rpeer $LOCAL_NET ${router_nids[1]} ||
3270                 return $?
3271
3272         check_router_ni_status $router "up" "up" ||
3273                 return $?
3274
3275
3276         check_route_aliveness "$HOSTNAME" "up" ||
3277                 return $?
3278
3279         check_route_aliveness "$rpeer" "up" ||
3280                 return $?
3281
3282         do_lnetctl ping ${rpeer_nids[0]} ||
3283                 error "Failed to ping ${rpeer_nids[0]}"
3284
3285         do_node $rpeer "$LNETCTL ping ${LNIDS[0]}" ||
3286                 error "$rpeer failed to ping ${LNIDS[0]}"
3287
3288         # Stop LNet on local host
3289         do_lnetctl lnet unconfigure ||
3290                 error "Failed to stop LNet rc=$?"
3291
3292         check_router_ni_status $router "down" "up" ||
3293                 return $?
3294
3295         check_route_aliveness "$rpeer" "up" ||
3296                 return $?
3297
3298         return 0
3299 }
3300
3301 test_224() {
3302         setup_router_test avoid_asym_router_failure=0 ||
3303                 return $?
3304
3305         do_aarf_disabled_test ||
3306                 return $?
3307
3308         cleanup_router_test ||
3309                 return $?
3310 }
3311 run_test 224 "Check avoid_asym_router_failure=0"
3312
3313 test_225() {
3314         local opts="avoid_asym_router_failure=0 lnet_peer_discovery_disabled=1"
3315
3316         setup_router_test $opts || return $?
3317
3318         do_aarf_disabled_test || return $?
3319
3320         cleanup_router_test ||
3321                 return $?
3322 }
3323 run_test 225 "Check avoid_asym_router_failure=0 w/DD disabled"
3324
3325 test_226() {
3326         ROUTERS_REQUIRED=2
3327         RPEERS_REQUIRED=1
3328
3329         setup_router_test || return $?
3330
3331         do_basic_rtr_test || return $?
3332
3333         # ping the peer from host to make sure it works
3334         local rpeer=${RPEERS[0]}
3335         local rpeer_nids=( ${RPEER_NIDS[$rpeer]} )
3336
3337         for i in {1..4}; do
3338                 do_lnetctl ping ${rpeer_nids[0]} ||
3339                         error "Failed to ping ${rpeer_nids[0]} on try $i"
3340         done
3341
3342         # remove a route from the peer
3343         local router_nids=( ${ROUTER_NIDS[${ROUTERS[0]}]} )
3344
3345         do_route_del $rpeer $LOCAL_NET ${router_nids[0]}
3346
3347         # should attempt to use both routes due to round-robin
3348         # failure case here is an LBUG on $rpeer
3349         for i in {1..4}; do
3350                 do_lnetctl ping ${rpeer_nids[0]}
3351         done
3352
3353         cleanup_router_test || return $?
3354 }
3355 run_test 226 "test missing route for 1 of 2 routers"
3356
3357 test_230() {
3358         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
3359
3360         # LU-12815
3361         echo "Check valid values; Should succeed"
3362         local i
3363         local lnid
3364         local cmd
3365         for ((i = 4; i < 16; i+=1)); do
3366                 reinit_dlc || return $?
3367                 add_net "tcp" "${INTERFACES[0]}" || return $?
3368                 do_lnetctl net set --all --conns-per-peer $i ||
3369                         error "should have succeeded $?"
3370                 $LNETCTL net show -v 1 | grep -q "conns_per_peer: $i" ||
3371                         error "failed to set conns-per-peer to $i"
3372                 lnid="$(lctl list_nids | head -n 1)"
3373                 do_lnetctl ping "$lnid" ||
3374                         error "failed to ping myself"
3375
3376                 # "lctl --net tcp conn_list" prints the list of active
3377                 # connections. Since we're pinging ourselves, there should be
3378                 # 2 Control connections plus 2*conns_per_peer connections
3379                 # created (one Bulk Input, one Bulk Output in each pair).
3380                 # Here's the sample output for conns_per_peer set to 1:
3381                 # 12345-1.1.1.1@tcp I[0]host01->host01:988 2626560/1061296 nonagle
3382                 # 12345-1.1.1.1@tcp O[0]host01->host01:1022 2626560/1061488 nonagle
3383                 # 12345-1.1.1.1@tcp C[0]host01->host01:988 2626560/1061296 nonagle
3384                 # 12345-1.1.1.1@tcp C[0]host01->host01:1023 2626560/1061488 nonagle
3385                 cmd="printf 'network tcp\nconn_list\n' | lctl | grep -c '$lnid'"
3386
3387                 # Expect 2+conns_per_peer*2 connections. Wait no longer
3388                 # than 2 seconds.
3389                 wait_update $HOSTNAME "$cmd" "$((2+i*2))" 2 ||
3390                         error "expected number of tcp connections $((2+i*2))"
3391         done
3392
3393         reinit_dlc || return $?
3394         add_net "tcp" "${INTERFACES[0]}" || return $?
3395         echo "Set > 127; Should fail"
3396         do_lnetctl net set --all --conns-per-peer 128 &&
3397                 error "should have failed $?"
3398
3399         reinit_dlc || return $?
3400         add_net "tcp" "${INTERFACES[0]}" || return $?
3401
3402         local default=$($LNETCTL net show -v 1 |
3403                         awk '/conns_per_peer/{print $NF}')
3404
3405         echo "Set < 0; Should be ignored"
3406         do_lnetctl net set --all --conns-per-peer -1 ||
3407                 error "should have succeeded $?"
3408         $LNETCTL net show -v 1 | grep -q "conns_per_peer: ${default}" ||
3409                 error "Did not stay at default"
3410 }
3411 run_test 230 "Test setting conns-per-peer"
3412
3413 test_231() {
3414         reinit_dlc || return $?
3415
3416         local net=${NETTYPE}231
3417
3418         do_lnetctl net add --net $net --if ${INTERFACES[0]} ||
3419                 error "Failed to add net"
3420
3421         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-expected.yaml
3422         sed -i 's/peer_timeout: .*$/peer_timeout: 0/' \
3423                 $TMP/sanity-lnet-$testnum-expected.yaml
3424
3425         reinit_dlc || return $?
3426
3427         do_lnetctl import $TMP/sanity-lnet-$testnum-expected.yaml ||
3428                 error "Failed to import configuration"
3429
3430         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
3431
3432         compare_yaml_files || error "Wrong config after import"
3433
3434         do_lnetctl net del --net $net --if ${INTERFACES[0]} ||
3435                 error "Failed to delete net $net"
3436
3437         do_lnetctl net add --net $net --if ${INTERFACES[0]} --peer-timeout=0 ||
3438                 error "Failed to add net with peer-timeout=0"
3439
3440         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
3441
3442         compare_yaml_files || error "Wrong config after lnetctl net add"
3443
3444         reinit_dlc || return $?
3445
3446         # lnet/include/lnet/lib-lnet.h defines DEFAULT_PEER_TIMEOUT 180
3447         sed -i 's/peer_timeout: .*$/peer_timeout: 180/' \
3448                 $TMP/sanity-lnet-$testnum-expected.yaml
3449
3450         sed -i '/^.*peer_timeout:.*$/d' $TMP/sanity-lnet-$testnum-actual.yaml
3451
3452         do_lnetctl import $TMP/sanity-lnet-$testnum-actual.yaml ||
3453                 error "Failed to import config without peer_timeout"
3454
3455         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
3456
3457         compare_yaml_files
3458 }
3459 run_test 231 "Check DLC handling of peer_timeout parameter"
3460
3461 test_232() {
3462         [[ ${NETTYPE} =~ ^(tcp|o2ib) ]] ||
3463                 skip "Need tcp or o2ib NETTYPE"
3464
3465         local i
3466         local modparam=-1
3467         local net=${NETTYPE}232
3468
3469         reinit_dlc || return $?
3470         if [[ ${NETTYPE} == tcp* ]];then
3471                 modparam=$(cat "/sys/module/ksocklnd/parameters/tos")
3472         elif [[ ${NETTYPE} == o2ib* ]]; then
3473                 modparam=$(cat "/sys/module/ko2iblnd/parameters/tos")
3474         fi
3475
3476         do_lnetctl net add --net $net --if ${INTERFACES[0]} ||
3477                 error "Failed to add net (no ToS)"
3478         do_lnetctl net show --net $net -v 1 | grep -q "tos: $modparam" ||
3479                 error "Failed ToS value should inherit from module parameter $modparam"
3480         do_lnetctl net del --net $net --if ${INTERFACES[0]} ||
3481                 error "Failed to delete net $net"
3482
3483         for i in -1 104 106; do
3484                 do_lnetctl net add --net $net --if ${INTERFACES[0]} --tos $i ||
3485                         error "Failed to add net (ToS: $i)"
3486                 do_lnetctl net show --net $net -v 1 | grep -q "tos: $i" ||
3487                         error "Failed to set ToS value to 104"
3488                 do_lnetctl net del --net $net --if ${INTERFACES[0]} ||
3489                         error "Failed to delete net $net"
3490         done
3491
3492         ! do_lnetctl net add --net $net --if ${INTERFACES[0]} --tos 300 ||
3493                 error "lnetctl should reject invalid ToS value (>255)"
3494 }
3495 run_test 232 "Test setting ToS value"
3496
3497 ### Test that linux route is added for each ni
3498 test_250() {
3499         local skip_param
3500
3501         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
3502
3503         reinit_dlc || return $?
3504         add_net "tcp" "${INTERFACES[0]}" || return $?
3505
3506         skip_param=$(cat /sys/module/ksocklnd/parameters/skip_mr_route_setup)
3507         [[ ${skip_param:-0} -ne 0 ]] &&
3508                 skip "Need skip_mr_route_setup=0 found $skip_param"
3509
3510         ip route show table ${INTERFACES[0]} | grep -q "${INTERFACES[0]}"
3511 }
3512 run_test 250 "test that linux routes are added"
3513
3514 test_251() {
3515         [[ ${NETTYPE} =~ kfi* ]] ||
3516                 skip "Need kfi NETTYPE"
3517
3518         reinit_dlc || return $?
3519         add_net "kfi" "${INTERFACES[0]}" || return $?
3520         add_net "kfi1" "${INTERFACES[0]}" || return $?
3521         add_net "kfi10" "${INTERFACES[0]}" || return $?
3522         return 0
3523 }
3524 run_test 251 "Define multiple kfi networks on single interface"
3525
3526 test_252() {
3527
3528         (( $MDS1_VERSION >= $(version_code v2_14_55-10-gc807e3f33b) )) ||
3529                 skip "need MDS >= 2.14.55.10 for memory leak fix"
3530
3531         setup_health_test false || return $?
3532
3533         local rc=0
3534
3535         do_rpc_nodes $RNODE unload_modules_local || rc=$?
3536
3537         if [[ $rc -ne 0 ]]; then
3538                 cleanup_health_test || return $?
3539
3540                 error "Failed to unload modules on $RNODE rc=$rc"
3541         else
3542                 RLOADED=false
3543         fi
3544
3545         local ts1=$(date +%s)
3546
3547         do_lnetctl ping --timeout 15 ${RNIDS[0]} &&
3548                 error "Expected ping ${RNIDS[0]} to fail"
3549
3550         local ts2=$(date +%s)
3551
3552         local delta=$(echo "$ts2 - $ts1" | bc)
3553
3554         [[ $delta -lt 15 ]] ||
3555                 error "Ping took longer than expected to fail: $delta"
3556
3557         cleanup_health_test
3558 }
3559 run_test 252 "Ping to down peer should unlink quickly"
3560
3561 do_expired_message_drop_test() {
3562         local rnid lnid old_tto
3563
3564         old_tto=$($LNETCTL global show |
3565                   awk '/transaction_timeout:/{print $NF}')
3566
3567         [[ -z $old_tto ]] &&
3568                 error "Cannot determine LNet transaction timeout"
3569
3570         local tto=10
3571
3572         do_lnetctl set transaction_timeout "${tto}" ||
3573                 error "Failed to set transaction_timeout"
3574
3575         # We want to consume all peer credits for at least transaction_timeout
3576         # seconds
3577         local delay
3578
3579         delay=$((tto + 1))
3580
3581         for lnid in "${LNIDS[@]}"; do
3582                 for rnid in "${RNIDS[@]}"; do
3583                         $LCTL net_delay_add -s "${lnid}" -d "${rnid}" \
3584                                 -l "${delay}" -r 1 -m GET ||
3585                                 error "Failed to add delay rule"
3586                 done
3587         done
3588
3589         declare -a pcs
3590
3591         pcs=( $($LNETCTL peer show -v --nid "${RNIDS[0]}" |
3592                 awk '/max_ni_tx_credits:/{print $NF}' |
3593                 xargs echo) )
3594
3595         [[ ${#RNIDS[@]} -ne ${#pcs[@]} ]] &&
3596                 error "Expect ${#RNIDS[@]} peer credit values found ${#pcs[@]}"
3597
3598         local rnet lnid lnet i j
3599
3600         # Need to use --source for multi-rail configs to ensure we consume
3601         # all available peer credits
3602         for ((i = 0; i < ${#RNIDS[@]}; i++)); do
3603                 local ping_args="--timeout $((delay+2))"
3604
3605                 rnet=${RNIDS[i]##*@}
3606                 for lnid in ${LNIDS[@]}; do
3607                         lnet=${lnid##*@}
3608                         [[ $rnet == $lnet ]] && break
3609                 done
3610
3611                 ping_args+=" --source ${lnid} ${RNIDS[i]}"
3612                 for j in $(seq 1 "${pcs[i]}"); do
3613                         $LNETCTL ping ${ping_args} 1>/dev/null &
3614                 done
3615
3616                 echo "Issued ${pcs[i]} pings to ${RNIDS[i]} from $lnid"
3617         done
3618
3619         # This ping should be queued on peer NI tx credit
3620         $LNETCTL ping --timeout $((delay+2)) "${RNIDS[0]}" &
3621
3622         sleep ${delay}
3623
3624         $LCTL net_delay_del -a
3625
3626         wait
3627
3628         # Messages sent from the delay list do not go through
3629         # lnet_post_send_locked(), thus we should only have a single drop
3630         local dropped
3631
3632         dropped=$($LNETCTL peer show -v 2 --nid "${RNIDS[0]}" |
3633                         grep -A 2 dropped_stats |
3634                         awk '/get:/{print $2}' |
3635                         xargs echo |
3636                         sed 's/ /\+/g' | bc)
3637
3638         [[ $dropped -ne 1 ]] &&
3639                 error "Expect 1 dropped GET but found $dropped"
3640
3641         do_lnetctl set transaction_timeout "${old_tto}"
3642
3643         return 0
3644 }
3645
3646 test_253() {
3647         setup_health_test false || return $?
3648
3649         do_expired_message_drop_test || return $?
3650
3651         cleanup_health_test
3652 }
3653 run_test 253 "Message delayed beyond deadline should be dropped (single-rail)"
3654
3655 test_254() {
3656         setup_health_test true || return $?
3657
3658         do_expired_message_drop_test || return $?
3659
3660         cleanup_health_test
3661 }
3662 run_test 254 "Message delayed beyond deadline should be dropped (multi-rail)"
3663
3664 test_255() {
3665         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
3666
3667         reinit_dlc || return $?
3668
3669         cleanup_lnet || return $?
3670
3671         local routes_str="o2ib ${IF0_NET}.[$GW_HOSTNUM-$((GW_HOSTNUM+4))]"
3672         local network_str="${NETTYPE}(${INTERFACES[0]})"
3673
3674         load_lnet "networks=\"${network_str}\" routes=\"${routes_str}\"" ||
3675                 error "Failed to load LNet"
3676
3677         $LCTL net up ||
3678                 error "Failed to load LNet with networks=\"${network_str}\" routes=\"${routes_str}\""
3679
3680         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
3681 net:
3682     - net type: ${NETTYPE}
3683       local NI(s):
3684         - interfaces:
3685               0: ${INTERFACES[0]}
3686 EOF
3687         append_net_tunables tcp
3688
3689         echo "route:" >> $TMP/sanity-lnet-$testnum-expected.yaml
3690         for i in $(seq $GW_HOSTNUM $((GW_HOSTNUM + 4))); do
3691                 cat <<EOF >> $TMP/sanity-lnet-$testnum-expected.yaml
3692     - net: o2ib
3693       gateway: ${IF0_NET}.${i}@${NETTYPE}
3694       hop: -1
3695       priority: 0
3696       health_sensitivity: 1
3697 EOF
3698         done
3699
3700         echo "peer:" >> $TMP/sanity-lnet-$testnum-expected.yaml
3701         for i in $(seq $GW_HOSTNUM $((GW_HOSTNUM + 4))); do
3702                 cat <<EOF >> $TMP/sanity-lnet-$testnum-expected.yaml
3703     - primary nid: ${IF0_NET}.${i}@${NETTYPE}
3704       Multi-Rail: False
3705       peer ni:
3706         - nid: ${IF0_NET}.${i}@${NETTYPE}
3707 EOF
3708         done
3709
3710         append_global_yaml
3711
3712         $LNETCTL export --backup >  $TMP/sanity-lnet-$testnum-actual.yaml ||
3713                 error "export failed $?"
3714
3715         validate_gateway_nids
3716
3717         # Since we have an complex YAML config file we can test import
3718         do_lnetctl lnet unconfigure ||
3719                 error "Failed to stop LNet rc=$?"
3720         do_lnetctl import <  ${GLOBAL_YAML_FILE} || error "Import failed $?"
3721 }
3722 run_test 255 "Use lnet routes param with pdsh syntax"
3723
3724 test_300() {
3725         # LU-13274
3726         local header
3727         local out=$TMP/$tfile
3728         local prefix=/usr/include/linux/lnet
3729
3730         # We use a hard coded prefix so that this test will not fail
3731         # when run in tree.
3732         CC=${CC:-cc}
3733         if ! which $CC > /dev/null 2>&1; then
3734                 skip_env "$CC is not installed"
3735         fi
3736
3737         cleanup_lnet || exit 1
3738         load_lnet
3739
3740         local cc_args="-Wall -Werror -std=c99 -c -x c /dev/null -o $out"
3741         if ! [[ -d $prefix ]]; then
3742                 # Assume we're running in tree and fixup the include path.
3743                 prefix=$LUSTRE/../lnet/include/uapi/linux/lnet
3744                 cc_args+=" -I $LUSTRE/../lnet/include/uapi"
3745         fi
3746
3747         for header in $prefix/*.h; do
3748                 if ! [[ -f "$header" ]]; then
3749                         continue
3750                 fi
3751
3752                 echo "$CC $cc_args -include $header"
3753                 $CC $cc_args -include $header ||
3754                         error "cannot compile '$header'"
3755         done
3756         rm -f $out
3757 }
3758 run_test 300 "packaged LNet UAPI headers can be compiled"
3759
3760 # LU-16081 lnet: Memory leak on adding existing interface
3761
3762 test_301() {
3763         reinit_dlc || return $?
3764         do_lnetctl net add --net ${NETTYPE} --if ${INTERFACES[0]} ||
3765                 error "Failed to add net"
3766         do_lnetctl net add --net ${NETTYPE} --if ${INTERFACES[0]} &&
3767                 error "add net should have failed"
3768         do_lnetctl net del --net ${NETTYPE} --if ${INTERFACES[0]} ||
3769                 error "Failed to del net"
3770         unload_modules
3771 }
3772 run_test 301 "Check for dynamic adds of same/wrong interface (memory leak)"
3773
3774 test_302() {
3775         ! [[ $NETTYPE =~ (tcp|o2ib) ]] && skip "Need tcp or o2ib NETTYPE"
3776
3777         reinit_dlc || return $?
3778
3779         add_net "${NETTYPE}" "${INTERFACES[0]}" || return $?
3780
3781         local nid=$($LCTL list_nids)
3782
3783         do_lnetctl ping ${nid} ||
3784                 error "pinging self failed $?"
3785         do_lnetctl debug peer --nid ${nid} ||
3786                 error "failed to dump peer debug info $?"
3787 }
3788 run_test 302 "Check that peer debug info can be dumped"
3789
3790 test_303() {
3791         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
3792
3793         setup_health_test true || return $?
3794
3795         cleanup_netns || error "Failed to cleanup netns before test execution"
3796         setup_fakeif || error "Failed to add fake IF"
3797         have_interface "$FAKE_IF" ||
3798                 error "Expect $FAKE_IF configured but not found"
3799
3800         add_net "${NETTYPE}99" "$FAKE_IF" || return $?
3801
3802         local nid=$($LCTL list_nids | tail --lines 1)
3803
3804         # Our updated config should be pushed to RNODE
3805         local found=$(do_node $RNODE "$LNETCTL peer show --nid $nid")
3806
3807         [[ -z $found ]] && error "Peer not updated on $RNODE"
3808
3809         local prim=$($LCTL list_nids | head -n 1)
3810
3811         if ! grep -q -- " primary nid: $prim"<<<"${found}"; then
3812                 echo "$found"
3813                 error "Wrong primary nid"
3814         fi
3815
3816         echo "Set $FAKE_IF down"
3817         echo "ip link set dev $FAKE_IF down"
3818         ip link set dev $FAKE_IF down
3819         check_ni_status "$nid" down
3820
3821         local hval=$(do_node $RNODE "$LNETCTL peer show --nid $nid -v 2 | \
3822                                      grep -e '- nid:' -e 'health value:'")
3823
3824         hval=$(grep -A 1 $nid<<<"$hval" | tail -n 1 | awk '{print $NF}')
3825         (( hval < 1000 )) ||
3826                 error "Expect $hval < 1000"
3827
3828         return 0
3829 }
3830 run_test 303 "Check peer NI health after link down"
3831
3832 test_304() {
3833         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
3834
3835         cleanup_netns || error "Failed to cleanup netns before test execution"
3836         cleanup_lnet || error "Failed to unload modules before test execution"
3837
3838         setup_fakeif || error "Failed to add fake IF"
3839         have_interface "$FAKE_IF" ||
3840                 error "Expect $FAKE_IF configured but not found"
3841
3842         reinit_dlc || return $?
3843
3844         add_net "tcp" "${INTERFACES[0]}" || return $?
3845         add_net "tcp" "$FAKE_IF" || return $?
3846
3847         local nid1=$(lctl list_nids | head -n 1)
3848         local nid2=$(lctl list_nids | tail --lines 1)
3849
3850         check_ni_status "$nid1" up
3851         check_ni_status "$nid2" up
3852
3853         do_lnetctl peer add --prim_nid ${nid2} --lock_prim ||
3854                 error "peer add failed $?"
3855         local locked_peer_state=($(do_lnetctl peer show -v 4 --nid ${nid2} |
3856                 awk '/peer state/{print $NF}'))
3857
3858         # Expect peer state bits:
3859         #   LNET_PEER_MULTI_RAIL(0) | LNET_PEER_CONFIGURED(3) |
3860         #   LNET_PEER_LOCK_PRIMARY(20)
3861         (( $locked_peer_state != "1048585")) &&
3862                 error "Wrong peer state \"$locked_peer_state\" expected 1048585"
3863
3864         # Clear LNET_PEER_CONFIGURED bit and verify
3865         do_lnetctl peer set --nid ${nid2} --state 1048577 ||
3866                 error "peer add failed $?"
3867         locked_peer_state=($(do_lnetctl peer show -v 4 --nid ${nid2} |
3868                 awk '/peer state/{print $NF}'))
3869         (( $locked_peer_state != "1048577")) &&
3870                 error "Wrong peer state \"$locked_peer_state\" expected 1048577"
3871         do_lnetctl discover ${nid1} ||
3872                 error "Failed to discover peer"
3873
3874         # Expect nid2 and nid1 peer entries to be consolidated,
3875         # nid2 to stay primary
3876         cat <<EOF >> $TMP/sanity-lnet-$testnum-expected.yaml
3877 peer:
3878     - primary nid: ${nid2}
3879       Multi-Rail: True
3880       peer ni:
3881         - nid: ${nid1}
3882           state: NA
3883         - nid: ${nid2}
3884           state: NA
3885 EOF
3886         $LNETCTL peer show > $TMP/sanity-lnet-$testnum-actual.yaml
3887         compare_yaml_files ||
3888                 error "Unexpected peer configuration"
3889
3890         locked_peer_state=($(do_lnetctl peer show -v 4 --nid ${nid2} |
3891                 awk '/peer state/{print $NF}'))
3892         # Expect peer state bits to be added:
3893         #   LNET_PEER_DISCOVERED(4) | LNET_PEER_NIDS_UPTODATE(8)
3894         (( $locked_peer_state != "1048849")) &&
3895                 error "Wrong peer state \"$locked_peer_state\" expected 1048849"
3896         return 0
3897 }
3898 run_test 304 "Check locked primary peer nid consolidation"
3899
3900 check_parameter() {
3901         local para=$1
3902         local value=$2
3903
3904         echo "check parameter ${para} value ${value}"
3905
3906         return $(( $(do_lnetctl net show -v | \
3907                      tee /dev/stderr | \
3908                      grep -c "^ \+${para}: ${value}$") != ${#INTERFACES[@]} ))
3909 }
3910
3911 static_config() {
3912         local module=$1
3913         local setting=$2
3914
3915         cleanup_lnet || error "Failed to cleanup LNet"
3916
3917         load_module ../libcfs/libcfs/libcfs ||
3918                 error "Failed to load module libcfs rc = $?"
3919
3920         load_module ../lnet/lnet/lnet ||
3921                 error "Failed to load module lnet rc = $?"
3922
3923         echo "loading ${module} ${setting} type ${NETTYPE}"
3924         load_module "${module}" "${setting}" ||
3925                 error "Failed to load module ${module} rc = $?"
3926
3927         do_lnetctl lnet configure --all || error "lnet configure failed rc = $?"
3928
3929         return 0
3930 }
3931
3932 test_310() {
3933         local value=65
3934
3935         if [[ ${NETTYPE} == tcp* ]];then
3936                 static_config "../lnet/klnds/socklnd/ksocklnd" \
3937                               "sock_timeout=${value}"
3938         elif [[ ${NETTYPE} == o2ib* ]]; then
3939                 static_config "../lnet/klnds/o2iblnd/ko2iblnd" \
3940                               "timeout=${value}"
3941         elif [[ ${NETTYPE} == gni* ]]; then
3942                 static_config "../lnet/klnds/gnilnd/kgnilnd" \
3943                               "timeout=${value}"
3944         else
3945                 skip "NETTYPE ${NETTYPE} not supported"
3946         fi
3947
3948         check_parameter "timeout" $value
3949
3950         return $?
3951 }
3952 run_test 310 "Set timeout and verify"
3953
3954 test_311() {
3955         [[ $NETTYPE == kfi* ]] ||
3956                 skip "Need kfi network type"
3957
3958         setupall || error "setupall failed"
3959
3960         mkdir -p $DIR/$tdir || error "mkdir failed"
3961         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 oflag=direct ||
3962                 error "dd write failed"
3963
3964         local list=$(comma_list $(osts_nodes))
3965
3966 #define CFS_KFI_FAIL_WAIT_SEND_COMP1 0xF115
3967         do_nodes $list $LCTL set_param fail_loc=0x8000F115
3968         dd if=$DIR/$tdir/$tfile of=/dev/null bs=1M count=1 ||
3969                 error "dd read failed"
3970
3971         rm -f $DIR/$tdir/$tfile
3972         rmdir $DIR/$tdir
3973
3974         cleanupall || error "Failed cleanup"
3975 }
3976 run_test 311 "Fail bulk put in send wait completion"
3977
3978 test_312() {
3979         [[ $NETTYPE == kfi* ]] ||
3980                 skip "Need kfi network type"
3981
3982         setupall || error "setupall failed"
3983
3984         mkdir -p $DIR/$tdir || error "mkdir failed"
3985
3986         local list=$(comma_list $(osts_nodes))
3987
3988 #define CFS_KFI_FAIL_WAIT_SEND_COMP3 0xF117
3989         do_nodes $list $LCTL set_param fail_loc=0x8000F117
3990         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 oflag=direct ||
3991                 error "dd write failed"
3992
3993         local tfile2="$DIR/$tdir/testfile2"
3994
3995         do_nodes $list $LCTL set_param fail_loc=0x8000F117
3996         dd if=$DIR/$tdir/$tfile of=$tfile2 bs=1M count=1 oflag=direct ||
3997                 error "dd read failed"
3998
3999         rm -f $DIR/$tdir/$tfile
4000         rm -f $tfile2
4001         rmdir $DIR/$tdir
4002
4003         cleanupall || error "Failed cleanup"
4004 }
4005 run_test 312 "TAG_RX_OK is possible after TX_FAIL"
4006
4007 check_udsp_prio() {
4008         local target_net="${1}"
4009         local target_nid="${2}"
4010         local expect_net="${3}"
4011         local expect_nid="${4}"
4012         local type="${5}"
4013
4014         declare -a nids
4015         declare -a net_prios
4016         declare -a nid_prios
4017
4018         nids=( $($LNETCTL ${type} show -v 5 | awk '/-\s+nid:/{print $NF}' |
4019                  xargs echo) )
4020
4021         net_prios=( $($LNETCTL ${type} show -v 5 |
4022                       awk '/net priority:/{print $NF}' | xargs echo) )
4023
4024         nid_prios=( $($LNETCTL ${type} show -v 5 |
4025                       awk '/nid priority:/{print $NF}' | xargs echo) )
4026
4027         (( ${#nids[@]} != ${#net_prios[@]} )) &&
4028                 error "Wrong # net prios ${#nids[@]} != ${#net_prios[@]}"
4029
4030         (( ${#nids[@]} != ${#nid_prios[@]} )) &&
4031                 error "Wrong # nid prios ${#nids[@]} != ${#nid_prios[@]}"
4032
4033         local i
4034
4035         for ((i = 0; i < ${#nids[@]}; i++)); do
4036                 [[ -n ${target_net} ]] &&
4037                         [[ ${nids[i]##*@} != "${target_net}" ]] &&
4038                         continue
4039                 [[ -n ${target_nid} ]] &&
4040                         [[ ${nids[i]} != "${target_nid}" ]] &&
4041                         continue
4042
4043                 echo "${nids[i]}: net_prio ${net_prios[i]} expect ${expect_net}"
4044                 (( net_prios[i] != expect_net )) &&
4045                         error "Wrong net priority \"${net_prios[i]}\" expect ${expect_net}"
4046
4047                 echo "${nids[i]}: nid_prio ${nid_prios[i]} expect ${expect_nid}"
4048                 (( nid_prios[i] != expect_nid )) &&
4049                         error "Wrong nid priority \"${nid_prios[i]}\" expect ${expect_nid}"
4050         done
4051
4052         return 0
4053 }
4054
4055 check_peer_udsp_prio() {
4056         check_udsp_prio "${1}" "${2}" "${3}" "${4}" "peer"
4057 }
4058
4059 check_net_udsp_prio() {
4060         check_udsp_prio "${1}" "${2}" "${3}" "${4}" "net"
4061 }
4062
4063 test_400() {
4064         reinit_dlc || return $?
4065
4066         do_lnetctl udsp add --src tcp --priority 0 ||
4067                 error "Failed to add udsp rule"
4068         do_lnetctl udsp del --idx 0 ||
4069                 error "Failed to del udsp rule"
4070         unload_modules
4071 }
4072 run_test 400 "Check for udsp add/delete net rule without net num"
4073
4074 test_401() {
4075         reinit_dlc || return $?
4076
4077         do_lnetctl net add --net ${NETTYPE} --if ${INTERFACES[0]} ||
4078                 error "Failed to add net"
4079
4080         do_lnetctl udsp add --dst ${NETTYPE} --prio 1 ||
4081                 error "Failed to add peer net priority rule"
4082
4083         do_lnetctl discover $($LCTL list_nids | head -n 1) ||
4084                 error "Failed to discover peer"
4085
4086         check_peer_udsp_prio "${NETTYPE}" "" "1" "-1"
4087
4088         return 0
4089 }
4090 run_test 401 "Discover peer after adding peer net UDSP rule"
4091
4092 test_402() {
4093         reinit_dlc || return $?
4094
4095         do_lnetctl udsp add --dst kfi --priority 0 ||
4096                 error "Failed to add UDSP rule"
4097
4098         do_lnetctl peer add --prim 402@kfi ||
4099                 error "Failed to add peer"
4100
4101         return 0
4102 }
4103 run_test 402 "Destination net rule should not panic"
4104
4105 test_500() {
4106         reinit_dlc || return $?
4107
4108         cleanup_netns || error "Failed to cleanup netns before test execution"
4109         setup_fakeif || error "Failed to add fake IF"
4110         have_interface "$FAKE_IF" ||
4111                 error "Expect $FAKE_IF configured but not found"
4112
4113         add_net "tcp" "${INTERFACES[0]}"
4114         add_net "tcp" "${FAKE_IF}"
4115
4116         do_lnetctl discover $($LCTL list_nids | head -n 1) ||
4117                 error "Failed to discover self"
4118
4119         $LCTL net_delay_add -s *@tcp -d *@tcp -r 1 -l 1 -m PUT ||
4120                 error "Failed to add delay rule"
4121
4122         $LCTL net_drop_add -s *@tcp -d $($LCTL list_nids | head -n 1) -m PUT \
4123                 -e local_timeout -r 1 ||
4124                 error "Failed to add drop rule"
4125         $LCTL net_drop_add -s *@tcp -d $($LCTL list_nids | tail -n 1) -m PUT \
4126                 -e local_timeout -r 1 ||
4127                 error "Failed to add drop rule"
4128
4129         ip link set $FAKE_IF down ||
4130                 error "Failed to set link down"
4131         ip link set $FAKE_IF up ||
4132                 error "Failed to set link up"
4133
4134         unload_modules
4135 }
4136 run_test 500 "Check deadlock on ping target update"
4137
4138 do_peer_set_health_test() {
4139         local test_val="$1"
4140         shift
4141         local nid_arg="$@"
4142
4143         local max_hval
4144
4145         if [[ ${nid_arg} == --all ]]; then
4146                 max_hval=$($LNETCTL peer show -v 2 2>/dev/null |
4147                            awk '/health value/{print $NF}' | xargs echo |
4148                            sed 's/ /+/g' | bc -l)
4149         else
4150                 max_hval=$($LNETCTL peer show ${nid_arg} -v 2 2>/dev/null |
4151                            awk '/health value/{print $NF}' | xargs echo |
4152                            sed 's/ /+/g' | bc -l)
4153         fi
4154
4155         (( max_hval >= 1000 )) && (( max_hval % 1000 == 0)) ||
4156                 error "Unexpected max health value $max_hval"
4157
4158         lnet_health_pre || return $?
4159
4160         do_lnetctl peer set --health $test_val ${nid_arg} ||
4161                 error "failed to set health value"
4162
4163         lnet_health_post || return $?
4164
4165         local hval
4166
4167         if [[ ${nid_arg} == --all ]]; then
4168                 hval=$($LNETCTL peer show -v 2 2>/dev/null |
4169                        awk '/health value/{print $NF}' | xargs echo |
4170                        sed 's/ /+/g' | bc -l)
4171         else
4172                 hval=$($LNETCTL peer show ${nid_arg} -v 2 2>/dev/null |
4173                        awk '/health value/{print $NF}' | xargs echo |
4174                        sed 's/ /+/g' | bc -l)
4175         fi
4176
4177         check_remote_health || return $?
4178
4179         echo "hval: $hval max_hval: $max_hval"
4180         (( hval == max_hval )) || error "Failed to reset health to max"
4181
4182         return 0
4183 }
4184
4185 test_501() {
4186         reinit_dlc || return $?
4187
4188         setup_health_test false || return $?
4189
4190         $LCTL set_param debug=-1
4191
4192         $LCTL net_drop_add -s *@tcp -d *@tcp -r 1 ||
4193                 error "Failed to add drop rule"
4194
4195         local test_val
4196
4197         for test_val in 0 500; do
4198                 do_peer_set_health_test $test_val --nid ${RNIDS[0]} || return $?
4199                 do_peer_set_health_test $test_val --all || return $?
4200         done
4201
4202         cleanup_health_test
4203 }
4204 run_test 501 "Verify lnetctl peer set --health (SR)"
4205
4206 test_502() {
4207         reinit_dlc || return $?
4208
4209         setup_health_test true || return $?
4210
4211         $LCTL set_param debug=-1
4212
4213         $LCTL net_drop_add -s *@tcp -d *@tcp -r 1 ||
4214                 error "Failed to add drop rule"
4215
4216         local test_val
4217
4218         for test_val in 0 500; do
4219                 do_peer_set_health_test $test_val --nid ${RNIDS[0]} || return $?
4220                 do_peer_set_health_test $test_val --all || return $?
4221         done
4222
4223         cleanup_health_test
4224 }
4225 run_test 502 "Verify lnetctl peer set --health (MR)"
4226
4227 complete_test $SECONDS
4228 cleanup_testsuite
4229 exit_status