Whamcloud - gitweb
LU-15210 tests: fix sanity-lnet to handle duplicate IP
[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 ### load lnet in default namespace, configure in target namespace
1262
1263 test_200() {
1264         cleanup_lnet || exit 1
1265         load_lnet "networks=\"\""
1266         do_ns $LNETCTL lnet configure --all || exit 1
1267         $LNETCTL net show --net tcp | grep -q "nid: ${FAKE_IP}@tcp$"
1268 }
1269 run_test 200 "load lnet w/o module option, configure in a non-default namespace"
1270
1271 test_201() {
1272         cleanup_lnet || exit 1
1273         load_lnet "networks=tcp($FAKE_IF)"
1274         do_ns $LNETCTL lnet configure --all || exit 1
1275         $LNETCTL net show --net tcp | grep -q "nid: ${FAKE_IP}@tcp$"
1276 }
1277 run_test 201 "load lnet using networks module options in a non-default namespace"
1278
1279 test_202() {
1280         cleanup_lnet || exit 1
1281         load_lnet "networks=\"\" ip2nets=\"tcp0($FAKE_IF) ${FAKE_IP}\""
1282         do_ns $LNETCTL lnet configure --all || exit 1
1283         $LNETCTL net show | grep -q "nid: ${FAKE_IP}@tcp$"
1284 }
1285 run_test 202 "load lnet using ip2nets in a non-default namespace"
1286
1287
1288 ### Add the interfaces in the target namespace
1289
1290 test_203() {
1291         cleanup_lnet || exit 1
1292         load_lnet
1293         do_lnetctl lnet configure || exit 1
1294         do_ns $LNETCTL net add --net tcp0 --if $FAKE_IF
1295 }
1296 run_test 203 "add a network using an interface in the non-default namespace"
1297
1298 LNET_PARAMS_FILE="$TMP/$TESTSUITE.parameters"
1299 function save_lnet_params() {
1300         $LNETCTL global show | egrep -v '^global:$' |
1301                                sed 's/://' > $LNET_PARAMS_FILE
1302 }
1303
1304 function restore_lnet_params() {
1305         local param value
1306         while read param value; do
1307                 [[ $param == max_intf ]] && continue
1308                 [[ $param == lnd_timeout ]] && continue
1309                 $LNETCTL set ${param} ${value} ||
1310                         error "Failed to restore ${param} to ${value}"
1311         done < $LNET_PARAMS_FILE
1312 }
1313
1314 function lnet_health_pre() {
1315         save_lnet_params
1316
1317         # Lower transaction timeout to speed up test execution
1318         $LNETCTL set transaction_timeout 10 ||
1319                 error "Failed to set transaction_timeout $?"
1320
1321         # Increase recovery interval so we have time to capture health values
1322         $LNETCTL set recovery_interval 20 ||
1323                 error "Failed to set recovery_interval $?"
1324
1325         RETRY_PARAM=$($LNETCTL global show | awk '/retry_count/{print $NF}')
1326         RSND_PRE=$($LNETCTL stats show | awk '/resend_count/{print $NF}')
1327         LO_HVAL_PRE=$($LNETCTL net show -v 2 | awk '/health value/{print $NF}' |
1328                       xargs echo | sed 's/ /+/g' | bc -l)
1329
1330         local my_nid=$($LCTL list_nids | head -n 1)
1331
1332         RMT_HVAL_PRE=$($LNETCTL peer show --nid $my_nid -v 2 2>/dev/null |
1333                        awk '/health value/{print $NF}' | xargs echo |
1334                        sed 's/ /+/g' | bc -l)
1335
1336         # Might not have any peers so initialize to zero.
1337         RMT_HVAL_PRE=${RMT_HVAL_PRE:-0}
1338
1339         return 0
1340 }
1341
1342 function lnet_health_post() {
1343         RSND_POST=$($LNETCTL stats show | awk '/resend_count/{print $NF}')
1344         LO_HVAL_POST=$($LNETCTL net show -v 2 |
1345                        awk '/health value/{print $NF}' |
1346                        xargs echo | sed 's/ /+/g' | bc -l)
1347
1348         local my_nid=$($LCTL list_nids | head -n 1)
1349
1350         RMT_HVAL_POST=$($LNETCTL peer show --nid $my_nid -v 2 2>/dev/null |
1351                         awk '/health value/{print $NF}' | xargs echo |
1352                         sed 's/ /+/g' | bc -l)
1353
1354         # Might not have any peers so initialize to zero.
1355         RMT_HVAL_POST=${RMT_HVAL_POST:-0}
1356
1357         ${VERBOSE} &&
1358         echo "Pre resends: $RSND_PRE" &&
1359         echo "Post resends: $RSND_POST" &&
1360         echo "Resends delta: $((RSND_POST - RSND_PRE))" &&
1361         echo "Pre local health: $LO_HVAL_PRE" &&
1362         echo "Post local health: $LO_HVAL_POST" &&
1363         echo "Pre remote health: $RMT_HVAL_PRE" &&
1364         echo "Post remote health: $RMT_HVAL_POST"
1365
1366         restore_lnet_params
1367
1368         return 0
1369 }
1370
1371 function check_no_resends() {
1372         echo "Check that no resends took place"
1373         [[ $RSND_POST -ne $RSND_PRE ]] &&
1374                 error "Found resends: $RSND_POST != $RSND_PRE"
1375
1376         return 0
1377 }
1378
1379 function check_resends() {
1380         local delta=$((RSND_POST - RSND_PRE))
1381
1382         echo "Check that $RETRY_PARAM resends took place"
1383         [[ $delta -ne $RETRY_PARAM ]] &&
1384                 error "Expected $RETRY_PARAM resends found $delta"
1385
1386         return 0
1387 }
1388
1389 function check_no_local_health() {
1390         echo "Check that local NI health is unchanged"
1391         [[ $LO_HVAL_POST -ne $LO_HVAL_PRE ]] &&
1392                 error "Local health changed: $LO_HVAL_POST != $LO_HVAL_PRE"
1393
1394         return 0
1395 }
1396
1397 function check_local_health() {
1398         echo "Check that local NI health has been changed"
1399         [[ $LO_HVAL_POST -eq $LO_HVAL_PRE ]] &&
1400                 error "Local health unchanged: $LO_HVAL_POST == $LO_HVAL_PRE"
1401
1402         return 0
1403 }
1404
1405 function check_no_remote_health() {
1406         echo "Check that remote NI health is unchanged"
1407         [[ $RMT_HVAL_POST -ne $RMT_HVAL_PRE ]] &&
1408                 error "Remote health changed: $RMT_HVAL_POST != $RMT_HVAL_PRE"
1409
1410         return 0
1411 }
1412
1413 function check_remote_health() {
1414         echo "Check that remote NI health has been changed"
1415         [[ $RMT_HVAL_POST -eq $RMT_HVAL_PRE ]] &&
1416                 error "Remote health unchanged: $RMT_HVAL_POST == $RMT_HVAL_PRE"
1417
1418         return 0
1419 }
1420
1421 # See lnet/lnet/lib-msg.c:lnet_health_check()
1422 LNET_LOCAL_RESEND_STATUSES="local_interrupt local_dropped local_aborted"
1423 LNET_LOCAL_RESEND_STATUSES+=" local_no_route local_timeout"
1424 LNET_LOCAL_NO_RESEND_STATUSES="local_error"
1425 test_204() {
1426         reinit_dlc || return $?
1427         add_net "tcp" "${INTERFACES[0]}" || return $?
1428
1429         lnet_health_pre || return $?
1430
1431         local hstatus
1432         for hstatus in ${LNET_LOCAL_RESEND_STATUSES} \
1433                        ${LNET_LOCAL_NO_RESEND_STATUSES}; do
1434                 echo "Simulate $hstatus"
1435                 $LCTL net_drop_add -s *@tcp -d *@tcp -m GET -r 1 -e ${hstatus}
1436                 do_lnetctl discover $($LCTL list_nids | head -n 1) &&
1437                         error "Should have failed"
1438                 $LCTL net_drop_del -a
1439         done
1440
1441         lnet_health_post
1442
1443         check_no_resends || return $?
1444         check_no_local_health || return $?
1445
1446         return 0
1447 }
1448 run_test 204 "Check no health or resends for single-rail local failures"
1449
1450 test_205() {
1451         local hstatus
1452         for hstatus in ${LNET_LOCAL_RESEND_STATUSES}; do
1453                 reinit_dlc || return $?
1454                 add_net "tcp" "${INTERFACES[0]}" || return $?
1455                 add_net "tcp1" "${INTERFACES[0]}" || return $?
1456
1457                 echo "Simulate $hstatus"
1458                 lnet_health_pre
1459
1460                 $LCTL net_drop_add -s *@tcp -d *@tcp -m GET -r 1 -e ${hstatus}
1461                 $LCTL net_drop_add -s *@tcp1 -d *@tcp1 -m GET -r 1 -e ${hstatus}
1462                 do_lnetctl discover $($LCTL list_nids | head -n 1) &&
1463                         error "Should have failed"
1464                 $LCTL net_drop_del -a
1465
1466                 lnet_health_post
1467
1468                 check_resends || return $?
1469                 check_local_health || return $?
1470         done
1471
1472         for hstatus in ${LNET_LOCAL_NO_RESEND_STATUSES}; do
1473                 reinit_dlc || return $?
1474                 add_net "tcp" "${INTERFACES[0]}" || return $?
1475                 add_net "tcp1" "${INTERFACES[0]}" || return $?
1476
1477                 echo "Simulate $hstatus"
1478                 lnet_health_pre || return $?
1479
1480                 $LCTL net_drop_add -s *@tcp -d *@tcp -m GET -r 1 -e ${hstatus}
1481                 $LCTL net_drop_add -s *@tcp1 -d *@tcp1 -m GET -r 1 -e ${hstatus}
1482                 do_lnetctl discover $($LCTL list_nids | head -n 1) &&
1483                         error "Should have failed"
1484                 $LCTL net_drop_del -a
1485
1486                 lnet_health_post
1487
1488                 check_no_resends || return $?
1489                 check_local_health || return $?
1490         done
1491
1492         return 0
1493 }
1494 run_test 205 "Check health and resends for multi-rail local failures"
1495
1496 # See lnet/lnet/lib-msg.c:lnet_health_check()
1497 LNET_REMOTE_RESEND_STATUSES="remote_dropped"
1498 LNET_REMOTE_NO_RESEND_STATUSES="remote_error remote_timeout"
1499 test_206() {
1500         reinit_dlc || return $?
1501         add_net "tcp" "${INTERFACES[0]}" || return $?
1502
1503         do_lnetctl discover $($LCTL list_nids | head -n 1) ||
1504                 error "failed to discover myself"
1505
1506         lnet_health_pre || return $?
1507
1508         local hstatus
1509         for hstatus in ${LNET_REMOTE_RESEND_STATUSES} \
1510                        ${LNET_REMOTE_NO_RESEND_STATUSES}; do
1511                 echo "Simulate $hstatus"
1512                 $LCTL net_drop_add -s *@tcp -d *@tcp -m GET -r 1 -e ${hstatus}
1513                 do_lnetctl discover $($LCTL list_nids | head -n 1) &&
1514                         error "Should have failed"
1515                 $LCTL net_drop_del -a
1516         done
1517
1518         lnet_health_post
1519
1520         check_no_resends || return $?
1521         check_no_local_health || return $?
1522         check_no_remote_health || return $?
1523
1524         return 0
1525 }
1526 run_test 206 "Check no health or resends for single-rail remote failures"
1527
1528 test_207() {
1529         local hstatus
1530         for hstatus in ${LNET_REMOTE_RESEND_STATUSES}; do
1531                 reinit_dlc || return $?
1532                 add_net "tcp" "${INTERFACES[0]}" || return $?
1533                 add_net "tcp1" "${INTERFACES[0]}" || return $?
1534
1535                 do_lnetctl discover $($LCTL list_nids | head -n 1) ||
1536                         error "failed to discover myself"
1537
1538                 echo "Simulate $hstatus"
1539                 lnet_health_pre || return $?
1540                 $LCTL net_drop_add -s *@tcp -d *@tcp -m GET -r 1 -e ${hstatus}
1541                 $LCTL net_drop_add -s *@tcp1 -d *@tcp1 -m GET -r 1 -e ${hstatus}
1542                 do_lnetctl discover $($LCTL list_nids | head -n 1) &&
1543                         error "Should have failed"
1544                 $LCTL net_drop_del -a
1545
1546                 lnet_health_post
1547
1548                 check_resends || return $?
1549                 check_no_local_health || return $?
1550                 check_remote_health || return $?
1551         done
1552         for hstatus in ${LNET_REMOTE_NO_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_no_resends || return $?
1571                 check_no_local_health || return $?
1572                 check_remote_health || return $?
1573         done
1574
1575         return 0
1576 }
1577 run_test 207 "Check health and resends for multi-rail remote errors"
1578
1579 test_208_load_and_check_lnet() {
1580         local ip2nets="$1"
1581         local p_nid="$2"
1582         local s_nid="$3"
1583         local num_expected=1
1584
1585         load_lnet "networks=\"\" ip2nets=\"${ip2nets_str}\""
1586
1587         $LCTL net up ||
1588                 error "Failed to load LNet with ip2nets \"${ip2nets_str}\""
1589
1590         [[ -n $s_nid ]] &&
1591                 num_expected=2
1592
1593         declare -a nids
1594         nids=( $($LCTL list_nids) )
1595
1596         [[ ${#nids[@]} -ne ${num_expected} ]] &&
1597                 error "Expect ${num_expected} NIDs found ${#nids[@]}"
1598
1599         [[ ${nids[0]} == ${p_nid} ]] ||
1600                 error "Expect NID \"${p_nid}\" found \"${nids[0]}\""
1601
1602         [[ -n $s_nid ]] && [[ ${nids[1]} != ${s_nid} ]] &&
1603                 error "Expect second NID \"${s_nid}\" found \"${nids[1]}\""
1604
1605         $LCTL net down &>/dev/null
1606         cleanup_lnet
1607 }
1608
1609 test_208() {
1610         cleanup_netns || error "Failed to cleanup netns before test execution"
1611         cleanup_lnet || error "Failed to unload modules before test execution"
1612         setup_fakeif || error "Failed to add fake IF"
1613
1614         have_interface "$FAKE_IF" ||
1615                 error "Expect $FAKE_IF configured but not found"
1616
1617         local if0_ip=$(ip --oneline addr show dev ${INTERFACES[0]} |
1618                        awk '/inet /{print $4}' |
1619                        sed 's:/.*::')
1620         if0_ip=($(echo "${if0_ip[@]}" | tr ' ' '\n' | uniq | tr '\n' ' '))
1621         local ip2nets_str="tcp(${INTERFACES[0]}) $if0_ip"
1622
1623         echo "Configure single NID \"$ip2nets_str\""
1624         test_208_load_and_check_lnet "${ip2nets_str}" "${if0_ip}@tcp"
1625
1626         ip2nets_str="tcp(${INTERFACES[0]}) $if0_ip; tcp1($FAKE_IF) $FAKE_IP"
1627         echo "Configure two NIDs; two NETs \"$ip2nets_str\""
1628         test_208_load_and_check_lnet "${ip2nets_str}" "${if0_ip}@tcp" \
1629                                      "${FAKE_IP}@tcp1"
1630
1631         ip2nets_str="tcp(${INTERFACES[0]}) $if0_ip; tcp($FAKE_IF) $FAKE_IP"
1632         echo "Configure two NIDs; one NET \"$ip2nets_str\""
1633         test_208_load_and_check_lnet "${ip2nets_str}" "${if0_ip}@tcp" \
1634                                      "${FAKE_IP}@tcp"
1635         local addr1=( ${if0_ip//./ } )
1636         local addr2=( ${FAKE_IP//./ } )
1637         local range="[${addr1[0]},${addr2[0]}]"
1638
1639         local i
1640         for i in $(seq 1 3); do
1641                 range+=".[${addr1[$i]},${addr2[$i]}]"
1642         done
1643         ip2nets_str="tcp(${INTERFACES[0]},${FAKE_IF}) ${range}"
1644
1645         echo "Configured two NIDs; one NET alt syntax \"$ip2nets_str\""
1646         test_208_load_and_check_lnet "${ip2nets_str}" "${if0_ip}@tcp" \
1647                                      "${FAKE_IP}@tcp"
1648
1649         cleanup_fakeif
1650
1651         echo "alt syntax with missing IF \"$ip2nets_str\""
1652         load_lnet "networks=\"\" ip2nets=\"${ip2nets_str}\""
1653
1654         echo "$LCTL net up should fail"
1655         $LCTL net up &&
1656                 error "LNet bringup should have failed"
1657
1658         cleanup_lnet
1659 }
1660 run_test 208 "Test various kernel ip2nets configurations"
1661
1662 test_209() {
1663         reinit_dlc || return $?
1664         add_net "tcp" "${INTERFACES[0]}" || return $?
1665
1666         do_lnetctl discover $($LCTL list_nids | head -n 1) ||
1667                 error "failed to discover myself"
1668
1669         echo "Simulate network_timeout w/SR config"
1670         lnet_health_pre
1671
1672         $LCTL net_drop_add -s *@tcp -d *@tcp -m GET -r 1 -e network_timeout
1673         do_lnetctl discover $($LCTL list_nids | head -n 1) &&
1674                 error "Should have failed"
1675         $LCTL net_drop_del -a
1676
1677         lnet_health_post
1678
1679         check_no_resends || return $?
1680         check_no_local_health || return $?
1681         check_no_remote_health || return $?
1682
1683         reinit_dlc || return $?
1684         add_net "tcp" "${INTERFACES[0]}" || return $?
1685         add_net "tcp1" "${INTERFACES[0]}" || return $?
1686
1687         do_lnetctl discover $($LCTL list_nids | head -n 1) ||
1688                 error "failed to discover myself"
1689
1690         echo "Simulate network_timeout w/MR config"
1691         lnet_health_pre
1692
1693         $LCTL net_drop_add -s *@tcp -d *@tcp -m GET -r 1 -e network_timeout
1694         $LCTL net_drop_add -s *@tcp1 -d *@tcp1 -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_local_health || return $?
1703         check_remote_health || return $?
1704
1705         return 0
1706 }
1707 run_test 209 "Check health, but not resends, for network timeout"
1708
1709 check_nid_in_recovq() {
1710         local recovq=$($LNETCTL debug recovery $1)
1711         local expect="$2"
1712         local nids=$($LCTL list_nids | xargs echo)
1713         local found=false
1714         local nid=""
1715
1716         echo "Check recovery queue"
1717         echo "$recovq"
1718         if [[ $(grep -c 'nid-'<<<$recovq) -ne $expect ]]; then
1719                 error "Expect $expect NIDs found: \"$recovq\""
1720         fi
1721
1722         [[ $expect -eq 0 ]] && return 0
1723
1724         for nid in ${nids}; do
1725                 grep -q "nid-0: $nid"<<<$recovq &&
1726                         found=true
1727         done
1728
1729         if ! $found; then
1730                 error "Didn't find local NIDs in recovery queue: \"$recovq\""
1731         fi
1732
1733         return 0
1734 }
1735
1736 # First enqueue happens at time 0.
1737 # 2nd at 0 + 2^0 = 1
1738 # 3rd at 1 + 2^1 = 3
1739 # 4th at 3 + 2^2 = 7
1740 # 5th at 7 + 2^3 = 15
1741 # e.g. after 10 seconds we would expect to have seen the 4th enqueue,
1742 # (3 pings sent, 4th about to happen) and the 5th enqueue is yet to
1743 # happen
1744 # If the recovery limit is 10 seconds, then when the 5th enqueue happens
1745 # we expect the peer NI to have aged out, so it will not actually be
1746 # queued.
1747 check_ping_count() {
1748         local queue="$1"
1749         local expect="$2"
1750
1751         echo "Check ping counts:"
1752         local ping_count
1753         if [[ $queue == "ni" ]]; then
1754                 $LNETCTL net show -v 2 | egrep 'nid|health value|ping'
1755                 ping_count=( $($LNETCTL net show -v 2 |
1756                                 awk '/ping_count/{print $NF}') )
1757         elif [[ $queue == "peer_ni" ]]; then
1758                 $LNETCTL peer show -v 2 | egrep 'nid|health value|ping'
1759                 ping_count=( $($LNETCTL peer show -v 2 |
1760                                 awk '/ping_count/{print $NF}') )
1761         else
1762                 error "Unrecognized queue \"$queue\""
1763                 return 1
1764         fi
1765
1766         local count
1767         local found=false
1768         for count in ${ping_count[@]}; do
1769                 if [[ $count -eq $expect ]]; then
1770                         if [[ $expect -ne 0 ]] && $found ; then
1771                                 error "Found more than one interface matching \"$expect\" ping count"
1772                                 return 1
1773                         else
1774                                 echo "Expect ping count \"$expect\" found \"$count\""
1775                                 found=true;
1776                         fi
1777                 elif [[ $count -ne 0 ]]; then
1778                         error "Found interface with ping count \"$count\" but expect \"$expect\""
1779                         return 1
1780                 fi
1781         done
1782
1783         return 0
1784 }
1785
1786 test_210() {
1787         reinit_dlc || return $?
1788         add_net "tcp" "${INTERFACES[0]}" || return $?
1789         add_net "tcp1" "${INTERFACES[0]}" || return $?
1790
1791         local prim_nid=$($LCTL list_nids | head -n 1)
1792
1793         do_lnetctl discover $prim_nid ||
1794                 error "failed to discover myself"
1795
1796         # Set recovery limit to 10 seconds.
1797         do_lnetctl set recovery_limit 10 ||
1798                 error "failed to set recovery_limit"
1799
1800         $LCTL set_param debug=+net
1801         # Use local_error so LNet doesn't attempt to resend the discovery ping
1802         $LCTL net_drop_add -s *@tcp -d *@tcp -m GET -r 1 -e local_error
1803         $LCTL net_drop_add -s *@tcp1 -d *@tcp1 -m GET -r 1 -e local_error
1804         do_lnetctl discover $($LCTL list_nids | head -n 1) &&
1805                 error "Expected discovery to fail"
1806
1807         sleep 5
1808         check_nid_in_recovq "-l" 1
1809         check_ping_count "ni" "2"
1810
1811         sleep 5
1812
1813         check_nid_in_recovq "-l" 1
1814         check_ping_count "ni" "3"
1815
1816         $LCTL net_drop_del -a
1817
1818         return 0
1819 }
1820 run_test 210 "Local NI recovery checks"
1821
1822 test_211() {
1823         reinit_dlc || return $?
1824         add_net "tcp" "${INTERFACES[0]}" || return $?
1825         add_net "tcp1" "${INTERFACES[0]}" || return $?
1826
1827         local prim_nid=$($LCTL list_nids | head -n 1)
1828
1829         do_lnetctl discover $prim_nid ||
1830                 error "failed to discover myself"
1831
1832         # Set recovery limit to 10 seconds.
1833         do_lnetctl set recovery_limit 10 ||
1834                 error "failed to set recovery_limit"
1835
1836         $LCTL net_drop_add -s *@tcp -d *@tcp -m GET -r 1 -e remote_error
1837         $LCTL net_drop_add -s *@tcp1 -d *@tcp1 -m GET -r 1 -e remote_error
1838
1839         # Set health to 0 on one interface. This forces it onto the recovery
1840         # queue.
1841         $LNETCTL peer set --nid $prim_nid --health 0
1842
1843         # After 5 seconds, we expect the peer NI to still be in recovery
1844         sleep 5
1845         check_nid_in_recovq "-p" 1
1846         check_ping_count "peer_ni" "2"
1847
1848         # After 15 seconds, the peer NI should have been fully processed out of
1849         # the recovery queue. We'll allow a total of 17 seconds to account for
1850         # differences in sleeping for whole seconds vs. the more accurate time
1851         # keeping that is done in the recovery code.
1852         sleep 12
1853         check_nid_in_recovq "-p" 0
1854         check_ping_count "peer_ni" "4"
1855
1856         $LCTL net_drop_del -a
1857
1858         # Set health to force it back onto the recovery queue. Set to 500 means
1859         # in 5 seconds it should be back at maximum value. We'll wait a couple
1860         # more seconds than that to be safe.
1861         # NB: we reset the recovery limit to 0 (indefinite) so the peer NI is
1862         # eligible again
1863         do_lnetctl set recovery_limit 0 ||
1864                 error "failed to set recovery_limit"
1865
1866         $LNETCTL peer set --nid $prim_nid --health 500
1867
1868         check_nid_in_recovq "-p" 1
1869         check_ping_count "peer_ni" "2"
1870
1871         sleep 7
1872
1873         check_nid_in_recovq "-p" 0
1874         check_ping_count "peer_ni" "0"
1875
1876         return 0
1877 }
1878 run_test 211 "Remote NI recovery checks"
1879
1880 test_212() {
1881         local rnodes=$(remote_nodes_list)
1882         [[ -z $rnodes ]] && skip "Need at least 1 remote node"
1883
1884         cleanup_lnet || error "Failed to cleanup before test execution"
1885
1886         # Loading modules should configure LNet with the appropriate
1887         # test-framework configuration
1888         load_modules || error "Failed to load modules"
1889
1890         local my_nid=$($LCTL list_nids | head -n 1)
1891         [[ -z $my_nid ]] &&
1892                 error "Failed to get primary NID for local host $HOSTNAME"
1893
1894         local rnode=$(awk '{print $1}' <<<$rnodes)
1895         local rnodenids=$(do_node $rnode $LCTL list_nids | xargs echo)
1896         local rloaded=false
1897
1898         if [[ -z $rnodenids ]]; then
1899                 do_rpc_nodes $rnode load_modules_local
1900                 rloaded=true
1901                 rnodenids=$(do_node $rnode $LCTL list_nids | xargs echo)
1902         fi
1903
1904         local rnodepnid=$(awk '{print $1}' <<< $rnodenids)
1905
1906         [[ -z $rnodepnid ]] &&
1907                 error "Failed to get primary NID for remote host $rnode"
1908
1909         log "Initial discovery"
1910         do_lnetctl discover --force $rnodepnid ||
1911                 error "Failed to discover $rnodepnid"
1912
1913         do_node $rnode "$LNETCTL discover --force $my_nid" ||
1914                 error "$rnode failed to discover $my_nid"
1915
1916         log "Fail local discover ping to set LNET_PEER_REDISCOVER flag"
1917         $LCTL net_drop_add -s "*@$NETTYPE" -d "*@$NETTYPE" -r 1 -e local_error
1918         do_lnetctl discover --force $rnodepnid &&
1919                 error "Discovery should have failed"
1920         $LCTL net_drop_del -a
1921
1922         local nid
1923         for nid in $rnodenids; do
1924                 # We need GET (PING) delay just long enough so we can trigger
1925                 # discovery on the remote peer
1926                 $LCTL net_delay_add -s "*@$NETTYPE" -d $nid -r 1 -m GET -l 3
1927                 $LCTL net_drop_add -s "*@$NETTYPE" -d $nid -r 1 -m GET -e local_error
1928                 # We need PUT (PUSH) delay just long enough so we can process
1929                 # the PING failure
1930                 $LCTL net_delay_add -s "*@$NETTYPE" -d $nid -r 1 -m PUT -l 6
1931         done
1932
1933         log "Force $HOSTNAME to discover $rnodepnid (in background)"
1934         # We want to get a PING sent that we know will eventually fail.
1935         # The delay rules we added will ensure the ping is not sent until
1936         # the PUSH is also in flight (see below), and the drop rule ensures that
1937         # when the PING is eventually sent it will error out
1938         do_lnetctl discover --force $rnodepnid &
1939         local pid1=$!
1940
1941         # We want a discovery PUSH from rnode to put rnode back on our
1942         # discovery queue. This should cause us to try and send a PUSH to rnode
1943         # while the PING is still outstanding.
1944         log "Force $rnode to discover $my_nid"
1945         do_node $rnode $LNETCTL discover --force $my_nid
1946
1947         # At this point we'll have both PING_SENT and PUSH_SENT set for the
1948         # rnode peer. Wait for the PING to error out which should terminate the
1949         # discovery process that we backgrounded.
1950         log "Wait for $pid1"
1951         wait $pid1
1952         log "Finished wait on $pid1"
1953
1954         # The PING send failure clears the PING_SENT flag and puts the peer back
1955         # on the discovery queue. When discovery thread processes the peer it
1956         # will mistakenly clear the PUSH_SENT flag (and set PUSH_FAILED).
1957         # Discovery will then complete for this peer even though we have an
1958         # outstanding PUSH.
1959         # When PUSH is actually unlinked it will be forced back onto the
1960         # discovery queue, but we no longer have a ref on the peer. When
1961         # discovery completes again, we'll trip the ASSERT in
1962         # lnet_destroy_peer_locked()
1963
1964         # Delete the delay rules to send the PUSH
1965         $LCTL net_delay_del -a
1966         # Delete the drop rules
1967         $LCTL net_drop_del -a
1968
1969         unload_modules ||
1970                 error "Failed to unload modules"
1971         if $rloaded; then
1972                 do_rpc_nodes $rnode unload_modules_local ||
1973                         error "Failed to unload modules on $rnode"
1974         fi
1975
1976         return 0
1977 }
1978 run_test 212 "Check discovery refcount loss bug (LU-14627)"
1979
1980 test_213() {
1981         cleanup_netns || error "Failed to cleanup netns before test execution"
1982         cleanup_lnet || error "Failed to unload modules before test execution"
1983
1984         setup_fakeif || error "Failed to add fake IF"
1985         have_interface "$FAKE_IF" ||
1986                 error "Expect $FAKE_IF configured but not found"
1987
1988         reinit_dlc || return $?
1989
1990         add_net "tcp" "${INTERFACES[0]}" || return $?
1991         add_net "tcp" "$FAKE_IF" || return $?
1992
1993         local nid1=$(lctl list_nids | head -n 1)
1994         local nid2=$(lctl list_nids | tail --lines 1)
1995
1996         [[ $(lctl which_nid $nid1 $nid2) == $nid1 ]] ||
1997                 error "Expect nid1 \"$nid1\" to be preferred"
1998
1999         [[ $(lctl which_nid $nid2 $nid1) == $nid2 ]] ||
2000                 error "Expect nid2 \"$nid2\" to be preferred"
2001
2002         return 0
2003 }
2004 run_test 213 "Check LNetDist calculation for multiple local NIDs"
2005
2006 function check_ni_status() {
2007         local nid="$1"
2008         local expect="$2"
2009
2010         local status=$($LNETCTL net show |
2011                        grep -A 1 ${nid} |
2012                        awk '/status/{print $NF}')
2013
2014         echo "NI ${nid} expect status \"${expect}\" found \"${status}\""
2015         if [[ $status != $expect ]]; then
2016                 error "Error: Expect NI status \"$expect\" for NID \"$nid\" but found \"$status\""
2017         fi
2018
2019         return 0
2020 }
2021
2022 test_214() {
2023         have_interface "eth0" || skip "Need eth0 interface with ipv4 configured"
2024
2025         cleanup_netns || error "Failed to cleanup netns before test execution"
2026         cleanup_lnet || error "Failed to unload modules before test execution"
2027
2028         setup_fakeif || error "Failed to add fake IF"
2029         have_interface "$FAKE_IF" ||
2030                 error "Expect $FAKE_IF configured but not found"
2031
2032         reinit_dlc || return $?
2033
2034         add_net "tcp" "eth0" || return $?
2035         add_net "tcp" "$FAKE_IF" || return $?
2036
2037         local nid1=$(lctl list_nids | head -n 1)
2038         local nid2=$(lctl list_nids | tail --lines 1)
2039
2040         check_ni_status "0@lo" up
2041         check_ni_status "$nid1" up
2042         check_ni_status "$nid2" up
2043
2044         echo "Set $FAKE_IF down"
2045         echo "ip link set dev $FAKE_IF down"
2046         ip link set dev $FAKE_IF down
2047         check_ni_status "0@lo" up
2048         check_ni_status "$nid1" up
2049         check_ni_status "$nid2" down
2050 }
2051 run_test 214 "Check local NI status when link is downed"
2052
2053 test_230() {
2054         # LU-12815
2055         echo "Check valid values; Should succeed"
2056         local i
2057         local lnid
2058         local cmd
2059         for ((i = 4; i < 16; i+=1)); do
2060                 reinit_dlc || return $?
2061                 add_net "tcp" "${INTERFACES[0]}" || return $?
2062                 do_lnetctl net set --all --conns-per-peer $i ||
2063                         error "should have succeeded $?"
2064                 $LNETCTL net show -v 1 | grep -q "conns_per_peer: $i" ||
2065                         error "failed to set conns-per-peer to $i"
2066                 lnid="$(lctl list_nids | head -n 1)"
2067                 do_lnetctl ping "$lnid" ||
2068                         error "failed to ping myself"
2069                 # "lctl --net tcp conn_list" prints the list of active
2070                 # connections. Since we're pinging ourselves, there should be
2071                 # 2 Control connections plus 2*conns_per_peer connections
2072                 # created (one Bulk Input, one Bulk Output in each pair).
2073                 # Here's the sample output for conns_per_peer set to 1:
2074                 # 12345-1.1.1.1@tcp I[0]host01->host01:988 2626560/1061296 nonagle
2075                 # 12345-1.1.1.1@tcp O[0]host01->host01:1022 2626560/1061488 nonagle
2076                 # 12345-1.1.1.1@tcp C[0]host01->host01:988 2626560/1061296 nonagle
2077                 # 12345-1.1.1.1@tcp C[0]host01->host01:1023 2626560/1061488 nonagle
2078                 cmd="printf 'network tcp\nconn_list\n' | lctl | grep -c '$lnid'"
2079
2080                 # Expect 2+conns_per_peer*2 connections. Wait no longer
2081                 # than 2 seconds.
2082                 wait_update $HOSTNAME "$cmd" "$((2+i*2))" 2 ||
2083                         error "expected number of tcp connections $((2+i*2))"
2084         done
2085
2086         reinit_dlc || return $?
2087         add_net "tcp" "${INTERFACES[0]}" || return $?
2088         echo "Set > 127; Should fail"
2089         do_lnetctl net set --all --conns-per-peer 128 &&
2090                 error "should have failed $?"
2091
2092         reinit_dlc || return $?
2093         add_net "tcp" "${INTERFACES[0]}" || return $?
2094         echo "Set < 0; Should be ignored"
2095         do_lnetctl net set --all --conns-per-peer -1 ||
2096                 error "should have succeeded $?"
2097         $LNETCTL net show -v 1 | grep -q "conns_per_peer: 1" ||
2098                 error "Did not stay at default"
2099 }
2100 run_test 230 "Test setting conns-per-peer"
2101
2102 test_300() {
2103         # LU-13274
2104         local header
2105         local out=$TMP/$tfile
2106         local prefix=/usr/include/linux/lnet
2107
2108         # We use a hard coded prefix so that this test will not fail
2109         # when run in tree.
2110         CC=${CC:-cc}
2111         if ! which $CC > /dev/null 2>&1; then
2112                 skip_env "$CC is not installed"
2113         fi
2114
2115         cleanup_lnet || exit 1
2116         load_lnet
2117
2118         local cc_args="-Wall -Werror -std=c99 -c -x c /dev/null -o $out"
2119         if ! [[ -d $prefix ]]; then
2120                 # Assume we're running in tree and fixup the include path.
2121                 prefix=$LUSTRE/../lnet/include/uapi/linux/lnet
2122                 cc_args+=" -I $LUSTRE/../lnet/include/uapi"
2123         fi
2124
2125         for header in $prefix/*.h; do
2126                 if ! [[ -f "$header" ]]; then
2127                         continue
2128                 fi
2129
2130                 echo "$CC $cc_args -include $header"
2131                 $CC $cc_args -include $header ||
2132                         error "cannot compile '$header'"
2133         done
2134         rm -f $out
2135 }
2136 run_test 300 "packaged LNet UAPI headers can be compiled"
2137
2138 complete $SECONDS
2139
2140 cleanup_testsuite
2141 exit_status