From d9cac93cd1bed31724f55857b934bcbbc8313b59 Mon Sep 17 00:00:00 2001 From: Bobby Eshleman Date: Sat, 8 Nov 2025 08:00:52 -0800 Subject: [PATCH 01/12] selftests/vsock: improve logging in vmtest.sh Improve usability of logging functions. Remove the test name prefix from logging functions so that logging calls can be made deeper into the call stack without passing down the test name or setting some global. Teach log function to accept a LOG_PREFIX variable to avoid unnecessary argument shifting. Remove log_setup() and instead use log_host(). The host/guest prefixes are useful to show whether a failure happened on the guest or host side, but "setup" doesn't really give additional useful information. Since all log_setup() calls happen on the host, lets just use log_host() instead. Signed-off-by: Bobby Eshleman Reviewed-by: Stefano Garzarella Link: https://patch.msgid.link/20251108-vsock-selftests-fixes-and-improvements-v4-1-d5e8d6c87289@meta.com Signed-off-by: Jakub Kicinski --- tools/testing/selftests/vsock/vmtest.sh | 71 +++++++++++-------------- 1 file changed, 30 insertions(+), 41 deletions(-) diff --git a/tools/testing/selftests/vsock/vmtest.sh b/tools/testing/selftests/vsock/vmtest.sh index 8ceeb8a7894f..bc16b13cdbe3 100755 --- a/tools/testing/selftests/vsock/vmtest.sh +++ b/tools/testing/selftests/vsock/vmtest.sh @@ -271,60 +271,51 @@ EOF host_wait_for_listener() { wait_for_listener "${TEST_HOST_PORT_LISTENER}" "${WAIT_PERIOD}" "${WAIT_PERIOD_MAX}" -} -__log_stdin() { - cat | awk '{ printf "%s:\t%s\n","'"${prefix}"'", $0 }' -} - -__log_args() { - echo "$*" | awk '{ printf "%s:\t%s\n","'"${prefix}"'", $0 }' } log() { - local prefix="$1" + local redirect + local prefix - shift - local redirect= if [[ ${VERBOSE} -eq 0 ]]; then redirect=/dev/null else redirect=/dev/stdout fi - if [[ "$#" -eq 0 ]]; then - __log_stdin | tee -a "${LOG}" > ${redirect} - else - __log_args "$@" | tee -a "${LOG}" > ${redirect} - fi -} + prefix="${LOG_PREFIX:-}" -log_setup() { - log "setup" "$@" + if [[ "$#" -eq 0 ]]; then + if [[ -n "${prefix}" ]]; then + awk -v prefix="${prefix}" '{printf "%s: %s\n", prefix, $0}' + else + cat + fi + else + if [[ -n "${prefix}" ]]; then + echo "${prefix}: " "$@" + else + echo "$@" + fi + fi | tee -a "${LOG}" > "${redirect}" } log_host() { - local testname=$1 - - shift - log "test:${testname}:host" "$@" + LOG_PREFIX=host log "$@" } log_guest() { - local testname=$1 - - shift - log "test:${testname}:guest" "$@" + LOG_PREFIX=guest log "$@" } test_vm_server_host_client() { - local testname="${FUNCNAME[0]#test_}" vm_ssh -- "${VSOCK_TEST}" \ --mode=server \ --control-port="${TEST_GUEST_PORT}" \ --peer-cid=2 \ - 2>&1 | log_guest "${testname}" & + 2>&1 | log_guest & vm_wait_for_listener "${TEST_GUEST_PORT}" @@ -332,18 +323,17 @@ test_vm_server_host_client() { --mode=client \ --control-host=127.0.0.1 \ --peer-cid="${VSOCK_CID}" \ - --control-port="${TEST_HOST_PORT}" 2>&1 | log_host "${testname}" + --control-port="${TEST_HOST_PORT}" 2>&1 | log_host return $? } test_vm_client_host_server() { - local testname="${FUNCNAME[0]#test_}" ${VSOCK_TEST} \ --mode "server" \ --control-port "${TEST_HOST_PORT_LISTENER}" \ - --peer-cid "${VSOCK_CID}" 2>&1 | log_host "${testname}" & + --peer-cid "${VSOCK_CID}" 2>&1 | log_host & host_wait_for_listener @@ -351,19 +341,18 @@ test_vm_client_host_server() { --mode=client \ --control-host=10.0.2.2 \ --peer-cid=2 \ - --control-port="${TEST_HOST_PORT_LISTENER}" 2>&1 | log_guest "${testname}" + --control-port="${TEST_HOST_PORT_LISTENER}" 2>&1 | log_guest return $? } test_vm_loopback() { - local testname="${FUNCNAME[0]#test_}" local port=60000 # non-forwarded local port vm_ssh -- "${VSOCK_TEST}" \ --mode=server \ --control-port="${port}" \ - --peer-cid=1 2>&1 | log_guest "${testname}" & + --peer-cid=1 2>&1 | log_guest & vm_wait_for_listener "${port}" @@ -371,7 +360,7 @@ test_vm_loopback() { --mode=client \ --control-host="127.0.0.1" \ --control-port="${port}" \ - --peer-cid=1 2>&1 | log_guest "${testname}" + --peer-cid=1 2>&1 | log_guest return $? } @@ -399,25 +388,25 @@ run_test() { host_oops_cnt_after=$(dmesg | grep -i 'Oops' | wc -l) if [[ ${host_oops_cnt_after} -gt ${host_oops_cnt_before} ]]; then - echo "FAIL: kernel oops detected on host" | log_host "${name}" + echo "FAIL: kernel oops detected on host" | log_host rc=$KSFT_FAIL fi host_warn_cnt_after=$(dmesg --level=warn | grep -c -i 'vsock') if [[ ${host_warn_cnt_after} -gt ${host_warn_cnt_before} ]]; then - echo "FAIL: kernel warning detected on host" | log_host "${name}" + echo "FAIL: kernel warning detected on host" | log_host rc=$KSFT_FAIL fi vm_oops_cnt_after=$(vm_ssh -- dmesg | grep -i 'Oops' | wc -l) if [[ ${vm_oops_cnt_after} -gt ${vm_oops_cnt_before} ]]; then - echo "FAIL: kernel oops detected on vm" | log_host "${name}" + echo "FAIL: kernel oops detected on vm" | log_host rc=$KSFT_FAIL fi vm_warn_cnt_after=$(vm_ssh -- dmesg --level=warn | grep -c -i 'vsock') if [[ ${vm_warn_cnt_after} -gt ${vm_warn_cnt_before} ]]; then - echo "FAIL: kernel warning detected on vm" | log_host "${name}" + echo "FAIL: kernel warning detected on vm" | log_host rc=$KSFT_FAIL fi @@ -452,10 +441,10 @@ handle_build echo "1..${#ARGS[@]}" -log_setup "Booting up VM" +log_host "Booting up VM" vm_start vm_wait_for_ssh -log_setup "VM booted up" +log_host "VM booted up" cnt_pass=0 cnt_fail=0 From 2ed3ce7efbd2854fb7eb76627ccec92362b2345b Mon Sep 17 00:00:00 2001 From: Bobby Eshleman Date: Sat, 8 Nov 2025 08:00:53 -0800 Subject: [PATCH 02/12] selftests/vsock: make wait_for_listener() work even if pipefail is on Rewrite wait_for_listener()'s pattern matching to avoid tripping the if-condition when pipefail is on. awk doesn't gracefully handle SIGPIPE with a non-zero exit code, so grep exiting upon finding a match causes false-positives when the pipefail option is used (grep exits, SIGPIPE emits, and awk complains with a non-zero exit code). Instead, move all of the pattern matching into awk so that SIGPIPE cannot happen and the correct exit code is returned. Signed-off-by: Bobby Eshleman Reviewed-by: Stefano Garzarella Link: https://patch.msgid.link/20251108-vsock-selftests-fixes-and-improvements-v4-2-d5e8d6c87289@meta.com Signed-off-by: Jakub Kicinski --- tools/testing/selftests/vsock/vmtest.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/vsock/vmtest.sh b/tools/testing/selftests/vsock/vmtest.sh index bc16b13cdbe3..01ce16523afb 100755 --- a/tools/testing/selftests/vsock/vmtest.sh +++ b/tools/testing/selftests/vsock/vmtest.sh @@ -251,9 +251,11 @@ wait_for_listener() # for tcp protocol additionally check the socket state [ "${protocol}" = "tcp" ] && pattern="${pattern}0A" + for i in $(seq "${max_intervals}"); do - if awk '{print $2" "$4}' /proc/net/"${protocol}"* | \ - grep -q "${pattern}"; then + if awk -v pattern="${pattern}" \ + 'BEGIN {rc=1} $2" "$4 ~ pattern {rc=0} END {exit rc}' \ + /proc/net/"${protocol}"*; then break fi sleep "${interval}" From 4f76ff14d3d96a21574e66222041757d679a8a10 Mon Sep 17 00:00:00 2001 From: Bobby Eshleman Date: Sat, 8 Nov 2025 08:00:54 -0800 Subject: [PATCH 03/12] selftests/vsock: reuse logic for vsock_test through wrapper functions Add wrapper functions vm_vsock_test() and host_vsock_test() to invoke the vsock_test binary. This encapsulates several items of repeat logic, such as waiting for the server to reach listening state and enabling/disabling the bash option pipefail to avoid pipe-style logging from hiding failures. Signed-off-by: Bobby Eshleman Reviewed-by: Stefano Garzarella Link: https://patch.msgid.link/20251108-vsock-selftests-fixes-and-improvements-v4-3-d5e8d6c87289@meta.com Signed-off-by: Jakub Kicinski --- tools/testing/selftests/vsock/vmtest.sh | 135 +++++++++++++++++------- 1 file changed, 95 insertions(+), 40 deletions(-) diff --git a/tools/testing/selftests/vsock/vmtest.sh b/tools/testing/selftests/vsock/vmtest.sh index 01ce16523afb..3bccd9b84e4a 100755 --- a/tools/testing/selftests/vsock/vmtest.sh +++ b/tools/testing/selftests/vsock/vmtest.sh @@ -272,8 +272,81 @@ EOF } host_wait_for_listener() { - wait_for_listener "${TEST_HOST_PORT_LISTENER}" "${WAIT_PERIOD}" "${WAIT_PERIOD_MAX}" + local port=$1 + wait_for_listener "${port}" "${WAIT_PERIOD}" "${WAIT_PERIOD_MAX}" +} + +vm_vsock_test() { + local host=$1 + local cid=$2 + local port=$3 + local rc + + # log output and use pipefail to respect vsock_test errors + set -o pipefail + if [[ "${host}" != server ]]; then + vm_ssh -- "${VSOCK_TEST}" \ + --mode=client \ + --control-host="${host}" \ + --peer-cid="${cid}" \ + --control-port="${port}" \ + 2>&1 | log_guest + rc=$? + else + vm_ssh -- "${VSOCK_TEST}" \ + --mode=server \ + --peer-cid="${cid}" \ + --control-port="${port}" \ + 2>&1 | log_guest & + rc=$? + + if [[ $rc -ne 0 ]]; then + set +o pipefail + return $rc + fi + + vm_wait_for_listener "${port}" + rc=$? + fi + set +o pipefail + + return $rc +} + +host_vsock_test() { + local host=$1 + local cid=$2 + local port=$3 + local rc + + # log output and use pipefail to respect vsock_test errors + set -o pipefail + if [[ "${host}" != server ]]; then + ${VSOCK_TEST} \ + --mode=client \ + --peer-cid="${cid}" \ + --control-host="${host}" \ + --control-port="${port}" 2>&1 | log_host + rc=$? + else + ${VSOCK_TEST} \ + --mode=server \ + --peer-cid="${cid}" \ + --control-port="${port}" 2>&1 | log_host & + rc=$? + + if [[ $rc -ne 0 ]]; then + set +o pipefail + return $rc + fi + + host_wait_for_listener "${port}" + rc=$? + fi + set +o pipefail + + return $rc } log() { @@ -312,59 +385,41 @@ log_guest() { } test_vm_server_host_client() { + if ! vm_vsock_test "server" 2 "${TEST_GUEST_PORT}"; then + return "${KSFT_FAIL}" + fi - vm_ssh -- "${VSOCK_TEST}" \ - --mode=server \ - --control-port="${TEST_GUEST_PORT}" \ - --peer-cid=2 \ - 2>&1 | log_guest & + if ! host_vsock_test "127.0.0.1" "${VSOCK_CID}" "${TEST_HOST_PORT}"; then + return "${KSFT_FAIL}" + fi - vm_wait_for_listener "${TEST_GUEST_PORT}" - - ${VSOCK_TEST} \ - --mode=client \ - --control-host=127.0.0.1 \ - --peer-cid="${VSOCK_CID}" \ - --control-port="${TEST_HOST_PORT}" 2>&1 | log_host - - return $? + return "${KSFT_PASS}" } test_vm_client_host_server() { + if ! host_vsock_test "server" "${VSOCK_CID}" "${TEST_HOST_PORT_LISTENER}"; then + return "${KSFT_FAIL}" + fi - ${VSOCK_TEST} \ - --mode "server" \ - --control-port "${TEST_HOST_PORT_LISTENER}" \ - --peer-cid "${VSOCK_CID}" 2>&1 | log_host & + if ! vm_vsock_test "10.0.2.2" 2 "${TEST_HOST_PORT_LISTENER}"; then + return "${KSFT_FAIL}" + fi - host_wait_for_listener - - vm_ssh -- "${VSOCK_TEST}" \ - --mode=client \ - --control-host=10.0.2.2 \ - --peer-cid=2 \ - --control-port="${TEST_HOST_PORT_LISTENER}" 2>&1 | log_guest - - return $? + return "${KSFT_PASS}" } test_vm_loopback() { local port=60000 # non-forwarded local port - vm_ssh -- "${VSOCK_TEST}" \ - --mode=server \ - --control-port="${port}" \ - --peer-cid=1 2>&1 | log_guest & + if ! vm_vsock_test "server" 1 "${port}"; then + return "${KSFT_FAIL}" + fi - vm_wait_for_listener "${port}" + if ! vm_vsock_test "127.0.0.1" 1 "${port}"; then + return "${KSFT_FAIL}" + fi - vm_ssh -- "${VSOCK_TEST}" \ - --mode=client \ - --control-host="127.0.0.1" \ - --control-port="${port}" \ - --peer-cid=1 2>&1 | log_guest - - return $? + return "${KSFT_PASS}" } run_test() { From ac8997e943bc035171e76c8457db6fa973c8a9ab Mon Sep 17 00:00:00 2001 From: Bobby Eshleman Date: Sat, 8 Nov 2025 08:00:55 -0800 Subject: [PATCH 04/12] selftests/vsock: avoid multi-VM pidfile collisions with QEMU Change QEMU to use generated pidfile names instead of just a single globally-defined pidfile. This allows multiple QEMU instances to co-exist with different pidfiles. This is required for future tests that use multiple VMs to check for CID collissions. Additionally, this also places the burden of killing the QEMU process and cleaning up the pidfile on the caller of vm_start(). To help with this, a function terminate_pidfiles() is introduced that callers use to perform the cleanup. The terminate_pidfiles() function supports multiple pidfile removals because future patches will need to process two pidfiles at a time. Change QEMU_OPTS to be initialized inside the vm_start(). This allows the generated pidfile to be passed to the string assignment, and prepares for future vm-specific options as well (e.g., cid). Signed-off-by: Bobby Eshleman Reviewed-by: Stefano Garzarella Link: https://patch.msgid.link/20251108-vsock-selftests-fixes-and-improvements-v4-4-d5e8d6c87289@meta.com Signed-off-by: Jakub Kicinski --- tools/testing/selftests/vsock/vmtest.sh | 62 +++++++++++++++++-------- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/tools/testing/selftests/vsock/vmtest.sh b/tools/testing/selftests/vsock/vmtest.sh index 3bccd9b84e4a..13b685280a67 100755 --- a/tools/testing/selftests/vsock/vmtest.sh +++ b/tools/testing/selftests/vsock/vmtest.sh @@ -23,7 +23,8 @@ readonly VSOCK_CID=1234 readonly WAIT_PERIOD=3 readonly WAIT_PERIOD_MAX=60 readonly WAIT_TOTAL=$(( WAIT_PERIOD * WAIT_PERIOD_MAX )) -readonly QEMU_PIDFILE=$(mktemp /tmp/qemu_vsock_vmtest_XXXX.pid) +readonly PIDFILE_TEMPLATE=/tmp/vsock_vmtest_XXXX.pid +declare -A PIDFILES # virtme-ng offers a netdev for ssh when using "--ssh", but we also need a # control port forwarded for vsock_test. Because virtme-ng doesn't support @@ -33,12 +34,6 @@ readonly QEMU_PIDFILE=$(mktemp /tmp/qemu_vsock_vmtest_XXXX.pid) # add the kernel cmdline options that virtme-init uses to setup the interface. readonly QEMU_TEST_PORT_FWD="hostfwd=tcp::${TEST_HOST_PORT}-:${TEST_GUEST_PORT}" readonly QEMU_SSH_PORT_FWD="hostfwd=tcp::${SSH_HOST_PORT}-:${SSH_GUEST_PORT}" -readonly QEMU_OPTS="\ - -netdev user,id=n0,${QEMU_TEST_PORT_FWD},${QEMU_SSH_PORT_FWD} \ - -device virtio-net-pci,netdev=n0 \ - -device vhost-vsock-pci,guest-cid=${VSOCK_CID} \ - --pidfile ${QEMU_PIDFILE} \ -" readonly KERNEL_CMDLINE="\ virtme.dhcp net.ifnames=0 biosdevname=0 \ virtme.ssh virtme_ssh_channel=tcp virtme_ssh_user=$USER \ @@ -90,15 +85,7 @@ vm_ssh() { } cleanup() { - if [[ -s "${QEMU_PIDFILE}" ]]; then - pkill -SIGTERM -F "${QEMU_PIDFILE}" > /dev/null 2>&1 - fi - - # If failure occurred during or before qemu start up, then we need - # to clean this up ourselves. - if [[ -e "${QEMU_PIDFILE}" ]]; then - rm "${QEMU_PIDFILE}" - fi + terminate_pidfiles "${!PIDFILES[@]}" } check_args() { @@ -188,10 +175,37 @@ handle_build() { popd &>/dev/null } +create_pidfile() { + local pidfile + + pidfile=$(mktemp "${PIDFILE_TEMPLATE}") + PIDFILES["${pidfile}"]=1 + + echo "${pidfile}" +} + +terminate_pidfiles() { + local pidfile + + for pidfile in "$@"; do + if [[ -s "${pidfile}" ]]; then + pkill -SIGTERM -F "${pidfile}" > /dev/null 2>&1 + fi + + if [[ -e "${pidfile}" ]]; then + rm -f "${pidfile}" + fi + + unset "PIDFILES[${pidfile}]" + done +} + vm_start() { + local pidfile=$1 local logfile=/dev/null local verbose_opt="" local kernel_opt="" + local qemu_opts="" local qemu qemu=$(command -v "${QEMU}") @@ -201,6 +215,13 @@ vm_start() { logfile=/dev/stdout fi + qemu_opts="\ + -netdev user,id=n0,${QEMU_TEST_PORT_FWD},${QEMU_SSH_PORT_FWD} \ + -device virtio-net-pci,netdev=n0 \ + -device vhost-vsock-pci,guest-cid=${VSOCK_CID} \ + --pidfile ${pidfile} + " + if [[ "${BUILD}" -eq 1 ]]; then kernel_opt="${KERNEL_CHECKOUT}" fi @@ -209,14 +230,14 @@ vm_start() { --run \ ${kernel_opt} \ ${verbose_opt} \ - --qemu-opts="${QEMU_OPTS}" \ + --qemu-opts="${qemu_opts}" \ --qemu="${qemu}" \ --user root \ --append "${KERNEL_CMDLINE}" \ --rw &> ${logfile} & if ! timeout ${WAIT_TOTAL} \ - bash -c 'while [[ ! -s '"${QEMU_PIDFILE}"' ]]; do sleep 1; done; exit 0'; then + bash -c 'while [[ ! -s '"${pidfile}"' ]]; do sleep 1; done; exit 0'; then die "failed to boot VM" fi } @@ -499,7 +520,8 @@ handle_build echo "1..${#ARGS[@]}" log_host "Booting up VM" -vm_start +pidfile="$(create_pidfile)" +vm_start "${pidfile}" vm_wait_for_ssh log_host "VM booted up" @@ -523,6 +545,8 @@ for arg in "${ARGS[@]}"; do cnt_total=$(( cnt_total + 1 )) done +terminate_pidfiles "${pidfile}" + echo "SUMMARY: PASS=${cnt_pass} SKIP=${cnt_skip} FAIL=${cnt_fail}" echo "Log: ${LOG}" From c7df4adc0679afa2da47c13cbf7960a26e0fe7cb Mon Sep 17 00:00:00 2001 From: Bobby Eshleman Date: Sat, 8 Nov 2025 08:00:56 -0800 Subject: [PATCH 05/12] selftests/vsock: do not unconditionally die if qemu fails If QEMU fails to boot, then set the returncode (via timeout) instead of unconditionally dying. This is in preparation for tests that expect QEMU to fail to boot. In that case, we just want to know if the boot failed or not so we can test the pass/fail criteria, and continue executing the next test. Reviewed-by: Simon Horman Signed-off-by: Bobby Eshleman Reviewed-by: Stefano Garzarella Link: https://patch.msgid.link/20251108-vsock-selftests-fixes-and-improvements-v4-5-d5e8d6c87289@meta.com Signed-off-by: Jakub Kicinski --- tools/testing/selftests/vsock/vmtest.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/vsock/vmtest.sh b/tools/testing/selftests/vsock/vmtest.sh index 13b685280a67..6889bdb8a31c 100755 --- a/tools/testing/selftests/vsock/vmtest.sh +++ b/tools/testing/selftests/vsock/vmtest.sh @@ -236,10 +236,8 @@ vm_start() { --append "${KERNEL_CMDLINE}" \ --rw &> ${logfile} & - if ! timeout ${WAIT_TOTAL} \ - bash -c 'while [[ ! -s '"${pidfile}"' ]]; do sleep 1; done; exit 0'; then - die "failed to boot VM" - fi + timeout "${WAIT_TOTAL}" \ + bash -c 'while [[ ! -s '"${pidfile}"' ]]; do sleep 1; done; exit 0' } vm_wait_for_ssh() { From 9e2ad0bc3640c384799c91da0b8b794c672da4d3 Mon Sep 17 00:00:00 2001 From: Bobby Eshleman Date: Sat, 8 Nov 2025 08:00:57 -0800 Subject: [PATCH 06/12] selftests/vsock: speed up tests by reducing the QEMU pidfile timeout Reduce the time waiting for the QEMU pidfile from three minutes to five seconds. The three minute time window was chosen to make sure QEMU had enough time to fully boot up. This, however, is an unreasonably long delay for QEMU to write the pidfile, which happens earlier when the QEMU process starts (not after VM boot). The three minute delay becomes noticeably wasteful in future tests that expect QEMU to fail and wait a full three minutes for a pidfile that will never exist. Reviewed-by: Simon Horman Signed-off-by: Bobby Eshleman Reviewed-by: Stefano Garzarella Link: https://patch.msgid.link/20251108-vsock-selftests-fixes-and-improvements-v4-6-d5e8d6c87289@meta.com Signed-off-by: Jakub Kicinski --- tools/testing/selftests/vsock/vmtest.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/vsock/vmtest.sh b/tools/testing/selftests/vsock/vmtest.sh index 6889bdb8a31c..bd231467c66b 100755 --- a/tools/testing/selftests/vsock/vmtest.sh +++ b/tools/testing/selftests/vsock/vmtest.sh @@ -22,7 +22,7 @@ readonly SSH_HOST_PORT=2222 readonly VSOCK_CID=1234 readonly WAIT_PERIOD=3 readonly WAIT_PERIOD_MAX=60 -readonly WAIT_TOTAL=$(( WAIT_PERIOD * WAIT_PERIOD_MAX )) +readonly WAIT_QEMU=5 readonly PIDFILE_TEMPLATE=/tmp/vsock_vmtest_XXXX.pid declare -A PIDFILES @@ -236,7 +236,7 @@ vm_start() { --append "${KERNEL_CMDLINE}" \ --rw &> ${logfile} & - timeout "${WAIT_TOTAL}" \ + timeout "${WAIT_QEMU}" \ bash -c 'while [[ ! -s '"${pidfile}"' ]]; do sleep 1; done; exit 0' } From 7fea50dff98812db3ee4ddd96405c3298d9aa4cb Mon Sep 17 00:00:00 2001 From: Bobby Eshleman Date: Sat, 8 Nov 2025 08:00:58 -0800 Subject: [PATCH 07/12] selftests/vsock: add check_result() for pass/fail counting Add check_result() function to reuse logic for incrementing the pass/fail counters. This function will get used by different callers as we add different types of tests in future patches (namely, namespace and non-namespace tests will be called at different places, and re-use this function). Reviewed-by: Simon Horman Signed-off-by: Bobby Eshleman Reviewed-by: Stefano Garzarella Link: https://patch.msgid.link/20251108-vsock-selftests-fixes-and-improvements-v4-7-d5e8d6c87289@meta.com Signed-off-by: Jakub Kicinski --- tools/testing/selftests/vsock/vmtest.sh | 32 ++++++++++++++++--------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/tools/testing/selftests/vsock/vmtest.sh b/tools/testing/selftests/vsock/vmtest.sh index bd231467c66b..2dd9bbb8c4a9 100755 --- a/tools/testing/selftests/vsock/vmtest.sh +++ b/tools/testing/selftests/vsock/vmtest.sh @@ -79,6 +79,26 @@ die() { exit "${KSFT_FAIL}" } +check_result() { + local rc arg + + rc=$1 + arg=$2 + + cnt_total=$(( cnt_total + 1 )) + + if [[ ${rc} -eq ${KSFT_PASS} ]]; then + cnt_pass=$(( cnt_pass + 1 )) + echo "ok ${cnt_total} ${arg}" + elif [[ ${rc} -eq ${KSFT_SKIP} ]]; then + cnt_skip=$(( cnt_skip + 1 )) + echo "ok ${cnt_total} ${arg} # SKIP" + elif [[ ${rc} -eq ${KSFT_FAIL} ]]; then + cnt_fail=$(( cnt_fail + 1 )) + echo "not ok ${cnt_total} ${arg} # exit=${rc}" + fi +} + vm_ssh() { ssh -q -o UserKnownHostsFile=/dev/null -p ${SSH_HOST_PORT} localhost "$@" return $? @@ -530,17 +550,7 @@ cnt_total=0 for arg in "${ARGS[@]}"; do run_test "${arg}" rc=$? - if [[ ${rc} -eq $KSFT_PASS ]]; then - cnt_pass=$(( cnt_pass + 1 )) - echo "ok ${cnt_total} ${arg}" - elif [[ ${rc} -eq $KSFT_SKIP ]]; then - cnt_skip=$(( cnt_skip + 1 )) - echo "ok ${cnt_total} ${arg} # SKIP" - elif [[ ${rc} -eq $KSFT_FAIL ]]; then - cnt_fail=$(( cnt_fail + 1 )) - echo "not ok ${cnt_total} ${arg} # exit=$rc" - fi - cnt_total=$(( cnt_total + 1 )) + check_result "${rc}" "${arg}" done terminate_pidfiles "${pidfile}" From d13fb04a4bf0811b593843f7d2385fac5cf313c8 Mon Sep 17 00:00:00 2001 From: Bobby Eshleman Date: Sat, 8 Nov 2025 08:00:59 -0800 Subject: [PATCH 08/12] selftests/vsock: identify and execute tests that can re-use VM In preparation for future patches that introduce tests that cannot re-use the same VM, add functions to identify those that *can* re-use a VM. By continuing to re-use the same VM for these tests we can save time by avoiding the delay of booting a VM for every test. Reviewed-by: Simon Horman Signed-off-by: Bobby Eshleman Reviewed-by: Stefano Garzarella Link: https://patch.msgid.link/20251108-vsock-selftests-fixes-and-improvements-v4-8-d5e8d6c87289@meta.com Signed-off-by: Jakub Kicinski --- tools/testing/selftests/vsock/vmtest.sh | 63 ++++++++++++++++++++----- 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/tools/testing/selftests/vsock/vmtest.sh b/tools/testing/selftests/vsock/vmtest.sh index 2dd9bbb8c4a9..a1c2969c44b6 100755 --- a/tools/testing/selftests/vsock/vmtest.sh +++ b/tools/testing/selftests/vsock/vmtest.sh @@ -46,6 +46,8 @@ readonly TEST_DESCS=( "Run vsock_test using the loopback transport in the VM." ) +readonly USE_SHARED_VM=(vm_server_host_client vm_client_host_server vm_loopback) + VERBOSE=0 usage() { @@ -461,7 +463,44 @@ test_vm_loopback() { return "${KSFT_PASS}" } -run_test() { +shared_vm_test() { + local tname + + tname="${1}" + + for testname in "${USE_SHARED_VM[@]}"; do + if [[ "${tname}" == "${testname}" ]]; then + return 0 + fi + done + + return 1 +} + +shared_vm_tests_requested() { + for arg in "$@"; do + if shared_vm_test "${arg}"; then + return 0 + fi + done + + return 1 +} + +run_shared_vm_tests() { + local arg + + for arg in "$@"; do + if ! shared_vm_test "${arg}"; then + continue + fi + + run_shared_vm_test "${arg}" + check_result "$?" "${arg}" + done +} + +run_shared_vm_test() { local host_oops_cnt_before local host_warn_cnt_before local vm_oops_cnt_before @@ -537,23 +576,21 @@ handle_build echo "1..${#ARGS[@]}" -log_host "Booting up VM" -pidfile="$(create_pidfile)" -vm_start "${pidfile}" -vm_wait_for_ssh -log_host "VM booted up" - cnt_pass=0 cnt_fail=0 cnt_skip=0 cnt_total=0 -for arg in "${ARGS[@]}"; do - run_test "${arg}" - rc=$? - check_result "${rc}" "${arg}" -done -terminate_pidfiles "${pidfile}" +if shared_vm_tests_requested "${ARGS[@]}"; then + log_host "Booting up VM" + pidfile="$(create_pidfile)" + vm_start "${pidfile}" + vm_wait_for_ssh + log_host "VM booted up" + + run_shared_vm_tests "${ARGS[@]}" + terminate_pidfiles "${pidfile}" +fi echo "SUMMARY: PASS=${cnt_pass} SKIP=${cnt_skip} FAIL=${cnt_fail}" echo "Log: ${LOG}" From 592e3d14cecf8ffebe718586f02007a082aa3193 Mon Sep 17 00:00:00 2001 From: Bobby Eshleman Date: Sat, 8 Nov 2025 08:01:00 -0800 Subject: [PATCH 09/12] selftests/vsock: add BUILD=0 definition Add the definition for BUILD and initialize it to zero. This avoids 'bash -u vmtest.sh` from throwing 'unbound variable' when BUILD is not set to 1 and is later checked for its value. Signed-off-by: Bobby Eshleman Reviewed-by: Stefano Garzarella Link: https://patch.msgid.link/20251108-vsock-selftests-fixes-and-improvements-v4-9-d5e8d6c87289@meta.com Signed-off-by: Jakub Kicinski --- tools/testing/selftests/vsock/vmtest.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/testing/selftests/vsock/vmtest.sh b/tools/testing/selftests/vsock/vmtest.sh index a1c2969c44b6..e961b65b4c6e 100755 --- a/tools/testing/selftests/vsock/vmtest.sh +++ b/tools/testing/selftests/vsock/vmtest.sh @@ -548,6 +548,7 @@ run_shared_vm_test() { return "${rc}" } +BUILD=0 QEMU="qemu-system-$(uname -m)" while getopts :hvsq:b o From 67422ef38f8cc1116c28a74c144c1ab3cbbdb3bb Mon Sep 17 00:00:00 2001 From: Bobby Eshleman Date: Sat, 8 Nov 2025 08:01:01 -0800 Subject: [PATCH 10/12] selftests/vsock: add 1.37 to tested virtme-ng versions Testing with 1.37 shows all tests passing but emits the warning: warning: vng version 'virtme-ng 1.37' has not been tested and may not function properly. The following versions have been tested: 1.33 1.36 This patch adds 1.37 to the virtme-ng versions to get rid of the above warning. Reviewed-by: Simon Horman Reviewed-by: Stefano Garzarella Signed-off-by: Bobby Eshleman Link: https://patch.msgid.link/20251108-vsock-selftests-fixes-and-improvements-v4-10-d5e8d6c87289@meta.com Signed-off-by: Jakub Kicinski --- tools/testing/selftests/vsock/vmtest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/vsock/vmtest.sh b/tools/testing/selftests/vsock/vmtest.sh index e961b65b4c6e..b611172da09e 100755 --- a/tools/testing/selftests/vsock/vmtest.sh +++ b/tools/testing/selftests/vsock/vmtest.sh @@ -156,7 +156,7 @@ check_vng() { local version local ok - tested_versions=("1.33" "1.36") + tested_versions=("1.33" "1.36" "1.37") version="$(vng --version)" ok=0 From 338c5ddf4c889926e931067418797cd1711dd939 Mon Sep 17 00:00:00 2001 From: Bobby Eshleman Date: Sat, 8 Nov 2025 08:01:02 -0800 Subject: [PATCH 11/12] selftests/vsock: add vsock_loopback module loading Add vsock_loopback module loading to the loopback test so that vmtest.sh can be used for kernels built with loopback as a module. This is not technically a fix as kselftest expects loopback to be built-in already (defined in selftests/vsock/config). This is useful only for using vmtest.sh outside of kselftest. Reviewed-by: Stefano Garzarella Signed-off-by: Bobby Eshleman Link: https://patch.msgid.link/20251108-vsock-selftests-fixes-and-improvements-v4-11-d5e8d6c87289@meta.com Signed-off-by: Jakub Kicinski --- tools/testing/selftests/vsock/vmtest.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/testing/selftests/vsock/vmtest.sh b/tools/testing/selftests/vsock/vmtest.sh index b611172da09e..42e155b45602 100755 --- a/tools/testing/selftests/vsock/vmtest.sh +++ b/tools/testing/selftests/vsock/vmtest.sh @@ -452,6 +452,8 @@ test_vm_client_host_server() { test_vm_loopback() { local port=60000 # non-forwarded local port + vm_ssh -- modprobe vsock_loopback &> /dev/null || : + if ! vm_vsock_test "server" 1 "${port}"; then return "${KSFT_FAIL}" fi From 99f932c9050911fab8ac82455fc4d74b1c0200af Mon Sep 17 00:00:00 2001 From: Bobby Eshleman Date: Sat, 8 Nov 2025 08:01:03 -0800 Subject: [PATCH 12/12] selftests/vsock: disable shellcheck SC2317 and SC2119 Disable shellcheck rules SC2317 and SC2119. These rules are being triggered due to false positives. For SC2317, many `return "${KSFT_PASS}"` lines are reported as unreachable, even though they are executed during normal runs. For SC2119, the fact that log_guest/log_host accept either stdin or arguments triggers SC2119, despite being valid. Signed-off-by: Bobby Eshleman Reviewed-by: Stefano Garzarella Link: https://patch.msgid.link/20251108-vsock-selftests-fixes-and-improvements-v4-12-d5e8d6c87289@meta.com Signed-off-by: Jakub Kicinski --- tools/testing/selftests/vsock/vmtest.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/testing/selftests/vsock/vmtest.sh b/tools/testing/selftests/vsock/vmtest.sh index 42e155b45602..c7b270dd77a9 100755 --- a/tools/testing/selftests/vsock/vmtest.sh +++ b/tools/testing/selftests/vsock/vmtest.sh @@ -7,6 +7,8 @@ # * virtme-ng # * busybox-static (used by virtme-ng) # * qemu (used by virtme-ng) +# +# shellcheck disable=SC2317,SC2119 readonly SCRIPT_DIR="$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)" readonly KERNEL_CHECKOUT=$(realpath "${SCRIPT_DIR}"/../../../../)