Whamcloud - gitweb
LU-15210 tests: fix sanity-lnet to handle duplicate IP
[fs/lustre-release.git] / lustre / tests / sanity-lnet.sh
index 485e105..ce4c27a 100755 (executable)
@@ -56,7 +56,7 @@ fi
 cleanup_testsuite() {
        trap "" EXIT
        # Cleanup any tmp files created by the sub tests
-       rm -f $TMP/sanity-lnet*
+       rm -f $TMP/sanity-lnet-*.yaml $LNET_PARAMS_FILE
        cleanup_netns
        cleanup_lnet
        if $restore_mounts; then
@@ -248,6 +248,31 @@ validate_gateway_nids() {
 cleanupall -f
 setup_netns || error "setup_netns failed with $?"
 
+# Determine the local interface(s) used for LNet
+load_modules || error "Failed to load modules"
+NIDS=( $($LCTL list_nids | xargs echo) )
+if [[ -z ${NIDS[@]} ]]; then
+       error "No NID configured after module load"
+fi
+
+do_lnetctl net show
+ip a
+
+declare -a INTERFACES
+for ((i = 0; i < ${#NIDS[@]}; i++)); do
+       ip=$(sed 's/^\(.*\)@.*$/\1/'<<<${NIDS[i]})
+       INTERFACES[i]=$(ip -o a s |
+                       awk '$4 ~ /^'$ip'\//{print $2}')
+       INTERFACES=($(echo "${INTERFACES[@]}" | tr ' ' '\n' | uniq | tr '\n' ' '))
+       if [[ -z ${INTERFACES[i]} ]]; then
+               error "Can't determine interface name for NID ${NIDS[i]}"
+       elif [[ 1 -ne $(wc -w <<<${INTERFACES[i]}) ]]; then
+               error "Found $(wc -w <<<${INTERFACES[i]}) interfaces for NID ${NIDS[i]}. Expect 1"
+       fi
+done
+
+cleanup_lnet || error "Failed to cleanup LNet"
+
 stack_trap 'cleanup_testsuite' EXIT
 
 test_0() {
@@ -1058,20 +1083,21 @@ compare_route_add() {
 }
 
 test_100() {
-       have_interface "eth0" || skip "Need eth0 interface with ipv4 configured"
        reinit_dlc || return $?
-       add_net "tcp" "eth0"
+       add_net "tcp" "${INTERFACES[0]}"
        cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
 net:
     - net type: tcp
       local NI(s):
         - interfaces:
-              0: eth0
+              0: ${INTERFACES[0]}
           tunables:
               peer_timeout: 180
               peer_credits: 8
               peer_buffer_credits: 0
               credits: 256
+          lnd tunables:
+              conns_per_peer: 1
 route:
     - net: tcp7
       gateway: 7.7.7.7@tcp
@@ -1091,20 +1117,21 @@ EOF
 run_test 100 "Add route with single gw (tcp)"
 
 test_101() {
-       have_interface "eth0" || skip "Need eth0 interface with ipv4 configured"
        reinit_dlc || return $?
-       add_net "tcp" "eth0"
+       add_net "tcp" "${INTERFACES[0]}"
        cat <<EOF > $TMP/sanity-lnet-$testnum-expected.yaml
 net:
     - net type: tcp
       local NI(s):
         - interfaces:
-              0: eth0
+              0: ${INTERFACES[0]}
           tunables:
               peer_timeout: 180
               peer_credits: 8
               peer_buffer_credits: 0
               credits: 256
+          lnd tunables:
+              conns_per_peer: 1
 route:
     - net: tcp8
       gateway: 8.8.8.10@tcp
@@ -1154,9 +1181,8 @@ compare_route_del() {
 }
 
 test_102() {
-       have_interface "eth0" || skip "Need eth0 interface with ipv4 configured"
        reinit_dlc || return $?
-       add_net "tcp" "eth0"
+       add_net "tcp" "${INTERFACES[0]}"
        $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-expected.yaml
        do_lnetctl route add --net tcp102 --gateway 102.102.102.102@tcp ||
                error "route add failed $?"
@@ -1165,9 +1191,8 @@ test_102() {
 run_test 102 "Delete route with single gw (tcp)"
 
 test_103() {
-       have_interface "eth0" || skip "Need eth0 interface with ipv4 configured"
        reinit_dlc || return $?
-       add_net "tcp" "eth0"
+       add_net "tcp" "${INTERFACES[0]}"
        $LNETCTL export --backup > $TMP/sanity-lnet-$testnum-expected.yaml
        do_lnetctl route add --net tcp103 \
                --gateway 103.103.103.[103-120/4]@tcp ||
@@ -1398,9 +1423,8 @@ LNET_LOCAL_RESEND_STATUSES="local_interrupt local_dropped local_aborted"
 LNET_LOCAL_RESEND_STATUSES+=" local_no_route local_timeout"
 LNET_LOCAL_NO_RESEND_STATUSES="local_error"
 test_204() {
-       have_interface "eth0" || skip "Need eth0 interface with ipv4 configured"
        reinit_dlc || return $?
-       add_net "tcp" "eth0" || return $?
+       add_net "tcp" "${INTERFACES[0]}" || return $?
 
        lnet_health_pre || return $?
 
@@ -1424,13 +1448,11 @@ test_204() {
 run_test 204 "Check no health or resends for single-rail local failures"
 
 test_205() {
-       have_interface "eth0" || skip "Need eth0 interface with ipv4 configured"
-
        local hstatus
        for hstatus in ${LNET_LOCAL_RESEND_STATUSES}; do
                reinit_dlc || return $?
-               add_net "tcp" "eth0" || return $?
-               add_net "tcp1" "eth0" || return $?
+               add_net "tcp" "${INTERFACES[0]}" || return $?
+               add_net "tcp1" "${INTERFACES[0]}" || return $?
 
                echo "Simulate $hstatus"
                lnet_health_pre
@@ -1449,8 +1471,8 @@ test_205() {
 
        for hstatus in ${LNET_LOCAL_NO_RESEND_STATUSES}; do
                reinit_dlc || return $?
-               add_net "tcp" "eth0" || return $?
-               add_net "tcp1" "eth0" || return $?
+               add_net "tcp" "${INTERFACES[0]}" || return $?
+               add_net "tcp1" "${INTERFACES[0]}" || return $?
 
                echo "Simulate $hstatus"
                lnet_health_pre || return $?
@@ -1475,9 +1497,8 @@ run_test 205 "Check health and resends for multi-rail local failures"
 LNET_REMOTE_RESEND_STATUSES="remote_dropped"
 LNET_REMOTE_NO_RESEND_STATUSES="remote_error remote_timeout"
 test_206() {
-       have_interface "eth0" || skip "Need eth0 interface with ipv4 configured"
        reinit_dlc || return $?
-       add_net "tcp" "eth0" || return $?
+       add_net "tcp" "${INTERFACES[0]}" || return $?
 
        do_lnetctl discover $($LCTL list_nids | head -n 1) ||
                error "failed to discover myself"
@@ -1505,13 +1526,11 @@ test_206() {
 run_test 206 "Check no health or resends for single-rail remote failures"
 
 test_207() {
-       have_interface "eth0" || skip "Need eth0 interface with ipv4 configured"
-
        local hstatus
        for hstatus in ${LNET_REMOTE_RESEND_STATUSES}; do
                reinit_dlc || return $?
-               add_net "tcp" "eth0" || return $?
-               add_net "tcp1" "eth0" || return $?
+               add_net "tcp" "${INTERFACES[0]}" || return $?
+               add_net "tcp1" "${INTERFACES[0]}" || return $?
 
                do_lnetctl discover $($LCTL list_nids | head -n 1) ||
                        error "failed to discover myself"
@@ -1532,8 +1551,8 @@ test_207() {
        done
        for hstatus in ${LNET_REMOTE_NO_RESEND_STATUSES}; do
                reinit_dlc || return $?
-               add_net "tcp" "eth0" || return $?
-               add_net "tcp1" "eth0" || return $?
+               add_net "tcp" "${INTERFACES[0]}" || return $?
+               add_net "tcp1" "${INTERFACES[0]}" || return $?
 
                do_lnetctl discover $($LCTL list_nids | head -n 1) ||
                        error "failed to discover myself"
@@ -1588,8 +1607,6 @@ test_208_load_and_check_lnet() {
 }
 
 test_208() {
-       have_interface "eth0" || skip "Need eth0 interface with ipv4 configured"
-
        cleanup_netns || error "Failed to cleanup netns before test execution"
        cleanup_lnet || error "Failed to unload modules before test execution"
        setup_fakeif || error "Failed to add fake IF"
@@ -1597,24 +1614,25 @@ test_208() {
        have_interface "$FAKE_IF" ||
                error "Expect $FAKE_IF configured but not found"
 
-       local eth0_ip=$(ip --oneline addr show dev eth0 |
-                       awk '/inet /{print $4}' |
-                       sed 's:/.*::')
-       local ip2nets_str="tcp(eth0) $eth0_ip"
+       local if0_ip=$(ip --oneline addr show dev ${INTERFACES[0]} |
+                      awk '/inet /{print $4}' |
+                      sed 's:/.*::')
+       if0_ip=($(echo "${if0_ip[@]}" | tr ' ' '\n' | uniq | tr '\n' ' '))
+       local ip2nets_str="tcp(${INTERFACES[0]}) $if0_ip"
 
        echo "Configure single NID \"$ip2nets_str\""
-       test_208_load_and_check_lnet "${ip2nets_str}" "${eth0_ip}@tcp"
+       test_208_load_and_check_lnet "${ip2nets_str}" "${if0_ip}@tcp"
 
-       ip2nets_str="tcp(eth0) $eth0_ip; tcp1($FAKE_IF) $FAKE_IP"
+       ip2nets_str="tcp(${INTERFACES[0]}) $if0_ip; tcp1($FAKE_IF) $FAKE_IP"
        echo "Configure two NIDs; two NETs \"$ip2nets_str\""
-       test_208_load_and_check_lnet "${ip2nets_str}" "${eth0_ip}@tcp" \
+       test_208_load_and_check_lnet "${ip2nets_str}" "${if0_ip}@tcp" \
                                     "${FAKE_IP}@tcp1"
 
-       ip2nets_str="tcp(eth0) $eth0_ip; tcp($FAKE_IF) $FAKE_IP"
+       ip2nets_str="tcp(${INTERFACES[0]}) $if0_ip; tcp($FAKE_IF) $FAKE_IP"
        echo "Configure two NIDs; one NET \"$ip2nets_str\""
-       test_208_load_and_check_lnet "${ip2nets_str}" "${eth0_ip}@tcp" \
+       test_208_load_and_check_lnet "${ip2nets_str}" "${if0_ip}@tcp" \
                                     "${FAKE_IP}@tcp"
-       local addr1=( ${eth0_ip//./ } )
+       local addr1=( ${if0_ip//./ } )
        local addr2=( ${FAKE_IP//./ } )
        local range="[${addr1[0]},${addr2[0]}]"
 
@@ -1622,10 +1640,10 @@ test_208() {
        for i in $(seq 1 3); do
                range+=".[${addr1[$i]},${addr2[$i]}]"
        done
-       ip2nets_str="tcp(eth0,${FAKE_IF}) ${range}"
+       ip2nets_str="tcp(${INTERFACES[0]},${FAKE_IF}) ${range}"
 
        echo "Configured two NIDs; one NET alt syntax \"$ip2nets_str\""
-       test_208_load_and_check_lnet "${ip2nets_str}" "${eth0_ip}@tcp" \
+       test_208_load_and_check_lnet "${ip2nets_str}" "${if0_ip}@tcp" \
                                     "${FAKE_IP}@tcp"
 
        cleanup_fakeif
@@ -1642,10 +1660,8 @@ test_208() {
 run_test 208 "Test various kernel ip2nets configurations"
 
 test_209() {
-       have_interface "eth0" || skip "Need eth0 interface with ipv4 configured"
-
        reinit_dlc || return $?
-       add_net "tcp" "eth0" || return $?
+       add_net "tcp" "${INTERFACES[0]}" || return $?
 
        do_lnetctl discover $($LCTL list_nids | head -n 1) ||
                error "failed to discover myself"
@@ -1665,8 +1681,8 @@ test_209() {
        check_no_remote_health || return $?
 
        reinit_dlc || return $?
-       add_net "tcp" "eth0" || return $?
-       add_net "tcp1" "eth0" || return $?
+       add_net "tcp" "${INTERFACES[0]}" || return $?
+       add_net "tcp1" "${INTERFACES[0]}" || return $?
 
        do_lnetctl discover $($LCTL list_nids | head -n 1) ||
                error "failed to discover myself"
@@ -1768,10 +1784,9 @@ check_ping_count() {
 }
 
 test_210() {
-       have_interface "eth0" || skip "Need eth0 interface with ipv4 configured"
        reinit_dlc || return $?
-       add_net "tcp" "eth0" || return $?
-       add_net "tcp1" "eth0" || return $?
+       add_net "tcp" "${INTERFACES[0]}" || return $?
+       add_net "tcp1" "${INTERFACES[0]}" || return $?
 
        local prim_nid=$($LCTL list_nids | head -n 1)
 
@@ -1805,10 +1820,9 @@ test_210() {
 run_test 210 "Local NI recovery checks"
 
 test_211() {
-       have_interface "eth0" || skip "Need eth0 interface with ipv4 configured"
        reinit_dlc || return $?
-       add_net "tcp" "eth0" || return $?
-       add_net "tcp1" "eth0" || return $?
+       add_net "tcp" "${INTERFACES[0]}" || return $?
+       add_net "tcp1" "${INTERFACES[0]}" || return $?
 
        local prim_nid=$($LCTL list_nids | head -n 1)
 
@@ -1844,13 +1858,16 @@ test_211() {
        # Set health to force it back onto the recovery queue. Set to 500 means
        # in 5 seconds it should be back at maximum value. We'll wait a couple
        # more seconds than that to be safe.
-       # NB: we need to increase the recovery limit so the peer NI is
+       # NB: we reset the recovery limit to 0 (indefinite) so the peer NI is
        # eligible again
-       do_lnetctl set recovery_limit 50 ||
+       do_lnetctl set recovery_limit 0 ||
                error "failed to set recovery_limit"
 
        $LNETCTL peer set --nid $prim_nid --health 500
 
+       check_nid_in_recovq "-p" 1
+       check_ping_count "peer_ni" "2"
+
        sleep 7
 
        check_nid_in_recovq "-p" 0
@@ -1961,8 +1978,6 @@ test_212() {
 run_test 212 "Check discovery refcount loss bug (LU-14627)"
 
 test_213() {
-       have_interface "eth0" || skip "Need eth0 interface with ipv4 configured"
-
        cleanup_netns || error "Failed to cleanup netns before test execution"
        cleanup_lnet || error "Failed to unload modules before test execution"
 
@@ -1972,7 +1987,7 @@ test_213() {
 
        reinit_dlc || return $?
 
-       add_net "tcp" "eth0" || return $?
+       add_net "tcp" "${INTERFACES[0]}" || return $?
        add_net "tcp" "$FAKE_IF" || return $?
 
        local nid1=$(lctl list_nids | head -n 1)
@@ -1988,6 +2003,102 @@ test_213() {
 }
 run_test 213 "Check LNetDist calculation for multiple local NIDs"
 
+function check_ni_status() {
+       local nid="$1"
+       local expect="$2"
+
+       local status=$($LNETCTL net show |
+                      grep -A 1 ${nid} |
+                      awk '/status/{print $NF}')
+
+       echo "NI ${nid} expect status \"${expect}\" found \"${status}\""
+       if [[ $status != $expect ]]; then
+               error "Error: Expect NI status \"$expect\" for NID \"$nid\" but found \"$status\""
+       fi
+
+       return 0
+}
+
+test_214() {
+       have_interface "eth0" || skip "Need eth0 interface with ipv4 configured"
+
+       cleanup_netns || error "Failed to cleanup netns before test execution"
+       cleanup_lnet || error "Failed to unload modules before test execution"
+
+       setup_fakeif || error "Failed to add fake IF"
+       have_interface "$FAKE_IF" ||
+               error "Expect $FAKE_IF configured but not found"
+
+       reinit_dlc || return $?
+
+       add_net "tcp" "eth0" || return $?
+       add_net "tcp" "$FAKE_IF" || return $?
+
+       local nid1=$(lctl list_nids | head -n 1)
+       local nid2=$(lctl list_nids | tail --lines 1)
+
+       check_ni_status "0@lo" up
+       check_ni_status "$nid1" up
+       check_ni_status "$nid2" up
+
+       echo "Set $FAKE_IF down"
+       echo "ip link set dev $FAKE_IF down"
+       ip link set dev $FAKE_IF down
+       check_ni_status "0@lo" up
+       check_ni_status "$nid1" up
+       check_ni_status "$nid2" down
+}
+run_test 214 "Check local NI status when link is downed"
+
+test_230() {
+       # LU-12815
+       echo "Check valid values; Should succeed"
+       local i
+       local lnid
+       local cmd
+       for ((i = 4; i < 16; i+=1)); do
+               reinit_dlc || return $?
+               add_net "tcp" "${INTERFACES[0]}" || return $?
+               do_lnetctl net set --all --conns-per-peer $i ||
+                       error "should have succeeded $?"
+               $LNETCTL net show -v 1 | grep -q "conns_per_peer: $i" ||
+                       error "failed to set conns-per-peer to $i"
+               lnid="$(lctl list_nids | head -n 1)"
+               do_lnetctl ping "$lnid" ||
+                       error "failed to ping myself"
+               # "lctl --net tcp conn_list" prints the list of active
+               # connections. Since we're pinging ourselves, there should be
+               # 2 Control connections plus 2*conns_per_peer connections
+               # created (one Bulk Input, one Bulk Output in each pair).
+               # Here's the sample output for conns_per_peer set to 1:
+               # 12345-1.1.1.1@tcp I[0]host01->host01:988 2626560/1061296 nonagle
+               # 12345-1.1.1.1@tcp O[0]host01->host01:1022 2626560/1061488 nonagle
+               # 12345-1.1.1.1@tcp C[0]host01->host01:988 2626560/1061296 nonagle
+               # 12345-1.1.1.1@tcp C[0]host01->host01:1023 2626560/1061488 nonagle
+               cmd="printf 'network tcp\nconn_list\n' | lctl | grep -c '$lnid'"
+
+               # Expect 2+conns_per_peer*2 connections. Wait no longer
+               # than 2 seconds.
+               wait_update $HOSTNAME "$cmd" "$((2+i*2))" 2 ||
+                       error "expected number of tcp connections $((2+i*2))"
+       done
+
+       reinit_dlc || return $?
+       add_net "tcp" "${INTERFACES[0]}" || return $?
+       echo "Set > 127; Should fail"
+       do_lnetctl net set --all --conns-per-peer 128 &&
+               error "should have failed $?"
+
+       reinit_dlc || return $?
+       add_net "tcp" "${INTERFACES[0]}" || return $?
+       echo "Set < 0; Should be ignored"
+       do_lnetctl net set --all --conns-per-peer -1 ||
+               error "should have succeeded $?"
+       $LNETCTL net show -v 1 | grep -q "conns_per_peer: 1" ||
+               error "Did not stay at default"
+}
+run_test 230 "Test setting conns-per-peer"
+
 test_300() {
        # LU-13274
        local header
@@ -2004,9 +2115,11 @@ test_300() {
        cleanup_lnet || exit 1
        load_lnet
 
+       local cc_args="-Wall -Werror -std=c99 -c -x c /dev/null -o $out"
        if ! [[ -d $prefix ]]; then
                # Assume we're running in tree and fixup the include path.
                prefix=$LUSTRE/../lnet/include/uapi/linux/lnet
+               cc_args+=" -I $LUSTRE/../lnet/include/uapi"
        fi
 
        for header in $prefix/*.h; do
@@ -2014,7 +2127,8 @@ test_300() {
                        continue
                fi
 
-               $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
+               echo "$CC $cc_args -include $header"
+               $CC $cc_args -include $header ||
                        error "cannot compile '$header'"
        done
        rm -f $out