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