Some PIDs can remain in the watched list even though their processes have
exited since a long time. It can easily happen if the main process of a forking
service manages to spawn a child before the control process exits for example.
However when a pid is about to be mapped to a unit by calling unit_watch_pid(),
the caller usually knows if the pid should belong to this unit exclusively: if
we just forked() off a child, then we can be sure that its PID is otherwise
unused. In this case we take this opportunity to remove any stalled PIDs from
the watched process list.
If we learnt about a PID in any other form (for example via PID file, via
searching, MAINPID= and so on), then we can't assume anything.
It's probably unexpected if we do a recursive chown() when dynamic users
are used but not on static users.
hence, let's tweak the logic slightly, and recursively chown in both
cases, except when operating on the configuration directory.
Fixes: #11842
Let's reduce the chance of failure: if we can't apply the chmod/chown
requested, check if it's applied anyway, and if so, supress the error.
This is even race-free since we operate on an O_PATH fd anyway.
This service uses PAM anyway, hence let pam_keyring set things up for
us. Moreover, this way we ensure that the invocation ID is not set for
this service as key, and thus can't confuse the user service's
invocation ID.
Fixes: #11649
As discussed in https://gitlab.freedesktop.org/libinput/libinput/issues/198#note_100642 the DPI for the Razer Abyssus mouse is not 3500 by default, but around 1600-1700 when measured with the mouse-dpi-tool.
So I have done some measurements now and always got a value of about 21000 device units on a distance of 12.5 inch. This would result in a calculated resolution of about 1680 DPI. Since such an odd number does not occur in the hwdb file I decided to round to 1600 DPI.
The function so far always returned -ECANCELLED, which is ignored in all
cases the function is invoked, except one: in unit_test_start_limit()
where -ECANCELLED is returned when the start limit is hit, which is part
of unit_start()'s protocol of return values.
Since the emergency_action() logic should be relatively generic and is
used in many places, let's drop the return value from it, since it's
constant anyway, and in alll cases useless. Instead, let's return it in
unit_test_start_limit(), where it's part of the protocol.
No change in behaviour.
Let's add a safety precaution: if the start condition checks for a unit
are tested too often and fail each time, let's rate limit this too.
This should add extra safety in case people define .path, .timer or
.automount units that trigger a service that as a conditoin that always
fails.
Just some renaming, no change in behaviour.
Background: I'd like to add more functions unit_test_xyz() that test
various things, hence let's streamline the naming a bit.
Introduced in 6d586a1371.
Reported by Felix Riemann in https://bugzilla.redhat.com/show_bug.cgi?id=1685286.
Reproducer:
for i in `seq 1 100`; do gdbus call --session -d org.freedesktop.systemd1 -m org.freedesktop.systemd1.Manager.StartUnit -o "/$(for x in `seq 0 28000`; do echo -n $x; done)" & done
I had a test machine with ulimit -n set to 1073741816 through pam
("session required pam_limits.so set_all", which copies the limits from PID 1,
left over from testing of #10921).
test-execute would "hang" and then fail with a timeout when running
exec-inaccessiblepaths-proc.service. It turns out that the problem was in
close_all_fds(), which would go to the fallback path of doing close()
1073741813 times. Let's just fail if we hit this case. This only matters
for cases where both /proc is inaccessible, and the *soft* limit has been
raised.
(gdb) bt
#0 0x00007f7e2e73fdc8 in close () from target:/lib64/libc.so.6
#1 0x00007f7e2e42cdfd in close_nointr ()
from target:/home/zbyszek/src/systemd-work3/build-rawhide/src/shared/libsystemd-shared-241.so
#2 0x00007f7e2e42d525 in close_all_fds ()
from target:/home/zbyszek/src/systemd-work3/build-rawhide/src/shared/libsystemd-shared-241.so
#3 0x0000000000426e53 in exec_child ()
#4 0x0000000000429578 in exec_spawn ()
#5 0x00000000004ce1ab in service_spawn ()
#6 0x00000000004cff77 in service_enter_start ()
#7 0x00000000004d028f in service_enter_start_pre ()
#8 0x00000000004d16f2 in service_start ()
#9 0x00000000004568f4 in unit_start ()
#10 0x0000000000416987 in test ()
#11 0x0000000000417632 in test_exec_inaccessiblepaths ()
#12 0x0000000000419362 in run_tests ()
#13 0x0000000000419632 in main ()
When debugging failure in one of the cases, it's annoying to have to wade
through the output from all the other cases. Let's allow picking select
cases.