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