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