diff --git a/tools/testing/selftests/net/rds/Makefile b/tools/testing/selftests/net/rds/Makefile index fe363be8e358..ec10ae24e4cf 100644 --- a/tools/testing/selftests/net/rds/Makefile +++ b/tools/testing/selftests/net/rds/Makefile @@ -3,7 +3,7 @@ all: @echo mk_build_dir="$(shell pwd)" > include.sh -TEST_PROGS := run.sh +TEST_PROGS := rds_run.sh TEST_FILES := \ include.sh \ diff --git a/tools/testing/selftests/net/rds/README.txt b/tools/testing/selftests/net/rds/README.txt index bac6f15a80d5..8aa41148b1b5 100644 --- a/tools/testing/selftests/net/rds/README.txt +++ b/tools/testing/selftests/net/rds/README.txt @@ -14,9 +14,9 @@ configs required for the RDMA transport. The kernel may optionally be configured to omit the coverage report as well. USAGE: - run.sh [-d logdir] [-l packet_loss] [-c packet_corruption] - [-u packet_duplicate] [-t timeout] - [-T tcp|rdma|tcp,rdma] + rds_run.sh [-d logdir] [-l packet_loss] [-c packet_corruption] + [-u packet_duplicate] [-t timeout] + [-T tcp|rdma|tcp,rdma] OPTIONS: -d Log directory. If set, logs will be stored in the @@ -73,5 +73,5 @@ EXAMPLE: "export PYTHONPATH=tools/testing/selftests/net/; \ export SUDO_USER=example_user; \ export RDS_LOG_DIR=tools/testing/selftests/net/rds/rds_logs; \ - tools/testing/selftests/net/rds/run.sh -T tcp,rdma" + tools/testing/selftests/net/rds/rds_run.sh -T tcp,rdma" diff --git a/tools/testing/selftests/net/rds/config b/tools/testing/selftests/net/rds/config index 3d62d0c750a8..97db7ecb892a 100644 --- a/tools/testing/selftests/net/rds/config +++ b/tools/testing/selftests/net/rds/config @@ -1,4 +1,3 @@ -CONFIG_MODULES=n CONFIG_NET_NS=y CONFIG_NET_SCH_NETEM=y CONFIG_RDS=y diff --git a/tools/testing/selftests/net/rds/config.sh b/tools/testing/selftests/net/rds/config.sh index be0668359a07..2df2226310ef 100755 --- a/tools/testing/selftests/net/rds/config.sh +++ b/tools/testing/selftests/net/rds/config.sh @@ -37,9 +37,6 @@ if [[ "$CONF_FILE" != "" ]]; then FLAGS=(--file "$CONF_FILE") fi -# no modules -scripts/config "${FLAGS[@]}" --disable CONFIG_MODULES - # enable RDS scripts/config "${FLAGS[@]}" --enable CONFIG_RDS scripts/config "${FLAGS[@]}" --enable CONFIG_RDS_TCP diff --git a/tools/testing/selftests/net/rds/run.sh b/tools/testing/selftests/net/rds/rds_run.sh similarity index 78% rename from tools/testing/selftests/net/rds/run.sh rename to tools/testing/selftests/net/rds/rds_run.sh index 07af2f927a2a..cdf487ec97dc 100755 --- a/tools/testing/selftests/net/rds/run.sh +++ b/tools/testing/selftests/net/rds/rds_run.sh @@ -93,42 +93,62 @@ check_gcov_conf() fi } +# Checks if a kconfig is enabled (set to =y or =m) +# $1: kconfig symbol to check +# $2: (optional) module name backing $1 +# Ex: check_conf_enabled CONFIG_RDS_TCP rds_tcp +# Modules for configs set to =m will be probed +# If omitted, only a built-in (=y) config is accepted. +# Returns on success. exits 4 on failure # Kselftest framework requirement - SKIP code is 4. check_conf_enabled() { - if ! grep -x "$1=y" "$kconfig" > /dev/null 2>&1; then - echo "selftests: [SKIP] This test requires $1 enabled" - echo "Please run tools/testing/selftests/net/rds/config.sh and rebuild the kernel" - exit 4 + if grep -x "$1=y" "$kconfig" > /dev/null 2>&1; then + return fi + if [ -n "${2:-}" ] && grep -x "$1=m" "$kconfig" > /dev/null 2>&1; then + probe_module "$2" + return + fi + echo "selftests: [SKIP] This test requires $1 enabled" + echo "Please run" \ + "tools/testing/selftests/net/rds/config.sh and rebuild the kernel" + exit 4 } check_rdma_conf_enabled() { - if ! grep -x "$1=y" "$kconfig" > /dev/null 2>&1; then - echo "selftests: [SKIP] rdma transport requires $1 enabled" - echo "To enable, run " \ - "tools/testing/selftests/net/rds/config.sh -r and rebuild" + if grep -x "$1=y" "$kconfig" > /dev/null 2>&1; then + return + fi + if [ -n "${2:-}" ] && grep -x "$1=m" "$kconfig" > /dev/null 2>&1; then + probe_module "$2" + return + fi + echo "selftests: [XFAIL] rdma transport requires $1 enabled" + echo "To enable, run" \ + "tools/testing/selftests/net/rds/config.sh -r and rebuild" + exit 2 +} + +# Load the module backing a config that is built as a loadable module +# (=m). Built-in (=y) configs are already available and don't reach +# here. Exits with the SKIP code if a required module cannot be loaded. +probe_module() { + if ! modprobe -q "$1"; then + echo "selftests: [SKIP] could not load required module $1" exit 4 fi } -check_conf_disabled() { - if grep -x "$1=y" "$kconfig" > /dev/null 2>&1; then - echo "selftests: [SKIP] This test requires $1 disabled" - echo "Please run tools/testing/selftests/net/rds/config.sh and rebuild the kernel" - exit 4 - fi -} check_conf() { - check_conf_enabled CONFIG_NET_SCH_NETEM - check_conf_enabled CONFIG_VETH + check_conf_enabled CONFIG_NET_SCH_NETEM sch_netem + check_conf_enabled CONFIG_VETH veth check_conf_enabled CONFIG_NET_NS - check_conf_enabled CONFIG_RDS_TCP - check_conf_enabled CONFIG_RDS - check_conf_disabled CONFIG_MODULES + check_conf_enabled CONFIG_RDS_TCP rds_tcp + check_conf_enabled CONFIG_RDS rds } # Check kernel config and host environment for RDS-RDMA support. -# Exits with SKIP (4) if the user requested rdma but prerequisites +# Exits with XFAIL (2) if the user requested rdma but prerequisites # are not met. check_rdma_conf() { @@ -139,13 +159,13 @@ check_rdma_conf() # Kconfig will enforce CONFIG_INFINIBAND_* as dependencies # of CONFIG_RDMA_RXE - check_rdma_conf_enabled CONFIG_RDMA_RXE - check_rdma_conf_enabled CONFIG_RDS_RDMA + check_rdma_conf_enabled CONFIG_RDMA_RXE rdma_rxe + check_rdma_conf_enabled CONFIG_RDS_RDMA rds_rdma if ! which rdma > /dev/null 2>&1; then - echo "selftests: [SKIP] rdma transport requires the 'rdma'" \ - " tool (iproute2)" - exit 4 + echo "selftests: [XFAIL] rdma transport requires the 'rdma'" \ + "tool (iproute2)" + exit 2 fi } @@ -209,8 +229,9 @@ while getopts "d:l:c:u:t:T:" opt; do TRANSPORT=${OPTARG} ;; :) - echo "USAGE: run.sh [-d logdir] [-l packet_loss] [-c packet_corruption]" \ - "[-u packet_duplicate] [-t timeout] [-T tcp|rdma|tcp,rdma]" + echo "USAGE: rds_run.sh [-d logdir] [-l packet_loss]" \ + "[-c packet_corruption] [-u packet_duplicate] [-t timeout]" \ + "[-T tcp|rdma|tcp,rdma]" exit 1 ;; ?) @@ -224,7 +245,7 @@ done IFS=',' read -ra transports <<< "$TRANSPORT" for t in "${transports[@]}"; do if [ "$t" != "tcp" ] && [ "$t" != "rdma" ]; then - echo "run.sh: unknown transport '$t' (expected tcp or rdma)" + echo "rds_run.sh: unknown transport '$t' (expected tcp or rdma)" exit 1 fi done diff --git a/tools/testing/selftests/net/rds/test.py b/tools/testing/selftests/net/rds/test.py index 08f2a846a8ab..9e4df01cb0d4 100755 --- a/tools/testing/selftests/net/rds/test.py +++ b/tools/testing/selftests/net/rds/test.py @@ -59,6 +59,14 @@ rdma_addrs = [ OP_FLAG_TCP = 0x1 OP_FLAG_RDMA = 0x2 +# from include/uapi/linux/rds.h: SO_RDS_TRANSPORT pins a socket to a +# specific RDS transport so connection setup cannot silently fall back +# to another (e.g. loopback) transport. +SOL_RDS = 276 +SO_RDS_TRANSPORT = 8 +RDS_TRANS_TCP = 2 +RDS_TRANS_IB = 0 + signal_handler_label = "" tap_idx = 0 @@ -214,11 +222,21 @@ def snd_rcv_packets(env): netns_socket(netns_list[0], socket.AF_RDS, socket.SOCK_SEQPACKET), netns_socket(netns_list[1], socket.AF_RDS, socket.SOCK_SEQPACKET), ] + + # Pin the sockets to the TCP transport so it doesn't fail over to a + # different transport during this test + for s in sockets: + s.setsockopt(SOL_RDS, SO_RDS_TRANSPORT, RDS_TRANS_TCP) elif flags & OP_FLAG_RDMA: sockets = [ socket.socket(socket.AF_RDS, socket.SOCK_SEQPACKET), socket.socket(socket.AF_RDS, socket.SOCK_SEQPACKET), ] + + # Pin the sockets to the RDMA transport so it doesn't fail over to a + # different transport during this test + for s in sockets: + s.setsockopt(SOL_RDS, SO_RDS_TRANSPORT, RDS_TRANS_IB) else: raise RuntimeError(f"Invalid transport flag sets no transports: {flags}")