]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
selftests/vsock: add tests for proc sys vsock ns_mode
authorBobby Eshleman <bobbyeshleman@meta.com>
Wed, 21 Jan 2026 22:11:49 +0000 (14:11 -0800)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 27 Jan 2026 09:45:38 +0000 (10:45 +0100)
Add tests for the /proc/sys/net/vsock/{ns_mode,child_ns_mode}
interfaces. Namely, that they accept/report "global" and "local" strings
and enforce their access policies.

Start a convention of commenting the test name over the test
description. Add test name comments over test descriptions that existed
before this convention.

Add a check_netns() function that checks if the test requires namespaces
and if the current kernel supports namespaces. Skip tests that require
namespaces if the system does not have namespace support.

This patch is the first to add tests that do *not* re-use the same
shared VM. For that reason, it adds a run_ns_tests() function to run
these tests and filter out the shared VM tests.

Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>
Link: https://patch.msgid.link/20260121-vsock-vmtest-v16-9-2859a7512097@meta.com
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
tools/testing/selftests/vsock/vmtest.sh

index 0e681d4c3a1528f0e4c741924ccf23b60f853eb6..38785a10223677ec845b0799afc948f71c45cf8f 100755 (executable)
@@ -41,14 +41,38 @@ readonly KERNEL_CMDLINE="\
        virtme.ssh virtme_ssh_channel=tcp virtme_ssh_user=$USER \
 "
 readonly LOG=$(mktemp /tmp/vsock_vmtest_XXXX.log)
-readonly TEST_NAMES=(vm_server_host_client vm_client_host_server vm_loopback)
+
+# Namespace tests must use the ns_ prefix. This is checked in check_netns() and
+# is used to determine if a test needs namespace setup before test execution.
+readonly TEST_NAMES=(
+       vm_server_host_client
+       vm_client_host_server
+       vm_loopback
+       ns_host_vsock_ns_mode_ok
+       ns_host_vsock_child_ns_mode_ok
+)
 readonly TEST_DESCS=(
+       # vm_server_host_client
        "Run vsock_test in server mode on the VM and in client mode on the host."
+
+       # vm_client_host_server
        "Run vsock_test in client mode on the VM and in server mode on the host."
+
+       # vm_loopback
        "Run vsock_test using the loopback transport in the VM."
+
+       # ns_host_vsock_ns_mode_ok
+       "Check /proc/sys/net/vsock/ns_mode strings on the host."
+
+       # ns_host_vsock_child_ns_mode_ok
+       "Check /proc/sys/net/vsock/ns_mode is read-only and child_ns_mode is writable."
 )
 
-readonly USE_SHARED_VM=(vm_server_host_client vm_client_host_server vm_loopback)
+readonly USE_SHARED_VM=(
+       vm_server_host_client
+       vm_client_host_server
+       vm_loopback
+)
 readonly NS_MODES=("local" "global")
 
 VERBOSE=0
@@ -196,6 +220,20 @@ check_deps() {
        fi
 }
 
+check_netns() {
+       local tname=$1
+
+       # If the test requires NS support, check if NS support exists
+       # using /proc/self/ns
+       if [[ "${tname}" =~ ^ns_ ]] &&
+          [[ ! -e /proc/self/ns ]]; then
+               log_host "No NS support detected for test ${tname}"
+               return 1
+       fi
+
+       return 0
+}
+
 check_vng() {
        local tested_versions
        local version
@@ -519,6 +557,54 @@ log_guest() {
        LOG_PREFIX=guest log "$@"
 }
 
+ns_get_mode() {
+       local ns=$1
+
+       ip netns exec "${ns}" cat /proc/sys/net/vsock/ns_mode 2>/dev/null
+}
+
+test_ns_host_vsock_ns_mode_ok() {
+       for mode in "${NS_MODES[@]}"; do
+               local actual
+
+               actual=$(ns_get_mode "${mode}0")
+               if [[ "${actual}" != "${mode}" ]]; then
+                       log_host "expected mode ${mode}, got ${actual}"
+                       return "${KSFT_FAIL}"
+               fi
+       done
+
+       return "${KSFT_PASS}"
+}
+
+test_ns_host_vsock_child_ns_mode_ok() {
+       local orig_mode
+       local rc
+
+       orig_mode=$(cat /proc/sys/net/vsock/child_ns_mode)
+
+       rc="${KSFT_PASS}"
+       for mode in "${NS_MODES[@]}"; do
+               local ns="${mode}0"
+
+               if echo "${mode}" 2>/dev/null > /proc/sys/net/vsock/ns_mode; then
+                       log_host "ns_mode should be read-only but write succeeded"
+                       rc="${KSFT_FAIL}"
+                       continue
+               fi
+
+               if ! echo "${mode}" > /proc/sys/net/vsock/child_ns_mode; then
+                       log_host "child_ns_mode should be writable to ${mode}"
+                       rc="${KSFT_FAIL}"
+                       continue
+               fi
+       done
+
+       echo "${orig_mode}" > /proc/sys/net/vsock/child_ns_mode
+
+       return "${rc}"
+}
+
 test_vm_server_host_client() {
        if ! vm_vsock_test "init_ns" "server" 2 "${TEST_GUEST_PORT}"; then
                return "${KSFT_FAIL}"
@@ -592,6 +678,11 @@ run_shared_vm_tests() {
                        continue
                fi
 
+               if ! check_netns "${arg}"; then
+                       check_result "${KSFT_SKIP}" "${arg}"
+                       continue
+               fi
+
                run_shared_vm_test "${arg}"
                check_result "$?" "${arg}"
        done
@@ -645,6 +736,49 @@ run_shared_vm_test() {
        return "${rc}"
 }
 
+run_ns_tests() {
+       for arg in "${ARGS[@]}"; do
+               if shared_vm_test "${arg}"; then
+                       continue
+               fi
+
+               if ! check_netns "${arg}"; then
+                       check_result "${KSFT_SKIP}" "${arg}"
+                       continue
+               fi
+
+               add_namespaces
+
+               name=$(echo "${arg}" | awk '{ print $1 }')
+               log_host "Executing test_${name}"
+
+               host_oops_before=$(dmesg 2>/dev/null | grep -c -i 'Oops')
+               host_warn_before=$(dmesg --level=warn 2>/dev/null | grep -c -i 'vsock')
+               eval test_"${name}"
+               rc=$?
+
+               host_oops_after=$(dmesg 2>/dev/null | grep -c -i 'Oops')
+               if [[ "${host_oops_after}" -gt "${host_oops_before}" ]]; then
+                       echo "FAIL: kernel oops detected on host" | log_host
+                       check_result "${KSFT_FAIL}" "${name}"
+                       del_namespaces
+                       continue
+               fi
+
+               host_warn_after=$(dmesg --level=warn 2>/dev/null | grep -c -i 'vsock')
+               if [[ "${host_warn_after}" -gt "${host_warn_before}" ]]; then
+                       echo "FAIL: kernel warning detected on host" | log_host
+                       check_result "${KSFT_FAIL}" "${name}"
+                       del_namespaces
+                       continue
+               fi
+
+               check_result "${rc}" "${name}"
+
+               del_namespaces
+       done
+}
+
 BUILD=0
 QEMU="qemu-system-$(uname -m)"
 
@@ -690,6 +824,8 @@ if shared_vm_tests_requested "${ARGS[@]}"; then
        terminate_pidfiles "${pidfile}"
 fi
 
+run_ns_tests "${ARGS[@]}"
+
 echo "SUMMARY: PASS=${cnt_pass} SKIP=${cnt_skip} FAIL=${cnt_fail}"
 echo "Log: ${LOG}"