2 # SPDX-License-Identifier: LGPL-2.1-or-later
6 # Test changing the main PID
8 # shellcheck source=test/units/util.sh
9 .
"$(dirname "$0")"/util.sh
11 # The main service PID should be the parent bash process
13 test "$(systemctl show -P MainPID TEST-07-PID1.service)" -eq "$MAINPID"
15 # Start a test process inside of our own cgroup
20 # Start a test process outside of our own cgroup
21 systemd-run
-p DynamicUser
=1 --unit=test-sleep.service
/bin
/sleep infinity
22 EXTERNALPID
="$(systemctl show -P MainPID test-sleep.service)"
24 # Update our own main PID to the external test PID, this should work
25 systemd-notify MAINPID
="$EXTERNALPID"
26 test "$(systemctl show -P MainPID TEST-07-PID1.service)" -eq "$EXTERNALPID"
28 # Update our own main PID to the internal test PID, this should work, too
29 systemd-notify MAINPID
=$INTERNALPID
30 test "$(systemctl show -P MainPID TEST-07-PID1.service)" -eq "$INTERNALPID"
32 # Update it back to our own PID, this should also work
33 systemd-notify MAINPID
="$MAINPID"
34 test "$(systemctl show -P MainPID TEST-07-PID1.service)" -eq "$MAINPID"
36 # Try to set it to PID 1, which it should ignore, because that's the manager
37 systemd-notify MAINPID
=1
38 test "$(systemctl show -P MainPID TEST-07-PID1.service)" -eq "$MAINPID"
40 # Try to set it to PID 0, which is invalid and should be ignored
41 systemd-notify MAINPID
=0
42 test "$(systemctl show -P MainPID TEST-07-PID1.service)" -eq "$MAINPID"
44 # Try to set it to a valid but non-existing PID, which should be ignored. (Note
45 # that we set the PID to a value well above any known /proc/sys/kernel/pid_max,
46 # which means we can be pretty sure it doesn't exist by coincidence)
47 systemd-notify MAINPID
=1073741824
48 test "$(systemctl show -P MainPID TEST-07-PID1.service)" -eq "$MAINPID"
50 # Change it again to the external PID, without privileges this time. This should be ignored, because the PID is from outside of our cgroup and we lack privileges.
51 systemd-notify
--uid=1000 MAINPID
="$EXTERNALPID"
52 test "$(systemctl show -P MainPID TEST-07-PID1.service)" -eq "$MAINPID"
54 # Change it again to the internal PID, without privileges this time. This should work, as the process is on our cgroup, and that's enough even if we lack privileges.
55 systemd-notify
--uid=1000 MAINPID
="$INTERNALPID"
56 test "$(systemctl show -P MainPID TEST-07-PID1.service)" -eq "$INTERNALPID"
58 # Update it back to our own PID, this should also work
59 systemd-notify
--uid=1000 MAINPID
="$MAINPID"
60 test "$(systemctl show -P MainPID TEST-07-PID1.service)" -eq "$MAINPID"
62 cat >/tmp
/test-mainpid.sh
<<\EOF
68 # Create a number of children, and make one the main one
79 echo $MAINPID >/run
/mainpidsh
/pid
81 chmod +x
/tmp
/test-mainpid.sh
83 systemd-run
--unit=test-mainpidsh.service \
84 -p StandardOutput
=tty \
85 -p StandardError
=tty \
87 -p RuntimeDirectory
=mainpidsh \
88 -p PIDFile
=/run
/mainpidsh
/pid \
90 test "$(systemctl show -P MainPID test-mainpidsh.service)" -eq "$(cat /run/mainpidsh/pid)"
92 cat >/tmp
/test-mainpid2.sh
<<\EOF
98 # Create a number of children, and make one the main one
109 echo $MAINPID >/run
/mainpidsh
2/pid
110 chown
1001:1001 /run
/mainpidsh
2/pid
112 chmod +x
/tmp
/test-mainpid2.sh
114 systemd-run
--unit=test-mainpidsh2.service \
115 -p StandardOutput
=tty \
116 -p StandardError
=tty \
118 -p RuntimeDirectory
=mainpidsh2 \
119 -p PIDFile
=/run
/mainpidsh
2/pid \
120 /tmp
/test-mainpid2.sh
121 test "$(systemctl show -P MainPID test-mainpidsh2.service)" -eq "$(cat /run/mainpidsh2/pid)"
123 cat >/dev
/shm
/test-mainpid3.sh
<<EOF
138 # Let's try to play games, and link up a privileged PID file
139 ln -s ../mainpidsh/pid /run/mainpidsh3/pid
141 # Quick assertion that the link isn't dead
142 test -f /run/mainpidsh3/pid
144 chmod 755 /dev
/shm
/test-mainpid3.sh
146 # This has to fail, as we shouldn't accept the dangerous PID file, and then
147 # inotify-wait on it to be corrected which we never do.
149 --unit=test-mainpidsh3.service \
150 -p StandardOutput
=tty \
151 -p StandardError
=tty \
153 -p RuntimeDirectory
=mainpidsh3 \
154 -p PIDFile
=/run
/mainpidsh
3/pid \
156 `# Make sanitizers happy when DynamicUser=1 pulls in instrumented systemd NSS modules` \
157 -p EnvironmentFile
=-/usr
/lib
/systemd
/systemd-asan-env \
158 -p TimeoutStartSec
=2s \
159 /dev
/shm
/test-mainpid3.sh
)
161 # Test that this failed due to timeout, and not some other error
162 test "$(systemctl show -P Result test-mainpidsh3.service)" = timeout
164 # Test that scope units work
165 systemd-run
--scope --unit test-true.scope
/bin
/true
166 test "$(systemctl show -P Result test-true.scope)" = success
168 # Test that user scope units work as well
170 systemctl start user@
4711.service
171 runas testuser systemd-run
--scope --user --unit test-true.scope
/bin
/true
172 test "$(systemctl show -P Result test-true.scope)" = success