Whamcloud - gitweb
LU-17744 ldiskfs: mballoc stats fixes
[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 ARR_IF0_IP=($(ip -o -4 a s ${INTERFACES[0]} |
1168             awk '{print $4}' | sed 's/\/.*//'))
1169 echo "Total IP for ${INTERFACES[0]} found [${#ARR_IF0_IP[@]}]"
1170 echo "Interface:IP are"
1171 for i in ${ARR_IF0_IP[@]}; do
1172         echo "${INTERFACES[0]}:$i"
1173 done
1174 IF0_IP=${ARR_IF0_IP[0]}
1175 IF0_NET=$(awk -F. '{print $1"."$2"."$3}'<<<"${IF0_IP}")
1176 IF0_HOSTNUM=$(awk -F. '{print $4}'<<<"${IF0_IP}")
1177 if (((IF0_HOSTNUM + 5) > 254)); then
1178         GW_HOSTNUM=1
1179 else
1180         GW_HOSTNUM=$((IF0_HOSTNUM + 1))
1181 fi
1182 GW_NID="${IF0_NET}.${GW_HOSTNUM}@${NETTYPE}"
1183 echo "Using GW_NID:$GW_NID"
1184
1185 test_100() {
1186         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
1187
1188         reinit_dlc || return $?
1189         add_net "${NETTYPE}" "${INTERFACES[0]}"
1190         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
1191 net:
1192     - net type: ${NETTYPE}
1193       local NI(s):
1194         - interfaces:
1195               0: ${INTERFACES[0]}
1196 EOF
1197         append_net_tunables tcp
1198         cat <<EOF >> $TMP/sanity-lnet-$testnum-expected.yaml
1199 route:
1200     - net: tcp7
1201       gateway: ${GW_NID}
1202       hop: -1
1203       priority: 0
1204       health_sensitivity: 1
1205 peer:
1206     - primary nid: ${GW_NID}
1207       Multi-Rail: False
1208       peer ni:
1209         - nid: ${GW_NID}
1210 EOF
1211         append_global_yaml
1212         compare_route_add "tcp7" "${GW_NID}"
1213 }
1214 run_test 100 "Add route with single gw (tcp)"
1215
1216 test_101() {
1217         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
1218
1219         reinit_dlc || return $?
1220         add_net "${NETTYPE}" "${INTERFACES[0]}"
1221         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
1222 net:
1223     - net type: ${NETTYPE}
1224       local NI(s):
1225         - interfaces:
1226               0: ${INTERFACES[0]}
1227 EOF
1228         append_net_tunables tcp
1229
1230         echo "route:" >> $TMP/sanity-lnet-$testnum-expected.yaml
1231         for i in $(seq $GW_HOSTNUM $((GW_HOSTNUM + 4))); do
1232                 cat <<EOF >> $TMP/sanity-lnet-$testnum-expected.yaml
1233     - net: tcp8
1234       gateway: ${IF0_NET}.${i}@tcp
1235       hop: -1
1236       priority: 0
1237       health_sensitivity: 1
1238 EOF
1239         done
1240
1241         echo "peer:" >> $TMP/sanity-lnet-$testnum-expected.yaml
1242         for i in $(seq $GW_HOSTNUM $((GW_HOSTNUM + 4))); do
1243                 cat <<EOF >> $TMP/sanity-lnet-$testnum-expected.yaml
1244     - primary nid: ${IF0_NET}.${i}@tcp
1245       Multi-Rail: False
1246       peer ni:
1247         - nid: ${IF0_NET}.${i}@tcp
1248 EOF
1249         done
1250         append_global_yaml
1251
1252         local gw="${IF0_NET}.[$GW_HOSTNUM-$((GW_HOSTNUM + 4))]@tcp"
1253
1254         compare_route_add "tcp8" "${gw}"
1255 }
1256 run_test 101 "Add route with multiple gw (tcp)"
1257
1258 compare_route_del() {
1259         local rnet="$1"
1260         local gw="$2"
1261
1262         local actual="$TMP/sanity-lnet-$testnum-actual.yaml"
1263
1264         do_lnetctl route del --net ${rnet} --gateway ${gw} ||
1265                 error "route del failed $?"
1266         $LNETCTL export --backup > $actual ||
1267                 error "export failed $?"
1268         validate_gateway_nids
1269 }
1270
1271 generate_gw_nid() {
1272         local net=${1}
1273
1274         if [[ ${net} =~ (tcp|o2ib)[0-9]* ]]; then
1275                 echo "${GW_NID}"
1276         else
1277                 echo "$((${testnum} % 255))@${net}"
1278         fi
1279 }
1280
1281 test_102() {
1282         reinit_dlc || return $?
1283         add_net "${NETTYPE}" "${INTERFACES[0]}"
1284         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-expected.yaml
1285
1286         local gwnid=$(generate_gw_nid ${NETTYPE})
1287
1288         do_lnetctl route add --net ${NETTYPE}2 --gateway ${gwnid} ||
1289                 error "route add failed $?"
1290         compare_route_del "${NETTYPE}2" "${gwnid}"
1291 }
1292 run_test 102 "Delete route with single gw"
1293
1294 IP_NID_EXPR='103.103.103.[103-120/4]'
1295 NUM_NID_EXPR='[103-120/4]'
1296 test_103() {
1297         reinit_dlc || return $?
1298         add_net "${NETTYPE}" "${INTERFACES[0]}"
1299         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-expected.yaml
1300
1301         local nid_expr
1302
1303         if [[ $NETTYPE =~ (tcp|o2ib)[0-9]* ]]; then
1304                 nid_expr="${IF0_NET}.[$GW_HOSTNUM-$((GW_HOSTNUM+5))/2]"
1305         else
1306                 nid_expr="${NUM_NID_EXPR}"
1307         fi
1308
1309         do_lnetctl route add --net ${NETTYPE}103 \
1310                 --gateway ${nid_expr}@${NETTYPE} ||
1311                 error "route add failed $?"
1312         compare_route_del "${NETTYPE}103" "${nid_expr}@${NETTYPE}"
1313 }
1314 run_test 103 "Delete route with multiple gw"
1315
1316 test_104() {
1317         local tyaml="$TMP/sanity-lnet-$testnum-expected.yaml"
1318
1319         reinit_dlc || return $?
1320
1321         # Default value is '3'
1322         local val=$($LNETCTL global show | awk '/response_tracking/{print $NF}')
1323         [[ $val -ne 3 ]] &&
1324                 error "Expect 3 found $val"
1325
1326         echo "Set < 0;  Should fail"
1327         do_lnetctl set response_tracking -1 &&
1328                 error "should have failed $?"
1329
1330         reinit_dlc || return $?
1331         cat <<EOF > $tyaml
1332 global:
1333     response_tracking: -10
1334 EOF
1335         do_lnetctl import < $tyaml &&
1336                 error "should have failed $?"
1337
1338         echo "Check valid values; Should succeed"
1339         local i
1340         for ((i = 0; i < 4; i++)); do
1341                 reinit_dlc || return $?
1342                 do_lnetctl set response_tracking $i ||
1343                         error "should have succeeded $?"
1344                 $LNETCTL global show | grep -q "response_tracking: $i" ||
1345                         error "Failed to set response_tracking to $i"
1346                 reinit_dlc || return $?
1347                 cat <<EOF > $tyaml
1348 global:
1349     response_tracking: $i
1350 EOF
1351                 do_lnetctl import < $tyaml ||
1352                         error "should have succeeded $?"
1353                 $LNETCTL global show | grep -q "response_tracking: $i" ||
1354                         error "Failed to set response_tracking to $i"
1355         done
1356
1357         reinit_dlc || return $?
1358         echo "Set > 3; Should fail"
1359         do_lnetctl set response_tracking 4 &&
1360                 error "should have failed $?"
1361
1362         reinit_dlc || return $?
1363         cat <<EOF > $tyaml
1364 global:
1365     response_tracking: 10
1366 EOF
1367         do_lnetctl import < $tyaml &&
1368                 error "should have failed $?"
1369         return 0
1370 }
1371 run_test 104 "Set/check response_tracking param"
1372
1373 test_105() {
1374         reinit_dlc || return $?
1375         add_net "${NETTYPE}" "${INTERFACES[0]}"
1376
1377         local gwnid=$(generate_gw_nid ${NETTYPE})
1378
1379         do_lnetctl route add --net ${NETTYPE}105 --gateway ${gwnid} ||
1380                 error "route add failed $?"
1381         do_lnetctl peer add --prim ${gwnid} &&
1382                 error "peer add should fail"
1383
1384         return 0
1385 }
1386 run_test 105 "Adding duplicate GW peer should fail"
1387
1388 test_106() {
1389         reinit_dlc || return $?
1390         add_net "${NETTYPE}" "${INTERFACES[0]}"
1391
1392         local gwnid=$(generate_gw_nid ${NETTYPE})
1393
1394         do_lnetctl route add --net ${NETTYPE}106 --gateway ${gwnid} ||
1395                 error "route add failed $?"
1396         do_lnetctl peer del --prim ${gwnid} &&
1397                 error "peer del should fail"
1398
1399         return 0
1400 }
1401 run_test 106 "Deleting GW peer should fail"
1402
1403 test_107() {
1404         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
1405
1406         cleanup_netns || error "Failed to cleanup netns before test execution"
1407         cleanup_lnet || error "Failed to unload modules before test execution"
1408
1409         setup_fakeif || error "Failed to add fake IF"
1410         have_interface "$FAKE_IF" ||
1411                 error "Expect $FAKE_IF configured but not found"
1412
1413         reinit_dlc || return $?
1414
1415         add_net "tcp" "${INTERFACES[0]}" || return $?
1416         add_net "tcp" "$FAKE_IF" || return $?
1417
1418         del_net "tcp" "$FAKE_IF" || return $?
1419
1420         cleanup_fakeif
1421         cleanup_lnet
1422         setup_netns
1423 }
1424 run_test 107 "Deleting extra interface doesn't crash node"
1425
1426 test_108() {
1427         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
1428
1429         cleanup_netns || error "Failed to cleanup netns before test execution"
1430         cleanup_lnet || error "Failed to unload modules before test execution"
1431
1432         setup_fakeif || error "Failed to add fake IF"
1433         have_interface "$FAKE_IF" ||
1434                 error "Expect $FAKE_IF configured but not found"
1435
1436         reinit_dlc || return $?
1437
1438         add_net "tcp" "${INTERFACES[0]}" || return $?
1439         $LNETCTL net show > $TMP/sanity-lnet-$testnum-expected.yaml
1440         add_net "tcp" "$FAKE_IF" || return $?
1441
1442         cat <<EOF >> $TMP/sanity-lnet-$testnum-expected.yaml
1443       -     nid: ${FAKE_IP}@tcp
1444             status: up
1445             interfaces:
1446                   0: ${FAKE_IF}
1447 EOF
1448         $LNETCTL net show > $TMP/sanity-lnet-$testnum-actual.yaml
1449         compare_yaml_files || error "not all interfaces were setup"
1450
1451         cleanup_fakeif
1452         cleanup_lnet
1453         setup_netns
1454
1455         return 0
1456 }
1457 run_test 108 "Check Multi-Rail setup"
1458
1459 test_109() {
1460         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
1461
1462         cleanup_netns || error "Failed to cleanup netns before test execution"
1463         cleanup_lnet || error "Failed to unload modules before test execution"
1464
1465         setup_fakeif || error "Failed to add fake IF"
1466         have_interface "$FAKE_IF" ||
1467                 error "Expect $FAKE_IF configured but not found"
1468
1469         FAKE_IF_ALIAS="${FAKE_IF}"
1470         FAKE_IF_ALIAS+=":0"
1471
1472         ifconfig "$FAKE_IF_ALIAS" "$FAKE_IP_ALIAS" up ||
1473                 error "Failed to add fake IF alias"
1474
1475         reinit_dlc || return $?
1476
1477         # add interface with longer name first
1478         add_net "tcp" "$FAKE_IF_ALIAS" || return $?
1479         add_net "tcp" "$FAKE_IF" || return $?
1480
1481         del_net "tcp" "$FAKE_IF" || return $?
1482         del_net "tcp" "$FAKE_IF_ALIAS" || return $?
1483
1484         # add interface with shorter name first
1485         add_net "tcp" "$FAKE_IF" || return $?
1486         add_net "tcp" "$FAKE_IF_ALIAS" || return $?
1487
1488         ifconfig "$FAKE_IF_ALIAS" "$FAKE_IP_ALIAS" down ||
1489                 error "Failed to clean up fake IF alias"
1490
1491         cleanup_fakeif
1492         cleanup_lnet
1493         setup_netns
1494 }
1495 run_test 109 "Add NI using a network interface alias (LU-16859)"
1496
1497 test_110() {
1498         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
1499
1500         cleanup_netns || error "Failed to cleanup netns before test execution"
1501         cleanup_lnet || error "Failed to unload modules before test execution"
1502
1503         configure_dlc || error "Failed to configure DLC rc = $?"
1504
1505         LOCAL_ADDR_LIST=$(local_addr_list)
1506         set -- $LOCAL_ADDR_LIST
1507         do_lnetctl net add --nid $2@tcp ||
1508                 error "Failed to add net tcp for IP $2@tcp"
1509
1510         $LNETCTL net show --net tcp | grep -q "nid: $2@tcp" ||
1511                 error "Failed to configure $2@tcp"
1512
1513         do_lnetctl net del --nid $2@tcp ||
1514                 error "Failed to del net tcp for IP $2@tcp"
1515
1516         $LNETCTL net show | grep -q "nid: $2@tcp"&&
1517                 error "$2@tcp should have been deleted"
1518
1519         cleanup_lnet
1520         setup_netns
1521 }
1522 run_test 110 "Add NI using a specific TCP / IP address"
1523
1524 test_200() {
1525         [[ ${NETTYPE} == tcp* ]] ||
1526                 skip "Need tcp NETTYPE"
1527         cleanup_lnet || exit 1
1528         load_lnet "networks=\"\""
1529         do_ns $LNETCTL lnet configure --all || exit 1
1530         $LNETCTL net show --net tcp | grep -q "nid: ${FAKE_IP}@tcp$"
1531 }
1532 run_test 200 "load lnet w/o module option, configure in a non-default namespace"
1533
1534 test_201() {
1535         [[ ${NETTYPE} == tcp* ]] ||
1536                 skip "Need tcp NETTYPE"
1537         cleanup_lnet || exit 1
1538         load_lnet "networks=tcp($FAKE_IF)"
1539         do_ns $LNETCTL lnet configure --all || exit 1
1540         $LNETCTL net show --net tcp | grep -q "nid: ${FAKE_IP}@tcp$"
1541 }
1542 run_test 201 "load lnet using networks module options in a non-default namespace"
1543
1544 test_202() {
1545         [[ ${NETTYPE} == tcp* ]] ||
1546                 skip "Need tcp NETTYPE"
1547         cleanup_lnet || exit 1
1548         load_lnet "networks=\"\" ip2nets=\"tcp0($FAKE_IF) ${FAKE_IP}\""
1549         do_ns $LNETCTL lnet configure --all || exit 1
1550         $LNETCTL net show | grep -q "nid: ${FAKE_IP}@tcp$"
1551 }
1552 run_test 202 "load lnet using ip2nets in a non-default namespace"
1553
1554
1555 ### Add the interfaces in the target namespace
1556
1557 test_203() {
1558         [[ ${NETTYPE} == tcp* ]] ||
1559                 skip "Need tcp NETTYPE"
1560         cleanup_lnet || exit 1
1561         load_lnet
1562         do_lnetctl lnet configure || exit 1
1563         do_ns $LNETCTL net add --net tcp0 --if $FAKE_IF
1564 }
1565 run_test 203 "add a network using an interface in the non-default namespace"
1566
1567 LNET_PARAMS_FILE="$TMP/$TESTSUITE.parameters"
1568 function save_lnet_params() {
1569         $LNETCTL global show | egrep -v '^global:$' |
1570                                sed 's/://' > $LNET_PARAMS_FILE
1571 }
1572
1573 function restore_lnet_params() {
1574         local param value
1575         while read param value; do
1576                 [[ $param == max_intf ]] && continue
1577                 [[ $param == lnd_timeout ]] && continue
1578                 $LNETCTL set ${param} ${value} ||
1579                         error "Failed to restore ${param} to ${value}"
1580         done < $LNET_PARAMS_FILE
1581 }
1582
1583 function lnet_health_pre() {
1584         save_lnet_params
1585
1586         # Lower transaction timeout to speed up test execution
1587         $LNETCTL set transaction_timeout 10 ||
1588                 error "Failed to set transaction_timeout $?"
1589
1590         RETRY_PARAM=$($LNETCTL global show | awk '/retry_count/{print $NF}')
1591         RSND_PRE=$($LNETCTL stats show | awk '/resend_count/{print $NF}')
1592         LO_HVAL_PRE=$($LNETCTL net show -v 2 | awk '/health value/{print $NF}' |
1593                       xargs echo | sed 's/ /+/g' | bc -l)
1594
1595         RMT_HVAL_PRE=$($LNETCTL peer show --nid ${RNIDS[0]} -v 2 2>/dev/null |
1596                        awk '/health value/{print $NF}' | xargs echo |
1597                        sed 's/ /+/g' | bc -l)
1598
1599         # Might not have any peers so initialize to zero.
1600         RMT_HVAL_PRE=${RMT_HVAL_PRE:-0}
1601
1602         return 0
1603 }
1604
1605 function lnet_health_post() {
1606         RSND_POST=$($LNETCTL stats show | awk '/resend_count/{print $NF}')
1607         LO_HVAL_POST=$($LNETCTL net show -v 2 |
1608                        awk '/health value/{print $NF}' |
1609                        xargs echo | sed 's/ /+/g' | bc -l)
1610
1611         RMT_HVAL_POST=$($LNETCTL peer show --nid ${RNIDS[0]} -v 2 2>/dev/null |
1612                         awk '/health value/{print $NF}' | xargs echo |
1613                         sed 's/ /+/g' | bc -l)
1614
1615         # Might not have any peers so initialize to zero.
1616         RMT_HVAL_POST=${RMT_HVAL_POST:-0}
1617
1618         ${VERBOSE} &&
1619         echo "Pre resends: $RSND_PRE" &&
1620         echo "Post resends: $RSND_POST" &&
1621         echo "Resends delta: $((RSND_POST - RSND_PRE))" &&
1622         echo "Pre local health: $LO_HVAL_PRE" &&
1623         echo "Post local health: $LO_HVAL_POST" &&
1624         echo "Pre remote health: $RMT_HVAL_PRE" &&
1625         echo "Post remote health: $RMT_HVAL_POST"
1626
1627         restore_lnet_params
1628
1629         do_lnetctl peer set --health 1000 --all
1630         do_lnetctl net set --health 1000 --all
1631
1632         return 0
1633 }
1634
1635 function check_no_resends() {
1636         echo "Check that no resends took place"
1637         [[ $RSND_POST -ne $RSND_PRE ]] &&
1638                 error "Found resends: $RSND_POST != $RSND_PRE"
1639
1640         return 0
1641 }
1642
1643 function check_resends() {
1644         local delta=$((RSND_POST - RSND_PRE))
1645
1646         echo "Check that $RETRY_PARAM resends took place"
1647         [[ $delta -ne $RETRY_PARAM ]] &&
1648                 error "Expected $RETRY_PARAM resends found $delta"
1649
1650         return 0
1651 }
1652
1653 function check_no_local_health() {
1654         echo "Check that local NI health is unchanged"
1655         [[ $LO_HVAL_POST -ne $LO_HVAL_PRE ]] &&
1656                 error "Local health changed: $LO_HVAL_POST != $LO_HVAL_PRE"
1657
1658         return 0
1659 }
1660
1661 function check_local_health() {
1662         echo "Check that local NI health has been changed"
1663         [[ $LO_HVAL_POST -eq $LO_HVAL_PRE ]] &&
1664                 error "Local health unchanged: $LO_HVAL_POST == $LO_HVAL_PRE"
1665
1666         return 0
1667 }
1668
1669 function check_no_remote_health() {
1670         echo "Check that remote NI health is unchanged"
1671         [[ $RMT_HVAL_POST -ne $RMT_HVAL_PRE ]] &&
1672                 error "Remote health changed: $RMT_HVAL_POST != $RMT_HVAL_PRE"
1673
1674         return 0
1675 }
1676
1677 function check_remote_health() {
1678         echo "Check that remote NI health has been changed"
1679         [[ $RMT_HVAL_POST -eq $RMT_HVAL_PRE ]] &&
1680                 error "Remote health unchanged: $RMT_HVAL_POST == $RMT_HVAL_PRE"
1681
1682         return 0
1683 }
1684
1685 RNODE=""
1686 RLOADED=false
1687 NET_DEL_ARGS=""
1688 RNIDS=( )
1689 LNIDS=( )
1690 setup_health_test() {
1691         local need_mr=$1
1692         local rc=0
1693
1694         [[ ${NETTYPE} == kfi* ]] && skip "kfi doesn't support drop rules"
1695
1696         local rnodes=$(remote_nodes_list)
1697         [[ -z $rnodes ]] && skip "Need at least 1 remote node"
1698
1699         cleanup_lnet || error "Failed to cleanup before test execution"
1700
1701         # Loading modules should configure LNet with the appropriate
1702         # test-framework configuration
1703         load_lnet "config_on_load=1" || error "Failed to load modules"
1704
1705         LNIDS=( $($LCTL list_nids | xargs echo) )
1706
1707         RNODE=$(awk '{print $1}' <<<$rnodes)
1708         RNIDS=( $(do_node $RNODE $LCTL list_nids | xargs echo) )
1709
1710         if [[ -z ${RNIDS[@]} ]]; then
1711                 do_rpc_nodes $RNODE load_lnet "config_on_load=1"
1712                 RLOADED=true
1713                 RNIDS=( $(do_node $RNODE $LCTL list_nids | xargs echo) )
1714         fi
1715
1716         [[ ${#LNIDS[@]} -lt 1 ]] &&
1717                 error "No NIDs configured for local host $HOSTNAME"
1718         [[ ${#RNIDS[@]} -lt 1 ]] &&
1719                 error "No NIDs configured for remote host $RNODE"
1720
1721         # Ensure all peer NIs are local (i.e. non-routed config)
1722         local rnid rnet lnid lnet
1723
1724         for rnid in ${RNIDS[@]}; do
1725                 rnet=${rnid##*@}
1726                 for lnid in ${LNIDS[@]}; do
1727                         lnet=${lnid##*@}
1728                         [[ ${lnet} == ${rnet} ]] &&
1729                                 break
1730                 done
1731                 [[ ${lnet} != ${rnet} ]] &&
1732                         skip "Need non-routed configuration"
1733         done
1734
1735         do_lnetctl discover ${RNIDS[0]} ||
1736                 error "Unable to discover ${RNIDS[0]}"
1737
1738         local mr=$($LNETCTL peer show --nid ${RNIDS[0]} |
1739                    awk '/Multi-Rail/{print $NF}')
1740
1741         if ${need_mr} && [[ $mr == False ]]; then
1742                 cleanup_health_test || return $?
1743                 skip "Need MR peer"
1744         fi
1745
1746         if ( ! ${need_mr} && [[ ${#RNIDS[@]} -gt 1 ]] ) ||
1747            ( ! ${need_mr} && [[ ${#LNIDS[@]} -gt 1 ]] ); then
1748                 cleanup_health_test || return $?
1749                 skip "Need SR peer"
1750         fi
1751
1752         if ${need_mr} && [[ ${#RNIDS[@]} -lt 2 ]]; then
1753                 # Add a second, reachable NID to rnode.
1754                 local net=${RNIDS[0]}
1755
1756                 net="${net//*@/}1"
1757
1758                 local if=$(do_rpc_nodes --quiet $RNODE lnet_if_list)
1759                 [[ -z $if ]] &&
1760                         error "Failed to determine interface for $RNODE"
1761
1762                 do_rpc_nodes $RNODE "$LNETCTL lnet configure"
1763                 do_rpc_nodes $RNODE "$LNETCTL net add --net $net --if $if" ||
1764                         rc=$?
1765                 if [[ $rc -ne 0 ]]; then
1766                         error "Failed to add interface to $RNODE rc=$?"
1767                 else
1768                         RNIDS[1]="${RNIDS[0]}1"
1769                         NET_DEL_ARGS="--net $net --if $if"
1770                 fi
1771         fi
1772
1773         if ${need_mr} && [[ ${#LNIDS[@]} -lt 2 ]]; then
1774                 local net=${LNIDS[0]}
1775                 net="${net//*@/}1"
1776
1777                 do_lnetctl lnet configure &&
1778                         do_lnetctl net add --net $net --if ${INTERFACES[0]} ||
1779                         rc=$?
1780                 if [[ $rc -ne 0 ]]; then
1781                         error "Failed to add interface rc=$?"
1782                 else
1783                         LNIDS[1]="${LNIDS[0]}1"
1784                 fi
1785         fi
1786
1787         $LNETCTL net show
1788
1789         $LNETCTL peer show -v 2 | egrep -e nid -e health
1790
1791         $LCTL set_param debug=+net
1792
1793         return 0
1794
1795 }
1796
1797 cleanup_health_test() {
1798         local rc=0
1799
1800         if [[ -n $NET_DEL_ARGS ]]; then
1801                 do_rpc_nodes $RNODE \
1802                         "$LNETCTL net del $NET_DEL_ARGS" ||
1803                         rc=$((rc + $?))
1804                 NET_DEL_ARGS=""
1805         fi
1806
1807         unload_modules || rc=$?
1808
1809         if $RLOADED; then
1810                 do_rpc_nodes $RNODE unload_modules_local ||
1811                         rc=$((rc + $?))
1812                 RLOADED=false
1813         fi
1814
1815         [[ $rc -ne 0 ]] &&
1816                 error "Failed cleanup"
1817
1818         return $rc
1819 }
1820
1821 add_health_test_drop_rules() {
1822         local args="-m GET -r 1 -e ${1}"
1823         local src dst
1824
1825         for src in "${LNIDS[@]}"; do
1826                 for dst in "${RNIDS[@]}" "${LNIDS[@]}"; do
1827                         $LCTL net_drop_add -s $src -d $dst ${args} ||
1828                                 error "Failed to add drop rule $src $dst $args"
1829                 done
1830         done
1831 }
1832
1833 do_lnet_health_ping_test() {
1834         local hstatus="$1"
1835
1836         echo "Simulate $hstatus"
1837
1838         lnet_health_pre || return $?
1839
1840         add_health_test_drop_rules ${hstatus}
1841         do_lnetctl ping ${RNIDS[0]} &&
1842                 error "Should have failed"
1843
1844         lnet_health_post
1845
1846         $LCTL net_drop_del -a
1847
1848         return 0
1849 }
1850
1851 # See lnet/lnet/lib-msg.c:lnet_health_check()
1852 LNET_LOCAL_RESEND_STATUSES="local_interrupt local_dropped local_aborted"
1853 LNET_LOCAL_RESEND_STATUSES+=" local_no_route local_timeout"
1854 LNET_LOCAL_NO_RESEND_STATUSES="local_error"
1855 test_204() {
1856         setup_health_test false || return $?
1857
1858         local hstatus
1859         for hstatus in ${LNET_LOCAL_RESEND_STATUSES} \
1860                        ${LNET_LOCAL_NO_RESEND_STATUSES}; do
1861                 do_lnet_health_ping_test "${hstatus}" || return $?
1862                 check_no_resends || return $?
1863                 check_no_local_health || return $?
1864         done
1865
1866         cleanup_health_test || return $?
1867
1868         return 0
1869 }
1870 run_test 204 "Check no health or resends for single-rail local failures"
1871
1872 test_205() {
1873         (( $MDS1_VERSION >= $(version_code 2.14.58) )) ||
1874                 skip "need at least 2.14.58"
1875
1876         setup_health_test true || return $?
1877
1878         local hstatus
1879         for hstatus in ${LNET_LOCAL_RESEND_STATUSES}; do
1880                 do_lnet_health_ping_test "${hstatus}" || return $?
1881                 check_resends || return $?
1882                 check_local_health || return $?
1883         done
1884
1885         for hstatus in ${LNET_LOCAL_NO_RESEND_STATUSES}; do
1886                 do_lnet_health_ping_test "${hstatus}" || return $?
1887                 check_no_resends || return $?
1888                 check_local_health || return $?
1889         done
1890
1891         cleanup_health_test || return $?
1892
1893         return 0
1894 }
1895 run_test 205 "Check health and resends for multi-rail local failures"
1896
1897 # See lnet/lnet/lib-msg.c:lnet_health_check()
1898 LNET_REMOTE_RESEND_STATUSES="remote_dropped"
1899 LNET_REMOTE_NO_RESEND_STATUSES="remote_error remote_timeout"
1900 test_206() {
1901         setup_health_test false || return $?
1902
1903         local hstatus
1904         for hstatus in ${LNET_REMOTE_RESEND_STATUSES} \
1905                        ${LNET_REMOTE_NO_RESEND_STATUSES}; do
1906                 do_lnet_health_ping_test "${hstatus}" || return $?
1907                 check_no_resends || return $?
1908                 check_no_local_health || return $?
1909                 check_no_remote_health || return $?
1910         done
1911
1912         cleanup_health_test || return $?
1913
1914         return 0
1915 }
1916 run_test 206 "Check no health or resends for single-rail remote failures"
1917
1918 test_207() {
1919         (( $MDS1_VERSION >= $(version_code 2.14.58) )) ||
1920                 skip "need at least 2.14.58"
1921
1922         setup_health_test true || return $?
1923
1924         local hstatus
1925         for hstatus in ${LNET_REMOTE_RESEND_STATUSES}; do
1926                 do_lnet_health_ping_test "${hstatus}" || return $?
1927                 check_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         for hstatus in ${LNET_REMOTE_NO_RESEND_STATUSES}; do
1934                 do_lnet_health_ping_test "${hstatus}" || return $?
1935                 check_no_resends || return $?
1936                 check_no_local_health || return $?
1937                 check_remote_health || return $?
1938                 do_lnetctl peer set --health 1000 --all ||
1939                         error "Unable to reset health rc=$?"
1940         done
1941
1942         cleanup_health_test || return $?
1943
1944         return 0
1945 }
1946 run_test 207 "Check health and resends for multi-rail remote errors"
1947
1948 test_208_load_and_check_lnet() {
1949         local ip2nets="$1"
1950         local p_nid="$2"
1951         local s_nid="$3"
1952         local num_expected=1
1953
1954         load_lnet "networks=\"\" ip2nets=\"${ip2nets_str}\""
1955
1956         $LCTL net up ||
1957                 error "Failed to load LNet with ip2nets \"${ip2nets_str}\""
1958
1959         [[ -n $s_nid ]] &&
1960                 num_expected=2
1961
1962         declare -a nids
1963         nids=( $($LCTL list_nids) )
1964
1965         [[ ${#nids[@]} -ne ${num_expected} ]] &&
1966                 error "Expect ${num_expected} NIDs found ${#nids[@]}"
1967
1968         [[ ${nids[0]} == ${p_nid} ]] ||
1969                 error "Expect NID \"${p_nid}\" found \"${nids[0]}\""
1970
1971         [[ -n $s_nid ]] && [[ ${nids[1]} != ${s_nid} ]] &&
1972                 error "Expect second NID \"${s_nid}\" found \"${nids[1]}\""
1973
1974         $LCTL net down &>/dev/null
1975         cleanup_lnet
1976 }
1977
1978 test_208() {
1979         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
1980
1981         cleanup_netns || error "Failed to cleanup netns before test execution"
1982         cleanup_lnet || error "Failed to unload modules before test execution"
1983         setup_fakeif || error "Failed to add fake IF"
1984
1985         have_interface "$FAKE_IF" ||
1986                 error "Expect $FAKE_IF configured but not found"
1987
1988         local if0_ip=$(ip --oneline addr show dev ${INTERFACES[0]} |
1989                        awk '/inet /{print $4}' |
1990                        sed 's:/.*::')
1991         if0_ip=($(echo "${if0_ip[@]}" | tr ' ' '\n' | uniq | tr '\n' ' '))
1992         local ip2nets_str="tcp(${INTERFACES[0]}) $if0_ip"
1993
1994         echo "Configure single NID \"$ip2nets_str\""
1995         test_208_load_and_check_lnet "${ip2nets_str}" "${if0_ip}@tcp"
1996
1997         ip2nets_str="tcp(${INTERFACES[0]}) $if0_ip; tcp1($FAKE_IF) $FAKE_IP"
1998         echo "Configure two NIDs; two NETs \"$ip2nets_str\""
1999         test_208_load_and_check_lnet "${ip2nets_str}" "${if0_ip}@tcp" \
2000                                      "${FAKE_IP}@tcp1"
2001
2002         ip2nets_str="tcp(${INTERFACES[0]}) $if0_ip; tcp($FAKE_IF) $FAKE_IP"
2003         echo "Configure two NIDs; one NET \"$ip2nets_str\""
2004         test_208_load_and_check_lnet "${ip2nets_str}" "${if0_ip}@tcp" \
2005                                      "${FAKE_IP}@tcp"
2006         local addr1=( ${if0_ip//./ } )
2007         local addr2=( ${FAKE_IP//./ } )
2008         local range="[${addr1[0]},${addr2[0]}]"
2009
2010         local i
2011         for i in $(seq 1 3); do
2012                 range+=".[${addr1[$i]},${addr2[$i]}]"
2013         done
2014         ip2nets_str="tcp(${INTERFACES[0]},${FAKE_IF}) ${range}"
2015
2016         echo "Configured two NIDs; one NET alt syntax \"$ip2nets_str\""
2017         test_208_load_and_check_lnet "${ip2nets_str}" "${if0_ip}@tcp" \
2018                                      "${FAKE_IP}@tcp"
2019
2020         cleanup_fakeif
2021
2022         echo "alt syntax with missing IF \"$ip2nets_str\""
2023         load_lnet "networks=\"\" ip2nets=\"${ip2nets_str}\""
2024
2025         echo "$LCTL net up should fail"
2026         $LCTL net up &&
2027                 error "LNet bring up should have failed"
2028
2029         cleanup_lnet
2030 }
2031 run_test 208 "Test various kernel ip2nets configurations"
2032
2033 test_209() {
2034         (( $MDS1_VERSION >= $(version_code 2.14.58) )) ||
2035                 skip "need at least 2.14.58"
2036
2037         setup_health_test false || return $?
2038
2039         echo "Simulate network_timeout w/SR config"
2040         lnet_health_pre
2041
2042         add_health_test_drop_rules network_timeout
2043
2044         do_lnetctl discover ${RNIDS[0]} &&
2045                 error "Should have failed"
2046
2047         lnet_health_post
2048
2049         check_no_resends || return $?
2050         check_no_local_health || return $?
2051         check_no_remote_health || return $?
2052
2053         cleanup_health_test || return $?
2054
2055         setup_health_test true || return $?
2056
2057         echo "Simulate network_timeout w/MR config"
2058
2059         lnet_health_pre
2060
2061         add_health_test_drop_rules network_timeout
2062
2063         do_lnetctl discover ${RNIDS[0]} &&
2064                 error "Should have failed"
2065
2066         lnet_health_post
2067
2068         check_no_resends || return $?
2069         check_local_health || return $?
2070         check_remote_health || return $?
2071
2072         cleanup_health_test || return $?
2073
2074         return 0
2075 }
2076 run_test 209 "Check health, but not resends, for network timeout"
2077
2078 check_nid_in_recovq() {
2079         local queue="$1"
2080         local nid="$2"
2081         local expect="$3"
2082         local max_wait="${4:-10}"
2083         local rc=0
2084
2085         (($expect == 0)) &&
2086                 echo "$queue recovery queue should be empty" ||
2087                 echo "$queue recovery queue should have $nid"
2088
2089         wait_update $HOSTNAME \
2090                 "$LNETCTL debug recovery $queue | \
2091                  grep -wc \"nid-0: $nid\"" \
2092                 "$expect" "$max_wait"
2093         rc=$?
2094         do_lnetctl debug recovery $queue
2095         (($rc == 0)) ||
2096                 error "Expect $expect NIDs in recovery."
2097
2098         return 0
2099 }
2100
2101 # First ping is sent at time 0.
2102 # 2nd at 0 + 2^1 = 2
2103 # 3rd at 2 + 2^2 = 6
2104 # 4th at 6 + 2^3 = 14
2105 # 5th at 14 + 2^4 = 30
2106 # e.g. after 10 seconds we would expect 3 pings to have been sent, and the
2107 # NI will have been enqueued for the 4th ping.
2108
2109 # If the recovery limit is 10 seconds, then after the 4th ping is sent
2110 # we expect the peer NI to have aged out, so it will not actually be
2111 # queued for a 5th ping.
2112 # If max_recovery_ping_interval is set to 4 then:
2113 #  First ping is sent at time 0
2114 #  2nd at  0 + min(2^1, 4) = 2
2115 #  3rd at  2 + min(2^2, 4) = 6
2116 #  4th at  6 + min(2^3, 4) = 10
2117 #  5th at 10 + min(2^4, 4) = 14
2118 #  6th at 14 + min(2^5, 4) = 18
2119 #  7th at 18 + min(2^6, 4) = 22
2120 # e.g. after 4 seconds we would expect 2 pings to have been sent, and
2121 # after 13 seconds we would expect 4 pings to have been sent
2122 check_ping_count() {
2123         local queue="$1"
2124         local nid="$2"
2125         local expect="$3"
2126         local max_wait="$4"
2127
2128         echo "Check ping counts:"
2129
2130         local rc=0
2131         if [[ $queue == "ni" ]]; then
2132                 wait_update $HOSTNAME \
2133                         "$LNETCTL net show -v 2 | \
2134                          grep -e $nid -e ping_count | grep -wA1 $nid | \
2135                          awk '/ping_count/{print \\\$NF}'" "$expect" "$max_wait"
2136                 rc=$?
2137                 $LNETCTL net show -v 2 | grep -e $nid -e ping_count
2138         elif [[ $queue == peer_ni ]]; then
2139                 wait_update $HOSTNAME \
2140                         "$LNETCTL peer show -v 2 --nid $nid | \
2141                          grep -v primary | \
2142                          grep -e $nid -e ping_count | grep -wA1 $nid | \
2143                          awk '/ping_count/{print \\\$NF}'" "$expect" "$max_wait"
2144                 rc=$?
2145                 $LNETCTL peer show -v 2 --nid $nid | grep -v primary |
2146                         grep -e $nid -e ping_count
2147         else
2148                 error "Unrecognized queue \"$queue\""
2149                 return 1
2150         fi
2151
2152         ((rc == 0)) || error "Unexpected ping count"
2153
2154         return 0
2155 }
2156
2157 test_210() {
2158         [[ ${NETTYPE} == kfi* ]] && skip "kfi doesn't support drop rules"
2159
2160         reinit_dlc || return $?
2161         add_net "${NETTYPE}" "${INTERFACES[0]}" || return $?
2162         add_net "${NETTYPE}1" "${INTERFACES[0]}" || return $?
2163
2164         local prim_nid=$($LCTL list_nids | head -n 1)
2165
2166         do_lnetctl discover $prim_nid ||
2167                 error "failed to discover myself"
2168
2169         local default=$($LNETCTL global show |
2170                         awk '/recovery_limit/{print $NF}')
2171         # Set recovery limit to 10 seconds.
2172         do_lnetctl set recovery_limit 10 ||
2173                 error "failed to set recovery_limit"
2174
2175         $LCTL set_param debug=+net
2176         $LCTL net_drop_add -s *@${NETTYPE} -d *@${NETTYPE} -m GET -r 1 \
2177                 -e local_error ||
2178                 error "Failed to add drop rule"
2179         $LCTL net_drop_add -s *@${NETTYPE}1 -d *@${NETTYPE}1 -m GET -r 1 \
2180                 -e local_error ||
2181                 error "Failed to add drop rule"
2182         $LCTL net_drop_add -s *@${NETTYPE} -d *@${NETTYPE} -r 1 ||
2183                 error "Failed to add drop rule"
2184         $LCTL net_drop_add -s *@${NETTYPE}1 -d *@${NETTYPE}1 -r 1 ||
2185                 error "Failed to add drop rule"
2186         do_lnetctl net set --health 0 --nid $prim_nid
2187
2188         check_ping_count "ni" "$prim_nid" "2" "10"
2189         check_nid_in_recovq "-l" "$prim_nid" "1"
2190
2191         check_ping_count "ni" "$prim_nid" "3" "10"
2192         check_nid_in_recovq "-l" "$prim_nid" "1"
2193
2194         $LCTL net_drop_del -a
2195
2196         reinit_dlc || return $?
2197         add_net "${NETTYPE}" "${INTERFACES[0]}" || return $?
2198         add_net "${NETTYPE}1" "${INTERFACES[0]}" || return $?
2199
2200         local prim_nid=$($LCTL list_nids | head -n 1)
2201
2202         do_lnetctl discover $prim_nid ||
2203                 error "failed to discover myself"
2204
2205         do_lnetctl set recovery_limit $default ||
2206                 error "failed to set recovery_limit"
2207
2208         default=$($LNETCTL global show |
2209                   awk '/max_recovery_ping_interval/{print $NF}')
2210         do_lnetctl set max_recovery_ping_interval 4 ||
2211                 error "failed to set max_recovery_ping_interval"
2212
2213         $LCTL set_param debug=+net
2214         $LCTL net_drop_add -s *@${NETTYPE} -d *@${NETTYPE} -m GET -r 1 \
2215                 -e local_error ||
2216                 error "Failed to add drop rule"
2217         $LCTL net_drop_add -s *@${NETTYPE}1 -d *@${NETTYPE}1 -m GET -r 1 \
2218                 -e local_error ||
2219                 error "Failed to add drop rule"
2220         $LCTL net_drop_add -s *@${NETTYPE} -d *@${NETTYPE} -r 1 ||
2221                 error "Failed to add drop rule"
2222         $LCTL net_drop_add -s *@${NETTYPE}1 -d *@${NETTYPE}1 -r 1 ||
2223                 error "Failed to add drop rule"
2224         do_lnetctl net set --health 0 --nid $prim_nid
2225
2226         check_ping_count "ni" "$prim_nid" "2" "10"
2227         check_nid_in_recovq "-l" "$prim_nid" "1"
2228
2229         check_ping_count "ni" "$prim_nid" "4" "10"
2230         check_nid_in_recovq "-l" "$prim_nid" "1"
2231
2232         $LCTL net_drop_del -a
2233
2234         do_lnetctl set max_recovery_ping_interval $default ||
2235                 error "failed to set max_recovery_ping_interval"
2236
2237         return 0
2238 }
2239 run_test 210 "Local NI recovery checks"
2240
2241 test_211() {
2242         [[ ${NETTYPE} == kfi* ]] && skip "kfi doesn't support drop rules"
2243
2244         reinit_dlc || return $?
2245         add_net "${NETTYPE}" "${INTERFACES[0]}" || return $?
2246         add_net "${NETTYPE}1" "${INTERFACES[0]}" || return $?
2247
2248         local prim_nid=$($LCTL list_nids | head -n 1)
2249
2250         do_lnetctl discover $prim_nid ||
2251                 error "failed to discover myself"
2252
2253         local default=$($LNETCTL global show |
2254                         awk '/recovery_limit/{print $NF}')
2255         # Set recovery limit to 10 seconds.
2256         do_lnetctl set recovery_limit 10 ||
2257                 error "failed to set recovery_limit"
2258
2259         $LCTL net_drop_add -s *@${NETTYPE} -d *@${NETTYPE} -m GET -r 1 \
2260                 -e remote_error ||
2261                 error "Failed to add drop rule"
2262         $LCTL net_drop_add -s *@${NETTYPE}1 -d *@${NETTYPE}1 -m GET -r 1 \
2263                 -e remote_error ||
2264                 error "Failed to add drop rule"
2265         $LCTL net_drop_add -s *@${NETTYPE} -d *@${NETTYPE} -r 1 ||
2266                 error "Failed to add drop rule"
2267         $LCTL net_drop_add -s *@${NETTYPE}1 -d *@${NETTYPE}1 -r 1 ||
2268                 error "Failed to add drop rule"
2269
2270         # Set health to 0 on one interface. This forces it onto the recovery
2271         # queue.
2272         do_lnetctl peer set --nid $prim_nid --health 0
2273
2274         check_nid_in_recovq "-p" "$prim_nid" "1"
2275
2276         # The peer should age out in 10-20 seconds
2277         check_nid_in_recovq "-p" "$prim_nid" "0" "20"
2278         # Ping count should reset to 0 when peer ages out
2279         check_ping_count "peer_ni" "$prim_nid" "0"
2280
2281         $LCTL net_drop_del -a
2282
2283         # Set health to force it back onto the recovery queue. Set to 500 means
2284         # in ~5 seconds it should be back at maximum value.
2285         # NB: we reset the recovery limit to 0 (indefinite) so the peer NI is
2286         # eligible again
2287         do_lnetctl set recovery_limit 0 ||
2288                 error "failed to set recovery_limit"
2289
2290         do_lnetctl peer set --nid $prim_nid --health 500
2291
2292         check_nid_in_recovq "-p" "$prim_nid" "1"
2293         check_nid_in_recovq "-p" "$prim_nid" "0" "20"
2294
2295         reinit_dlc || return $?
2296         add_net "${NETTYPE}" "${INTERFACES[0]}" || return $?
2297         add_net "${NETTYPE}1" "${INTERFACES[0]}" || return $?
2298
2299         local prim_nid=$($LCTL list_nids | head -n 1)
2300
2301         do_lnetctl discover $prim_nid ||
2302                 error "failed to discover myself"
2303
2304         do_lnetctl set recovery_limit $default ||
2305                 error "failed to set recovery_limit"
2306
2307         default=$($LNETCTL global show |
2308                   awk '/max_recovery_ping_interval/{print $NF}')
2309         do_lnetctl set max_recovery_ping_interval 4 ||
2310                 error "failed to set max_recovery_ping_interval"
2311
2312         $LCTL net_drop_add -s *@${NETTYPE} -d *@${NETTYPE} -m GET -r 1 \
2313                 -e remote_error ||
2314                 error "Failed to add drop rule"
2315         $LCTL net_drop_add -s *@${NETTYPE}1 -d *@${NETTYPE}1 -m GET -r 1 \
2316                 -e remote_error ||
2317                 error "Failed to add drop rule"
2318         $LCTL net_drop_add -s *@${NETTYPE} -d *@${NETTYPE} -r 1 ||
2319                 error "Failed to add drop rule"
2320         $LCTL net_drop_add -s *@${NETTYPE}1 -d *@${NETTYPE}1 -r 1 ||
2321                 error "Failed to add drop rule"
2322
2323         # Set health to 0 on one interface. This forces it onto the recovery
2324         # queue.
2325         do_lnetctl peer set --nid $prim_nid --health 0
2326
2327         check_ping_count "peer_ni" "$prim_nid" "1" "4"
2328         check_nid_in_recovq "-p" "$prim_nid" "1"
2329
2330         # After we detect the 1st ping above, the 4th ping should be sent after
2331         # ~13 seconds
2332         check_ping_count "peer_ni" "$prim_nid" "4" "14"
2333         check_nid_in_recovq "-p" "$prim_nid" "1"
2334
2335         $LCTL net_drop_del -a
2336
2337         do_lnetctl set max_recovery_ping_interval $default ||
2338                 error "failed to set max_recovery_ping_interval"
2339
2340         return 0
2341 }
2342 run_test 211 "Remote NI recovery checks"
2343
2344 test_212() {
2345         [[ ${NETTYPE} == kfi* ]] && skip "kfi doesn't support drop rules"
2346
2347         local rnodes=$(remote_nodes_list)
2348         [[ -z $rnodes ]] && skip "Need at least 1 remote node"
2349
2350         cleanup_lnet || error "Failed to cleanup before test execution"
2351
2352         # Loading modules should configure LNet with the appropriate
2353         # test-framework configuration
2354         load_lnet "config_on_load=1" || error "Failed to load modules"
2355
2356         local my_nid=$($LCTL list_nids | head -n 1)
2357         [[ -z $my_nid ]] &&
2358                 error "Failed to get primary NID for local host $HOSTNAME"
2359
2360         local rnode=$(awk '{print $1}' <<<$rnodes)
2361         local rnodenids=$(do_node $rnode $LCTL list_nids | xargs echo)
2362         local rloaded=false
2363
2364         if [[ -z $rnodenids ]]; then
2365                 do_rpc_nodes $rnode load_lnet "config_on_load=1"
2366                 rloaded=true
2367                 rnodenids=$(do_node $rnode $LCTL list_nids | xargs echo)
2368         fi
2369
2370         local rnodepnid=$(awk '{print $1}' <<< $rnodenids)
2371
2372         [[ -z $rnodepnid ]] &&
2373                 error "Failed to get primary NID for remote host $rnode"
2374
2375         log "Initial discovery"
2376         do_lnetctl discover --force $rnodepnid ||
2377                 error "Failed to discover $rnodepnid"
2378
2379         do_node $rnode "$LNETCTL discover --force $my_nid" ||
2380                 error "$rnode failed to discover $my_nid"
2381
2382         log "Fail local discover ping to set LNET_PEER_REDISCOVER flag"
2383         $LCTL net_drop_add -s "*@$NETTYPE" -d "*@$NETTYPE" -r 1 \
2384                 -e local_error ||
2385                 error "Failed to add drop rule"
2386         do_lnetctl discover --force $rnodepnid &&
2387                 error "Discovery should have failed"
2388         $LCTL net_drop_del -a
2389
2390         local nid
2391         for nid in $rnodenids; do
2392                 # We need GET (PING) delay just long enough so we can trigger
2393                 # discovery on the remote peer
2394                 $LCTL net_delay_add -s "*@$NETTYPE" -d $nid -r 1 -m GET -l 3 ||
2395                         error "Failed to add delay rule"
2396                 $LCTL net_drop_add -s "*@$NETTYPE" -d $nid -r 1 -m GET \
2397                         -e local_error ||
2398                         error "Failed to add drop rule"
2399                 # We need PUT (PUSH) delay just long enough so we can process
2400                 # the PING failure
2401                 $LCTL net_delay_add -s "*@$NETTYPE" -d $nid -r 1 -m PUT -l 6 ||
2402                         error "Failed to add delay rule"
2403         done
2404
2405         log "Force $HOSTNAME to discover $rnodepnid (in background)"
2406         # We want to get a PING sent that we know will eventually fail.
2407         # The delay rules we added will ensure the ping is not sent until
2408         # the PUSH is also in flight (see below), and the drop rule ensures that
2409         # when the PING is eventually sent it will error out
2410         do_lnetctl discover --force $rnodepnid &
2411         local pid1=$!
2412
2413         # We want a discovery PUSH from rnode to put rnode back on our
2414         # discovery queue. This should cause us to try and send a PUSH to rnode
2415         # while the PING is still outstanding.
2416         log "Force $rnode to discover $my_nid"
2417         do_node $rnode $LNETCTL discover --force $my_nid
2418
2419         # At this point we'll have both PING_SENT and PUSH_SENT set for the
2420         # rnode peer. Wait for the PING to error out which should terminate the
2421         # discovery process that we backgrounded.
2422         log "Wait for $pid1"
2423         wait $pid1
2424         log "Finished wait on $pid1"
2425
2426         # The PING send failure clears the PING_SENT flag and puts the peer back
2427         # on the discovery queue. When discovery thread processes the peer it
2428         # will mistakenly clear the PUSH_SENT flag (and set PUSH_FAILED).
2429         # Discovery will then complete for this peer even though we have an
2430         # outstanding PUSH.
2431         # When PUSH is actually unlinked it will be forced back onto the
2432         # discovery queue, but we no longer have a ref on the peer. When
2433         # discovery completes again, we'll trip the ASSERT in
2434         # lnet_destroy_peer_locked()
2435
2436         # Delete the delay rules to send the PUSH
2437         $LCTL net_delay_del -a
2438         # Delete the drop rules
2439         $LCTL net_drop_del -a
2440
2441         unload_modules ||
2442                 error "Failed to unload modules"
2443         if $rloaded; then
2444                 do_rpc_nodes $rnode unload_modules_local ||
2445                         error "Failed to unload modules on $rnode"
2446         fi
2447
2448         return 0
2449 }
2450 run_test 212 "Check discovery refcount loss bug (LU-14627)"
2451
2452 test_213() {
2453         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
2454
2455         cleanup_netns || error "Failed to cleanup netns before test execution"
2456         cleanup_lnet || error "Failed to unload modules before test execution"
2457
2458         setup_fakeif || error "Failed to add fake IF"
2459         have_interface "$FAKE_IF" ||
2460                 error "Expect $FAKE_IF configured but not found"
2461
2462         reinit_dlc || return $?
2463
2464         add_net "tcp" "${INTERFACES[0]}" || return $?
2465         add_net "tcp" "$FAKE_IF" || return $?
2466
2467         local nid1=$(lctl list_nids | head -n 1)
2468         local nid2=$(lctl list_nids | tail --lines 1)
2469
2470         [[ $(lctl which_nid $nid1 $nid2) == $nid1 ]] ||
2471                 error "Expect nid1 \"$nid1\" to be preferred"
2472
2473         [[ $(lctl which_nid $nid2 $nid1) == $nid2 ]] ||
2474                 error "Expect nid2 \"$nid2\" to be preferred"
2475
2476         return 0
2477 }
2478 run_test 213 "Check LNetDist calculation for multiple local NIDs"
2479
2480 function check_ni_status() {
2481         local nid="$1"
2482         local expect="$2"
2483
2484         local status=$($LNETCTL net show |
2485                        grep -A 1 ${nid} |
2486                        awk '/status/{print $NF}')
2487
2488         echo "NI ${nid} expect status \"${expect}\" found \"${status}\""
2489         if [[ $status != $expect ]]; then
2490                 error "Error: Expect NI status \"$expect\" for NID \"$nid\" but found \"$status\""
2491         fi
2492
2493         return 0
2494 }
2495
2496 test_214() {
2497         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
2498
2499         cleanup_netns || error "Failed to cleanup netns before test execution"
2500         cleanup_lnet || error "Failed to unload modules before test execution"
2501
2502         setup_fakeif || error "Failed to add fake IF"
2503         have_interface "$FAKE_IF" ||
2504                 error "Expect $FAKE_IF configured but not found"
2505
2506         reinit_dlc || return $?
2507
2508         add_net "tcp" "${INTERFACES[0]}" || return $?
2509         add_net "tcp" "$FAKE_IF" || return $?
2510
2511         local nid1=$(lctl list_nids | head -n 1)
2512         local nid2=$(lctl list_nids | tail --lines 1)
2513
2514         check_ni_status "0@lo" up
2515         check_ni_status "$nid1" up
2516         check_ni_status "$nid2" up
2517
2518         do_lnetctl ping --source $nid2 $nid1 ||
2519                 error "$LNETCTL ping --source $nid2 $nid1 failed"
2520
2521         echo "Set $FAKE_IF down"
2522         echo "ip link set dev $FAKE_IF down"
2523         ip link set dev $FAKE_IF down
2524         check_ni_status "0@lo" up
2525         check_ni_status "$nid1" up
2526         check_ni_status "$nid2" down
2527 }
2528 run_test 214 "Check local NI status when link is downed"
2529
2530 get_ni_stat() {
2531         local nid=$1
2532         local stat=$2
2533
2534         $LNETCTL net show -v 2 |
2535                 egrep -e nid -e $stat |
2536                 grep -wA 1 $nid |
2537                 awk '/'$stat':/{print $NF}'
2538 }
2539
2540 ni_stats_pre() {
2541         local nidvar s
2542         for nidvar in nid1 nid2; do
2543                 for stat in send_count recv_count; do
2544                         s=$(get_ni_stat ${!nidvar} $stat)
2545                         eval ${nidvar}_pre_${stat}=$s
2546                 done
2547         done
2548 }
2549
2550 ni_stats_post() {
2551         local nidvar s
2552         for nidvar in nid1 nid2; do
2553                 for stat in send_count recv_count; do
2554                         s=$(get_ni_stat ${!nidvar} $stat)
2555                         eval ${nidvar}_post_${stat}=$s
2556                 done
2557         done
2558 }
2559
2560 ni_stat_changed() {
2561         local nidvar=$1
2562         local stat=$2
2563
2564         local pre post
2565         eval pre=\${${nidvar}_pre_${stat}}
2566         eval post=\${${nidvar}_post_${stat}}
2567
2568         echo "${!nidvar} pre ${stat} $pre post ${stat} $post"
2569
2570         [[ $pre -ne $post ]]
2571 }
2572
2573 test_215() {
2574         cleanup_netns || error "Failed to cleanup netns before test execution"
2575         cleanup_lnet || error "Failed to unload modules before test execution"
2576
2577         reinit_dlc || return $?
2578
2579         add_net "${NETTYPE}1" "${INTERFACES[0]}" || return $?
2580         add_net "${NETTYPE}2" "${INTERFACES[0]}" || return $?
2581
2582         local nid1=$($LCTL list_nids | head -n 1)
2583         local nid2=$($LCTL list_nids | tail --lines 1)
2584
2585         do_lnetctl peer add --prim $nid1 --nid $nid2 ||
2586                 error "Failed to add peer"
2587
2588         local npings=25
2589
2590         for nidvarA in nid1 nid2; do
2591                 src=${!nidvarA}
2592                 dst=${!nidvarA}
2593                 for nidvarB in nid1 nid2; do
2594                         [[ $nidvarA == $nidvarB ]] && continue
2595
2596                         ni_stats_pre
2597
2598                         echo "$LNETCTL ping $dst x $npings"
2599                         for i in $(seq 1 $npings); do
2600                                 $LNETCTL ping $dst &>/dev/null ||
2601                                         error "$LNETCTL ping $dst failed"
2602                         done
2603
2604                         ni_stats_post
2605
2606                         # No source specified, sends to either NID should cause
2607                         # counts to increase across both NIs
2608                         for nidvar in nid1 nid2; do
2609                                 for stat in send_count recv_count; do
2610                                         ni_stat_changed $nidvar $stat ||
2611                                                 error "$stat unchanged for ${!nidvar}"
2612                                 done
2613                         done
2614
2615                         ni_stats_pre
2616
2617                         echo "$LNETCTL ping --source $src $dst x $npings"
2618                         for i in $(seq 1 $npings); do
2619                                 $LNETCTL ping --source $src $dst &>/dev/null ||
2620                                         error "$LNETCTL ping --source $src $dst failed"
2621                         done
2622
2623                         ni_stats_post
2624
2625                         # src nid == dest nid means stats for the _other_ NI
2626                         # should be unchanged
2627                         for nidvar in nid1 nid2; do
2628                                 for stat in send_count recv_count; do
2629                                         if [[ ${!nidvar} == $src ]]; then
2630                                                 ni_stat_changed $nidvar $stat ||
2631                                                         error "$stat unchanged for ${!nidvar}"
2632                                         else
2633                                                 ni_stat_changed $nidvar $stat &&
2634                                                         error "$stat changed for ${!nidvar}"
2635                                         fi
2636                                 done
2637                         done
2638                 done
2639                 # Double number of pings for next iteration because the net
2640                 # sequence numbers will have diverged
2641                 npings=$(($npings * 2))
2642         done
2643
2644         # Ping from nid1 to nid2 should fail
2645         do_lnetctl ping --source $nid1 $nid2 &&
2646                 error "ping from $nid1 to $nid2 should fail"
2647
2648         # Ping from nid2 to nid1 should fail
2649         do_lnetctl ping --source $nid2 $nid1 &&
2650                 error "ping from $nid2 to $nid1 should fail"
2651
2652         return 0
2653 }
2654 run_test 215 "Test lnetctl ping --source option"
2655
2656 test_216() {
2657         [[ ${NETTYPE} == kfi* ]] && skip "kfi doesn't support drop rules"
2658
2659         local rc=0
2660
2661         reinit_dlc || return $?
2662
2663         add_net "${NETTYPE}" "${INTERFACES[0]}" || return $?
2664         add_net "${NETTYPE}1" "${INTERFACES[0]}" || return $?
2665
2666         local nids=( $($LCTL list_nids | xargs echo) )
2667
2668         do_lnetctl discover ${nids[0]} ||
2669                 error "Initial discovery failed"
2670
2671         do_lnetctl ping --source ${nids[0]} ${nids[0]} ||
2672                 error "Initial ping failed $?"
2673
2674         do_lnetctl ping --source ${nids[1]} ${nids[1]} ||
2675                 error "Initial ping failed $?"
2676
2677         local src dst
2678         for src in "${nids[@]}"; do
2679                 for dst in "${nids[@]}"; do
2680                         $LCTL net_drop_add -r 1 -s $src -d $dst \
2681                                 -e network_timeout ||
2682                                 error "Failed to add drop rule"
2683                 done
2684         done
2685
2686         do_lnetctl ping ${nids[0]} || rc=$?
2687
2688         $LCTL net_drop_del -a
2689
2690         [[ $rc -eq 0 ]] &&
2691                 error "expected ping to fail"
2692
2693         check_nid_in_recovq "-p" "${nids[0]}" "0"
2694         check_nid_in_recovq "-l" "${nids[0]}" "1"
2695
2696         return 0
2697 }
2698 run_test 216 "Failed send to peer NI owned by local host should not trigger peer NI recovery"
2699
2700 test_217() {
2701         reinit_dlc || return $?
2702
2703         [[ $($LNETCTL net show | grep -c nid) -ne 1 ]] &&
2704                 error "Unexpected number of NIs after initalizing DLC"
2705
2706         do_lnetctl discover 0@lo ||
2707                 error "Failed to discover 0@lo"
2708
2709         unload_modules
2710 }
2711 run_test 217 "Don't leak memory when discovering peer with nnis <= 1"
2712
2713 test_218() {
2714         [[ ${NETTYPE} == kfi* ]] && skip "kfi doesn't support drop rules"
2715
2716         reinit_dlc || return $?
2717
2718         [[ ${#INTERFACES[@]} -lt 2 ]] &&
2719                 skip "Need two LNet interfaces"
2720
2721         add_net "${NETTYPE}" "${INTERFACES[0]}" || return $?
2722
2723         local nid1=$($LCTL list_nids | head -n 1)
2724
2725         do_lnetctl ping $nid1 ||
2726                 error "ping failed"
2727
2728         add_net "${NETTYPE}" "${INTERFACES[1]}" || return $?
2729
2730         local nid2=$($LCTL list_nids | tail --lines 1)
2731
2732         do_lnetctl ping $nid2 ||
2733                 error "ping failed"
2734
2735         $LCTL net_drop_add -s $nid1 -d $nid1 -e local_error -r 1 ||
2736                 error "Failed to add drop rule"
2737
2738         do_lnetctl ping --source $nid1 $nid1 &&
2739                 error "ping should have failed"
2740
2741         local health_recovered
2742         local i
2743
2744         for i in $(seq 1 5); do
2745                 health_recovered=$($LNETCTL net show -v 2 |
2746                                    grep -c 'health value: 1000')
2747
2748                 if [[ $health_recovered -ne 2 ]]; then
2749                         echo "Wait 1 second for health to recover"
2750                         sleep 1
2751                 else
2752                         break
2753                 fi
2754         done
2755
2756         health_recovered=$($LNETCTL net show -v 2 |
2757                            grep -c 'health value: 1000')
2758
2759         $LCTL net_drop_del -a
2760
2761         [[ $health_recovered -ne 2 ]] &&
2762                 do_lnetctl net show -v 2 | egrep -e nid -e health &&
2763                 error "Health hasn't recovered"
2764
2765         return 0
2766 }
2767 run_test 218 "Local recovery pings should exercise all available paths"
2768
2769 test_219() {
2770         reinit_dlc || return $?
2771         add_net "${NETTYPE}" "${INTERFACES[0]}" || return $?
2772         add_net "${NETTYPE}1" "${INTERFACES[0]}" || return $?
2773
2774         local nid1=$(lctl list_nids | head -n 1)
2775         local nid2=$(lctl list_nids | tail --lines 1)
2776
2777         do_lnetctl ping $nid1 ||
2778                 error "Ping failed $?"
2779         do_lnetctl ping $nid2 ||
2780                 error "Ping failed $?"
2781
2782         do_lnetctl discover $nid2 ||
2783                 error "Discovery failed"
2784
2785         $LNETCTL peer show --nid $nid1 | grep -q $nid2 ||
2786                 error "$nid2 is not listed under $nid1"
2787 }
2788 run_test 219 "Consolidate peer entries"
2789
2790 do_net_add() {
2791         local node=$1
2792         local net=$2
2793         local if=$3
2794
2795         do_rpc_nodes $node "$LNETCTL net add --net $net --if $if" ||
2796                 error "add $net on interface $if on node $node failed rc=$?"
2797 }
2798
2799 do_route_add() {
2800         local node=$1
2801         local net=$2
2802         local gw=$3
2803
2804         do_node $node "$LNETCTL route add --net $net --gateway $gw" ||
2805                 error "route add to $net via $gw failed rc=$?"
2806 }
2807
2808 ROUTERS_REQUIRED=
2809 ROUTERS=()
2810 declare -A ROUTER_INTERFACES
2811 RPEERS_REQUIRED=
2812 RPEERS=()
2813 declare -A RPEER_INTERFACES
2814 init_router_test_vars() {
2815         local rnodes_required
2816         ((rnodes_required=ROUTERS_REQUIRED+RPEERS_REQUIRED))
2817         # all remote nodes, including some that may not be used
2818         local rnodes_all=( $(remote_nodes_list) )
2819         [[ -z $rnodes_all || "${#rnodes_all[@]}" -lt $rnodes_required ]] &&
2820                 skip "Need at least $rnodes_required remote nodes" \
2821                         "found \"${rnodes_all[@]}\""
2822
2823         ROUTERS=( "${rnodes_all[@]:0:${ROUTERS_REQUIRED}}" )
2824         RPEERS=( "${rnodes_all[@]:${ROUTERS_REQUIRED}:${RPEERS_REQUIRED}}" )
2825
2826         local rnodes=$(comma_list ${ROUTERS[@]} ${RPEERS[@]})
2827         local all_nodes=$(comma_list ${ROUTERS[@]} ${RPEERS[@]} $HOSTNAME)
2828
2829         do_nodes $rnodes $LUSTRE_RMMOD ||
2830                 error "failed to unload modules"
2831
2832         do_rpc_nodes $rnodes "load_lnet config_on_load=1" ||
2833                 error "Failed to load and configure LNet"
2834
2835         for router in ${ROUTERS[@]}; do
2836                 ROUTER_INTERFACES[$router]=$(do_rpc_nodes --quiet \
2837                                                 $router lnet_if_list)
2838         done
2839
2840         for rpeer in ${RPEERS[@]}; do
2841                 RPEER_INTERFACES[$rpeer]=$(do_rpc_nodes --quiet \
2842                                                 $rpeer lnet_if_list)
2843         done
2844
2845         do_nodes $all_nodes $LUSTRE_RMMOD ||
2846                 error "Failed to unload modules"
2847
2848         [[ ${#INTERFACES[@]} -eq 0 ]] &&
2849                 error "No interfaces configured for local host $HOSTNAME"
2850         for router in ${!ROUTER_INTERFACES[@]}; do
2851                 [[ -z "${ROUTER_INTERFACES[$router]}" ]] &&
2852                         error "No interfaces configured for router $router"
2853         done
2854         for rpeer in ${!RPEER_INTERFACES[@]}; do
2855                 [[ -z "${RPEER_INTERFACES[$rpeer]}" ]] &&
2856                         error "No interfaces configured for remote peer $rpeer"
2857         done
2858
2859         return 0
2860 }
2861
2862 declare -A ROUTER_NIDS
2863 declare -A RPEER_NIDS
2864 LNIDS=()
2865 LOCAL_NET=${NETTYPE}1
2866 REMOTE_NET=${NETTYPE}2
2867 setup_router_test() {
2868         local mod_opts="$@"
2869
2870         (( $MDS1_VERSION >= $(version_code 2.15.0) )) ||
2871                 skip "need at least 2.15.0 for load_lnet"
2872
2873         if [[ ${#RPEER_INTERFACES[@]} -eq 0 ]]; then
2874                 init_router_test_vars ||
2875                         return $?
2876         fi
2877
2878         local all_nodes=$(comma_list ${ROUTERS[@]} ${RPEERS[@]} $HOSTNAME)
2879
2880         do_nodes $all_nodes $LUSTRE_RMMOD ||
2881                 error "failed to unload modules"
2882
2883         mod_opts+=" alive_router_check_interval=5"
2884         mod_opts+=" router_ping_timeout=5"
2885         mod_opts+=" large_router_buffers=4"
2886         mod_opts+=" small_router_buffers=8"
2887         mod_opts+=" tiny_router_buffers=16"
2888         do_rpc_nodes $all_nodes load_lnet "${mod_opts}" ||
2889                 error "Failed to load lnet"
2890
2891         do_nodes $all_nodes "$LNETCTL lnet configure" ||
2892                 error "Failed to initialize DLC"
2893
2894         for router in ${!ROUTER_INTERFACES[@]}; do
2895                 local router_interfaces=( ${ROUTER_INTERFACES[$router]} )
2896
2897                 do_net_add $router $LOCAL_NET ${router_interfaces[0]} ||
2898                         return $?
2899                 do_net_add $router $REMOTE_NET ${router_interfaces[0]} ||
2900                         return $?
2901         done
2902
2903         for rpeer in ${!RPEER_INTERFACES[@]}; do
2904                 local rpeer_interfaces=( ${RPEER_INTERFACES[$rpeer]} )
2905
2906                 do_net_add $rpeer $REMOTE_NET ${rpeer_interfaces[0]} ||
2907                         return $?
2908         done
2909
2910         add_net $LOCAL_NET ${INTERFACES[0]} ||
2911                 return $?
2912
2913         for router in ${!ROUTER_INTERFACES[@]}; do
2914                 ROUTER_NIDS[$router]=$(do_node $router $LCTL list_nids
2915                                         2>/dev/null | xargs echo)
2916         done
2917
2918         for rpeer in ${!RPEER_INTERFACES[@]}; do
2919                 RPEER_NIDS[$rpeer]=$(do_node $rpeer $LCTL list_nids
2920                                         2>/dev/null | xargs echo)
2921         done
2922
2923         LNIDS=( $($LCTL list_nids 2>/dev/null | xargs echo) )
2924 }
2925
2926 do_route_del() {
2927         local node=$1
2928         local net=$2
2929         local gw=$3
2930
2931         do_nodesv $node \
2932         'output="$($LNETCTL route show --net $net --gateway $gw 2>/dev/null)"; \
2933                 if [[ "x${lnetctl_text}x" != "xx" ]]; then                     \
2934                                 $LNETCTL route del --net $net --gateway $gw;   \
2935                         else                                                   \
2936                                 exit 0;                                        \
2937                         fi'
2938 }
2939
2940 cleanup_router_test() {
2941         local all_nodes=$(comma_list $HOSTNAME ${ROUTERS[@]} ${RPEERS[@]})
2942
2943         for router in ${!ROUTER_NIDS[@]}; do
2944                 local router_nids=( ${ROUTER_NIDS[$router]} )
2945
2946                 do_route_del $HOSTNAME $REMOTE_NET ${router_nids[0]} ||
2947                         error "Failed to delete $HOSTNAME -> "\
2948                                 "$REMOTE_NET via ${router_nids[0]} route"
2949         done
2950
2951         for router in ${!ROUTER_INTERFACES[@]}; do
2952                 local router_nids=( ${ROUTER_NIDS[$router]} )
2953
2954                 do_route_del $rpeer $LOCAL_NET ${router_nids[1]} ||
2955                         error "Failed to delete $rpeer -> "\
2956                                 "$LOCAL_NET via ${router_nids[1]} route"
2957         done
2958
2959         do_nodes $all_nodes $LUSTRE_RMMOD ||
2960                 error "failed to unload modules"
2961
2962         return 0
2963 }
2964
2965 # check that all routes are up
2966 check_route_aliveness() {
2967         local node="$1"
2968         local expected="$2"
2969
2970         local lctl_actual
2971         local lnetctl_actual
2972         local chk_intvl
2973         local i
2974
2975         chk_intvl=$(cat /sys/module/lnet/parameters/alive_router_check_interval)
2976
2977         lctl_actual=$(do_node $node $LCTL show_route |
2978                         awk '{print $7}' | sort -u | xargs)
2979         lnetctl_actual=$(do_node $node $LNETCTL route show -v |
2980                         awk '/state/{print $NF}' | sort -u | xargs)
2981
2982         for ((i = 0; i < $chk_intvl; i++)); do
2983                 if [[ $lctl_actual == $expected ]] &&
2984                    [[ $lnetctl_actual == $expected ]]; then
2985                         break
2986                 fi
2987
2988                 echo "wait 1s for route state change"
2989                 sleep 1
2990
2991                 lctl_actual=$(do_node $node $LCTL show_route |
2992                                 awk '{print $7}' | sort -u | xargs)
2993                 lnetctl_actual=$(do_node $node $LNETCTL route show -v |
2994                                 awk '/state/{print $NF}' | sort -u | xargs)
2995         done
2996
2997         [[ $lctl_actual != $expected ]] &&
2998                 error "Wanted \"$expected\" lctl found \"$lctl_actual\""
2999
3000         [[ $lnetctl_actual != $expected ]] &&
3001                 error "Wanted \"$expected\" lnetctl found \"$lnetctl_actual\""
3002
3003         return 0
3004 }
3005
3006 check_router_ni_status() {
3007         local router="$1"
3008         local expected_local="$2"
3009         local expected_remote="$3"
3010
3011         local actual_local
3012         local actual_remote
3013         local chk_intvl
3014         local timeout
3015         local i
3016
3017         chk_intvl=$(cat /sys/module/lnet/parameters/alive_router_check_interval)
3018         timeout=$(cat /sys/module/lnet/parameters/router_ping_timeout)
3019
3020         actual_local=$(do_node $router "$LNETCTL net show --net $LOCAL_NET" |
3021                        awk '/status/{print $NF}')
3022         actual_remote=$(do_node $router "$LNETCTL net show --net $REMOTE_NET" |
3023                         awk '/status/{print $NF}')
3024
3025         for ((i = 0; i < $((chk_intvl + timeout)); i++)); do
3026                 if [[ $actual_local == $expected_local ]] &&
3027                    [[ $actual_remote == $expected_remote ]]; then
3028                         break
3029                 fi
3030
3031                 echo "wait 1s for NI state change"
3032                 sleep 1
3033
3034                 actual_local=$(do_node $router \
3035                                "$LNETCTL net show --net $LOCAL_NET" |
3036                                 awk '/status/{print $NF}')
3037                 actual_remote=$(do_node $router \
3038                                 "$LNETCTL net show --net $REMOTE_NET" |
3039                                 awk '/status/{print $NF}')
3040         done
3041
3042         [[ $actual_local == $expected_local ]] ||
3043                 error "$LOCAL_NET should be $expected_local"
3044
3045         [[ $actual_remote == $expected_remote ]] ||
3046                 error "$REMOTE_NET should be $expected_remote"
3047
3048         return 0
3049 }
3050
3051
3052 do_basic_rtr_test() {
3053         for router in ${!ROUTER_INTERFACES[@]}; do
3054                 do_node $router "$LNETCTL set routing 1" ||
3055                         error "Unable to enable routing on $router"
3056         done
3057
3058         for router in ${!ROUTER_NIDS[@]}; do
3059                 local router_nids=( ${ROUTER_NIDS[$router]} )
3060
3061                 do_route_add $HOSTNAME $REMOTE_NET ${router_nids[0]} ||
3062                 error "Failed to add route $HOSTNAME -> "\
3063                         "$REMOTE_NET via ${router_nids[0]}"
3064         done
3065
3066         for router in ${!ROUTER_INTERFACES[@]}; do
3067                 local router_nids=( ${ROUTER_NIDS[$router]} )
3068
3069                 for rpeer in ${!RPEER_INTERFACES[@]}; do
3070                         do_route_add $rpeer $LOCAL_NET ${router_nids[1]} ||
3071                                 error "Failed to add route $rpeer -> "\
3072                                         "$LOCAL_NET via ${router_nids[1]}"
3073                 done
3074         done
3075
3076         check_route_aliveness "$HOSTNAME" "up" ||
3077                 return $?
3078
3079         for rpeer in ${RPEERS[@]}; do
3080                 check_route_aliveness "$rpeer" "up" ||
3081                         return $?
3082         done
3083
3084         for rpeer in ${!RPEER_NIDS[@]}; do
3085                 local rpeer_nids=( ${RPEER_NIDS[$rpeer]} )
3086
3087                 do_lnetctl ping ${rpeer_nids[0]} ||
3088                         error "Failed to ping ${rpeer_nids[0]}"
3089         done
3090
3091         for rpeer in ${RPEERS[@]}; do
3092                 do_node $rpeer "$LNETCTL ping ${LNIDS[0]}" ||
3093                         error "$rpeer failed to ping ${LNIDS[0]}"
3094         done
3095
3096         return 0
3097 }
3098
3099 test_220() {
3100         ROUTERS_REQUIRED=1
3101         RPEERS_REQUIRED=1
3102
3103         setup_router_test || return $?
3104
3105         do_basic_rtr_test || return $?
3106
3107         do_rpc_nodes $HOSTNAME,${RPEERS[0]} load_module \
3108                 ../lnet/selftest/lnet_selftest ||
3109                         error "Failed to load lnet-selftest module"
3110
3111         $LSTSH -H -t $HOSTNAME -f ${RPEERS[0]} -m rw -s 4k ||
3112                 error "lst failed"
3113
3114         $LSTSH -H -t $HOSTNAME -f ${RPEERS[0]} -m rw ||
3115                 error "lst failed"
3116
3117         cleanup_router_test || return $?
3118 }
3119 run_test 220 "Add routes w/default options - check aliveness"
3120
3121 test_221() {
3122         ROUTERS_REQUIRED=1
3123         RPEERS_REQUIRED=1
3124
3125         setup_router_test lnet_peer_discovery_disabled=1 || return $?
3126
3127         do_basic_rtr_test || return $?
3128
3129         cleanup_router_test || return $?
3130 }
3131 run_test 221 "Add routes w/DD disabled - check aliveness"
3132
3133 # assumes 1 router, 1 peer
3134 do_aarf_enabled_test() {
3135
3136         local router=${ROUTERS[0]}
3137         local router_nids=( ${ROUTER_NIDS[$router]} )
3138         local rpeer=${RPEERS[0]}
3139         local rpeer_nids=( ${RPEER_NIDS[$rpeer]} )
3140
3141         do_node $router "$LNETCTL set routing 1" ||
3142                 error "Unable to enable routing on $ROUTER"
3143
3144         check_router_ni_status $router "down" "down"
3145
3146         do_lnetctl ping ${rpeer_nids[0]} &&
3147                 error "Ping should fail"
3148
3149         do_node $rpeer "$LNETCTL ping ${LNIDS[0]}" &&
3150                 error "$rpeer ping should fail"
3151
3152         # Adding a route should cause the router's NI on LOCAL_NET to get up
3153         do_route_add $HOSTNAME $REMOTE_NET ${router_nids[0]} ||
3154                 return $?
3155
3156         check_router_ni_status $router "up" "down" ||
3157                 return $?
3158
3159         # But route should still be down because of avoid_asym_router_failure
3160         check_route_aliveness "$HOSTNAME" "down" ||
3161                 return $?
3162
3163         do_lnetctl ping ${rpeer_nids[0]} &&
3164                 error "Ping should fail"
3165
3166         do_node $rpeer "$LNETCTL ping ${LNIDS[0]}" &&
3167                 error "$rpeer ping should fail"
3168
3169         # Adding the symmetric route should cause the remote NI to go up and
3170         # routes to go up
3171         do_route_add $rpeer $LOCAL_NET ${router_nids[1]} ||
3172                 return $?
3173
3174         check_router_ni_status $router "up" "up" ||
3175                 return $?
3176
3177         check_route_aliveness "$HOSTNAME" "up" ||
3178                 return $?
3179
3180         check_route_aliveness "$rpeer" "up" ||
3181                 return $?
3182
3183         do_lnetctl ping ${rpeer_nids[0]} ||
3184                 error "Failed to ping ${rpeer_nids[0]}"
3185
3186         do_node $rpeer "$LNETCTL ping ${LNIDS[0]}" ||
3187                 error "$rpeer failed to ping ${LNIDS[0]}"
3188
3189         # Stop LNet on local host
3190         do_lnetctl lnet unconfigure ||
3191                 error "Failed to stop LNet rc=$?"
3192
3193         check_router_ni_status $router "down" "up" ||
3194                 return $?
3195
3196         check_route_aliveness "$rpeer" "down" ||
3197                 return $?
3198
3199         do_lnetctl ping ${rpeer_nids[0]} &&
3200                 error "Ping should fail"
3201
3202         do_node $rpeer "$LNETCTL ping ${LNIDS[0]}" &&
3203                 error "$rpeer ping should fail"
3204
3205         return 0
3206 }
3207
3208 test_222() {
3209         ROUTERS_REQUIRED=1
3210         RPEERS_REQUIRED=1
3211
3212         setup_router_test avoid_asym_router_failure=1 || return $?
3213
3214         do_aarf_enabled_test || return $?
3215
3216         cleanup_router_test || return $?
3217 }
3218 run_test 222 "Check avoid_asym_router_failure=1"
3219
3220 test_223() {
3221         ROUTERS_REQUIRED=1
3222         RPEERS_REQUIRED=1
3223
3224         local opts="avoid_asym_router_failure=1 lnet_peer_discovery_disabled=1"
3225
3226         setup_router_test $opts || return $?
3227
3228         do_aarf_enabled_test || return $?
3229
3230         cleanup_router_test || return $?
3231 }
3232 run_test 223 "Check avoid_asym_router_failure=1 w/DD disabled"
3233
3234 do_aarf_disabled_test() {
3235         local router=${ROUTERS[0]}
3236         local router_nids=( ${ROUTER_NIDS[$router]} )
3237         local rpeer=${RPEERS[0]}
3238         local rpeer_nids=( ${RPEER_NIDS[$rpeer]} )
3239
3240         do_node $router "$LNETCTL set routing 1" ||
3241                 error "Unable to enable routing on $router"
3242
3243         check_router_ni_status $router "down" "down"
3244
3245         do_route_add $HOSTNAME $REMOTE_NET ${router_nids[0]} ||
3246                 return $?
3247
3248         check_router_ni_status $router "up" "down" ||
3249                 return $?
3250
3251         check_route_aliveness "$HOSTNAME" "up" ||
3252                 return $?
3253
3254         do_route_add $rpeer $LOCAL_NET ${router_nids[1]} ||
3255                 return $?
3256
3257         check_router_ni_status $router "up" "up" ||
3258                 return $?
3259
3260
3261         check_route_aliveness "$HOSTNAME" "up" ||
3262                 return $?
3263
3264         check_route_aliveness "$rpeer" "up" ||
3265                 return $?
3266
3267         do_lnetctl ping ${rpeer_nids[0]} ||
3268                 error "Failed to ping ${rpeer_nids[0]}"
3269
3270         do_node $rpeer "$LNETCTL ping ${LNIDS[0]}" ||
3271                 error "$rpeer failed to ping ${LNIDS[0]}"
3272
3273         # Stop LNet on local host
3274         do_lnetctl lnet unconfigure ||
3275                 error "Failed to stop LNet rc=$?"
3276
3277         check_router_ni_status $router "down" "up" ||
3278                 return $?
3279
3280         check_route_aliveness "$rpeer" "up" ||
3281                 return $?
3282
3283         return 0
3284 }
3285
3286 test_224() {
3287         ROUTERS_REQUIRED=1
3288         RPEERS_REQUIRED=1
3289
3290         setup_router_test avoid_asym_router_failure=0 ||
3291                 return $?
3292
3293         do_aarf_disabled_test ||
3294                 return $?
3295
3296         cleanup_router_test ||
3297                 return $?
3298 }
3299 run_test 224 "Check avoid_asym_router_failure=0"
3300
3301 test_225() {
3302         ROUTERS_REQUIRED=1
3303         RPEERS_REQUIRED=1
3304
3305         local opts="avoid_asym_router_failure=0 lnet_peer_discovery_disabled=1"
3306
3307         setup_router_test $opts || return $?
3308
3309         do_aarf_disabled_test || return $?
3310
3311         cleanup_router_test ||
3312                 return $?
3313 }
3314 run_test 225 "Check avoid_asym_router_failure=0 w/DD disabled"
3315
3316 test_226() {
3317         ROUTERS_REQUIRED=2
3318         RPEERS_REQUIRED=1
3319
3320         setup_router_test || return $?
3321
3322         do_basic_rtr_test || return $?
3323
3324         # ping the peer from host to make sure it works
3325         local rpeer=${RPEERS[0]}
3326         local rpeer_nids=( ${RPEER_NIDS[$rpeer]} )
3327
3328         for i in {1..4}; do
3329                 do_lnetctl ping ${rpeer_nids[0]} ||
3330                         error "Failed to ping ${rpeer_nids[0]} on try $i"
3331         done
3332
3333         # remove a route from the peer
3334         local router_nids=( ${ROUTER_NIDS[${ROUTERS[0]}]} )
3335
3336         do_route_del $rpeer $LOCAL_NET ${router_nids[0]}
3337
3338         # should attempt to use both routes due to round-robin
3339         # failure case here is an LBUG on $rpeer
3340         for i in {1..4}; do
3341                 do_lnetctl ping ${rpeer_nids[0]}
3342         done
3343
3344         cleanup_router_test || return $?
3345 }
3346 run_test 226 "test missing route for 1 of 2 routers"
3347
3348 test_230() {
3349         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
3350
3351         # LU-12815
3352         echo "Check valid values; Should succeed"
3353         local i
3354         local lnid
3355         local cmd
3356         for ((i = 4; i < 16; i+=1)); do
3357                 reinit_dlc || return $?
3358                 add_net "tcp" "${INTERFACES[0]}" || return $?
3359                 do_lnetctl net set --all --conns-per-peer $i ||
3360                         error "should have succeeded $?"
3361                 $LNETCTL net show -v 1 | grep -q "conns_per_peer: $i" ||
3362                         error "failed to set conns-per-peer to $i"
3363                 lnid="$(lctl list_nids | head -n 1)"
3364                 do_lnetctl ping "$lnid" ||
3365                         error "failed to ping myself"
3366
3367                 # "lctl --net tcp conn_list" prints the list of active
3368                 # connections. Since we're pinging ourselves, there should be
3369                 # 2 Control connections plus 2*conns_per_peer connections
3370                 # created (one Bulk Input, one Bulk Output in each pair).
3371                 # Here's the sample output for conns_per_peer set to 1:
3372                 # 12345-1.1.1.1@tcp I[0]host01->host01:988 2626560/1061296 nonagle
3373                 # 12345-1.1.1.1@tcp O[0]host01->host01:1022 2626560/1061488 nonagle
3374                 # 12345-1.1.1.1@tcp C[0]host01->host01:988 2626560/1061296 nonagle
3375                 # 12345-1.1.1.1@tcp C[0]host01->host01:1023 2626560/1061488 nonagle
3376                 cmd="printf 'network tcp\nconn_list\n' | lctl | grep -c '$lnid'"
3377
3378                 # Expect 2+conns_per_peer*2 connections. Wait no longer
3379                 # than 2 seconds.
3380                 wait_update $HOSTNAME "$cmd" "$((2+i*2))" 2 ||
3381                         error "expected number of tcp connections $((2+i*2))"
3382         done
3383
3384         reinit_dlc || return $?
3385         add_net "tcp" "${INTERFACES[0]}" || return $?
3386         echo "Set > 127; Should fail"
3387         do_lnetctl net set --all --conns-per-peer 128 &&
3388                 error "should have failed $?"
3389
3390         reinit_dlc || return $?
3391         add_net "tcp" "${INTERFACES[0]}" || return $?
3392
3393         local default=$($LNETCTL net show -v 1 |
3394                         awk '/conns_per_peer/{print $NF}')
3395
3396         echo "Set < 0; Should be ignored"
3397         do_lnetctl net set --all --conns-per-peer -1 ||
3398                 error "should have succeeded $?"
3399         $LNETCTL net show -v 1 | grep -q "conns_per_peer: ${default}" ||
3400                 error "Did not stay at default"
3401 }
3402 run_test 230 "Test setting conns-per-peer"
3403
3404 test_231() {
3405         reinit_dlc || return $?
3406
3407         local net=${NETTYPE}231
3408
3409         do_lnetctl net add --net $net --if ${INTERFACES[0]} ||
3410                 error "Failed to add net"
3411
3412         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-expected.yaml
3413         sed -i 's/peer_timeout: .*$/peer_timeout: 0/' \
3414                 $TMP/sanity-lnet-$testnum-expected.yaml
3415
3416         reinit_dlc || return $?
3417
3418         do_lnetctl import $TMP/sanity-lnet-$testnum-expected.yaml ||
3419                 error "Failed to import configuration"
3420
3421         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
3422
3423         compare_yaml_files || error "Wrong config after import"
3424
3425         do_lnetctl net del --net $net --if ${INTERFACES[0]} ||
3426                 error "Failed to delete net $net"
3427
3428         do_lnetctl net add --net $net --if ${INTERFACES[0]} --peer-timeout=0 ||
3429                 error "Failed to add net with peer-timeout=0"
3430
3431         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
3432
3433         compare_yaml_files || error "Wrong config after lnetctl net add"
3434
3435         reinit_dlc || return $?
3436
3437         # lnet/include/lnet/lib-lnet.h defines DEFAULT_PEER_TIMEOUT 180
3438         sed -i 's/peer_timeout: .*$/peer_timeout: 180/' \
3439                 $TMP/sanity-lnet-$testnum-expected.yaml
3440
3441         sed -i '/^.*peer_timeout:.*$/d' $TMP/sanity-lnet-$testnum-actual.yaml
3442
3443         do_lnetctl import $TMP/sanity-lnet-$testnum-actual.yaml ||
3444                 error "Failed to import config without peer_timeout"
3445
3446         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
3447
3448         compare_yaml_files
3449 }
3450 run_test 231 "Check DLC handling of peer_timeout parameter"
3451
3452 test_232() {
3453         [[ ${NETTYPE} =~ ^(tcp|o2ib) ]] ||
3454                 skip "Need tcp or o2ib NETTYPE"
3455
3456         local i
3457         local modparam=-1
3458         local net=${NETTYPE}232
3459
3460         reinit_dlc || return $?
3461         if [[ ${NETTYPE} == tcp* ]];then
3462                 modparam=$(cat "/sys/module/ksocklnd/parameters/tos")
3463         elif [[ ${NETTYPE} == o2ib* ]]; then
3464                 modparam=$(cat "/sys/module/ko2iblnd/parameters/tos")
3465         fi
3466
3467         do_lnetctl net add --net $net --if ${INTERFACES[0]} ||
3468                 error "Failed to add net (no ToS)"
3469         do_lnetctl net show --net $net -v 1 | grep -q "tos: $modparam" ||
3470                 error "Failed ToS value should inherit from module parameter $modparam"
3471         do_lnetctl net del --net $net --if ${INTERFACES[0]} ||
3472                 error "Failed to delete net $net"
3473
3474         for i in -1 104 106; do
3475                 do_lnetctl net add --net $net --if ${INTERFACES[0]} --tos $i ||
3476                         error "Failed to add net (ToS: $i)"
3477                 do_lnetctl net show --net $net -v 1 | grep -q "tos: $i" ||
3478                         error "Failed to set ToS value to 104"
3479                 do_lnetctl net del --net $net --if ${INTERFACES[0]} ||
3480                         error "Failed to delete net $net"
3481         done
3482
3483         ! do_lnetctl net add --net $net --if ${INTERFACES[0]} --tos 300 ||
3484                 error "lnetctl should reject invalid ToS value (>255)"
3485 }
3486 run_test 232 "Test setting ToS value"
3487
3488 ### Test that linux route is added for each ni
3489 test_250() {
3490         local skip_param
3491
3492         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
3493
3494         reinit_dlc || return $?
3495         add_net "tcp" "${INTERFACES[0]}" || return $?
3496
3497         skip_param=$(cat /sys/module/ksocklnd/parameters/skip_mr_route_setup)
3498         [[ ${skip_param:-0} -ne 0 ]] &&
3499                 skip "Need skip_mr_route_setup=0 found $skip_param"
3500
3501         ip route show table ${INTERFACES[0]} | grep -q "${INTERFACES[0]}"
3502 }
3503 run_test 250 "test that linux routes are added"
3504
3505 test_251() {
3506         [[ ${NETTYPE} =~ kfi* ]] ||
3507                 skip "Need kfi NETTYPE"
3508
3509         reinit_dlc || return $?
3510         add_net "kfi" "${INTERFACES[0]}" || return $?
3511         add_net "kfi1" "${INTERFACES[0]}" || return $?
3512         add_net "kfi10" "${INTERFACES[0]}" || return $?
3513         return 0
3514 }
3515 run_test 251 "Define multiple kfi networks on single interface"
3516
3517 test_252() {
3518
3519         (( $MDS1_VERSION >= $(version_code v2_14_55-10-gc807e3f33b) )) ||
3520                 skip "need MDS >= 2.14.55.10 for memory leak fix"
3521
3522         setup_health_test false || return $?
3523
3524         local rc=0
3525
3526         do_rpc_nodes $RNODE unload_modules_local || rc=$?
3527
3528         if [[ $rc -ne 0 ]]; then
3529                 cleanup_health_test || return $?
3530
3531                 error "Failed to unload modules on $RNODE rc=$rc"
3532         else
3533                 RLOADED=false
3534         fi
3535
3536         local ts1=$(date +%s)
3537
3538         do_lnetctl ping --timeout 15 ${RNIDS[0]} &&
3539                 error "Expected ping ${RNIDS[0]} to fail"
3540
3541         local ts2=$(date +%s)
3542
3543         local delta=$(echo "$ts2 - $ts1" | bc)
3544
3545         [[ $delta -lt 15 ]] ||
3546                 error "Ping took longer than expected to fail: $delta"
3547
3548         cleanup_health_test
3549 }
3550 run_test 252 "Ping to down peer should unlink quickly"
3551
3552 do_expired_message_drop_test() {
3553         local rnid lnid old_tto
3554
3555         old_tto=$($LNETCTL global show |
3556                   awk '/transaction_timeout:/{print $NF}')
3557
3558         [[ -z $old_tto ]] &&
3559                 error "Cannot determine LNet transaction timeout"
3560
3561         local tto=10
3562
3563         do_lnetctl set transaction_timeout "${tto}" ||
3564                 error "Failed to set transaction_timeout"
3565
3566         # We want to consume all peer credits for at least transaction_timeout
3567         # seconds
3568         local delay
3569
3570         delay=$((tto + 1))
3571
3572         for lnid in "${LNIDS[@]}"; do
3573                 for rnid in "${RNIDS[@]}"; do
3574                         $LCTL net_delay_add -s "${lnid}" -d "${rnid}" \
3575                                 -l "${delay}" -r 1 -m GET ||
3576                                 error "Failed to add delay rule"
3577                 done
3578         done
3579
3580         declare -a pcs
3581
3582         pcs=( $($LNETCTL peer show -v --nid "${RNIDS[0]}" |
3583                 awk '/max_ni_tx_credits:/{print $NF}' |
3584                 xargs echo) )
3585
3586         [[ ${#RNIDS[@]} -ne ${#pcs[@]} ]] &&
3587                 error "Expect ${#RNIDS[@]} peer credit values found ${#pcs[@]}"
3588
3589         local rnet lnid lnet i j
3590
3591         # Need to use --source for multi-rail configs to ensure we consume
3592         # all available peer credits
3593         for ((i = 0; i < ${#RNIDS[@]}; i++)); do
3594                 local ping_args="--timeout $((delay+2))"
3595
3596                 rnet=${RNIDS[i]##*@}
3597                 for lnid in ${LNIDS[@]}; do
3598                         lnet=${lnid##*@}
3599                         [[ $rnet == $lnet ]] && break
3600                 done
3601
3602                 ping_args+=" --source ${lnid} ${RNIDS[i]}"
3603                 for j in $(seq 1 "${pcs[i]}"); do
3604                         $LNETCTL ping ${ping_args} 1>/dev/null &
3605                 done
3606
3607                 echo "Issued ${pcs[i]} pings to ${RNIDS[i]} from $lnid"
3608         done
3609
3610         # This ping should be queued on peer NI tx credit
3611         $LNETCTL ping --timeout $((delay+2)) "${RNIDS[0]}" &
3612
3613         sleep ${delay}
3614
3615         $LCTL net_delay_del -a
3616
3617         wait
3618
3619         # Messages sent from the delay list do not go through
3620         # lnet_post_send_locked(), thus we should only have a single drop
3621         local dropped
3622
3623         dropped=$($LNETCTL peer show -v 2 --nid "${RNIDS[0]}" |
3624                         grep -A 2 dropped_stats |
3625                         awk '/get:/{print $2}' |
3626                         xargs echo |
3627                         sed 's/ /\+/g' | bc)
3628
3629         [[ $dropped -ne 1 ]] &&
3630                 error "Expect 1 dropped GET but found $dropped"
3631
3632         do_lnetctl set transaction_timeout "${old_tto}"
3633
3634         return 0
3635 }
3636
3637 test_253() {
3638         setup_health_test false || return $?
3639
3640         do_expired_message_drop_test || return $?
3641
3642         cleanup_health_test
3643 }
3644 run_test 253 "Message delayed beyond deadline should be dropped (single-rail)"
3645
3646 test_254() {
3647         setup_health_test true || return $?
3648
3649         do_expired_message_drop_test || return $?
3650
3651         cleanup_health_test
3652 }
3653 run_test 254 "Message delayed beyond deadline should be dropped (multi-rail)"
3654
3655 test_255() {
3656         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
3657
3658         reinit_dlc || return $?
3659
3660         cleanup_lnet || return $?
3661
3662         local routes_str="o2ib ${IF0_NET}.[$GW_HOSTNUM-$((GW_HOSTNUM+4))]"
3663         local network_str="${NETTYPE}(${INTERFACES[0]})"
3664
3665         load_lnet "networks=\"${network_str}\" routes=\"${routes_str}\"" ||
3666                 error "Failed to load LNet"
3667
3668         $LCTL net up ||
3669                 error "Failed to load LNet with networks=\"${network_str}\" routes=\"${routes_str}\""
3670
3671         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
3672 net:
3673     - net type: ${NETTYPE}
3674       local NI(s):
3675         - interfaces:
3676               0: ${INTERFACES[0]}
3677 EOF
3678         append_net_tunables tcp
3679
3680         echo "route:" >> $TMP/sanity-lnet-$testnum-expected.yaml
3681         for i in $(seq $GW_HOSTNUM $((GW_HOSTNUM + 4))); do
3682                 cat <<EOF >> $TMP/sanity-lnet-$testnum-expected.yaml
3683     - net: o2ib
3684       gateway: ${IF0_NET}.${i}@${NETTYPE}
3685       hop: -1
3686       priority: 0
3687       health_sensitivity: 1
3688 EOF
3689         done
3690
3691         echo "peer:" >> $TMP/sanity-lnet-$testnum-expected.yaml
3692         for i in $(seq $GW_HOSTNUM $((GW_HOSTNUM + 4))); do
3693                 cat <<EOF >> $TMP/sanity-lnet-$testnum-expected.yaml
3694     - primary nid: ${IF0_NET}.${i}@${NETTYPE}
3695       Multi-Rail: False
3696       peer ni:
3697         - nid: ${IF0_NET}.${i}@${NETTYPE}
3698 EOF
3699         done
3700
3701         append_global_yaml
3702
3703         $LNETCTL export --backup >  $TMP/sanity-lnet-$testnum-actual.yaml ||
3704                 error "export failed $?"
3705
3706         validate_gateway_nids
3707
3708         # Since we have an complex YAML config file we can test import
3709         do_lnetctl lnet unconfigure ||
3710                 error "Failed to stop LNet rc=$?"
3711         do_lnetctl import <  ${GLOBAL_YAML_FILE} || error "Import failed $?"
3712 }
3713 run_test 255 "Use lnet routes param with pdsh syntax"
3714
3715 test_300() {
3716         # LU-13274
3717         local header
3718         local out=$TMP/$tfile
3719         local prefix=/usr/include/linux/lnet
3720
3721         # We use a hard coded prefix so that this test will not fail
3722         # when run in tree.
3723         CC=${CC:-cc}
3724         if ! which $CC > /dev/null 2>&1; then
3725                 skip_env "$CC is not installed"
3726         fi
3727
3728         cleanup_lnet || exit 1
3729         load_lnet
3730
3731         local cc_args="-Wall -Werror -std=c99 -c -x c /dev/null -o $out"
3732         if ! [[ -d $prefix ]]; then
3733                 # Assume we're running in tree and fixup the include path.
3734                 prefix=$LUSTRE/../lnet/include/uapi/linux/lnet
3735                 cc_args+=" -I $LUSTRE/../lnet/include/uapi"
3736         fi
3737
3738         for header in $prefix/*.h; do
3739                 if ! [[ -f "$header" ]]; then
3740                         continue
3741                 fi
3742
3743                 echo "$CC $cc_args -include $header"
3744                 $CC $cc_args -include $header ||
3745                         error "cannot compile '$header'"
3746         done
3747         rm -f $out
3748 }
3749 run_test 300 "packaged LNet UAPI headers can be compiled"
3750
3751 # LU-16081 lnet: Memory leak on adding existing interface
3752
3753 test_301() {
3754         reinit_dlc || return $?
3755         do_lnetctl net add --net ${NETTYPE} --if ${INTERFACES[0]} ||
3756                 error "Failed to add net"
3757         do_lnetctl net add --net ${NETTYPE} --if ${INTERFACES[0]} &&
3758                 error "add net should have failed"
3759         do_lnetctl net del --net ${NETTYPE} --if ${INTERFACES[0]} ||
3760                 error "Failed to del net"
3761         unload_modules
3762 }
3763 run_test 301 "Check for dynamic adds of same/wrong interface (memory leak)"
3764
3765 test_302() {
3766         ! [[ $NETTYPE =~ (tcp|o2ib) ]] && skip "Need tcp or o2ib NETTYPE"
3767
3768         reinit_dlc || return $?
3769
3770         add_net "${NETTYPE}" "${INTERFACES[0]}" || return $?
3771
3772         local nid=$($LCTL list_nids)
3773
3774         do_lnetctl ping ${nid} ||
3775                 error "pinging self failed $?"
3776         do_lnetctl debug peer --nid ${nid} ||
3777                 error "failed to dump peer debug info $?"
3778 }
3779 run_test 302 "Check that peer debug info can be dumped"
3780
3781 test_303() {
3782         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
3783
3784         setup_health_test true || return $?
3785
3786         cleanup_netns || error "Failed to cleanup netns before test execution"
3787         setup_fakeif || error "Failed to add fake IF"
3788         have_interface "$FAKE_IF" ||
3789                 error "Expect $FAKE_IF configured but not found"
3790
3791         add_net "${NETTYPE}99" "$FAKE_IF" || return $?
3792
3793         local nid=$($LCTL list_nids | tail --lines 1)
3794
3795         # Our updated config should be pushed to RNODE
3796         local found=$(do_node $RNODE "$LNETCTL peer show --nid $nid")
3797
3798         [[ -z $found ]] && error "Peer not updated on $RNODE"
3799
3800         local prim=$($LCTL list_nids | head -n 1)
3801
3802         if ! grep -q -- " primary nid: $prim"<<<"${found}"; then
3803                 echo "$found"
3804                 error "Wrong primary nid"
3805         fi
3806
3807         echo "Set $FAKE_IF down"
3808         echo "ip link set dev $FAKE_IF down"
3809         ip link set dev $FAKE_IF down
3810         check_ni_status "$nid" down
3811
3812         local hval=$(do_node $RNODE "$LNETCTL peer show --nid $nid -v 2 | \
3813                                      grep -e '- nid:' -e 'health value:'")
3814
3815         hval=$(grep -A 1 $nid<<<"$hval" | tail -n 1 | awk '{print $NF}')
3816         (( hval < 1000 )) ||
3817                 error "Expect $hval < 1000"
3818
3819         return 0
3820 }
3821 run_test 303 "Check peer NI health after link down"
3822
3823 test_304() {
3824         [[ ${NETTYPE} == tcp* ]] || skip "Need tcp NETTYPE"
3825
3826         cleanup_netns || error "Failed to cleanup netns before test execution"
3827         cleanup_lnet || error "Failed to unload modules before test execution"
3828
3829         setup_fakeif || error "Failed to add fake IF"
3830         have_interface "$FAKE_IF" ||
3831                 error "Expect $FAKE_IF configured but not found"
3832
3833         reinit_dlc || return $?
3834
3835         add_net "tcp" "${INTERFACES[0]}" || return $?
3836         add_net "tcp" "$FAKE_IF" || return $?
3837
3838         local nid1=$(lctl list_nids | head -n 1)
3839         local nid2=$(lctl list_nids | tail --lines 1)
3840
3841         check_ni_status "$nid1" up
3842         check_ni_status "$nid2" up
3843
3844         do_lnetctl peer add --prim_nid ${nid2} --lock_prim ||
3845                 error "peer add failed $?"
3846         local locked_peer_state=($(do_lnetctl peer show -v 4 --nid ${nid2} |
3847                 awk '/peer state/{print $NF}'))
3848
3849         # Expect peer state bits:
3850         #   LNET_PEER_MULTI_RAIL(0) | LNET_PEER_CONFIGURED(3) |
3851         #   LNET_PEER_LOCK_PRIMARY(20)
3852         (( $locked_peer_state != "1048585")) &&
3853                 error "Wrong peer state \"$locked_peer_state\" expected 1048585"
3854
3855         # Clear LNET_PEER_CONFIGURED bit and verify
3856         do_lnetctl peer set --nid ${nid2} --state 1048577 ||
3857                 error "peer add failed $?"
3858         locked_peer_state=($(do_lnetctl peer show -v 4 --nid ${nid2} |
3859                 awk '/peer state/{print $NF}'))
3860         (( $locked_peer_state != "1048577")) &&
3861                 error "Wrong peer state \"$locked_peer_state\" expected 1048577"
3862         do_lnetctl discover ${nid1} ||
3863                 error "Failed to discover peer"
3864
3865         # Expect nid2 and nid1 peer entries to be consolidated,
3866         # nid2 to stay primary
3867         cat <<EOF >> $TMP/sanity-lnet-$testnum-expected.yaml
3868 peer:
3869     - primary nid: ${nid2}
3870       Multi-Rail: True
3871       peer ni:
3872         - nid: ${nid1}
3873           state: NA
3874         - nid: ${nid2}
3875           state: NA
3876 EOF
3877         $LNETCTL peer show > $TMP/sanity-lnet-$testnum-actual.yaml
3878         compare_yaml_files ||
3879                 error "Unexpected peer configuration"
3880
3881         locked_peer_state=($(do_lnetctl peer show -v 4 --nid ${nid2} |
3882                 awk '/peer state/{print $NF}'))
3883         # Expect peer state bits to be added:
3884         #   LNET_PEER_DISCOVERED(4) | LNET_PEER_NIDS_UPTODATE(8)
3885         (( $locked_peer_state != "1048849")) &&
3886                 error "Wrong peer state \"$locked_peer_state\" expected 1048849"
3887         return 0
3888 }
3889 run_test 304 "Check locked primary peer nid consolidation"
3890
3891 check_parameter() {
3892         local para=$1
3893         local value=$2
3894
3895         echo "check parameter ${para} value ${value}"
3896
3897         return $(( $(do_lnetctl net show -v | \
3898                      tee /dev/stderr | \
3899                      grep -c "^ \+${para}: ${value}$") != ${#INTERFACES[@]} ))
3900 }
3901
3902 static_config() {
3903         local module=$1
3904         local setting=$2
3905
3906         cleanup_lnet || error "Failed to cleanup LNet"
3907
3908         load_module ../libcfs/libcfs/libcfs ||
3909                 error "Failed to load module libcfs rc = $?"
3910
3911         load_module ../lnet/lnet/lnet ||
3912                 error "Failed to load module lnet rc = $?"
3913
3914         echo "loading ${module} ${setting} type ${NETTYPE}"
3915         load_module "${module}" "${setting}" ||
3916                 error "Failed to load module ${module} rc = $?"
3917
3918         do_lnetctl lnet configure --all || error "lnet configure failed rc = $?"
3919
3920         return 0
3921 }
3922
3923 test_310() {
3924         local value=65
3925
3926         if [[ ${NETTYPE} == tcp* ]];then
3927                 static_config "../lnet/klnds/socklnd/ksocklnd" \
3928                               "sock_timeout=${value}"
3929         elif [[ ${NETTYPE} == o2ib* ]]; then
3930                 static_config "../lnet/klnds/o2iblnd/ko2iblnd" \
3931                               "timeout=${value}"
3932         elif [[ ${NETTYPE} == gni* ]]; then
3933                 static_config "../lnet/klnds/gnilnd/kgnilnd" \
3934                               "timeout=${value}"
3935         else
3936                 skip "NETTYPE ${NETTYPE} not supported"
3937         fi
3938
3939         check_parameter "timeout" $value
3940
3941         return $?
3942 }
3943 run_test 310 "Set timeout and verify"
3944
3945 test_311() {
3946         [[ $NETTYPE == kfi* ]] ||
3947                 skip "Need kfi network type"
3948
3949         setupall || error "setupall failed"
3950
3951         mkdir -p $DIR/$tdir || error "mkdir failed"
3952         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 oflag=direct ||
3953                 error "dd write failed"
3954
3955         local list=$(comma_list $(osts_nodes))
3956
3957 #define CFS_KFI_FAIL_WAIT_SEND_COMP1 0xF115
3958         do_nodes $list $LCTL set_param fail_loc=0x8000F115
3959         dd if=$DIR/$tdir/$tfile of=/dev/null bs=1M count=1 ||
3960                 error "dd read failed"
3961
3962         rm -f $DIR/$tdir/$tfile
3963         rmdir $DIR/$tdir
3964
3965         cleanupall || error "Failed cleanup"
3966 }
3967 run_test 311 "Fail bulk put in send wait completion"
3968
3969 test_312() {
3970         [[ $NETTYPE == kfi* ]] ||
3971                 skip "Need kfi network type"
3972
3973         setupall || error "setupall failed"
3974
3975         mkdir -p $DIR/$tdir || error "mkdir failed"
3976
3977         local list=$(comma_list $(osts_nodes))
3978
3979 #define CFS_KFI_FAIL_WAIT_SEND_COMP3 0xF117
3980         do_nodes $list $LCTL set_param fail_loc=0x8000F117
3981         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 oflag=direct ||
3982                 error "dd write failed"
3983
3984         local tfile2="$DIR/$tdir/testfile2"
3985
3986         do_nodes $list $LCTL set_param fail_loc=0x8000F117
3987         dd if=$DIR/$tdir/$tfile of=$tfile2 bs=1M count=1 oflag=direct ||
3988                 error "dd read failed"
3989
3990         rm -f $DIR/$tdir/$tfile
3991         rm -f $tfile2
3992         rmdir $DIR/$tdir
3993
3994         cleanupall || error "Failed cleanup"
3995 }
3996 run_test 312 "TAG_RX_OK is possible after TX_FAIL"
3997
3998 check_udsp_prio() {
3999         local target_net="${1}"
4000         local target_nid="${2}"
4001         local expect_net="${3}"
4002         local expect_nid="${4}"
4003         local type="${5}"
4004
4005         declare -a nids
4006         declare -a net_prios
4007         declare -a nid_prios
4008
4009         nids=( $($LNETCTL ${type} show -v 5 | awk '/-\s+nid:/{print $NF}' |
4010                  xargs echo) )
4011
4012         net_prios=( $($LNETCTL ${type} show -v 5 |
4013                       awk '/net priority:/{print $NF}' | xargs echo) )
4014
4015         nid_prios=( $($LNETCTL ${type} show -v 5 |
4016                       awk '/nid priority:/{print $NF}' | xargs echo) )
4017
4018         (( ${#nids[@]} != ${#net_prios[@]} )) &&
4019                 error "Wrong # net prios ${#nids[@]} != ${#net_prios[@]}"
4020
4021         (( ${#nids[@]} != ${#nid_prios[@]} )) &&
4022                 error "Wrong # nid prios ${#nids[@]} != ${#nid_prios[@]}"
4023
4024         local i
4025
4026         for ((i = 0; i < ${#nids[@]}; i++)); do
4027                 [[ -n ${target_net} ]] &&
4028                         [[ ${nids[i]##*@} != "${target_net}" ]] &&
4029                         continue
4030                 [[ -n ${target_nid} ]] &&
4031                         [[ ${nids[i]} != "${target_nid}" ]] &&
4032                         continue
4033
4034                 echo "${nids[i]}: net_prio ${net_prios[i]} expect ${expect_net}"
4035                 (( net_prios[i] != expect_net )) &&
4036                         error "Wrong net priority \"${net_prios[i]}\" expect ${expect_net}"
4037
4038                 echo "${nids[i]}: nid_prio ${nid_prios[i]} expect ${expect_nid}"
4039                 (( nid_prios[i] != expect_nid )) &&
4040                         error "Wrong nid priority \"${nid_prios[i]}\" expect ${expect_nid}"
4041         done
4042
4043         return 0
4044 }
4045
4046 check_peer_udsp_prio() {
4047         check_udsp_prio "${1}" "${2}" "${3}" "${4}" "peer"
4048 }
4049
4050 check_net_udsp_prio() {
4051         check_udsp_prio "${1}" "${2}" "${3}" "${4}" "net"
4052 }
4053
4054 test_400() {
4055         reinit_dlc || return $?
4056
4057         do_lnetctl udsp add --src tcp --priority 0 ||
4058                 error "Failed to add udsp rule"
4059         do_lnetctl udsp del --idx 0 ||
4060                 error "Failed to del udsp rule"
4061         unload_modules
4062 }
4063 run_test 400 "Check for udsp add/delete net rule without net num"
4064
4065 test_401() {
4066         reinit_dlc || return $?
4067
4068         do_lnetctl net add --net ${NETTYPE} --if ${INTERFACES[0]} ||
4069                 error "Failed to add net"
4070
4071         do_lnetctl udsp add --dst ${NETTYPE} --prio 1 ||
4072                 error "Failed to add peer net priority rule"
4073
4074         do_lnetctl discover $($LCTL list_nids | head -n 1) ||
4075                 error "Failed to discover peer"
4076
4077         check_peer_udsp_prio "${NETTYPE}" "" "1" "-1"
4078
4079         return 0
4080 }
4081 run_test 401 "Discover peer after adding peer net UDSP rule"
4082
4083 test_402() {
4084         reinit_dlc || return $?
4085
4086         do_lnetctl udsp add --dst kfi --priority 0 ||
4087                 error "Failed to add UDSP rule"
4088
4089         do_lnetctl peer add --prim 402@kfi ||
4090                 error "Failed to add peer"
4091
4092         return 0
4093 }
4094 run_test 402 "Destination net rule should not panic"
4095
4096 test_500() {
4097         reinit_dlc || return $?
4098
4099         cleanup_netns || error "Failed to cleanup netns before test execution"
4100         setup_fakeif || error "Failed to add fake IF"
4101         have_interface "$FAKE_IF" ||
4102                 error "Expect $FAKE_IF configured but not found"
4103
4104         add_net "tcp" "${INTERFACES[0]}"
4105         add_net "tcp" "${FAKE_IF}"
4106
4107         do_lnetctl discover $($LCTL list_nids | head -n 1) ||
4108                 error "Failed to discover self"
4109
4110         $LCTL net_delay_add -s *@tcp -d *@tcp -r 1 -l 1 -m PUT ||
4111                 error "Failed to add delay rule"
4112
4113         $LCTL net_drop_add -s *@tcp -d $($LCTL list_nids | head -n 1) -m PUT \
4114                 -e local_timeout -r 1 ||
4115                 error "Failed to add drop rule"
4116         $LCTL net_drop_add -s *@tcp -d $($LCTL list_nids | tail -n 1) -m PUT \
4117                 -e local_timeout -r 1 ||
4118                 error "Failed to add drop rule"
4119
4120         ip link set $FAKE_IF down ||
4121                 error "Failed to set link down"
4122         ip link set $FAKE_IF up ||
4123                 error "Failed to set link up"
4124
4125         unload_modules
4126 }
4127 run_test 500 "Check deadlock on ping target update"
4128
4129 do_peer_set_health_test() {
4130         local test_val="$1"
4131         shift
4132         local nid_arg="$@"
4133
4134         local max_hval
4135
4136         if [[ ${nid_arg} == --all ]]; then
4137                 max_hval=$($LNETCTL peer show -v 2 2>/dev/null |
4138                            awk '/health value/{print $NF}' | xargs echo |
4139                            sed 's/ /+/g' | bc -l)
4140         else
4141                 max_hval=$($LNETCTL peer show ${nid_arg} -v 2 2>/dev/null |
4142                            awk '/health value/{print $NF}' | xargs echo |
4143                            sed 's/ /+/g' | bc -l)
4144         fi
4145
4146         (( max_hval >= 1000 )) && (( max_hval % 1000 == 0)) ||
4147                 error "Unexpected max health value $max_hval"
4148
4149         lnet_health_pre || return $?
4150
4151         do_lnetctl peer set --health $test_val ${nid_arg} ||
4152                 error "failed to set health value"
4153
4154         lnet_health_post || return $?
4155
4156         local hval
4157
4158         if [[ ${nid_arg} == --all ]]; then
4159                 hval=$($LNETCTL peer show -v 2 2>/dev/null |
4160                        awk '/health value/{print $NF}' | xargs echo |
4161                        sed 's/ /+/g' | bc -l)
4162         else
4163                 hval=$($LNETCTL peer show ${nid_arg} -v 2 2>/dev/null |
4164                        awk '/health value/{print $NF}' | xargs echo |
4165                        sed 's/ /+/g' | bc -l)
4166         fi
4167
4168         check_remote_health || return $?
4169
4170         echo "hval: $hval max_hval: $max_hval"
4171         (( hval == max_hval )) || error "Failed to reset health to max"
4172
4173         return 0
4174 }
4175
4176 test_501() {
4177         reinit_dlc || return $?
4178
4179         setup_health_test false || return $?
4180
4181         $LCTL set_param debug=-1
4182
4183         $LCTL net_drop_add -s *@tcp -d *@tcp -r 1 ||
4184                 error "Failed to add drop rule"
4185
4186         local test_val
4187
4188         for test_val in 0 500; do
4189                 do_peer_set_health_test $test_val --nid ${RNIDS[0]} || return $?
4190                 do_peer_set_health_test $test_val --all || return $?
4191         done
4192
4193         cleanup_health_test
4194 }
4195 run_test 501 "Verify lnetctl peer set --health (SR)"
4196
4197 test_502() {
4198         reinit_dlc || return $?
4199
4200         setup_health_test true || return $?
4201
4202         $LCTL set_param debug=-1
4203
4204         $LCTL net_drop_add -s *@tcp -d *@tcp -r 1 ||
4205                 error "Failed to add drop rule"
4206
4207         local test_val
4208
4209         for test_val in 0 500; do
4210                 do_peer_set_health_test $test_val --nid ${RNIDS[0]} || return $?
4211                 do_peer_set_health_test $test_val --all || return $?
4212         done
4213
4214         cleanup_health_test
4215 }
4216 run_test 502 "Verify lnetctl peer set --health (MR)"
4217
4218 complete_test $SECONDS
4219 cleanup_testsuite
4220 exit_status