From 70429d67d570ba58f7e386c04510ef24635b302e Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Thu, 4 Jun 2026 15:49:06 +0200 Subject: [PATCH] test: read the namespace symlink directly instead of using lsns lsns scans all of /proc/*/ns/* even when a single PID is specified which can be racy. Let's just read and compare the procfs symlinks directly to both avoid doing the whole procfs scan and to, hopefully, get rid of the occasional test fail where lsns fails to resolve the namespace for the "old" process: [ 1517.791471] TEST-07-PID1.sh[22279]: + systemd-run --unit=oldservice --property=Type=notify --property=NotifyAccess=all --property=PrivateUsers=true --property=PrivateNetwork=true bash -c 'systemd-notify --ready; exec sleep> [ 1517.839514] TEST-07-PID1.sh[22329]: Running as unit: oldservice.service; invocation ID: 840ba49490f349c8b3b2116a43fb6f54 [ 1517.840403] TEST-07-PID1.sh[22335]: ++ systemctl show oldservice -p MainPID [ 1517.841707] TEST-07-PID1.sh[22336]: ++ awk -F= '{print $2}' [ 1517.849691] TEST-07-PID1.sh[22279]: + OLD_PID=22330 [ 1517.849691] TEST-07-PID1.sh[22279]: + systemd-run --unit=newservice --property=Type=notify --property=NotifyAccess=all --property=UserNamespacePath=/proc/22330/ns/user --property=NetworkNamespacePath=/proc/22330/ns/net bas> [ 1517.951239] TEST-07-PID1.sh[22337]: Running as unit: newservice.service; invocation ID: 515b7f71240344aba2864e8510a18cbf [ 1517.951475] TEST-07-PID1.sh[22343]: ++ awk -F= '{print $2}' [ 1517.951915] TEST-07-PID1.sh[22342]: ++ systemctl show newservice -p MainPID [ 1517.972557] TEST-07-PID1.sh[22279]: + NEW_PID=22338 [ 1517.972696] TEST-07-PID1.sh[22344]: ++ lsns -p 22330 -o NS -t net -n [ 1518.003546] TEST-07-PID1.sh[22345]: ++ lsns -p 22338 -o NS -t net -n [ 1518.030831] TEST-07-PID1.sh[22279]: + assert_eq '' 4026532280 [ 1518.031106] TEST-07-PID1.sh[22348]: + set +ex [ 1518.031106] TEST-07-PID1.sh[22348]: FAIL: expected: '4026532280' actual: '' [ 1518.031342] TEST-07-PID1.sh[111]: + echo 'Subtest /usr/lib/systemd/tests/testdata/units/TEST-07-PID1.user-namespace-path.sh failed' Also, don't swallow the exit code from the command substitution in case readlink fails, which could lead to a false-positive test result if it happened for both readlinks. Resolves: #39546 --- .../units/TEST-07-PID1.user-namespace-path.sh | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/test/units/TEST-07-PID1.user-namespace-path.sh b/test/units/TEST-07-PID1.user-namespace-path.sh index f868b0ce68..6d64a52bf8 100755 --- a/test/units/TEST-07-PID1.user-namespace-path.sh +++ b/test/units/TEST-07-PID1.user-namespace-path.sh @@ -13,8 +13,12 @@ OLD_PID=$(systemctl show oldservice -p MainPID | awk -F= '{print $2}') systemd-run --unit=newservice --property=Type=notify --property=NotifyAccess=all --property=UserNamespacePath=/proc/"$OLD_PID"/ns/user --property=PrivateNetwork=true bash -c 'systemd-notify --ready; exec sleep 3600' NEW_PID=$(systemctl show newservice -p MainPID | awk -F= '{print $2}') -assert_neq "$(lsns -p "$OLD_PID" -o NS -t net -n)" "$(lsns -p "$NEW_PID" -o NS -t net -n)" -assert_eq "$(lsns -p "$OLD_PID" -o NS -t user -n)" "$(lsns -p "$NEW_PID" -o NS -t user -n)" +OLD_NETNS="$(readlink -v /proc/"$OLD_PID"/ns/net)" +NEW_NETNS="$(readlink -v /proc/"$NEW_PID"/ns/net)" +assert_neq "$OLD_NETNS" "$NEW_NETNS" +OLD_USERNS="$(readlink -v /proc/"$OLD_PID"/ns/user)" +NEW_USERNS="$(readlink -v /proc/"$NEW_PID"/ns/user)" +assert_eq "$OLD_USERNS" "$NEW_USERNS" systemctl stop oldservice newservice @@ -25,8 +29,12 @@ OLD_PID=$(systemctl show oldservice -p MainPID | awk -F= '{print $2}') systemd-run --unit=newservice --property=Type=notify --property=NotifyAccess=all --property=UserNamespacePath=/proc/"$OLD_PID"/ns/user --property=NetworkNamespacePath=/proc/"$OLD_PID"/ns/net bash -c 'systemd-notify --ready; exec sleep 3600' NEW_PID=$(systemctl show newservice -p MainPID | awk -F= '{print $2}') -assert_eq "$(lsns -p "$OLD_PID" -o NS -t net -n)" "$(lsns -p "$NEW_PID" -o NS -t net -n)" -assert_eq "$(lsns -p "$OLD_PID" -o NS -t user -n)" "$(lsns -p "$NEW_PID" -o NS -t user -n)" +OLD_NETNS="$(readlink -v /proc/"$OLD_PID"/ns/net)" +NEW_NETNS="$(readlink -v /proc/"$NEW_PID"/ns/net)" +assert_eq "$OLD_NETNS" "$NEW_NETNS" +OLD_USERNS="$(readlink -v /proc/"$OLD_PID"/ns/user)" +NEW_USERNS="$(readlink -v /proc/"$NEW_PID"/ns/user)" +assert_eq "$OLD_USERNS" "$NEW_USERNS" systemctl stop oldservice newservice @@ -37,7 +45,11 @@ OLD_PID=$(systemctl show oldservice -p MainPID | awk -F= '{print $2}') systemd-run --unit=newservice --property=Type=notify --property=NotifyAccess=all --property=UserNamespacePath=/proc/"$OLD_PID"/ns/user --property=DelegateNamespaces=net --property=PrivateNetwork=true bash -c 'systemd-notify --ready; exec sleep 3600' NEW_PID=$(systemctl show newservice -p MainPID | awk -F= '{print $2}') -assert_neq "$(lsns -p "$OLD_PID" -o NS -t net -n)" "$(lsns -p "$NEW_PID" -o NS -t net -n)" -assert_eq "$(lsns -p "$OLD_PID" -o NS -t user -n)" "$(lsns -p "$NEW_PID" -o NS -t user -n)" +OLD_NETNS="$(readlink -v /proc/"$OLD_PID"/ns/net)" +NEW_NETNS="$(readlink -v /proc/"$NEW_PID"/ns/net)" +assert_neq "$OLD_NETNS" "$NEW_NETNS" +OLD_USERNS="$(readlink -v /proc/"$OLD_PID"/ns/user)" +NEW_USERNS="$(readlink -v /proc/"$NEW_PID"/ns/user)" +assert_eq "$OLD_USERNS" "$NEW_USERNS" systemctl stop oldservice newservice