selftests: rds: Handle errors in netns_socket

Sockets created by child processes in netns_socket may raise
exceptions that are currently not handled by the parent.  If for
example a namespace didn't exist or the rds module didn't load. Because
these exceptions occur with in a child thread, the child thread exits,
but the parent does not check the return status.

Further, allowing the child processes to quietly raise exceptions
will cause problems later if the parent registers clean up functions
with atexit.  Since the child processes inherit the parents handlers,
they may prematurely call the parents cleanup routines without the
parent being aware.

Fix this by all catching exceptions raised by the child processes.
Child errors surface as a non-zero exit status, which are then
properly raised in the parent process.

Signed-off-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/20260518012443.2629206-9-achender@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Allison Henderson 2026-05-17 18:24:40 -07:00 committed by Jakub Kicinski
parent 3bd27901aa
commit 0c4d043f61

View File

@ -56,27 +56,28 @@ def netns_socket(netns, *sock_args):
child = os.fork()
if child == 0:
# change network namespace
with open(f'/var/run/netns/{netns}', encoding='utf-8') as f:
try:
try:
# change network namespace
with open(f'/var/run/netns/{netns}', encoding='utf-8') as f:
setns(f.fileno(), 0)
except IOError as e:
print(e.errno)
print(e)
# create socket in target namespace
sock = socket.socket(*sock_args)
# create socket in target namespace
sock = socket.socket(*sock_args)
# send resulting socket to parent
socket.send_fds(u0, [], [sock.fileno()])
# send resulting socket to parent
socket.send_fds(u0, [], [sock.fileno()])
os._exit(0)
os._exit(0)
except BaseException:
os._exit(1)
# receive socket from child
_, fds, _, _ = socket.recv_fds(u1, 0, 1)
os.waitpid(child, 0)
_, status = os.waitpid(child, 0)
u0.close()
u1.close()
if not os.WIFEXITED(status) or os.WEXITSTATUS(status) != 0:
raise RuntimeError(
f"netns_socket child failed in netns {netns} (status={status})")
return socket.fromfd(fds[0], *sock_args)
def send_burst(socks, ip_addrs, snd_hashes, nr_sent, nr_total):