From: Bobby Eshleman <bobbyeshleman@gmail.com>
To: netdev-bot+sashiko@kernel.org
Cc: sgarzare@redhat.com, davem@davemloft.net, edumazet@google.com,
kuba@kernel.org, pabeni@redhat.com, horms@kernel.org,
corbet@lwn.net, skhan@linuxfoundation.org, stefanha@redhat.com,
mst@redhat.com, jasowangio@gmail.com, xuanzhuo@linux.alibaba.com,
eperezma@redhat.com, shuah@kernel.org, rdunlap@infradead.org,
donald.hunter@gmail.com, virtualization@lists.linux.dev,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-doc@vger.kernel.org, kvm@vger.kernel.org,
linux-kselftest@vger.kernel.org, sargun@sargun.me,
jlinbox@meta.com, sdf.kernel@gmail.com, bobbyeshleman@meta.com
Subject: Re: [PATCH net-next v2 5/6] selftests/vsock: test the guest vsock device network namespace
Date: Wed, 23 Sep 2026 17:42:56 -0700 [thread overview]
Message-ID: <arRyEMltRgwxJIbI@devvm29614.prn0.facebook.com> (raw)
In-Reply-To: <179019126563.2160803.9263469000405874269@kernel.org>
On Wed, Sep 23, 2026 at 07:21:05PM +0000, netdev-bot+sashiko@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 6 potential
> issue(s) to consider.
>
> Critical: 0 · High: 0 · Medium: 4 · Low: 2 (1)
>
> If you believe none of the issues are legitimate, please reply to each
> issue of Medium severity or higher and explain why the AI is wrong.
> If any of them are legitimate and you plan to respin, please let patchwork
> know by including "pw-bot: cr" as a separate line at the end of your reply
> (one such reply per series is enough).
>
> - [Medium] check_deps() in tools/testing/selftests/vsock/vmtest.sh now
> hard-requires two files that live outside the selftests directory —…
> - [Medium] vm_ns_start() (vmtest.sh:588-596) reports success even when
> the guest-side namespace setup fails.
> - [Medium] test_ns_guest_assign_g2h_netns_old_conn_send_fails()
> (vmtest.sh:1594-1653) orders three concurrent actors — the guest…
> - [Medium] host_send_to_guest() (vmtest.sh:1582-1591) and
> test_ns_guest_assign_g2h_netns_old_conn_send_fails()…
> - [Low] guest_send_to_host() (vmtest.sh:1568) and host_send_to_guest()
> (vmtest.sh:1591) release their background listeners with…
> - [Low] vm_ns_start() (vmtest.sh:594-595) backgrounds `unshare -n sleep
> infinity` in the guest and immediately echoes `$!`, with no…
>
> Pre-existing issues:
> - [Low] The new helpers splice an unquoted path into a string handed to
> an inner shell: `timeout "${WAIT_PERIOD}" bash -c 'while [[ !
>
> --
>
> selftests/vsock: test the guest vsock device network namespace
>
> This adds six new shared-VM tests to vmtest.sh that exercise assigning the
> guest vsock device to a network namespace, using tools/net/ynl/pyynl/cli.py
> plus Documentation/netlink/specs/vsock.yaml to drive dev-netns-set. The
> dependency checks in check_deps() gain unshare, python3 and PyYAML.
>
> A few questions about the new harness code below.
>
> > diff --git a/tools/testing/selftests/vsock/vmtest.sh b/tools/testing/selftests/vsock/vmtest.sh
> > index 310dfc2a39ad5..e94cc2fd90ccd 100755
> > --- a/tools/testing/selftests/vsock/vmtest.sh
> > +++ b/tools/testing/selftests/vsock/vmtest.sh
> > @@ -17,6 +17,8 @@ readonly KERNEL_CHECKOUT=$(realpath "${SCRIPT_DIR}"/../../../../)
> > source "${SCRIPT_DIR}"/../kselftest/ktap_helpers.sh
> >
> > readonly VSOCK_TEST="${SCRIPT_DIR}"/vsock_test
> > +readonly YNL_CLI="${KERNEL_CHECKOUT}"/tools/net/ynl/pyynl/cli.py
> > +readonly VSOCK_SPEC="${KERNEL_CHECKOUT}"/Documentation/netlink/specs/vsock.yaml
>
> [ ... ]
>
> > @@ -314,6 +347,18 @@ check_deps() {
> > printf " Please build the kselftest vsock target.\n"
> > exit "${KSFT_SKIP}"
> > fi
> > +
> > + if ! python3 -c "import yaml" &>/dev/null; then
> > + echo -e "skip: python3 yaml module not found!\n"
> > + exit "${KSFT_SKIP}"
> > + fi
> > +
> > + for dep in "${YNL_CLI}" "${VSOCK_SPEC}"; do
> > + if [[ ! -r "${dep}" ]]; then
> > + printf "skip: %s not found!\n" "${dep}"
> > + exit "${KSFT_SKIP}"
> > + fi
> > + done
> > }
>
> [Severity: Medium]
> Does this turn the whole suite into a skip when vmtest.sh is run from an
> installed tree? Both new dependencies are anchored at KERNEL_CHECKOUT
> (SCRIPT_DIR/../../../../), so they only resolve inside a kernel source
> tree, and check_deps() exits before any test is selected:
>
> readonly YNL_CLI="${KERNEL_CHECKOUT}"/tools/net/ynl/pyynl/cli.py
> readonly VSOCK_SPEC="${KERNEL_CHECKOUT}"/Documentation/netlink/specs/vsock.yaml
>
> tools/testing/selftests/vsock/Makefile still ships only:
>
> TEST_PROGS += vmtest.sh
> TEST_GEN_FILES := vsock_test
>
> There is no TEST_FILES entry for cli.py, its pyynl/lib package, or
> vsock.yaml, so after "make -C tools/testing/selftests install" the new
> check can never be satisfied, and the 24 pre-existing tests that do not
> need ynl at all are skipped too. Would adding these to TEST_FILES (the way
> tools/testing/selftests/net/ovpn/Makefile lists
> ../../../../net/ynl/pyynl/cli.py) work here, or alternatively limiting the
> skip to the six new tests instead of the whole script?
>
> [ ... ]
valid, will fix.
>
> > @@ -528,6 +584,59 @@ vm_wait_for_ssh() {
> > done
> > }
> >
> > +# Create a local mode namespace in the VM and echo the pid holding it open.
> > +vm_ns_start() {
> > + local ns=$1
> > +
> > + vm_ssh "${ns}" -- \
> > + "echo local > /proc/sys/net/vsock/child_ns_mode" &>/dev/null
> > +
> > + vm_ssh "${ns}" -- "unshare -n sleep infinity" \
> > + '>/dev/null 2>&1 & echo $!'
> > +}
>
> [Severity: Medium]
> Can vm_ns_start() ever report failure? The remote shell runs
>
> unshare -n sleep infinity >/dev/null 2>&1 & echo $!
>
> so the pid is printed at fork time, regardless of whether unshare actually
> ran (missing binary, missing privilege, immediate exit). The write to
> /proc/sys/net/vsock/child_ns_mode is also discarded with &>/dev/null and
> its status is never looked at.
>
> That makes the guard used by all six new tests unable to detect the
> condition its message names:
>
> nspid=$(vm_ns_start "init_ns")
> if [[ -z "${nspid}" ]]; then
> log_host "failed to create a namespace inside the guest"
> return "${KSFT_FAIL}"
> fi
valid, will fix.
>
> For the two negative tests, test_ns_guest_local_connect_to_host_fails()
> and test_ns_guest_assign_g2h_netns_init_ns_connect_fails(), the pass
> condition is an empty outfile:
>
> if [[ "${result}" == TEST ]]; then
> return "${KSFT_FAIL}"
> fi
>
> return "${KSFT_PASS}"
>
> An empty outfile is also what a broken harness produces, since vm_ns_exec()
> discards stderr and does not check the status of nsenter, and
> wait_for_listener() always returns 0. Would it make sense to verify the
> namespace exists before testing, for example comparing
> readlink /proc/<nspid>/ns/net against /proc/self/ns/net, so a setup failure
> cannot be reported as ok?
Sure, if that is the only way the test could break. Will look into and
fix / find a better way.
>
> [Severity: Low]
> Separately, is there anything ordering the unshare against its first use?
> The pid is echoed as soon as the child is forked, and the consumer is a
> later, separate ssh invocation:
>
> vm_ssh "${ns}" -- nsenter -t "${nspid}" -n sh -c "'${cmd}'"
>
> If the guest child has not reached unshare(CLONE_NEWNET) yet,
> /proc/<nspid>/ns/net is still the guest's initial netns, so dev-netns-set
> targets the initial namespace and the _ok tests fail while the _fails tests
> assert nothing. The window looks small, because a fresh SSH connection has
> to be set up first, but nothing structurally prevents it.
ssh is unlikely to win this race, but wierder things have happend. I
guess we can wait until the ns exists before proceeding.
>
> > +
> > +# Returns once the holder is gone, so that the namespace is unreferenced and
> > +# the kernel can start tearing it down.
> > +vm_ns_stop() {
> > + local ns=$1
> > + local nspid=$2
> > +
> > + vm_ssh "${ns}" <<-EOF &>/dev/null
> > + kill ${nspid}
> > + for ((i = 0; i < ${WAIT_PERIOD_MAX}; i++)); do
> > + kill -0 ${nspid} 2>/dev/null || break
> > + sleep 1
> > + done
> > + EOF
> > +}
> > +
> > +# Runs in the guest's initial namespace when <nspid> is empty. The command must
> > +# not contain single quotes.
> > +vm_ns_exec() {
> > + local ns=$1
> > + local nspid=$2
> > + local cmd=$3
> > +
> > + if [[ -z "${nspid}" ]]; then
> > + vm_ssh "${ns}" -- "${cmd}"
> > + return
> > + fi
> > +
> > + vm_ssh "${ns}" -- nsenter -t "${nspid}" -n sh -c "'${cmd}'"
> > +}
>
> [Severity: Low]
> This isn't a bug introduced by this patch, and the same idiom already
> exists in vm_start() and check_ns_delete_doesnt_break_connection(), but the
> quoting here rests on a comment rather than on the code: vm_ns_exec()
> builds a remote root command as sh -c "'${cmd}'" and the new wait loops
> splice an unquoted path into an inner shell:
>
> timeout "${WAIT_PERIOD}" \
> bash -c 'while [[ ! -s '"${outfile}"' ]]; do sleep 1; done'
>
> Whitespace or shell metacharacters in the path (for instance through TMPDIR
> affecting mktemp) would be interpreted by the inner shell and the wait loop
> would return immediately on a parse error. Would passing the path as a
> positional argument to bash -c be preferable?
won't fix in this series.
>
> [ ... ]
>
> > @@ -1421,6 +1546,292 @@ test_ns_delete_both_ok() {
> > check_ns_delete_doesnt_break_connection "both"
> > }
> >
> > +# Send a string from the guest to a host listener and leave what the host
> > +# received in <outfile>.
> > +guest_send_to_host() {
> > + local ns=$1
> > + local nspid=$2
> > + local port=$3
> > + local outfile=$4
> > + local cmd="echo TEST | socat -u STDIN VSOCK-CONNECT:2:${port}"
> > + local pid
> > +
> > + socat -u VSOCK-LISTEN:"${port}" STDOUT > "${outfile}" 2>/dev/null &
> > + pid=$!
> > + host_wait_for_listener "${ns}" "${port}" "vsock"
> > +
> > + vm_ns_exec "${ns}" "${nspid}" "${cmd}" 2>/dev/null
> > +
> > + timeout "${WAIT_PERIOD}" \
> > + bash -c 'while [[ ! -s '"${outfile}"' ]]; do sleep 1; done'
> > +
> > + terminate_pids "${pid}"
> > +}
>
> [Severity: Low]
> Can the host listener still hold the port when the next test binds it?
> terminate_pids() only signals and returns:
>
> terminate_pids() {
> local pid
>
> for pid in "$@"; do
> kill -SIGTERM "${pid}" &>/dev/null || :
> done
> }
>
> There is no wait, and the six new shared-VM tests reuse hard-coded ports
> (12345 in four tests, 12345..12349 and 12346 in the last two) back to back
> in the same VM. socat's stderr goes to /dev/null so an EADDRINUSE is
> invisible, and host_wait_for_listener() would then be satisfied by the
> stale listener because wait_for_listener() just greps
> ss --listening --vsock for the port, leaving the new test reading an outfile
> nothing writes. Would a wait on the pid, a bind-success check, or unique
> per-test ports close that?
will fix by waiting on pid.
>
> > +
> > +# Send a string from the host to a listener in the guest and leave what the
> > +# guest received in <outfile>.
> > +host_send_to_guest() {
> > + local ns=$1
> > + local nspid=$2
> > + local port=$3
> > + local outfile=$4
> > + local cmd="socat -u VSOCK-LISTEN:${port} STDOUT"
> > + local dst="VSOCK-CONNECT:${VSOCK_CID}:${port}"
> > + local pid
> > +
> > + vm_ns_exec "${ns}" "${nspid}" "${cmd}" > "${outfile}" 2>/dev/null &
> > + pid=$!
> > + vm_ns_wait_for_listener "${ns}" "${nspid}" "${port}" "vsock"
> > +
> > + echo TEST | socat -u STDIN "${dst}" 2>/dev/null
> > +
> > + timeout "${WAIT_PERIOD}" \
> > + bash -c 'while [[ ! -s '"${outfile}"' ]]; do sleep 1; done'
> > +
> > + terminate_pids "${pid}"
> > +}
>
> [Severity: Medium]
> Which process does pid=$! name here? vm_ns_exec() is a shell function with
> several commands, so backgrounding it makes bash fork a subshell, and $! is
> that subshell rather than ssh. terminate_pids() then SIGTERMs only the
> wrapper, while the ssh child and the guest-side
> socat -u VSOCK-LISTEN:<port> STDOUT keep running.
>
> The same applies to the sender in
> test_ns_guest_assign_g2h_netns_old_conn_send_fails():
>
> vm_ssh "init_ns" -- \
> "(echo FIRST; sleep ${gap}; echo SECOND) |" \
> "socat -u STDIN VSOCK-CONNECT:2:${port}" &>/dev/null &
> sender=$!
>
> If that is right, then the v2 changelog entry
>
> "Terminate the guest socat sender too, it sometimes outlived the
> test and kept holding on to a port the next test binds"
>
> does not have the described effect, since killing a local wrapper subshell
> cannot terminate the remote process.
>
> A leftover guest socat also keeps a reference on the namespace created by
> vm_ns_start(), so the postcondition documented on vm_ns_stop()
>
> # Returns once the holder is gone, so that the namespace is unreferenced and
> # the kernel can start tearing it down.
>
> may not hold, which is exactly what
> test_ns_guest_assign_g2h_netns_reset_on_ns_delete_ok() relies on. Would
> killing the remote command explicitly (or using ssh with a process group /
> pkill inside the guest) be more reliable?
>
> > +
> > +test_ns_guest_assign_g2h_netns_old_conn_send_fails() {
> > + local gap=$(( WAIT_PERIOD * 3 ))
> > + local port=12346
>
> [ ... ]
>
> > + outfile=$(mktemp)
> > + socat -u VSOCK-LISTEN:"${port}" STDOUT > "${outfile}" 2>/dev/null &
> > + pid=$!
> > + host_wait_for_listener "init_ns" "${port}" "vsock"
> > +
> > + # Send a message, wait, then send another. While waiting, assign the
> > + # device to a namespace. Confirm the second message does not arrive.
> > + vm_ssh "init_ns" -- \
> > + "(echo FIRST; sleep ${gap}; echo SECOND) |" \
> > + "socat -u STDIN VSOCK-CONNECT:2:${port}" &>/dev/null &
> > + sender=$!
> > +
> > + sleep "${WAIT_PERIOD}"
> > +
> > + if ! vm_ns_assign_g2h "init_ns" "${nspid}"; then
>
> [Severity: Medium]
> Is a fixed sleep enough to order these three actors? The guest sender, the
> host listener and the assign are only sequenced by sleeps, and nothing
> confirms FIRST actually arrived before the assign (unlike
> guest_send_to_host(), which polls the outfile).
>
> If ssh plus socat startup in the VM takes longer than WAIT_PERIOD (3s), the
> assign happens first, the connection is never established, the outfile stays
> empty, and the test reports
>
> log_host "no connection before the assign: [${result}]"
>
> against a correctly behaving kernel.
>
> > + log_host "failed to assign the vsock device to the guest ns"
> > + terminate_pids "${pid}" "${sender}"
> > + rm -f "${outfile}"
> > + vm_ns_stop "init_ns" "${nspid}"
> > + vm_reset_g2h
> > + return "${KSFT_FAIL}"
> > + fi
> > +
> > + # Let the second write happen and land, if it is going to.
> > + sleep $(( gap + WAIT_PERIOD ))
>
> [Severity: Medium]
> And in the other direction, can the assign lose the race against the
> sender's gap? vm_ns_assign_g2h() is an ssh connection plus nsenter plus a
> python3 interpreter start and a PyYAML spec parse. If that exceeds the
> sender's sleep of 9s, SECOND is delivered before the device moves and the
> test reports "old connection still delivered after the assign" for a kernel
> that is behaving as intended.
>
> Could the same polling already used in guest_send_to_host() be applied
> here, waiting for FIRST in the outfile before the assign and for the assign
> to complete before the second write is expected?
>
This is probably the right thing to do... though I'm not a big fan of
having a custom wait_for_X function for every single type of event.
I'll explore if its possible to have more generic/reusable coordination,
or otherwise fix this as is.
next prev parent reply other threads:[~2026-09-24 0:43 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-22 1:18 [PATCH net-next v2 0/6] vsock: assign the guest vsock device to a " Bobby Eshleman
2026-09-22 1:18 ` [PATCH net-next v2 1/6] vsock: constify the transport in vsock_for_each_connected_socket() Bobby Eshleman
2026-09-22 1:18 ` [PATCH net-next v2 2/6] vsock: rename the vsock pernet operations Bobby Eshleman
2026-09-22 1:18 ` [PATCH net-next v2 3/6] vsock: add a netlink command to assign the g2h device to a netns Bobby Eshleman
2026-09-23 19:21 ` netdev-bot+sashiko
2026-09-24 22:40 ` Bobby Eshleman
2026-09-22 1:18 ` [PATCH net-next v2 4/6] vsock/virtio: support guest device network namespace Bobby Eshleman
2026-09-23 19:21 ` netdev-bot+sashiko
2026-09-24 1:16 ` Bobby Eshleman
2026-09-22 1:18 ` [PATCH net-next v2 5/6] selftests/vsock: test the guest vsock " Bobby Eshleman
2026-09-23 19:21 ` netdev-bot+sashiko
2026-09-24 0:42 ` Bobby Eshleman [this message]
2026-09-22 1:18 ` [PATCH net-next v2 6/6] selftests/vsock: test the netns assign privilege checks Bobby Eshleman
2026-09-23 19:21 ` netdev-bot+sashiko
2026-09-24 0:24 ` Bobby Eshleman
2026-09-24 0:55 ` Bobby Eshleman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=arRyEMltRgwxJIbI@devvm29614.prn0.facebook.com \
--to=bobbyeshleman@gmail.com \
--cc=bobbyeshleman@meta.com \
--cc=corbet@lwn.net \
--cc=davem@davemloft.net \
--cc=donald.hunter@gmail.com \
--cc=edumazet@google.com \
--cc=eperezma@redhat.com \
--cc=horms@kernel.org \
--cc=jasowangio@gmail.com \
--cc=jlinbox@meta.com \
--cc=kuba@kernel.org \
--cc=kvm@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=mst@redhat.com \
--cc=netdev-bot+sashiko@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=rdunlap@infradead.org \
--cc=sargun@sargun.me \
--cc=sdf.kernel@gmail.com \
--cc=sgarzare@redhat.com \
--cc=shuah@kernel.org \
--cc=skhan@linuxfoundation.org \
--cc=stefanha@redhat.com \
--cc=virtualization@lists.linux.dev \
--cc=xuanzhuo@linux.alibaba.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®