From: Bobby Eshleman bobbyeshleman@meta.com
Add tests to check that module loading order does not break vsock_loopback. Because vsock_loopback has some per-namespace data structure initialization that affects vsock namespace modes, lets make sure that namespace modes are respected and loopback sockets are functional even when the namespaces and modes are set prior to loading the vsock_loopback module.
Signed-off-by: Bobby Eshleman bobbyeshleman@meta.com --- tools/testing/selftests/vsock/vmtest.sh | 131 ++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+)
diff --git a/tools/testing/selftests/vsock/vmtest.sh b/tools/testing/selftests/vsock/vmtest.sh index f8fa8b16d6e3..648ae71bf45a 100755 --- a/tools/testing/selftests/vsock/vmtest.sh +++ b/tools/testing/selftests/vsock/vmtest.sh @@ -68,6 +68,8 @@ readonly TEST_NAMES=( ns_delete_vm_ok ns_delete_host_ok ns_delete_both_ok + ns_loopback_global_global_late_module_load_ok + ns_loopback_local_local_late_module_load_fails ) readonly TEST_DESCS=( # vm_server_host_client @@ -153,6 +155,12 @@ readonly TEST_DESCS=(
# ns_delete_both_ok "Check that deleting the VM and host's namespaces does not break the socket connection" + + # ns_loopback_global_global_late_module_load_ok + "Test that loopback still works in global namespaces initialized prior to loading the vsock_loopback kmod" + + # ns_loopback_local_local_late_module_load_fails + "Test that loopback connections still fail between local namespaces initialized prior to loading the vsock_loopback kmod" )
readonly USE_SHARED_VM=(vm_server_host_client vm_client_host_server vm_loopback) @@ -912,6 +920,23 @@ test_ns_diff_local_vm_connect_to_local_host_fails() { return "${KSFT_FAIL}" }
+unload_module() { + local module=$1 + local i + + for ((i = 0; i < 5; i++)); do + modprobe -r "${module}" 2>/dev/null || : + + if [[ "$(lsmod | grep -c ${module})" -eq 0 ]]; then + return 0 + fi + + sleep 1 + done + + return 1 +} + __test_loopback_two_netns() { local ns0=$1 local ns1=$2 @@ -1264,6 +1289,112 @@ test_ns_delete_both_ok() { check_ns_changes_dont_break_connection "both" "delete" }
+test_ns_loopback_global_global_late_module_load_ok() { + declare -a pids + local unixfile + local ns0 ns1 + local pids + local port + + if ! unload_module vsock_loopback; then + log_host "Unable to unload vsock_loopback, skipping..." + return "${KSFT_SKIP}" + fi + + ns0=loopback_ns0 + ns1=loopback_ns1 + + ip netns del "${ns0}" &>/dev/null || : + ip netns del "${ns1}" &>/dev/null || : + ip netns add "${ns0}" + ip netns add "${ns1}" + ns_set_mode "${ns0}" global + ns_set_mode "${ns1}" global + ip netns exec "${ns0}" ip link set dev lo up + ip netns exec "${ns1}" ip link set dev lo up + + modprobe vsock_loopback &> /dev/null || : + + unixfile=$(mktemp -u /tmp/XXXX.sock) + port=321 + ip netns exec "${ns1}" \ + socat TCP-LISTEN:"${port}",fork \ + UNIX-CONNECT:"${unixfile}" & + pids+=($!) + + host_wait_for_listener "${ns1}" "${port}" + ip netns exec "${ns0}" socat UNIX-LISTEN:"${unixfile}",fork \ + TCP-CONNECT:localhost:"${port}" & + pids+=($!) + + if ! host_vsock_test "${ns0}" "server" 1 "${port}"; then + ip netns del "${ns0}" &>/dev/null || : + ip netns del "${ns1}" &>/dev/null || : + terminate_pids "${pids[@]}" + return "${KSFT_FAIL}" + fi + + if ! host_vsock_test "${ns1}" "127.0.0.1" 1 "${port}"; then + ip netns del "${ns0}" &>/dev/null || : + ip netns del "${ns1}" &>/dev/null || : + terminate_pids "${pids[@]}" + return "${KSFT_FAIL}" + fi + + ip netns del "${ns0}" &>/dev/null || : + ip netns del "${ns1}" &>/dev/null || : + terminate_pids "${pids[@]}" + + return "${KSFT_PASS}" +} + +test_ns_loopback_local_local_late_module_load_fails() { + declare -a pids + local ns0 ns1 + local outfile + local pids + local rc + + if ! unload_module vsock_loopback; then + log_host "Unable to unload vsock_loopback, skipping..." + return "${KSFT_SKIP}" + fi + + ns0=loopback_ns0 + ns1=loopback_ns1 + + ip netns del "${ns0}" &>/dev/null || : + ip netns del "${ns1}" &>/dev/null || : + ip netns add "${ns0}" + ip netns add "${ns1}" + ns_set_mode "${ns0}" local + ns_set_mode "${ns1}" local + + modprobe vsock_loopback &> /dev/null || : + + outfile=$(mktemp /tmp/XXXX.vmtest.out) + ip netns exec "${ns0}" socat VSOCK-LISTEN:${port} STDOUT \ + > "${outfile}" 2>/dev/null & + pids+=($!) + + echo TEST | \ + ip netns exec "${ns1}" socat STDIN VSOCK-CONNECT:1:${port} \ + 2>/dev/null + + if grep -q "TEST" "${outfile}" 2>/dev/null; then + rc="${KSFT_FAIL}" + else + rc="${KSFT_PASS}" + fi + + ip netns del "${ns0}" &>/dev/null || : + ip netns del "${ns1}" &>/dev/null || : + terminate_pids "${pids[@]}" + rm -f "${outfile}" + + return "${rc}" +} + shared_vm_test() { local tname