Whamcloud - gitweb
LU-15103 tests: clean up busy cifs mount
[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 # skip the grant tests for ARM until they are fixed
16 if [[ $(uname -m) = aarch64 ]]; then
17         # bug number:    LU-14067
18         ALWAYS_EXCEPT+=" 300"
19 fi
20
21 [ "$SLOW" = "no" ] && EXCEPT_SLOW=""
22
23 LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
24
25 . $LUSTRE/tests/test-framework.sh
26 CLEANUP=${CLEANUP:-:}
27 SETUP=${SETUP:-:}
28 init_test_env $@
29 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
30 init_logging
31
32 build_test_filter
33
34 [[ -z $LNETCTL ]] && skip "Need lnetctl"
35
36 restore_mounts=false
37
38 if is_mounted $MOUNT || is_mounted $MOUNT2; then
39         cleanupall || error "Failed cleanup prior to test execution"
40         restore_mounts=true
41 fi
42
43 cleanup_lnet() {
44         echo "Cleaning up LNet"
45         lsmod | grep -q lnet &&
46                 $LNETCTL lnet unconfigure 2>/dev/null
47         unload_modules
48 }
49
50 restore_modules=false
51 if module_loaded lnet ; then
52         cleanup_lnet || error "Failed to unload modules before test execution"
53         restore_modules=true
54 fi
55
56 cleanup_testsuite() {
57         trap "" EXIT
58         # Cleanup any tmp files created by the sub tests
59         rm -f $TMP/sanity-lnet*
60         cleanup_netns
61         cleanup_lnet
62         if $restore_mounts; then
63                 setupall || error "Failed to setup Lustre after test execution"
64         elif $restore_modules; then
65                 load_modules ||
66                         error "Couldn't load modules after test execution"
67         fi
68         return 0
69 }
70
71 load_lnet() {
72         load_module ../libcfs/libcfs/libcfs
73         # Prevent local MODOPTS_LIBCFS being passed as part of environment
74         # variable to remote nodes
75         unset MODOPTS_LIBCFS
76
77         set_default_debug "neterror net nettrace malloc"
78         load_module ../lnet/lnet/lnet "$@"
79
80         LNDPATH=${LNDPATH:-"../lnet/klnds"}
81         if [ -z "$LNETLND" ]; then
82                 case $NETTYPE in
83                 o2ib*)  LNETLND="o2iblnd/ko2iblnd" ;;
84                 tcp*)   LNETLND="socklnd/ksocklnd" ;;
85                 *)      local lnd="${NETTYPE%%[0-9]}lnd"
86                         [ -f "$LNDPATH/$lnd/k$lnd.ko" ] &&
87                                 LNETLND="$lnd/k$lnd" ||
88                                 LNETLND="socklnd/ksocklnd"
89                 esac
90         fi
91         load_module ../lnet/klnds/$LNETLND
92 }
93
94 do_lnetctl() {
95         echo "$LNETCTL $@"
96         $LNETCTL "$@"
97 }
98
99 TESTNS='test_ns'
100 FAKE_IF="test1pg"
101 FAKE_IP="10.1.2.3"
102 do_ns() {
103         echo "ip netns exec $TESTNS $@"
104         ip netns exec $TESTNS "$@"
105 }
106
107 setup_fakeif() {
108         local netns="$1"
109
110         local netns_arg=""
111         [[ -n $netns ]] &&
112                 netns_arg="netns $netns"
113
114         ip link add 'test1pl' type veth peer name $FAKE_IF $netns_arg
115         ip link set 'test1pl' up
116         if [[ -n $netns ]]; then
117                 do_ns ip addr add "${FAKE_IP}/31" dev $FAKE_IF
118                 do_ns ip link set $FAKE_IF up
119         else
120                 ip addr add "${FAKE_IP}/31" dev $FAKE_IF
121                 ip link set $FAKE_IF up
122         fi
123 }
124
125 cleanup_fakeif() {
126         ip link show test1pl >& /dev/null && ip link del test1pl || return 0
127 }
128
129 setup_netns() {
130         cleanup_netns
131
132         ip netns add $TESTNS
133         setup_fakeif $TESTNS
134 }
135
136 cleanup_netns() {
137         (ip netns list | grep -q $TESTNS) && ip netns del $TESTNS
138         cleanup_fakeif
139 }
140
141 configure_dlc() {
142         echo "Loading LNet and configuring DLC"
143         load_lnet
144         do_lnetctl lnet configure
145 }
146
147 GLOBAL_YAML_FILE=$TMP/sanity-lnet-global.yaml
148 define_global_yaml() {
149         $LNETCTL export --backup >${GLOBAL_YAML_FILE} ||
150                 error "Failed to export global yaml $?"
151 }
152
153 reinit_dlc() {
154         if lsmod | grep -q lnet; then
155                 do_lnetctl lnet unconfigure ||
156                         error "lnetctl lnet unconfigure failed $?"
157                 do_lnetctl lnet configure ||
158                         error "lnetctl lnet configure failed $?"
159         else
160                 configure_dlc || error "configure_dlc failed $?"
161         fi
162         define_global_yaml
163 }
164
165 append_global_yaml() {
166         [[ ! -e ${GLOBAL_YAML_FILE} ]] &&
167                 error "Missing global yaml at ${GLOBAL_YAML_FILE}"
168
169         cat ${GLOBAL_YAML_FILE} >> $TMP/sanity-lnet-$testnum-expected.yaml
170 }
171
172 create_base_yaml_file() {
173         append_global_yaml
174 }
175
176 compare_yaml_files() {
177         local expected="$TMP/sanity-lnet-$testnum-expected.yaml"
178         local actual="$TMP/sanity-lnet-$testnum-actual.yaml"
179         local rc=0
180         ! [[ -e $expected ]] && echo "$expected not found" && return 1
181         ! [[ -e $actual ]] && echo "$actual not found" && return 1
182         diff -upN ${actual} ${expected} || rc=$?
183         echo "Expected:"
184         cat $expected
185         echo "Actual:"
186         cat $actual
187         return $rc
188 }
189
190 validate_nid() {
191         local nid="$1"
192         local net="${nid//*@/}"
193         local addr="${nid//@*/}"
194
195         local num_re='[0-9]\+'
196         local ip_re="[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"
197
198         if [[ $net =~ gni[0-9]* ]]; then
199                 [[ $addr =~ ${num_re} ]] && return 0
200         else
201                 [[ $addr =~ ${ip_re} ]] && return 0
202         fi
203 }
204
205 validate_nids() {
206         local yfile=$TMP/sanity-lnet-$testnum-actual.yaml
207         local primary_nids=$(awk '/- primary nid:/{print $NF}' $yfile | xargs echo)
208         local secondary_nids=$(awk '/- nid:/{print $NF}' $yfile | xargs echo)
209         local gateway_nids=$(awk '/gateway:/{print $NF}' $yfile | xargs echo)
210
211         local nid
212         for nid in $primary_nids $secondary_nids; do
213                 validate_nid "$nid" || error "Bad NID \"${nid}\""
214         done
215         return 0
216 }
217
218 validate_peer_nids() {
219         local num_peers="$1"
220         local nids_per_peer="$2"
221
222         local expect_p="$num_peers"
223         # The primary nid also shows up in the list of secondary nids
224         local expect_s="$(($num_peers + $(($nids_per_peer*$num_peers))))"
225
226         local actual_p=$(grep -c -- '- primary nid:' $TMP/sanity-lnet-$testnum-actual.yaml)
227         local actual_s=$(grep -c -- '- nid:' $TMP/sanity-lnet-$testnum-actual.yaml)
228         if [[ $expect_p -ne $actual_p ]]; then
229                 compare_yaml_files
230                 error "Expected $expect_p but found $actual_p primary nids"
231         elif [[ $expect_s -ne $actual_s ]]; then
232                 compare_yaml_files
233                 error "Expected $expect_s but found $actual_s secondary nids"
234         fi
235         validate_nids
236 }
237
238 validate_gateway_nids() {
239         local expect_gw=$(grep -c -- 'gateway:' $TMP/sanity-lnet-$testnum-expected.yaml)
240         local actual_gw=$(grep -c -- 'gateway:' $TMP/sanity-lnet-$testnum-actual.yaml)
241         if [[ $expect_gw -ne $actual_gw ]]; then
242                 compare_yaml_files
243                 error "Expected $expect_gw gateways but found $actual_gw gateways"
244         fi
245         validate_nids
246 }
247
248 cleanupall -f
249 setup_netns || error "setup_netns failed with $?"
250
251 # Determine the local interface(s) used for LNet
252 load_modules || error "Failed to load modules"
253 NIDS=( $($LCTL list_nids | xargs echo) )
254 if [[ -z ${NIDS[@]} ]]; then
255         error "No NID configured after module load"
256 fi
257
258 declare -a INTERFACES
259 for ((i = 0; i < ${#NIDS[@]}; i++)); do
260         ip=$(sed 's/^\(.*\)@.*$/\1/'<<<${NIDS[i]})
261         INTERFACES[i]=$(ip -o a s |
262                         awk '$4 ~ /^'$ip'\//{print $2}')
263         if [[ -z ${INTERFACES[i]} ]]; then
264                 error "Can't determine interface name for NID ${NIDS[i]}"
265         elif [[ 1 -ne $(wc -w <<<${INTERFACES[i]}) ]]; then
266                 error "Found $(wc -w <<<${INTERFACES[i]}) interfaces for NID ${NIDS[i]}. Expect 1"
267         fi
268 done
269
270 cleanup_lnet || error "Failed to cleanup LNet"
271
272 stack_trap 'cleanup_testsuite' EXIT
273
274 test_0() {
275         load_module ../lnet/lnet/lnet || error "Failed to load module rc = $?"
276         do_lnetctl lnet configure || error "lnet configure failed rc = $?"
277         define_global_yaml
278         reinit_dlc || return $?
279         do_lnetctl import <  ${GLOBAL_YAML_FILE} || error "Import failed $?"
280         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
281         create_base_yaml_file
282         compare_yaml_files || error "Configuration changed after import"
283 }
284 run_test 0 "Export empty config, import the config, compare"
285
286 compare_peer_add() {
287         local prim_nid="${1:+--prim_nid $1}"
288         local nid="${2:+--nid $2}"
289
290         local actual="$TMP/sanity-lnet-$testnum-actual.yaml"
291
292         do_lnetctl peer add ${prim_nid} ${nid} || error "peer add failed $?"
293         $LNETCTL export --backup > $actual || error "export failed $?"
294         compare_yaml_files
295         return $?
296 }
297
298 test_1() {
299         reinit_dlc || return $?
300         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
301 peer:
302     - primary nid: 1.1.1.1@tcp
303       Multi-Rail: True
304       peer ni:
305         - nid: 1.1.1.1@tcp
306 EOF
307         append_global_yaml
308         compare_peer_add "1.1.1.1@tcp"
309 }
310 run_test 1 "Add peer with single nid (tcp)"
311
312 test_2() {
313         reinit_dlc || return $?
314         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
315 peer:
316     - primary nid: 2.2.2.2@o2ib
317       Multi-Rail: True
318       peer ni:
319         - nid: 2.2.2.2@o2ib
320 EOF
321         append_global_yaml
322         compare_peer_add "2.2.2.2@o2ib"
323 }
324 run_test 2 "Add peer with single nid (o2ib)"
325
326 test_3() {
327         reinit_dlc || return $?
328         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
329 peer:
330     - primary nid: 3.3.3.3@tcp
331       Multi-Rail: True
332       peer ni:
333         - nid: 3.3.3.3@tcp
334         - nid: 3.3.3.3@o2ib
335 EOF
336         append_global_yaml
337         compare_peer_add "3.3.3.3@tcp" "3.3.3.3@o2ib"
338 }
339 run_test 3 "Add peer with tcp primary o2ib secondary"
340
341 test_4() {
342         reinit_dlc || return $?
343         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
344 peer:
345     - primary nid: 4.4.4.4@tcp
346       Multi-Rail: True
347       peer ni:
348         - nid: 4.4.4.4@tcp
349         - nid: 4.4.4.1@tcp
350         - nid: 4.4.4.2@tcp
351         - nid: 4.4.4.3@tcp
352 EOF
353         append_global_yaml
354         echo "Add peer with nidrange (tcp)"
355         compare_peer_add "4.4.4.4@tcp" "4.4.4.[1-3]@tcp"
356
357         echo "Add peer with nidrange that overlaps primary nid (tcp)"
358         compare_peer_add "4.4.4.4@tcp" "4.4.4.[1-4]@tcp"
359 }
360 run_test 4 "Add peer with nidrange (tcp)"
361
362 test_5() {
363         reinit_dlc || return $?
364         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
365 peer:
366     - primary nid: 5.5.5.5@o2ib
367       Multi-Rail: True
368       peer ni:
369         - nid: 5.5.5.5@o2ib
370         - nid: 5.5.5.1@o2ib
371         - nid: 5.5.5.2@o2ib
372         - nid: 5.5.5.3@o2ib
373         - nid: 5.5.5.4@o2ib
374 EOF
375         append_global_yaml
376         echo "Add peer with nidrange (o2ib)"
377         compare_peer_add "5.5.5.5@o2ib" "5.5.5.[1-4]@o2ib"
378
379         echo "Add peer with nidranage that overlaps primary nid (o2ib)"
380         compare_peer_add "5.5.5.5@o2ib" "5.5.5.[1-4]@o2ib"
381 }
382 run_test 5 "Add peer with nidrange (o2ib)"
383
384 test_6() {
385         reinit_dlc || return $?
386         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
387 peer:
388     - primary nid: 6.6.6.6@tcp
389       Multi-Rail: True
390       peer ni:
391         - nid: 6.6.6.6@tcp
392         - nid: 6.6.6.0@tcp
393         - nid: 6.6.6.2@tcp
394         - nid: 6.6.6.4@tcp
395         - nid: 6.6.7.0@tcp
396         - nid: 6.6.7.2@tcp
397         - nid: 6.6.7.4@tcp
398         - nid: 6.6.1.0@o2ib
399         - nid: 6.6.1.3@o2ib
400         - nid: 6.6.1.6@o2ib
401         - nid: 6.6.3.0@o2ib
402         - nid: 6.6.3.3@o2ib
403         - nid: 6.6.3.6@o2ib
404         - nid: 6@gni
405         - nid: 10@gni
406 EOF
407         append_global_yaml
408         compare_peer_add "6.6.6.6@tcp" \
409                 "6.6.[6-7].[0-4/2]@tcp,6.6.[1-4/2].[0-6/3]@o2ib,[6-12/4]@gni"
410 }
411 run_test 6 "Add peer with multiple nidranges"
412
413 compare_peer_del() {
414         local prim_nid="${1:+--prim_nid $1}"
415         local nid="${2:+--nid $2}"
416
417         local actual="$TMP/sanity-lnet-$testnum-actual.yaml"
418
419         do_lnetctl peer del ${prim_nid} ${nid} || error "peer del failed $?"
420         $LNETCTL export --backup > $actual || error "export failed $?"
421         compare_yaml_files
422         return $?
423 }
424
425 test_7() {
426         reinit_dlc || return $?
427         create_base_yaml_file
428
429         echo "Delete peer with single nid (tcp)"
430         do_lnetctl peer add --prim_nid 7.7.7.7@tcp || error "Peer add failed $?"
431         compare_peer_del "7.7.7.7@tcp"
432
433         echo "Delete peer with single nid (o2ib)"
434         do_lnetctl peer add --prim_nid 7.7.7.7@o2ib || error "Peer add failed $?"
435         compare_peer_del "7.7.7.7@o2ib"
436
437         echo "Delete peer that has multiple nids (tcp)"
438         do_lnetctl peer add --prim_nid 7.7.7.7@tcp --nid 7.7.7.[8-12]@tcp ||
439                 error "Peer add failed $?"
440         compare_peer_del "7.7.7.7@tcp"
441
442         echo "Delete peer that has multiple nids (o2ib)"
443         do_lnetctl peer add --prim_nid 7.7.7.7@o2ib --nid 7.7.7.[8-12]@o2ib ||
444                 error "Peer add failed $?"
445         compare_peer_del "7.7.7.7@o2ib"
446
447         echo "Delete peer that has both tcp and o2ib nids"
448         do_lnetctl peer add --prim_nid 7.7.7.7@tcp \
449                 --nid 7.7.7.[9-12]@tcp,7.7.7.[13-15]@o2ib ||
450                 error "Peer add failed $?"
451         compare_peer_del "7.7.7.7@tcp"
452
453         echo "Delete peer with single nid (gni)"
454         do_lnetctl peer add --prim_nid 7@gni || error "Peer add failed $?"
455         compare_peer_del "7@gni"
456
457         echo "Delete peer that has multiple nids (gni)"
458         do_lnetctl peer add --prim_nid 7@gni --nid [8-12]@gni ||
459                 error "Peer add failed $?"
460         compare_peer_del "7@gni"
461
462         echo "Delete peer that has tcp, o2ib and gni nids"
463         do_lnetctl peer add --prim_nid 7@gni \
464                 --nid [8-12]@gni,7.7.7.[9-12]@tcp,7.7.7.[13-15]@o2ib ||
465                 error "Peer add failed $?"
466         compare_peer_del "7@gni"
467 }
468 run_test 7 "Various peer delete tests"
469
470 test_8() {
471         reinit_dlc || return $?
472
473         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
474 peer:
475     - primary nid: 8.8.8.8@tcp
476       Multi-Rail: True
477       peer ni:
478         - nid: 8.8.8.8@tcp
479         - nid: 8.8.8.10@tcp
480         - nid: 8.8.8.11@tcp
481         - nid: 8.8.8.12@tcp
482         - nid: 8.8.8.14@tcp
483         - nid: 8.8.8.15@tcp
484 EOF
485         append_global_yaml
486
487         do_lnetctl peer add --prim_nid 8.8.8.8@tcp --nid 8.8.8.[10-15]@tcp ||
488                 error "Peer add failed $?"
489         compare_peer_del "8.8.8.8@tcp" "8.8.8.13@tcp"
490 }
491 run_test 8 "Delete single secondary nid from peer (tcp)"
492
493 test_9() {
494         reinit_dlc || return $?
495
496         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
497 peer:
498     - primary nid: 9.9.9.9@tcp
499       Multi-Rail: True
500       peer ni:
501         - nid: 9.9.9.9@tcp
502 EOF
503         append_global_yaml
504
505         do_lnetctl peer add --prim_nid 9.9.9.9@tcp \
506                 --nid 9.9.9.[11-16]@tcp || error "Peer add failed $?"
507         compare_peer_del "9.9.9.9@tcp" "9.9.9.[11-16]@tcp"
508 }
509 run_test 9 "Delete all secondary nids from peer (tcp)"
510
511 test_10() {
512         reinit_dlc || return $?
513
514         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
515 peer:
516     - primary nid: 10.10.10.10@tcp
517       Multi-Rail: True
518       peer ni:
519         - nid: 10.10.10.10@tcp
520         - nid: 10.10.10.12@tcp
521         - nid: 10.10.10.13@tcp
522         - nid: 10.10.10.15@tcp
523         - nid: 10.10.10.16@tcp
524 EOF
525         append_global_yaml
526         do_lnetctl peer add --prim_nid 10.10.10.10@tcp \
527                 --nid 10.10.10.[12-16]@tcp || error "Peer add failed $?"
528         compare_peer_del "10.10.10.10@tcp" "10.10.10.14@tcp"
529 }
530 run_test 10 "Delete single secondary nid from peer (o2ib)"
531
532 test_11() {
533         reinit_dlc || return $?
534
535         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
536 peer:
537     - primary nid: 11.11.11.11@tcp
538       Multi-Rail: True
539       peer ni:
540         - nid: 11.11.11.11@tcp
541 EOF
542         append_global_yaml
543         do_lnetctl peer add --prim_nid 11.11.11.11@tcp \
544                 --nid 11.11.11.[13-17]@tcp || error "Peer add failed $?"
545         compare_peer_del "11.11.11.11@tcp" "11.11.11.[13-17]@tcp"
546 }
547 run_test 11 "Delete all secondary nids from peer (o2ib)"
548
549 test_12() {
550         reinit_dlc || return $?
551
552         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
553 peer:
554     - primary nid: 12.12.12.12@o2ib
555       Multi-Rail: True
556       peer ni:
557         - nid: 12.12.12.12@o2ib
558         - nid: 13.13.13.13@o2ib
559         - nid: 14.13.13.13@o2ib
560         - nid: 14.15.13.13@o2ib
561         - nid: 15.17.1.5@tcp
562         - nid: 15.17.1.10@tcp
563         - nid: 15.17.1.20@tcp
564 EOF
565         append_global_yaml
566         do_lnetctl peer add --prim_nid 12.12.12.12@o2ib \
567                 --nid [13-14/1].[13-15/2].13.13@o2ib,[15-16/3].[17-19/4].[1].[5-20/5]@tcp ||
568                 error "Peer add failed $?"
569         compare_peer_del "12.12.12.12@o2ib" "13.15.13.13@o2ib,15.17.1.15@tcp"
570 }
571 run_test 12 "Delete a secondary nid from peer (tcp and o2ib)"
572
573 test_13() {
574         reinit_dlc || return $?
575
576         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
577 peer:
578     - primary nid: 13.13.13.13@o2ib
579       Multi-Rail: True
580       peer ni:
581         - nid: 13.13.13.13@o2ib
582 EOF
583         append_global_yaml
584         do_lnetctl peer add --prim_nid 13.13.13.13@o2ib \
585                 --nid [14-15].[1-2/1].[1].[100-254/10]@tcp,14.14.[254].14@o2ib ||
586                 error "Peer add failed $?"
587         compare_peer_del "13.13.13.13@o2ib" \
588                 "[14-15].[1-2/1].[1].[100-254/10]@tcp,14.14.[254].14@o2ib"
589 }
590 run_test 13 "Delete all secondary nids from peer (tcp and o2ib)"
591
592 create_nid() {
593         local num="$1"
594         local net="$2"
595
596         if [[ $net =~ gni* ]]; then
597                 echo "${num}@${net}"
598         else
599                 echo "${num}.${num}.${num}.${num}@${net}"
600         fi
601 }
602
603 create_mr_peer_yaml() {
604         local num_peers="$1"
605         local secondary_nids="$2"
606         local net="$3"
607
608         echo "Generating peer yaml for $num_peers peers with $secondary_nids secondary nids"
609         echo "peer:" >> $TMP/sanity-lnet-$testnum-expected.yaml
610         local i
611         local total_nids=$((num_peers + $((num_peers * secondary_nids))))
612         local created=0
613         local nidnum=1
614         while [[ $created -lt $num_peers ]]; do
615                 local primary=$(create_nid ${nidnum} ${net})
616         cat <<EOF >> $TMP/sanity-lnet-$testnum-expected.yaml
617     - primary nid: $primary
618       Multi-Rail: True
619       peer ni:
620         - nid: $primary
621 EOF
622                 local j
623                 local start=$((nidnum + 1))
624                 local end=$((nidnum + $secondary_nids))
625                 for j in $(seq ${start} ${end}); do
626                         local nid=$(create_nid $j ${net})
627                         echo "        - nid: $nid" >> $TMP/sanity-lnet-$testnum-expected.yaml
628                 done
629                 nidnum=$((end + 1))
630                 ((created++))
631         done
632 }
633
634 test_14() {
635         reinit_dlc || return $?
636
637         echo "Create single peer, single nid, using import"
638         create_mr_peer_yaml 1 0 tcp
639         do_lnetctl import < $TMP/sanity-lnet-$testnum-expected.yaml ||
640                 error "Import failed $?"
641         append_global_yaml
642         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
643         compare_yaml_files
644
645         echo "Delete single peer using import --del"
646         do_lnetctl import --del < $TMP/sanity-lnet-$testnum-expected.yaml ||
647                 error "Import failed $?"
648         rm -f $TMP/sanity-lnet-$testnum-expected.yaml
649         create_base_yaml_file
650         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
651         compare_yaml_files
652 }
653 run_test 14 "import peer create/delete with single nid"
654
655 test_15() {
656         reinit_dlc || return $?
657
658         echo "Create multiple peers, single nid per peer, using import"
659         create_mr_peer_yaml 5 0 o2ib
660         # The ordering of nids for this use-case is non-deterministic, so we
661         # we can't just diff the expected/actual output.
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 5 0
666
667         echo "Delete multiple peers, single nid per peer, 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 15 "import multi peer create/delete with single nid per peer"
676
677 test_16() {
678         reinit_dlc || return $?
679
680         echo "Create single peer, multiple nids, using import"
681         create_mr_peer_yaml 1 5 tcp
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 1 5
686
687         echo "Delete single peer, multiple nids, 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 16 "import peer create/delete with multiple nids"
696
697 test_17() {
698         reinit_dlc || return $?
699
700         echo "Create multiple peers, multiple nids per peer, using import"
701         create_mr_peer_yaml 5 7 o2ib
702         do_lnetctl import < $TMP/sanity-lnet-$testnum-expected.yaml ||
703                 error "Import failed $?"
704         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
705         validate_peer_nids 5 7
706
707         echo "Delete multiple peers, multiple nids per peer, using import --del"
708         do_lnetctl import --del < $TMP/sanity-lnet-$testnum-expected.yaml ||
709                 error "Import failed $?"
710         rm -f $TMP/sanity-lnet-$testnum-expected.yaml
711         create_base_yaml_file
712         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
713         compare_yaml_files
714 }
715 run_test 17 "import multi peer create/delete with multiple nids"
716
717 test_18a() {
718         reinit_dlc || return $?
719
720         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
721 peer:
722     - primary nid: 1.1.1.1@tcp
723       Multi-Rail: True
724       peer ni:
725         - nid: 1.1.1.1@tcp
726         - nid: 2.2.2.2@tcp
727         - nid: 4.4.4.4@tcp
728         - nid: 3.3.3.3@o2ib
729         - nid: 5@gni
730 EOF
731         echo "Import peer with 5 nids"
732         cat $TMP/sanity-lnet-$testnum-expected.yaml
733         do_lnetctl import < $TMP/sanity-lnet-$testnum-expected.yaml ||
734                 error "Import failed $?"
735         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
736 peer:
737     - primary nid: 1.1.1.1@tcp
738       Multi-Rail: True
739       peer ni:
740         - nid: 2.2.2.2@tcp
741         - nid: 3.3.3.3@o2ib
742         - nid: 5@gni
743 EOF
744         echo "Delete three of the nids"
745         cat $TMP/sanity-lnet-$testnum-expected.yaml
746         do_lnetctl import --del < $TMP/sanity-lnet-$testnum-expected.yaml
747         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
748 peer:
749     - primary nid: 1.1.1.1@tcp
750       Multi-Rail: True
751       peer ni:
752         - nid: 1.1.1.1@tcp
753         - nid: 4.4.4.4@tcp
754 EOF
755         echo "Check peer has expected nids remaining"
756         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
757         append_global_yaml
758         compare_yaml_files
759 }
760 run_test 18a "Delete a subset of nids from a single peer using import --del"
761
762 test_18b() {
763         reinit_dlc || return $?
764
765         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
766 peer:
767     - primary nid: 1.1.1.1@tcp
768       Multi-Rail: True
769       peer ni:
770         - nid: 1.1.1.1@tcp
771         - nid: 2.2.2.2@tcp
772         - nid: 4.4.4.4@tcp
773         - nid: 3.3.3.3@o2ib
774         - nid: 5@gni
775     - primary nid: 6.6.6.6@o2ib
776       Multi-Rail: True
777       peer ni:
778         - nid: 6.6.6.6@o2ib
779         - nid: 7.7.7.7@tcp
780         - nid: 8.8.8.8@tcp
781         - nid: 9.9.9.9@tcp
782         - nid: 10@gni
783 EOF
784         echo "Import two peers with 5 nids each"
785         cat $TMP/sanity-lnet-$testnum-expected.yaml
786         do_lnetctl import < $TMP/sanity-lnet-$testnum-expected.yaml ||
787                 error "Import failed $?"
788         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
789 peer:
790     - primary nid: 1.1.1.1@tcp
791       Multi-Rail: True
792       peer ni:
793         - nid: 2.2.2.2@tcp
794         - nid: 3.3.3.3@o2ib
795         - nid: 5@gni
796     - primary nid: 6.6.6.6@o2ib
797       Multi-Rail: True
798       peer ni:
799         - nid: 7.7.7.7@tcp
800         - nid: 8.8.8.8@tcp
801         - nid: 10@gni
802 EOF
803         echo "Delete three of the nids from each peer"
804         cat $TMP/sanity-lnet-$testnum-expected.yaml
805         do_lnetctl import --del < $TMP/sanity-lnet-$testnum-expected.yaml
806         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
807 peer:
808     - primary nid: 6.6.6.6@o2ib
809       Multi-Rail: True
810       peer ni:
811         - nid: 6.6.6.6@o2ib
812         - nid: 7.7.7.7@tcp
813     - primary nid: 1.1.1.1@tcp
814       Multi-Rail: True
815       peer ni:
816         - nid: 1.1.1.1@tcp
817         - nid: 4.4.4.4@tcp
818 EOF
819         append_global_yaml
820         echo "Check peers have expected nids remaining"
821         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
822         compare_yaml_files
823         validate_peer_nids 2 1
824 }
825 run_test 18b "Delete multiple nids from multiple peers using import --del"
826
827 test_19() {
828         reinit_dlc || return $?
829         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
830 peer:
831     - primary nid: 19@gni
832       Multi-Rail: True
833       peer ni:
834         - nid: 19@gni
835 EOF
836         append_global_yaml
837         compare_peer_add "19@gni"
838 }
839 run_test 19 "Add peer with single nid (gni)"
840
841 test_20() {
842         reinit_dlc || return $?
843         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
844 peer:
845     - primary nid: 20@gni
846       Multi-Rail: True
847       peer ni:
848         - nid: 20@gni
849         - nid: 20.20.20.20@tcp
850         - nid: 20.20.20.20@o2ib
851 EOF
852         append_global_yaml
853         compare_peer_add "20@gni" "20.20.20.20@tcp,20.20.20.20@o2ib"
854 }
855 run_test 20 "Add peer with gni primary and tcp, o2ib secondary"
856
857 test_21() {
858         reinit_dlc || return $?
859         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
860 peer:
861     - primary nid: 21@gni
862       Multi-Rail: True
863       peer ni:
864         - nid: 21@gni
865         - nid: 22@gni
866         - nid: 23@gni
867         - nid: 24@gni
868         - nid: 25@gni
869 EOF
870         append_global_yaml
871         echo "Add peer with nidrange (gni)"
872         compare_peer_add "21@gni" "[22-25]@gni" || error
873         echo "Add peer with nidrange that overlaps primary nid (gni)"
874         compare_peer_add "21@gni" "[21-25]@gni"
875 }
876 run_test 21 "Add peer with nidrange (gni)"
877
878 test_22() {
879         reinit_dlc || return $?
880         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
881 peer:
882     - primary nid: 22@gni
883       Multi-Rail: True
884       peer ni:
885         - nid: 22@gni
886         - nid: 24@gni
887         - nid: 25@gni
888         - nid: 27@gni
889         - nid: 28@gni
890         - nid: 29@gni
891 EOF
892         append_global_yaml
893         do_lnetctl peer add --prim_nid 22@gni --nid [24-29]@gni ||
894                 error "Peer add failed $?"
895         compare_peer_del "22@gni" "26@gni"
896 }
897 run_test 22 "Delete single secondary nid from peer (gni)"
898
899 test_23() {
900         reinit_dlc || return $?
901         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
902 peer:
903     - primary nid: 23@gni
904       Multi-Rail: True
905       peer ni:
906         - nid: 23@gni
907 EOF
908         append_global_yaml
909
910         do_lnetctl peer add --prim_nid 23@gni --nid [25-29]@gni ||
911                 error "Peer add failed $?"
912         compare_peer_del "23@gni" "[25-29]@gni"
913 }
914 run_test 23 "Delete all secondary nids from peer (gni)"
915
916 test_24() {
917         reinit_dlc || return $?
918         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
919 peer:
920     - primary nid: 24@gni
921       Multi-Rail: True
922       peer ni:
923         - nid: 24@gni
924         - nid: 11@gni
925         - nid: 13.13.13.13@o2ib
926         - nid: 14.13.13.13@o2ib
927         - nid: 14.15.13.13@o2ib
928         - nid: 15.17.1.5@tcp
929         - nid: 15.17.1.10@tcp
930         - nid: 15.17.1.20@tcp
931 EOF
932         append_global_yaml
933         do_lnetctl peer add --prim_nid 24@gni \
934                 --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 ||
935                 error "Peer add failed $?"
936         compare_peer_del "24@gni" "5@gni,13.15.13.13@o2ib,15.17.1.15@tcp"
937 }
938 run_test 24 "Delete a secondary nid from peer (tcp, o2ib and gni)"
939
940 test_25() {
941         reinit_dlc || return $?
942         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
943 peer:
944     - primary nid: 25@gni
945       Multi-Rail: True
946       peer ni:
947         - nid: 25@gni
948 EOF
949         append_global_yaml
950         do_lnetctl peer add --prim_nid 25@gni \
951                 --nid [26-27].[4-10/3].26.26@tcp,26.26.26.26@o2ib,[30-35]@gni ||
952                 error "Peer add failed $?"
953         compare_peer_del "25@gni" \
954                 "[26-27].[4-10/3].26.26@tcp,26.26.26.26@o2ib,[30-35]@gni"
955 }
956 run_test 25 "Delete all secondary nids from peer (tcp, gni and o2ib)"
957
958 test_99a() {
959         reinit_dlc || return $?
960
961         echo "Invalid prim_nid - peer add"
962         do_lnetctl peer add --prim_nid foobar &&
963                 error "Command should have failed"
964
965         echo "Invalid prim_nid - peer del"
966         do_lnetctl peer del --prim_nid foobar &&
967                 error "Command should have failed"
968
969         echo "Delete non-existing peer"
970         do_lnetctl peer del --prim_nid 1.1.1.1@o2ib &&
971                 error "Command should have failed"
972
973         echo "Don't provide mandatory argument for peer del"
974         do_lnetctl peer del --nid 1.1.1.1@tcp &&
975                 error "Command should have failed"
976
977         echo "Don't provide mandatory argument for peer add"
978         do_lnetctl peer add --nid 1.1.1.1@tcp &&
979                 error "Command should have failed"
980
981         echo "Don't provide mandatory arguments peer add"
982         do_lnetctl peer add &&
983                 error "Command should have failed"
984
985         echo "Invalid secondary nids"
986         do_lnetctl peer add --prim_nid 1.1.1.1@tcp --nid foobar &&
987                 error "Command should have failed"
988
989         echo "Exceed max nids per peer"
990         do_lnetctl peer add --prim_nid 1.1.1.1@tcp --nid 1.1.1.[2-255]@tcp &&
991                 error "Command should have failed"
992
993         echo "Invalid net type"
994         do_lnetctl peer add --prim_nid 1@foo &&
995                 error "Command should have failed"
996
997         echo "Invalid nid format"
998         local invalid_nids="1@tcp 1@o2ib 1.1.1.1@gni"
999
1000         local nid
1001         for nid in ${invalid_nids}; do
1002                 echo "Check invalid primary nid - '$nid'"
1003                 do_lnetctl peer add --prim_nid $nid &&
1004                         error "Command should have failed"
1005         done
1006
1007         local invalid_strs="[2-1]@gni [a-f/x]@gni 256.256.256.256@tcp"
1008         invalid_strs+=" 1.1.1.1.[2-5/f]@tcp 1.]2[.3.4@o2ib"
1009         invalid_strs+="1.[2-4,[5-6],7-8].1.1@tcp foobar"
1010
1011         local nidstr
1012         for nidstr in ${invalid_strs}; do
1013                 echo "Check invalid nidstring - '$nidstr'"
1014                 do_lnetctl peer add --prim_nid 1.1.1.1@tcp --nid $nidstr &&
1015                         error "Command should have failed"
1016         done
1017
1018         echo "Add non-local gateway"
1019         do_lnetctl route add --net tcp --gateway 1@gni &&
1020                 error "Command should have failed"
1021
1022         return 0
1023 }
1024 run_test 99a "Check various invalid inputs to lnetctl peer"
1025
1026 test_99b() {
1027         reinit_dlc || return $?
1028
1029         create_base_yaml_file
1030
1031         cat <<EOF > $TMP/sanity-lnet-$testnum-invalid.yaml
1032 peer:
1033     - primary nid: 99.99.99.99@tcp
1034       Multi-Rail: Foobar
1035       peer ni:
1036         - nid: 99.99.99.99@tcp
1037 EOF
1038         do_lnetctl import < $TMP/sanity-lnet-$testnum-invalid.yaml &&
1039                 error "import should have failed"
1040         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-actual.yaml
1041         compare_yaml_files
1042 }
1043 run_test 99b "Invalid value for Multi-Rail in yaml import"
1044
1045 have_interface() {
1046         local if="$1"
1047         local ip=$(ip addr show dev $if | awk '/ inet /{print $2}')
1048         [[ -n $ip ]]
1049 }
1050
1051 add_net() {
1052         local net="$1"
1053         local if="$2"
1054
1055         if ! lsmod | grep -q ksocklnd ; then
1056                 load_module ../lnet/klnds/socklnd/ksocklnd ||
1057                         error "Can't load ksocklnd.ko"
1058         fi
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         # CPT configuration is pruned from the exported yaml, since the default
1073         # can vary across test systems (unlike default values for things like
1074         # peer_credits, peer_timeout, etc.)
1075         $LNETCTL export --backup | grep -v CPT > $actual ||
1076                 error "export failed $?"
1077         validate_gateway_nids
1078         return $?
1079 }
1080
1081 test_100() {
1082         reinit_dlc || return $?
1083         add_net "tcp" "${INTERFACES[0]}"
1084         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
1085 net:
1086     - net type: tcp
1087       local NI(s):
1088         - interfaces:
1089               0: ${INTERFACES[0]}
1090           tunables:
1091               peer_timeout: 180
1092               peer_credits: 8
1093               peer_buffer_credits: 0
1094               credits: 256
1095           lnd tunables:
1096               conns_per_peer: 1
1097 route:
1098     - net: tcp7
1099       gateway: 7.7.7.7@tcp
1100       hop: -1
1101       priority: 0
1102       health_sensitivity: 1
1103 peer:
1104     - primary nid: 7.7.7.7@tcp
1105       Multi-Rail: False
1106       peer ni:
1107         - nid: 7.7.7.7@tcp
1108 EOF
1109         append_global_yaml
1110         compare_route_add "tcp7" "7.7.7.7@tcp" || return $?
1111         compare_yaml_files
1112 }
1113 run_test 100 "Add route with single gw (tcp)"
1114
1115 test_101() {
1116         reinit_dlc || return $?
1117         add_net "tcp" "${INTERFACES[0]}"
1118         cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
1119 net:
1120     - net type: tcp
1121       local NI(s):
1122         - interfaces:
1123               0: ${INTERFACES[0]}
1124           tunables:
1125               peer_timeout: 180
1126               peer_credits: 8
1127               peer_buffer_credits: 0
1128               credits: 256
1129           lnd tunables:
1130               conns_per_peer: 1
1131 route:
1132     - net: tcp8
1133       gateway: 8.8.8.10@tcp
1134       hop: -1
1135       priority: 0
1136       health_sensitivity: 1
1137     - net: tcp8
1138       gateway: 8.8.8.9@tcp
1139       hop: -1
1140       priority: 0
1141       health_sensitivity: 1
1142     - net: tcp8
1143       gateway: 8.8.8.8@tcp
1144       hop: -1
1145       priority: 0
1146       health_sensitivity: 1
1147 peer:
1148     - primary nid: 8.8.8.9@tcp
1149       Multi-Rail: False
1150       peer ni:
1151         - nid: 8.8.8.9@tcp
1152     - primary nid: 8.8.8.10@tcp
1153       Multi-Rail: False
1154       peer ni:
1155         - nid: 8.8.8.10@tcp
1156     - primary nid: 8.8.8.8@tcp
1157       Multi-Rail: False
1158       peer ni:
1159         - nid: 8.8.8.8@tcp
1160 EOF
1161         append_global_yaml
1162         compare_route_add "tcp8" "8.8.8.[8-10]@tcp"
1163 }
1164 run_test 101 "Add route with multiple gw (tcp)"
1165
1166 compare_route_del() {
1167         local rnet="$1"
1168         local gw="$2"
1169
1170         local actual="$TMP/sanity-lnet-$testnum-actual.yaml"
1171
1172         do_lnetctl route del --net ${rnet} --gateway ${gw} ||
1173                 error "route del failed $?"
1174         $LNETCTL export --backup > $actual ||
1175                 error "export failed $?"
1176         validate_gateway_nids
1177 }
1178
1179 test_102() {
1180         reinit_dlc || return $?
1181         add_net "tcp" "${INTERFACES[0]}"
1182         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-expected.yaml
1183         do_lnetctl route add --net tcp102 --gateway 102.102.102.102@tcp ||
1184                 error "route add failed $?"
1185         compare_route_del "tcp102" "102.102.102.102@tcp"
1186 }
1187 run_test 102 "Delete route with single gw (tcp)"
1188
1189 test_103() {
1190         reinit_dlc || return $?
1191         add_net "tcp" "${INTERFACES[0]}"
1192         $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-expected.yaml
1193         do_lnetctl route add --net tcp103 \
1194                 --gateway 103.103.103.[103-120/4]@tcp ||
1195                 error "route add failed $?"
1196         compare_route_del "tcp103" "103.103.103.[103-120/4]@tcp"
1197 }
1198 run_test 103 "Delete route with multiple gw (tcp)"
1199
1200 test_104() {
1201         local tyaml="$TMP/sanity-lnet-$testnum-expected.yaml"
1202
1203         reinit_dlc || return $?
1204
1205         # Default value is '3'
1206         local val=$($LNETCTL global show | awk '/response_tracking/{print $NF}')
1207         [[ $val -ne 3 ]] &&
1208                 error "Expect 3 found $val"
1209
1210         echo "Set < 0;  Should fail"
1211         do_lnetctl set response_tracking -1 &&
1212                 error "should have failed $?"
1213
1214         reinit_dlc || return $?
1215         cat <<EOF > $tyaml
1216 global:
1217     response_tracking: -10
1218 EOF
1219         do_lnetctl import < $tyaml &&
1220                 error "should have failed $?"
1221
1222         echo "Check valid values; Should succeed"
1223         local i
1224         for ((i = 0; i < 4; i++)); do
1225                 reinit_dlc || return $?
1226                 do_lnetctl set response_tracking $i ||
1227                         error "should have succeeded $?"
1228                 $LNETCTL global show | grep -q "response_tracking: $i" ||
1229                         error "Failed to set response_tracking to $i"
1230                 reinit_dlc || return $?
1231                 cat <<EOF > $tyaml
1232 global:
1233     response_tracking: $i
1234 EOF
1235                 do_lnetctl import < $tyaml ||
1236                         error "should have succeeded $?"
1237                 $LNETCTL global show | grep -q "response_tracking: $i" ||
1238                         error "Failed to set response_tracking to $i"
1239         done
1240
1241         reinit_dlc || return $?
1242         echo "Set > 3; Should fail"
1243         do_lnetctl set response_tracking 4 &&
1244                 error "should have failed $?"
1245
1246         reinit_dlc || return $?
1247         cat <<EOF > $tyaml
1248 global:
1249     response_tracking: 10
1250 EOF
1251         do_lnetctl import < $tyaml &&
1252                 error "should have failed $?"
1253         return 0
1254 }
1255 run_test 104 "Set/check response_tracking param"
1256
1257 ### load lnet in default namespace, configure in target namespace
1258
1259 test_200() {
1260         cleanup_lnet || exit 1
1261         load_lnet "networks=\"\""
1262         do_ns $LNETCTL lnet configure --all || exit 1
1263         $LNETCTL net show --net tcp | grep -q "nid: ${FAKE_IP}@tcp$"
1264 }
1265 run_test 200 "load lnet w/o module option, configure in a non-default namespace"
1266
1267 test_201() {
1268         cleanup_lnet || exit 1
1269         load_lnet "networks=tcp($FAKE_IF)"
1270         do_ns $LNETCTL lnet configure --all || exit 1
1271         $LNETCTL net show --net tcp | grep -q "nid: ${FAKE_IP}@tcp$"
1272 }
1273 run_test 201 "load lnet using networks module options in a non-default namespace"
1274
1275 test_202() {
1276         cleanup_lnet || exit 1
1277         load_lnet "networks=\"\" ip2nets=\"tcp0($FAKE_IF) ${FAKE_IP}\""
1278         do_ns $LNETCTL lnet configure --all || exit 1
1279         $LNETCTL net show | grep -q "nid: ${FAKE_IP}@tcp$"
1280 }
1281 run_test 202 "load lnet using ip2nets in a non-default namespace"
1282
1283
1284 ### Add the interfaces in the target namespace
1285
1286 test_203() {
1287         cleanup_lnet || exit 1
1288         load_lnet
1289         do_lnetctl lnet configure || exit 1
1290         do_ns $LNETCTL net add --net tcp0 --if $FAKE_IF
1291 }
1292 run_test 203 "add a network using an interface in the non-default namespace"
1293
1294 LNET_PARAMS_FILE="$TMP/$TESTSUITE.parameters"
1295 function save_lnet_params() {
1296         $LNETCTL global show | egrep -v '^global:$' |
1297                                sed 's/://' > $LNET_PARAMS_FILE
1298 }
1299
1300 function restore_lnet_params() {
1301         local param value
1302         while read param value; do
1303                 [[ $param == max_intf ]] && continue
1304                 [[ $param == lnd_timeout ]] && continue
1305                 $LNETCTL set ${param} ${value} ||
1306                         error "Failed to restore ${param} to ${value}"
1307         done < $LNET_PARAMS_FILE
1308 }
1309
1310 function lnet_health_pre() {
1311         save_lnet_params
1312
1313         # Lower transaction timeout to speed up test execution
1314         $LNETCTL set transaction_timeout 10 ||
1315                 error "Failed to set transaction_timeout $?"
1316
1317         # Increase recovery interval so we have time to capture health values
1318         $LNETCTL set recovery_interval 20 ||
1319                 error "Failed to set recovery_interval $?"
1320
1321         RETRY_PARAM=$($LNETCTL global show | awk '/retry_count/{print $NF}')
1322         RSND_PRE=$($LNETCTL stats show | awk '/resend_count/{print $NF}')
1323         LO_HVAL_PRE=$($LNETCTL net show -v 2 | awk '/health value/{print $NF}' |
1324                       xargs echo | sed 's/ /+/g' | bc -l)
1325
1326         local my_nid=$($LCTL list_nids | head -n 1)
1327
1328         RMT_HVAL_PRE=$($LNETCTL peer show --nid $my_nid -v 2 2>/dev/null |
1329                        awk '/health value/{print $NF}' | xargs echo |
1330                        sed 's/ /+/g' | bc -l)
1331
1332         # Might not have any peers so initialize to zero.
1333         RMT_HVAL_PRE=${RMT_HVAL_PRE:-0}
1334
1335         return 0
1336 }
1337
1338 function lnet_health_post() {
1339         RSND_POST=$($LNETCTL stats show | awk '/resend_count/{print $NF}')
1340         LO_HVAL_POST=$($LNETCTL net show -v 2 |
1341                        awk '/health value/{print $NF}' |
1342                        xargs echo | sed 's/ /+/g' | bc -l)
1343
1344         local my_nid=$($LCTL list_nids | head -n 1)
1345
1346         RMT_HVAL_POST=$($LNETCTL peer show --nid $my_nid -v 2 2>/dev/null |
1347                         awk '/health value/{print $NF}' | xargs echo |
1348                         sed 's/ /+/g' | bc -l)
1349
1350         # Might not have any peers so initialize to zero.
1351         RMT_HVAL_POST=${RMT_HVAL_POST:-0}
1352
1353         ${VERBOSE} &&
1354         echo "Pre resends: $RSND_PRE" &&
1355         echo "Post resends: $RSND_POST" &&
1356         echo "Resends delta: $((RSND_POST - RSND_PRE))" &&
1357         echo "Pre local health: $LO_HVAL_PRE" &&
1358         echo "Post local health: $LO_HVAL_POST" &&
1359         echo "Pre remote health: $RMT_HVAL_PRE" &&
1360         echo "Post remote health: $RMT_HVAL_POST"
1361
1362         restore_lnet_params
1363
1364         return 0
1365 }
1366
1367 function check_no_resends() {
1368         echo "Check that no resends took place"
1369         [[ $RSND_POST -ne $RSND_PRE ]] &&
1370                 error "Found resends: $RSND_POST != $RSND_PRE"
1371
1372         return 0
1373 }
1374
1375 function check_resends() {
1376         local delta=$((RSND_POST - RSND_PRE))
1377
1378         echo "Check that $RETRY_PARAM resends took place"
1379         [[ $delta -ne $RETRY_PARAM ]] &&
1380                 error "Expected $RETRY_PARAM resends found $delta"
1381
1382         return 0
1383 }
1384
1385 function check_no_local_health() {
1386         echo "Check that local NI health is unchanged"
1387         [[ $LO_HVAL_POST -ne $LO_HVAL_PRE ]] &&
1388                 error "Local health changed: $LO_HVAL_POST != $LO_HVAL_PRE"
1389
1390         return 0
1391 }
1392
1393 function check_local_health() {
1394         echo "Check that local NI health has been changed"
1395         [[ $LO_HVAL_POST -eq $LO_HVAL_PRE ]] &&
1396                 error "Local health unchanged: $LO_HVAL_POST == $LO_HVAL_PRE"
1397
1398         return 0
1399 }
1400
1401 function check_no_remote_health() {
1402         echo "Check that remote NI health is unchanged"
1403         [[ $RMT_HVAL_POST -ne $RMT_HVAL_PRE ]] &&
1404                 error "Remote health changed: $RMT_HVAL_POST != $RMT_HVAL_PRE"
1405
1406         return 0
1407 }
1408
1409 function check_remote_health() {
1410         echo "Check that remote NI health has been changed"
1411         [[ $RMT_HVAL_POST -eq $RMT_HVAL_PRE ]] &&
1412                 error "Remote health unchanged: $RMT_HVAL_POST == $RMT_HVAL_PRE"
1413
1414         return 0
1415 }
1416
1417 # See lnet/lnet/lib-msg.c:lnet_health_check()
1418 LNET_LOCAL_RESEND_STATUSES="local_interrupt local_dropped local_aborted"
1419 LNET_LOCAL_RESEND_STATUSES+=" local_no_route local_timeout"
1420 LNET_LOCAL_NO_RESEND_STATUSES="local_error"
1421 test_204() {
1422         reinit_dlc || return $?
1423         add_net "tcp" "${INTERFACES[0]}" || return $?
1424
1425         lnet_health_pre || return $?
1426
1427         local hstatus
1428         for hstatus in ${LNET_LOCAL_RESEND_STATUSES} \
1429                        ${LNET_LOCAL_NO_RESEND_STATUSES}; do
1430                 echo "Simulate $hstatus"
1431                 $LCTL net_drop_add -s *@tcp -d *@tcp -m GET -r 1 -e ${hstatus}
1432                 do_lnetctl discover $($LCTL list_nids | head -n 1) &&
1433                         error "Should have failed"
1434                 $LCTL net_drop_del -a
1435         done
1436
1437         lnet_health_post
1438
1439         check_no_resends || return $?
1440         check_no_local_health || return $?
1441
1442         return 0
1443 }
1444 run_test 204 "Check no health or resends for single-rail local failures"
1445
1446 test_205() {
1447         local hstatus
1448         for hstatus in ${LNET_LOCAL_RESEND_STATUSES}; do
1449                 reinit_dlc || return $?
1450                 add_net "tcp" "${INTERFACES[0]}" || return $?
1451                 add_net "tcp1" "${INTERFACES[0]}" || return $?
1452
1453                 echo "Simulate $hstatus"
1454                 lnet_health_pre
1455
1456                 $LCTL net_drop_add -s *@tcp -d *@tcp -m GET -r 1 -e ${hstatus}
1457                 $LCTL net_drop_add -s *@tcp1 -d *@tcp1 -m GET -r 1 -e ${hstatus}
1458                 do_lnetctl discover $($LCTL list_nids | head -n 1) &&
1459                         error "Should have failed"
1460                 $LCTL net_drop_del -a
1461
1462                 lnet_health_post
1463
1464                 check_resends || return $?
1465                 check_local_health || return $?
1466         done
1467
1468         for hstatus in ${LNET_LOCAL_NO_RESEND_STATUSES}; do
1469                 reinit_dlc || return $?
1470                 add_net "tcp" "${INTERFACES[0]}" || return $?
1471                 add_net "tcp1" "${INTERFACES[0]}" || return $?
1472
1473                 echo "Simulate $hstatus"
1474                 lnet_health_pre || return $?
1475
1476                 $LCTL net_drop_add -s *@tcp -d *@tcp -m GET -r 1 -e ${hstatus}
1477                 $LCTL net_drop_add -s *@tcp1 -d *@tcp1 -m GET -r 1 -e ${hstatus}
1478                 do_lnetctl discover $($LCTL list_nids | head -n 1) &&
1479                         error "Should have failed"
1480                 $LCTL net_drop_del -a
1481
1482                 lnet_health_post
1483
1484                 check_no_resends || return $?
1485                 check_local_health || return $?
1486         done
1487
1488         return 0
1489 }
1490 run_test 205 "Check health and resends for multi-rail local failures"
1491
1492 # See lnet/lnet/lib-msg.c:lnet_health_check()
1493 LNET_REMOTE_RESEND_STATUSES="remote_dropped"
1494 LNET_REMOTE_NO_RESEND_STATUSES="remote_error remote_timeout"
1495 test_206() {
1496         reinit_dlc || return $?
1497         add_net "tcp" "${INTERFACES[0]}" || return $?
1498
1499         do_lnetctl discover $($LCTL list_nids | head -n 1) ||
1500                 error "failed to discover myself"
1501
1502         lnet_health_pre || return $?
1503
1504         local hstatus
1505         for hstatus in ${LNET_REMOTE_RESEND_STATUSES} \
1506                        ${LNET_REMOTE_NO_RESEND_STATUSES}; do
1507                 echo "Simulate $hstatus"
1508                 $LCTL net_drop_add -s *@tcp -d *@tcp -m GET -r 1 -e ${hstatus}
1509                 do_lnetctl discover $($LCTL list_nids | head -n 1) &&
1510                         error "Should have failed"
1511                 $LCTL net_drop_del -a
1512         done
1513
1514         lnet_health_post
1515
1516         check_no_resends || return $?
1517         check_no_local_health || return $?
1518         check_no_remote_health || return $?
1519
1520         return 0
1521 }
1522 run_test 206 "Check no health or resends for single-rail remote failures"
1523
1524 test_207() {
1525         local hstatus
1526         for hstatus in ${LNET_REMOTE_RESEND_STATUSES}; do
1527                 reinit_dlc || return $?
1528                 add_net "tcp" "${INTERFACES[0]}" || return $?
1529                 add_net "tcp1" "${INTERFACES[0]}" || return $?
1530
1531                 do_lnetctl discover $($LCTL list_nids | head -n 1) ||
1532                         error "failed to discover myself"
1533
1534                 echo "Simulate $hstatus"
1535                 lnet_health_pre || return $?
1536                 $LCTL net_drop_add -s *@tcp -d *@tcp -m GET -r 1 -e ${hstatus}
1537                 $LCTL net_drop_add -s *@tcp1 -d *@tcp1 -m GET -r 1 -e ${hstatus}
1538                 do_lnetctl discover $($LCTL list_nids | head -n 1) &&
1539                         error "Should have failed"
1540                 $LCTL net_drop_del -a
1541
1542                 lnet_health_post
1543
1544                 check_resends || return $?
1545                 check_no_local_health || return $?
1546                 check_remote_health || return $?
1547         done
1548         for hstatus in ${LNET_REMOTE_NO_RESEND_STATUSES}; do
1549                 reinit_dlc || return $?
1550                 add_net "tcp" "${INTERFACES[0]}" || return $?
1551                 add_net "tcp1" "${INTERFACES[0]}" || return $?
1552
1553                 do_lnetctl discover $($LCTL list_nids | head -n 1) ||
1554                         error "failed to discover myself"
1555
1556                 echo "Simulate $hstatus"
1557                 lnet_health_pre || return $?
1558                 $LCTL net_drop_add -s *@tcp -d *@tcp -m GET -r 1 -e ${hstatus}
1559                 $LCTL net_drop_add -s *@tcp1 -d *@tcp1 -m GET -r 1 -e ${hstatus}
1560                 do_lnetctl discover $($LCTL list_nids | head -n 1) &&
1561                         error "Should have failed"
1562                 $LCTL net_drop_del -a
1563
1564                 lnet_health_post
1565
1566                 check_no_resends || return $?
1567                 check_no_local_health || return $?
1568                 check_remote_health || return $?
1569         done
1570
1571         return 0
1572 }
1573 run_test 207 "Check health and resends for multi-rail remote errors"
1574
1575 test_208_load_and_check_lnet() {
1576         local ip2nets="$1"
1577         local p_nid="$2"
1578         local s_nid="$3"
1579         local num_expected=1
1580
1581         load_lnet "networks=\"\" ip2nets=\"${ip2nets_str}\""
1582
1583         $LCTL net up ||
1584                 error "Failed to load LNet with ip2nets \"${ip2nets_str}\""
1585
1586         [[ -n $s_nid ]] &&
1587                 num_expected=2
1588
1589         declare -a nids
1590         nids=( $($LCTL list_nids) )
1591
1592         [[ ${#nids[@]} -ne ${num_expected} ]] &&
1593                 error "Expect ${num_expected} NIDs found ${#nids[@]}"
1594
1595         [[ ${nids[0]} == ${p_nid} ]] ||
1596                 error "Expect NID \"${p_nid}\" found \"${nids[0]}\""
1597
1598         [[ -n $s_nid ]] && [[ ${nids[1]} != ${s_nid} ]] &&
1599                 error "Expect second NID \"${s_nid}\" found \"${nids[1]}\""
1600
1601         $LCTL net down &>/dev/null
1602         cleanup_lnet
1603 }
1604
1605 test_208() {
1606         cleanup_netns || error "Failed to cleanup netns before test execution"
1607         cleanup_lnet || error "Failed to unload modules before test execution"
1608         setup_fakeif || error "Failed to add fake IF"
1609
1610         have_interface "$FAKE_IF" ||
1611                 error "Expect $FAKE_IF configured but not found"
1612
1613         local if0_ip=$(ip --oneline addr show dev ${INTERFACES[0]} |
1614                        awk '/inet /{print $4}' |
1615                        sed 's:/.*::')
1616         local ip2nets_str="tcp(${INTERFACES[0]}) $if0_ip"
1617
1618         echo "Configure single NID \"$ip2nets_str\""
1619         test_208_load_and_check_lnet "${ip2nets_str}" "${if0_ip}@tcp"
1620
1621         ip2nets_str="tcp(${INTERFACES[0]}) $if0_ip; tcp1($FAKE_IF) $FAKE_IP"
1622         echo "Configure two NIDs; two NETs \"$ip2nets_str\""
1623         test_208_load_and_check_lnet "${ip2nets_str}" "${if0_ip}@tcp" \
1624                                      "${FAKE_IP}@tcp1"
1625
1626         ip2nets_str="tcp(${INTERFACES[0]}) $if0_ip; tcp($FAKE_IF) $FAKE_IP"
1627         echo "Configure two NIDs; one NET \"$ip2nets_str\""
1628         test_208_load_and_check_lnet "${ip2nets_str}" "${if0_ip}@tcp" \
1629                                      "${FAKE_IP}@tcp"
1630         local addr1=( ${if0_ip//./ } )
1631         local addr2=( ${FAKE_IP//./ } )
1632         local range="[${addr1[0]},${addr2[0]}]"
1633
1634         local i
1635         for i in $(seq 1 3); do
1636                 range+=".[${addr1[$i]},${addr2[$i]}]"
1637         done
1638         ip2nets_str="tcp(${INTERFACES[0]},${FAKE_IF}) ${range}"
1639
1640         echo "Configured two NIDs; one NET alt syntax \"$ip2nets_str\""
1641         test_208_load_and_check_lnet "${ip2nets_str}" "${if0_ip}@tcp" \
1642                                      "${FAKE_IP}@tcp"
1643
1644         cleanup_fakeif
1645
1646         echo "alt syntax with missing IF \"$ip2nets_str\""
1647         load_lnet "networks=\"\" ip2nets=\"${ip2nets_str}\""
1648
1649         echo "$LCTL net up should fail"
1650         $LCTL net up &&
1651                 error "LNet bringup should have failed"
1652
1653         cleanup_lnet
1654 }
1655 run_test 208 "Test various kernel ip2nets configurations"
1656
1657 test_209() {
1658         reinit_dlc || return $?
1659         add_net "tcp" "${INTERFACES[0]}" || return $?
1660
1661         do_lnetctl discover $($LCTL list_nids | head -n 1) ||
1662                 error "failed to discover myself"
1663
1664         echo "Simulate network_timeout w/SR config"
1665         lnet_health_pre
1666
1667         $LCTL net_drop_add -s *@tcp -d *@tcp -m GET -r 1 -e network_timeout
1668         do_lnetctl discover $($LCTL list_nids | head -n 1) &&
1669                 error "Should have failed"
1670         $LCTL net_drop_del -a
1671
1672         lnet_health_post
1673
1674         check_no_resends || return $?
1675         check_no_local_health || return $?
1676         check_no_remote_health || return $?
1677
1678         reinit_dlc || return $?
1679         add_net "tcp" "${INTERFACES[0]}" || return $?
1680         add_net "tcp1" "${INTERFACES[0]}" || return $?
1681
1682         do_lnetctl discover $($LCTL list_nids | head -n 1) ||
1683                 error "failed to discover myself"
1684
1685         echo "Simulate network_timeout w/MR config"
1686         lnet_health_pre
1687
1688         $LCTL net_drop_add -s *@tcp -d *@tcp -m GET -r 1 -e network_timeout
1689         $LCTL net_drop_add -s *@tcp1 -d *@tcp1 -m GET -r 1 -e network_timeout
1690         do_lnetctl discover $($LCTL list_nids | head -n 1) &&
1691                 error "Should have failed"
1692         $LCTL net_drop_del -a
1693
1694         lnet_health_post
1695
1696         check_no_resends || return $?
1697         check_local_health || return $?
1698         check_remote_health || return $?
1699
1700         return 0
1701 }
1702 run_test 209 "Check health, but not resends, for network timeout"
1703
1704 check_nid_in_recovq() {
1705         local recovq=$($LNETCTL debug recovery $1)
1706         local expect="$2"
1707         local nids=$($LCTL list_nids | xargs echo)
1708         local found=false
1709         local nid=""
1710
1711         echo "Check recovery queue"
1712         echo "$recovq"
1713         if [[ $(grep -c 'nid-'<<<$recovq) -ne $expect ]]; then
1714                 error "Expect $expect NIDs found: \"$recovq\""
1715         fi
1716
1717         [[ $expect -eq 0 ]] && return 0
1718
1719         for nid in ${nids}; do
1720                 grep -q "nid-0: $nid"<<<$recovq &&
1721                         found=true
1722         done
1723
1724         if ! $found; then
1725                 error "Didn't find local NIDs in recovery queue: \"$recovq\""
1726         fi
1727
1728         return 0
1729 }
1730
1731 # First enqueue happens at time 0.
1732 # 2nd at 0 + 2^0 = 1
1733 # 3rd at 1 + 2^1 = 3
1734 # 4th at 3 + 2^2 = 7
1735 # 5th at 7 + 2^3 = 15
1736 # e.g. after 10 seconds we would expect to have seen the 4th enqueue,
1737 # (3 pings sent, 4th about to happen) and the 5th enqueue is yet to
1738 # happen
1739 # If the recovery limit is 10 seconds, then when the 5th enqueue happens
1740 # we expect the peer NI to have aged out, so it will not actually be
1741 # queued.
1742 check_ping_count() {
1743         local queue="$1"
1744         local expect="$2"
1745
1746         echo "Check ping counts:"
1747         local ping_count
1748         if [[ $queue == "ni" ]]; then
1749                 $LNETCTL net show -v 2 | egrep 'nid|health value|ping'
1750                 ping_count=( $($LNETCTL net show -v 2 |
1751                                 awk '/ping_count/{print $NF}') )
1752         elif [[ $queue == "peer_ni" ]]; then
1753                 $LNETCTL peer show -v 2 | egrep 'nid|health value|ping'
1754                 ping_count=( $($LNETCTL peer show -v 2 |
1755                                 awk '/ping_count/{print $NF}') )
1756         else
1757                 error "Unrecognized queue \"$queue\""
1758                 return 1
1759         fi
1760
1761         local count
1762         local found=false
1763         for count in ${ping_count[@]}; do
1764                 if [[ $count -eq $expect ]]; then
1765                         if [[ $expect -ne 0 ]] && $found ; then
1766                                 error "Found more than one interface matching \"$expect\" ping count"
1767                                 return 1
1768                         else
1769                                 echo "Expect ping count \"$expect\" found \"$count\""
1770                                 found=true;
1771                         fi
1772                 elif [[ $count -ne 0 ]]; then
1773                         error "Found interface with ping count \"$count\" but expect \"$expect\""
1774                         return 1
1775                 fi
1776         done
1777
1778         return 0
1779 }
1780
1781 test_210() {
1782         reinit_dlc || return $?
1783         add_net "tcp" "${INTERFACES[0]}" || return $?
1784         add_net "tcp1" "${INTERFACES[0]}" || return $?
1785
1786         local prim_nid=$($LCTL list_nids | head -n 1)
1787
1788         do_lnetctl discover $prim_nid ||
1789                 error "failed to discover myself"
1790
1791         # Set recovery limit to 10 seconds.
1792         do_lnetctl set recovery_limit 10 ||
1793                 error "failed to set recovery_limit"
1794
1795         $LCTL set_param debug=+net
1796         # Use local_error so LNet doesn't attempt to resend the discovery ping
1797         $LCTL net_drop_add -s *@tcp -d *@tcp -m GET -r 1 -e local_error
1798         $LCTL net_drop_add -s *@tcp1 -d *@tcp1 -m GET -r 1 -e local_error
1799         do_lnetctl discover $($LCTL list_nids | head -n 1) &&
1800                 error "Expected discovery to fail"
1801
1802         sleep 5
1803         check_nid_in_recovq "-l" 1
1804         check_ping_count "ni" "2"
1805
1806         sleep 5
1807
1808         check_nid_in_recovq "-l" 1
1809         check_ping_count "ni" "3"
1810
1811         $LCTL net_drop_del -a
1812
1813         return 0
1814 }
1815 run_test 210 "Local NI recovery checks"
1816
1817 test_211() {
1818         reinit_dlc || return $?
1819         add_net "tcp" "${INTERFACES[0]}" || return $?
1820         add_net "tcp1" "${INTERFACES[0]}" || return $?
1821
1822         local prim_nid=$($LCTL list_nids | head -n 1)
1823
1824         do_lnetctl discover $prim_nid ||
1825                 error "failed to discover myself"
1826
1827         # Set recovery limit to 10 seconds.
1828         do_lnetctl set recovery_limit 10 ||
1829                 error "failed to set recovery_limit"
1830
1831         $LCTL net_drop_add -s *@tcp -d *@tcp -m GET -r 1 -e remote_error
1832         $LCTL net_drop_add -s *@tcp1 -d *@tcp1 -m GET -r 1 -e remote_error
1833
1834         # Set health to 0 on one interface. This forces it onto the recovery
1835         # queue.
1836         $LNETCTL peer set --nid $prim_nid --health 0
1837
1838         # After 5 seconds, we expect the peer NI to still be in recovery
1839         sleep 5
1840         check_nid_in_recovq "-p" 1
1841         check_ping_count "peer_ni" "2"
1842
1843         # After 15 seconds, the peer NI should have been fully processed out of
1844         # the recovery queue. We'll allow a total of 17 seconds to account for
1845         # differences in sleeping for whole seconds vs. the more accurate time
1846         # keeping that is done in the recovery code.
1847         sleep 12
1848         check_nid_in_recovq "-p" 0
1849         check_ping_count "peer_ni" "4"
1850
1851         $LCTL net_drop_del -a
1852
1853         # Set health to force it back onto the recovery queue. Set to 500 means
1854         # in 5 seconds it should be back at maximum value. We'll wait a couple
1855         # more seconds than that to be safe.
1856         # NB: we reset the recovery limit to 0 (indefinite) so the peer NI is
1857         # eligible again
1858         do_lnetctl set recovery_limit 0 ||
1859                 error "failed to set recovery_limit"
1860
1861         $LNETCTL peer set --nid $prim_nid --health 500
1862
1863         check_nid_in_recovq "-p" 1
1864         check_ping_count "peer_ni" "2"
1865
1866         sleep 7
1867
1868         check_nid_in_recovq "-p" 0
1869         check_ping_count "peer_ni" "0"
1870
1871         return 0
1872 }
1873 run_test 211 "Remote NI recovery checks"
1874
1875 test_212() {
1876         local rnodes=$(remote_nodes_list)
1877         [[ -z $rnodes ]] && skip "Need at least 1 remote node"
1878
1879         cleanup_lnet || error "Failed to cleanup before test execution"
1880
1881         # Loading modules should configure LNet with the appropriate
1882         # test-framework configuration
1883         load_modules || error "Failed to load modules"
1884
1885         local my_nid=$($LCTL list_nids | head -n 1)
1886         [[ -z $my_nid ]] &&
1887                 error "Failed to get primary NID for local host $HOSTNAME"
1888
1889         local rnode=$(awk '{print $1}' <<<$rnodes)
1890         local rnodenids=$(do_node $rnode $LCTL list_nids | xargs echo)
1891         local rloaded=false
1892
1893         if [[ -z $rnodenids ]]; then
1894                 do_rpc_nodes $rnode load_modules_local
1895                 rloaded=true
1896                 rnodenids=$(do_node $rnode $LCTL list_nids | xargs echo)
1897         fi
1898
1899         local rnodepnid=$(awk '{print $1}' <<< $rnodenids)
1900
1901         [[ -z $rnodepnid ]] &&
1902                 error "Failed to get primary NID for remote host $rnode"
1903
1904         log "Initial discovery"
1905         do_lnetctl discover --force $rnodepnid ||
1906                 error "Failed to discover $rnodepnid"
1907
1908         do_node $rnode "$LNETCTL discover --force $my_nid" ||
1909                 error "$rnode failed to discover $my_nid"
1910
1911         log "Fail local discover ping to set LNET_PEER_REDISCOVER flag"
1912         $LCTL net_drop_add -s "*@$NETTYPE" -d "*@$NETTYPE" -r 1 -e local_error
1913         do_lnetctl discover --force $rnodepnid &&
1914                 error "Discovery should have failed"
1915         $LCTL net_drop_del -a
1916
1917         local nid
1918         for nid in $rnodenids; do
1919                 # We need GET (PING) delay just long enough so we can trigger
1920                 # discovery on the remote peer
1921                 $LCTL net_delay_add -s "*@$NETTYPE" -d $nid -r 1 -m GET -l 3
1922                 $LCTL net_drop_add -s "*@$NETTYPE" -d $nid -r 1 -m GET -e local_error
1923                 # We need PUT (PUSH) delay just long enough so we can process
1924                 # the PING failure
1925                 $LCTL net_delay_add -s "*@$NETTYPE" -d $nid -r 1 -m PUT -l 6
1926         done
1927
1928         log "Force $HOSTNAME to discover $rnodepnid (in background)"
1929         # We want to get a PING sent that we know will eventually fail.
1930         # The delay rules we added will ensure the ping is not sent until
1931         # the PUSH is also in flight (see below), and the drop rule ensures that
1932         # when the PING is eventually sent it will error out
1933         do_lnetctl discover --force $rnodepnid &
1934         local pid1=$!
1935
1936         # We want a discovery PUSH from rnode to put rnode back on our
1937         # discovery queue. This should cause us to try and send a PUSH to rnode
1938         # while the PING is still outstanding.
1939         log "Force $rnode to discover $my_nid"
1940         do_node $rnode $LNETCTL discover --force $my_nid
1941
1942         # At this point we'll have both PING_SENT and PUSH_SENT set for the
1943         # rnode peer. Wait for the PING to error out which should terminate the
1944         # discovery process that we backgrounded.
1945         log "Wait for $pid1"
1946         wait $pid1
1947         log "Finished wait on $pid1"
1948
1949         # The PING send failure clears the PING_SENT flag and puts the peer back
1950         # on the discovery queue. When discovery thread processes the peer it
1951         # will mistakenly clear the PUSH_SENT flag (and set PUSH_FAILED).
1952         # Discovery will then complete for this peer even though we have an
1953         # outstanding PUSH.
1954         # When PUSH is actually unlinked it will be forced back onto the
1955         # discovery queue, but we no longer have a ref on the peer. When
1956         # discovery completes again, we'll trip the ASSERT in
1957         # lnet_destroy_peer_locked()
1958
1959         # Delete the delay rules to send the PUSH
1960         $LCTL net_delay_del -a
1961         # Delete the drop rules
1962         $LCTL net_drop_del -a
1963
1964         unload_modules ||
1965                 error "Failed to unload modules"
1966         if $rloaded; then
1967                 do_rpc_nodes $rnode unload_modules_local ||
1968                         error "Failed to unload modules on $rnode"
1969         fi
1970
1971         return 0
1972 }
1973 run_test 212 "Check discovery refcount loss bug (LU-14627)"
1974
1975 test_213() {
1976         cleanup_netns || error "Failed to cleanup netns before test execution"
1977         cleanup_lnet || error "Failed to unload modules before test execution"
1978
1979         setup_fakeif || error "Failed to add fake IF"
1980         have_interface "$FAKE_IF" ||
1981                 error "Expect $FAKE_IF configured but not found"
1982
1983         reinit_dlc || return $?
1984
1985         add_net "tcp" "${INTERFACES[0]}" || return $?
1986         add_net "tcp" "$FAKE_IF" || return $?
1987
1988         local nid1=$(lctl list_nids | head -n 1)
1989         local nid2=$(lctl list_nids | tail --lines 1)
1990
1991         [[ $(lctl which_nid $nid1 $nid2) == $nid1 ]] ||
1992                 error "Expect nid1 \"$nid1\" to be preferred"
1993
1994         [[ $(lctl which_nid $nid2 $nid1) == $nid2 ]] ||
1995                 error "Expect nid2 \"$nid2\" to be preferred"
1996
1997         return 0
1998 }
1999 run_test 213 "Check LNetDist calculation for multiple local NIDs"
2000
2001 function check_ni_status() {
2002         local nid="$1"
2003         local expect="$2"
2004
2005         local status=$($LNETCTL net show |
2006                        grep -A 1 ${nid} |
2007                        awk '/status/{print $NF}')
2008
2009         echo "NI ${nid} expect status \"${expect}\" found \"${status}\""
2010         if [[ $status != $expect ]]; then
2011                 error "Error: Expect NI status \"$expect\" for NID \"$nid\" but found \"$status\""
2012         fi
2013
2014         return 0
2015 }
2016
2017 test_214() {
2018         have_interface "eth0" || skip "Need eth0 interface with ipv4 configured"
2019
2020         cleanup_netns || error "Failed to cleanup netns before test execution"
2021         cleanup_lnet || error "Failed to unload modules before test execution"
2022
2023         setup_fakeif || error "Failed to add fake IF"
2024         have_interface "$FAKE_IF" ||
2025                 error "Expect $FAKE_IF configured but not found"
2026
2027         reinit_dlc || return $?
2028
2029         add_net "tcp" "eth0" || return $?
2030         add_net "tcp" "$FAKE_IF" || return $?
2031
2032         local nid1=$(lctl list_nids | head -n 1)
2033         local nid2=$(lctl list_nids | tail --lines 1)
2034
2035         check_ni_status "0@lo" up
2036         check_ni_status "$nid1" up
2037         check_ni_status "$nid2" up
2038
2039         echo "Set $FAKE_IF down"
2040         echo "ip link set dev $FAKE_IF down"
2041         ip link set dev $FAKE_IF down
2042         check_ni_status "0@lo" up
2043         check_ni_status "$nid1" up
2044         check_ni_status "$nid2" down
2045 }
2046 run_test 214 "Check local NI status when link is downed"
2047
2048 test_230() {
2049         # LU-12815
2050         echo "Check valid values; Should succeed"
2051         local i
2052         local lnid
2053         local cmd
2054         for ((i = 4; i < 16; i+=1)); do
2055                 reinit_dlc || return $?
2056                 add_net "tcp" "${INTERFACES[0]}" || return $?
2057                 do_lnetctl net set --all --conns-per-peer $i ||
2058                         error "should have succeeded $?"
2059                 $LNETCTL net show -v 1 | grep -q "conns_per_peer: $i" ||
2060                         error "failed to set conns-per-peer to $i"
2061                 lnid="$(lctl list_nids | head -n 1)"
2062                 do_lnetctl ping "$lnid" ||
2063                         error "failed to ping myself"
2064                 # "lctl --net tcp conn_list" prints the list of active
2065                 # connections. Since we're pinging ourselves, there should be
2066                 # 2 Control connections plus 2*conns_per_peer connections
2067                 # created (one Bulk Input, one Bulk Output in each pair).
2068                 # Here's the sample output for conns_per_peer set to 1:
2069                 # 12345-1.1.1.1@tcp I[0]host01->host01:988 2626560/1061296 nonagle
2070                 # 12345-1.1.1.1@tcp O[0]host01->host01:1022 2626560/1061488 nonagle
2071                 # 12345-1.1.1.1@tcp C[0]host01->host01:988 2626560/1061296 nonagle
2072                 # 12345-1.1.1.1@tcp C[0]host01->host01:1023 2626560/1061488 nonagle
2073                 cmd="printf 'network tcp\nconn_list\n' | lctl | grep -c '$lnid'"
2074
2075                 # Expect 2+conns_per_peer*2 connections. Wait no longer
2076                 # than 2 seconds.
2077                 wait_update $HOSTNAME "$cmd" "$((2+i*2))" 2 ||
2078                         error "expected number of tcp connections $((2+i*2))"
2079         done
2080
2081         reinit_dlc || return $?
2082         add_net "tcp" "${INTERFACES[0]}" || return $?
2083         echo "Set > 127; Should fail"
2084         do_lnetctl net set --all --conns-per-peer 128 &&
2085                 error "should have failed $?"
2086
2087         reinit_dlc || return $?
2088         add_net "tcp" "${INTERFACES[0]}" || return $?
2089         echo "Set < 0; Should be ignored"
2090         do_lnetctl net set --all --conns-per-peer -1 ||
2091                 error "should have succeeded $?"
2092         $LNETCTL net show -v 1 | grep -q "conns_per_peer: 1" ||
2093                 error "Did not stay at default"
2094 }
2095 run_test 230 "Test setting conns-per-peer"
2096
2097 test_300() {
2098         # LU-13274
2099         local header
2100         local out=$TMP/$tfile
2101         local prefix=/usr/include/linux/lnet
2102
2103         # We use a hard coded prefix so that this test will not fail
2104         # when run in tree.
2105         CC=${CC:-cc}
2106         if ! which $CC > /dev/null 2>&1; then
2107                 skip_env "$CC is not installed"
2108         fi
2109
2110         cleanup_lnet || exit 1
2111         load_lnet
2112
2113         local cc_args="-Wall -Werror -std=c99 -c -x c /dev/null -o $out"
2114         if ! [[ -d $prefix ]]; then
2115                 # Assume we're running in tree and fixup the include path.
2116                 prefix=$LUSTRE/../lnet/include/uapi/linux/lnet
2117                 cc_args+=" -I $LUSTRE/../lnet/include/uapi"
2118         fi
2119
2120         for header in $prefix/*.h; do
2121                 if ! [[ -f "$header" ]]; then
2122                         continue
2123                 fi
2124
2125                 echo "$CC $cc_args -include $header"
2126                 $CC $cc_args -include $header ||
2127                         error "cannot compile '$header'"
2128         done
2129         rm -f $out
2130 }
2131 run_test 300 "packaged LNet UAPI headers can be compiled"
2132
2133 complete $SECONDS
2134
2135 cleanup_testsuite
2136 exit_status