Commit Graph
113 Commits
Author SHA1 Message Date
Lennart Poettering 9cc545447e core: split out cgroup specific state fields from Unit → CGroupRuntime
This refactors the Unit structure a bit: all cgroup-related state fields
are moved to a new structure CGroupRuntime, which is only allocated as
we realize a cgroup.

This is both a nice cleanup and should make unit structures considerably
smaller that have no cgroup associated, because never realized or
because they belong to a unit type that doesn#t have cgroups anyway.

This makes things nicely symmetric:

        ExecContext → static user configuration about execution
        ExecRuntime → dynamic user state of execution
        CGroupContext → static user configuration about cgroups
        CGroupRuntime → dynamic user state of cgroups

And each time the XyzContext is part of the unit type structures such as
Service or Slice that need it, but the runtime object is only allocated
when a unit is started.
2024-02-16 10:17:40 +01:00
Lennart Poettering 8017ed7e0e service: don't try to determine selinux label for socket activation if RootImage= is used
We cannot determine the SELinux label ahead of time if RootImage= is
used, since we'd have to mount the image then, hence don't, and handle
this cleanly, and gracefully.

While we are at it, stop "reaching over" so much from the socket code to
the service code, and instead provide function that most of the hard
work in service.c that socket.c just calls.

While we are at it, add debug logging and stuff.

I noticed the issue when also noticing #30560, but that one is harder to
fix, hence I avoided it for now.
2023-12-22 11:51:51 +09:00
Lennart Poettering c79ab77cd3 core: reference main/control pid of .service units via PidRef
The first conversion to PidRef. It's mostly an excercise of
search/replace, but with some special care taken for life-cycle (i.e. we
need to destroy the structure properly once done, to release the pidfd).

It also uses pidfd based killing for some of the killing but leaves most
as it is to make the conversion minimal.
2023-09-09 14:03:31 +02:00
Richard Phibel e568fea9fc service: add new RestartMode option
When this option is set to direct, the service restarts without entering a failed
state. Dependent units are not notified of transitory failure.

This is useful for the following use case:

We have a target with Requires=my-service, After=my-service.
my-service.service is a oneshot service and has Restart=on-failure in
its definition.

my-service.service can get stuck for various reasons and time out, in
which case it is restarted. Currently, when it fails the first time, the
target fails, even though my-service is restarted.

The behavior we're looking for is that until my-service is not restarted
anymore, the target stays pending waiting for my-service.service to
start successfully or fail without being restarted anymore.
2023-07-06 14:33:52 +02:00
Mike Yuan 49b34f75e7 core: get rid of unused Service.will_auto_restart logic
The announced new behavior for OnFailure= never worked properly,
and we've fixed the document instead in #27675.
Therefore, let's get rid of the unused logic completely. More at #27594.

The to-be-added RestartMode= option should cover the use case hopefully.

Closes #27594
2023-05-24 21:37:02 +08:00
Mike Yuan e9f17fa8dd core: rename RestartSecMax to RestartMaxDelaySec 2023-05-18 00:23:49 +08:00
Lennart Poettering 81a1d6d679 service: rename service_close_socket_fd() → service_release_socket_fd()
Just to match service_release_stdio_fd() and service_release_fd_store()
in the name, since they do similar things.

This follows the concept that we "release" resources, and this is all
generically wrapped in "service_release_resources()".
2023-04-13 06:44:27 +02:00
Lennart Poettering b9c1883a9c service: add ability to pin fd store
Oftentimes it is useful to allow the per-service fd store to survive
longer than for a restart. This is useful in various scenarios:

1. An fd to some security relevant object needs to be stashed somewhere,
   that should not be cleaned automatically, because the security
   enforcement would be dropped then.

2. A user namespace fd should be allocated on first invocation and be
   kept around until the user logs out (i.e. systemd --user ends), á la
   #16328 (This does not implement what #16318 asks for, but should
   solve the use-case discussed there.)

3. There's interest in allow a concept of "userspace reboots" where the
   kernel stays running, and userspace is swapped out (i.e. all services
   exit, and the rootfs transitioned into a new version of it) while
   keeping some select resources pinned, very similar to how we
   implement a switch root. Thus it is useful to allow services to exit,
   while leaving their fds around till the very end.

This is exposed through a new FileDescriptorStorePreserve= setting that
is closely modelled after RuntimeDirectoryPreserve= (in fact it reused
the same internal type), since we want similar behaviour in the end, and
quite often they probably want to be used together.
2023-04-13 06:44:27 +02:00
Mike Yuan 5171356eee core: always calculate the next restart interval
Follow-up for #26902 and #26971

Let's always calculate the next restart interval
since that's more useful.

For that, we add 1 to s->n_restarts unconditionally,
and change RestartUSecCurrent property to RestartUSecNext.
2023-03-31 01:22:58 +01:00
Lennart Poettering 2e34aed32b Merge pull request #26971 from poettering/autostart-dead-failed
pid1: introduce new SERVICE_{DEAD|FAILED}_BEFORE_AUTO_RESTART service…
2023-03-29 21:41:31 +02:00
Lennart Poettering a7b6eee4ac Merge pull request #26968 from DaanDeMeyer/exec-runtime
core: Introduce unit private exec runtime
2023-03-29 21:40:48 +02:00
Lennart Poettering a1d315730f pid1: introduce new SERVICE_{DEAD|FAILED}_BEFORE_AUTO_RESTART service substates
When a service deactivates and is then automatically restarted via
Restart= we currently quickly transition through
SERVICE_DEAD/SERVICE_FAILED. Which is weird given it's not the
normal ("permanent") dead/failed state, but a transitory one we
immediately leave from again. We do this so that software that looks for
failures/successes can take notice, even if we restart as a consequence
of the deactivation.

Let's clean this up a bit: let's introduce two new states:
SERVICE_DEAD_BEFORE_AUTO_RESTART and SERVICE_FAILED_BEFORE_AUTO_RESTART
that are used for the transitory states. Both the SERVICE_DEAD and
SERVICE_DEAD_BEFORE_AUTO_RESTART will map to the high-level
UNIT_INACTIVE state though. (and similar for the respective failed
states). This means the high-level state machine won't change by this,
only the low-level one.

This clearly seperates the substates, which makes the state engine
cleaner, and allows clients to follow precisely whether we are in a
transitory dead/failed state, or a permanent one, by looking at the
service substate. Moreover it allows us to remove the 'n_keep_fd_store'
which so far we used to ensure the fdstore was not released during this
transitory dead/failed state but only during the permanent one. Since we
can now distinguish these states properly we can just use that.

This has been bugging me for a while. Let's clean this up.

Note that the unit restart logic is already nicely covered in the
testsiute, hence this adds no new tests for that.

And yes, this could be considered a compat break, but sofar we took the
liberty to make changes to the low-level state machine (i.e. SERVICE_xyz
states, sometimes called "substates") without considering this a bad
breakage – the high-level state machine (i.e.  UNIT_xyz states) should
be considered API that cannot be changed.
2023-03-29 17:22:07 +02:00
Daan De Meyer 1522077269 core: Move DynamicCreds into ExecRuntime
This is just another piece of runtime data so let's store it in
ExecRuntime alongside the other runtime data.
2023-03-27 14:47:30 +02:00
Daan De Meyer 28135da3cd core: Introduce unit private exec runtime
Currently, exec runtimes can be shared between units (using
JoinsNamespaceOf=). Let's introduce a concept of a private exec
runtime that isn't shared with JoinsNamespaceOf=. The existing
ExecRuntime struct is renamed to ExecRuntimeShared and becomes a
private member of the new private ExecRuntime.
2023-03-27 14:46:57 +02:00
Daan De Meyer e76506b748 execute: Rename ExecRuntime to ExecSharedRuntime
Preparation for next commit
2023-03-27 14:05:30 +02:00
Mike Yuan be1adc27fc core: add RestartSteps= and RestartSecMax= for exponentially increasing
interval between restarts

RestartSteps= accepts a positive integer as the number of steps
to take to increase the interval between auto-restarts from
RestartSec= to RestartSecMax=, or 0 to disable it.

Closes #6129
2023-03-27 19:31:12 +08:00
Mike Yuan 19dff6914d core: support overriding NOTIFYACCESS= through sd-notify during runtime
Closes #25963
2023-03-22 06:33:12 +08:00
Lennart Poettering 3bd28bf721 pid1: add new Type=notify-reload service type
Fixes: #6162
2023-01-10 18:28:38 +01:00
Richard Phibel cd48e23f6a core: add OpenFile setting 2023-01-10 15:16:26 +01:00
Nishal Kulkarni 38c41427c7 core/oomd: Use oom-kill ServiceResult for oomd
To notify user of kill events from systemd-oomd we now use
`SERVICE_FAILURE_OOM_KILL` as the failure result.

`unit_check_oomd_kill` now calls `notify_cgroup_oom` to
update the service result to `oom-kill`.

We add a new xattr `user.oomd_ooms` to keep track of the OOM kills
initiated by systemd-oomd, this helps us resolve a race between sending
SIGKILL to processes and checking for OOM kill status from the xattr.

Related to: #20649
2022-03-22 17:57:59 +05:30
Lennart Poettering e39eb045a5 pid1: lookup owning PID of BusName= name of services asynchronously
A first step of removing blocking calls to the D-Bus broker from PID 1.
There's a lot more to got (i.e. grep src/core/ for sd_bus_creds
basically), but it's a start.

Removing blocking calls to D-Bus broker deals systematicallly with
deadlocks caused by dbus-daemon blocking on synchronous IPC calls back
to PID1 (e.g. Varlink calls through nss-systemd). Bugs such as #15316.

Also-see: https://github.com/systemd/systemd/pull/22038#issuecomment-1042958390
2022-02-18 10:49:31 +01:00
Lennart Poettering 3fabebf45e socket: always pass socket, fd and SocketPeer ownership to service together
Per-connection socket instances we currently maintain three fields
related to the socket: a reference to the Socket unit, the connection fd,
and a reference to the SocketPeer object that counts socket peers.

Let's synchronize their lifetime, i.e. always set them all three
together or unset them together, so that their reference counters stay
synchronous.

THis will in particuar ensure that we'll drop the SocketPeer reference
whenever we leave an active state of the service unit, i.e. at the same
time we close the fd for it.

Fixes: #20685
2021-11-25 00:05:03 +01:00
Henri Chain 596e447076 Reintroduce ExitType
This introduces `ExitType=main|cgroup` for services.
Similar to how `Type` specifies the launch of a service, `ExitType` is
concerned with how systemd determines that a service exited.

- If set to `main` (the current behavior), the service manager will consider
  the unit stopped when the main process exits.

- The `cgroup` exit type is meant for applications whose forking model is not
  known ahead of time and which might not have a specific main process.
  The service will stay running as long as at least one process in the cgroup
  is running. This is intended for transient or automatically generated
  services, such as graphical applications inside of a desktop environment.

Motivation for this is #16805. The original PR (#18782) was reverted (#20073)
after realizing that the exit status of "the last process in the cgroup" can't
reliably be known (#19385)

This version instead uses the main process exit status if there is one and just
listens to the cgroup empty event otherwise.

The advantages of a service with `ExitType=cgroup` over scopes are:
- Integrated logging / stdout redirection
- Avoids the race / synchronisation issue between launch and scope creation
- More extensive use of drop-ins and thus distro-level configuration:
  by moving from scopes to services we can have drop ins that will affect
  properties that can only be set during service creation,
  like `OOMPolicy` and security-related properties
- It makes systemd-xdg-autostart-generator usable by fixing [1], as obviously
  only services can be used in the generator, not scopes.

[1] https://bugs.kde.org/show_bug.cgi?id=433299
2021-11-08 10:15:23 +01:00
Albert Brox 5918a93355 core: implement RuntimeMaxDeltaSec directive 2021-09-28 16:46:20 +02:00
Zbigniew Jędrzejewski-Szmek abaf5edd08 Revert "Introduce ExitType"
This reverts commit cb0e818f7c.

After this was merged, some design and implementation issues were discovered,
see the discussion in #18782 and #19385. They certainly can be fixed, but so
far nobody has stepped up, and we're nearing a release. Hopefully, this feature
can be merged again after a rework.

Fixes #19345.
2021-06-30 21:56:47 +02:00
Zbigniew Jędrzejewski-Szmek 35243b7736 test-unit-serialize: add a very basic test that command deserialization works
We should test both serialization and deserialization works properly.
But the serialization/deserialization code is deeply entwined with the
manager state, and I think quite a bit of refactoring will be required before
this is possible. But let's at least add this simple test for now.
2021-04-26 16:15:26 +02:00
Henri Chain cb0e818f7c Introduce ExitType 2021-03-31 10:26:07 +02:00
Zbigniew Jędrzejewski-Szmek 2d93c20e5f tree-wide: use -EINVAL for enum invalid values
As suggested in https://github.com/systemd/systemd/pull/11484#issuecomment-775288617.

This does not touch anything exposed in src/systemd. Changing the defines there
would be a compatibility break.

Note that tests are broken after this commit. They will be fixed in the next one.
2021-02-10 14:46:59 +01:00
Yu Watanabe db9ecf0501 license: LGPL-2.1+ -> LGPL-2.1-or-later 2020-11-09 13:23:58 +09:00
Jan Klötzke bf76080180 core: let user define start-/stop-timeout behaviour
The usual behaviour when a timeout expires is to terminate/kill the
service. This is what user usually want in production systems. To debug
services that fail to start/stop (especially sporadic failures) it
might be necessary to trigger the watchdog machinery and write core
dumps, though. Likewise, it is usually just a waste of time to
gracefully stop a stuck service. Instead it might save time to go
directly into kill mode.

This commit adds two new options to services: TimeoutStartFailureMode=
and TimeoutStopFailureMode=. Both take the same values and tweak the
behavior of systemd when a start/stop timeout expires:

 * 'terminate': is the default behaviour as it has always been,
 * 'abort': triggers the watchdog machinery and will send SIGABRT
   (unless WatchdogSignal was changed) and
 * 'kill' will directly send SIGKILL.

To handle the stop failure mode in stop-post state too a new
final-watchdog state needs to be introduced.
2020-06-09 10:04:57 +02:00
Chris Down 4793c31083 service: Display updated WatchdogUSec from sd_notify
Suppose a service has WatchdogSec set to 2 seconds in its unit file. I
then start the service and WatchdogUSec is set correctly:

    % systemctl --user show psi-notify -p WatchdogUSec
    WatchdogUSec=2s

Now I call `sd_notify(0, "WATCHDOG_USEC=10000000")`. The new timer seems
to have taken effect, since I only send `WATCHDOG=1` every 4 seconds,
and systemd isn't triggering the watchdog handler. However, `systemctl
show` still shows WatchdogUSec as 2s:

    % systemctl --user show psi-notify -p WatchdogUSec
    WatchdogUSec=2s

This seems surprising, since this "original" watchdog timer isn't the
one taking effect any more. This patch makes it so that we instead
display the new watchdog timer after sd_notify(WATCHDOG_USEC):

    % systemctl --user show psi-notify -p WatchdogUSec
    WatchdogUSec=10s

Fixes #15726.
2020-05-27 09:09:40 +02:00
Kenny Levinsen 3052049260 core: (De-)Serialize poll flag for fds in fdstore
This replaces manual string splitting and unescaping with
extract_first_word.
2020-04-30 19:42:53 +02:00
Yu Watanabe 12213aed12 core: move timeout_clean_usec from Service to ExecContext 2019-08-28 23:09:54 +09:00
Anita Zhang 31cd5f63ce core: ExecCondition= for services
Closes #10596
2019-07-17 11:35:02 +02:00
Lennart Poettering 4c2f584230 core: hook up service unit type with the new clean operation
The implementation is pretty straight-foward: when we get a request to
clean some type of resources we fork off a process doing that, and while
it is running we are in the "cleaning" state.
2019-07-11 12:18:51 +02:00
Anita Zhang b3d593673c core: add ExecStartXYZEx= with dbus support for executable prefixes
Closes #11654
2019-05-30 20:41:42 -07:00
Yu Watanabe 9c79f0e0a0 core: add assertion in two inline functions 2019-04-14 20:46:24 +09:00
Yu Watanabe 54c1a6ab8c core: change type of Service::timeout_abort_set to bool
Follow-up for dc653bf487 (#11211).
2019-04-14 20:13:47 +09:00
Jan Klötzke dc653bf487 service: handle abort stops with dedicated timeout
When shooting down a service with SIGABRT the user might want to have a
much longer stop timeout than on regular stops/shutdowns. Especially in
the face of short stop timeouts the time might not be sufficient to
write huge core dumps before the service is killed.

This commit adds a dedicated (Default)TimeoutAbortSec= timer that is
used when stopping a service via SIGABRT. In all other cases the
existing TimeoutStopSec= is used. The timer value is unset by default
to skip the special handling and use TimeoutStopSec= for state
'stop-watchdog' to keep the old behaviour.

If the service is in state 'stop-watchdog' and the service should be
stopped explicitly we still go to 'stop-sigterm' and re-apply the usual
TimeoutStopSec= timeout.
2019-04-12 17:32:52 +02:00
Lennart Poettering afcfaa695c core: implement OOMPolicy= and watch cgroups for OOM killings
This adds a new per-service OOMPolicy= (along with a global
DefaultOOMPolicy=) that controls what to do if a process of the service
is killed by the kernel's OOM killer. It has three different values:
"continue" (old behaviour), "stop" (terminate the service), "kill" (let
the kernel kill all the service's processes).

On top of that, track OOM killer events per unit: generate a per-unit
structured, recognizable log message when we see an OOM killer event,
and put the service in a failure state if an OOM killer event was seen
and the selected policy was not "continue". A new "result" is defined
for this case: "oom-kill".

All of this relies on new cgroupv2 kernel functionality: the
"memory.events" notification interface and the "memory.oom.group"
attribute (which makes the kernel kill all cgroup processes
automatically).
2019-04-09 11:17:58 +02:00
Lennart Poettering 0a6991e0bb tree-wide: reorder various structures to make them smaller and use fewer cache lines
Some "pahole" spelunking.
2019-03-27 18:11:11 +01:00
Lennart Poettering aa8c4bbf6a service: when starting a service make a copy of the watchdog timeout and use that
When we start a service process we pass the selected watchdog timeout to
it with the $WATCHDOG_USEC environment variable. If the unit file is
reconfigured later, we need to make sure to continue to honour the
original timeout, i.e. watch $WATCHDOG_USEC was set to, otherwise we'll
expect the ping at a different time as the service process is sending it
to us.

Hence, whenever we start a unit, save the watchdog timeout, and stick to
that for everything we do.

Fixes: #9467
2018-10-26 13:00:04 +02:00
Lennart Poettering 3eac1bcae9 core: enforce a limit on STATUS= texts recvd from services
Let's better be safe than sorry, and put a limit on what we receive.
2018-10-26 10:40:01 +02:00
Lennart Poettering 5686391b00 core: introduce new Type=exec service type
Users are often surprised that "systemd-run" command lines like
"systemd-run -p User=idontexist /bin/true" will return successfully,
even though the logs show that the process couldn't be invoked, as the
user "idontexist" doesn't exist. This is because Type=simple will only
wait until fork() succeeded before returning start-up success.

This patch adds a new service type Type=exec, which is very similar to
Type=simple, but waits until the child process completed the execve()
before returning success. It uses a pipe that has O_CLOEXEC set for this
logic, so that the kernel automatically sends POLLHUP on it when the
execve() succeeded but leaves the pipe open if not. This means PID 1
waits exactly until the execve() succeeded in the child, and not longer
and not shorter, which is the desired functionality.

Making use of this new functionality, the command line
"systemd-run -p User=idontexist -p Type=exec /bin/true" will now fail,
as expected.
2018-07-25 22:48:11 +02:00
Lennart Poettering 0c69794138 tree-wide: remove Lennart's copyright lines
These lines are generally out-of-date, incomplete and unnecessary. With
SPDX and git repository much more accurate and fine grained information
about licensing and authorship is available, hence let's drop the
per-file copyright notice. Of course, removing copyright lines of others
is problematic, hence this commit only removes my own lines and leaves
all others untouched. It might be nicer if sooner or later those could
go away too, making git the only and accurate source of authorship
information.
2018-06-14 10:20:20 +02:00
Lennart Poettering 818bf54632 tree-wide: drop 'This file is part of systemd' blurb
This part of the copyright blurb stems from the GPL use recommendations:

https://www.gnu.org/licenses/gpl-howto.en.html

The concept appears to originate in times where version control was per
file, instead of per tree, and was a way to glue the files together.
Ultimately, we nowadays don't live in that world anymore, and this
information is entirely useless anyway, as people are very welcome to
copy these files into any projects they like, and they shouldn't have to
change bits that are part of our copyright header for that.

hence, let's just get rid of this old cruft, and shorten our codebase a
bit.
2018-06-14 10:20:20 +02:00
Felipe Sateler 57b7a260c2 core: undo the dependency inversion between unit.h and all unit types 2018-05-15 14:24:34 -04:00
Lennart Poettering da6053d0a7 tree-wide: be more careful with the type of array sizes
Previously we were a bit sloppy with the index and size types of arrays,
we'd regularly use unsigned. While I don't think this ever resulted in
real issues I think we should be more careful there and follow a
stricter regime: unless there's a strong reason not to use size_t for
array sizes and indexes, size_t it should be. Any allocations we do
ultimately will use size_t anyway, and converting forth and back between
unsigned and size_t will always be a source of problems.

Note that on 32bit machines "unsigned" and "size_t" are equivalent, and
on 64bit machines our arrays shouldn't grow that large anyway, and if
they do we have a problem, however that kind of overly large allocation
we have protections for usually, but for overflows we do not have that
so much, hence let's add it.

So yeah, it's a story of the current code being already "good enough",
but I think some extra type hygiene is better.

This patch tries to be comprehensive, but it probably isn't and I missed
a few cases. But I guess we can cover that later as we notice it. Among
smaller fixes, this changes:

1. strv_length()' return type becomes size_t

2. the unit file changes array size becomes size_t

3. DNS answer and query array sizes become size_t

Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=76745
2018-04-27 14:29:06 +02:00
Zbigniew Jędrzejewski-Szmek 11a1589223 tree-wide: drop license boilerplate
Files which are installed as-is (any .service and other unit files, .conf
files, .policy files, etc), are left as is. My assumption is that SPDX
identifiers are not yet that well known, so it's better to retain the
extended header to avoid any doubt.

I also kept any copyright lines. We can probably remove them, but it'd nice to
obtain explicit acks from all involved authors before doing that.
2018-04-06 18:58:55 +02:00
Michal Koutný deb4e7080d service: Don't stop unneeded units needed by restarted service (#7526)
An auto-restarted unit B may depend on unit A with StopWhenUnneeded=yes.
If A stops before B's restart timeout expires, it'll be started again as part
of B's dependent jobs. However, if stopping takes longer than the timeout, B's
running stop job collides start job which also cancels B's start job. Result is
that neither A or B are active.

Currently, when a service with automatic restarting fails, it transitions
through following states:
        1) SERVICE_FAILED or SERVICE_DEAD to indicate the failure,
        2) SERVICE_AUTO_RESTART while restart timer is running.

The StopWhenUnneeded= check takes place in service_enter_dead between the two
state mentioned above. We temporarily store the auto restart flag to query it
during the check. Because we don't return control to the main event loop, this
new service unit flag needn't be serialized.

This patch prevents the pathologic situation when the service with Restart=
won't restart automatically. As a side effect it also avoid restarting the
dependency unit with StopWhenUnneeded=yes.

Fixes: #7377
2017-12-05 16:51:19 +01:00