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