Commit Graph
350 Commits
Author SHA1 Message Date
Łukasz Stelmach e0ebc81b2d core: drop ambient capabilities in systemd-executor
Since the commit 963b6b906e ("core: drop ambient capabilities in
user manager") systemd running as the session manager has dropped ambient
capabilities retaining other sets allowing user services to be started
with elevated capabilities. This, worked fine until the introduction of
sd-executor. For a non-root process to be started with elevated
capabilities by a non-root parent it either needs file capabilities or
ambient capabilities in the parent process. Thus, systemd needs to allow
sd-executor to inherit its ambient capabilities and sd-executor should
drop them as systemd did before.

The ambient set is managed for both system and session managers, but
with the default set for PID#1 being empty, this code does not affect
operation of PID#1.

Fixes: bb5232b6a3 ("core: add systemd-executor binary")
2024-07-31 11:09:58 +02:00
Lennart Poettering 25ff515b39 sd-varlink: make our internal Varlink API public as sd-varlink.[ch]
It's time. sd-json was already done earlier in this cycle, let's now
make sd-varlink public too.

This is mostly just a search/replace job of epical proportions.

I left some functions internal (mostly IDL handling), and I turned some
static inline calls into regular calls.
2024-07-16 11:57:32 +02:00
Lennart Poettering 817062e621 manager: add socket for receiving handoff timestamps from forked children
This adds an AF_UNIX socket pair to the manager that we can collect
handoff timestamp messages on.

The idea is that forked off children send a datagram with a timestamp
and we use its sender PID to match it against the right forked off
process.

This part only implements the receiving side: a socket is created, and
listened on. Received datagrams are parsed, verified and then dispatched
to the interested units.
2024-04-25 13:33:03 +02:00
Zbigniew Jędrzejewski-Szmek d851637ca6 core: drop unused param, move taint calculation to separate file
Follow-up for 2b28dfe6e6.

I also considered moving the function to src/basic, but since it's only used by
the manager, it doesn't seem useful.
2024-04-24 15:17:49 +02:00
Mike Yuan 37ca2ccf33 core/manager: introduce ManagerObjective string table lookup 2024-04-18 20:32:20 +08:00
Luca Boccassi b3f548615f core: rename SoftRebootStartTimestamp -> ShutdownStartTimestamp and generalize
Follow-up for 54f86b86ba
2024-04-17 18:19:27 +01:00
Luca Boccassi 8c15bf36e1 manager: serialize current objective
So that we can tell what happened before the exec. It is overwritten
shortly after deserialization. Use it to bump the soft reboots counter.
2024-04-17 18:19:27 +01:00
Luca Boccassi 8312b17a29 core: apply ReloadLimit to reexec too
Same reason as the reload, reexec is disruptive and it requires the
same privileges, so if somebody wants to limit reloads, they'll also
want to limit reexecs, so use the same setting.
2024-03-29 12:03:32 +00:00
Luca Boccassi 66f35161f6 core: add counter for soft-reboot iterations
Allow to query via D-Bus how many times the current booted system has
been soft rebooted
2024-03-27 01:27:35 +00:00
Luca Boccassi 54f86b86ba core: add SoftRebootStartTimestamp
Will be useful to calculate how long it took to shut down the system before starting
in the new root
2024-03-27 01:25:49 +00:00
Lennart Poettering b2d6bb5b34 core: notify supervisor over targets we reach, as we reach them
Let's inform the the supervisor about various happenings of our service
manager, specifically the boot milestones we reach.

We so far have only a singular READY=1 message, to inform about bootup
completion. But sometimes it is interesting to have something for
finegrained, in particular something that indicates optional components
that have been activated.

Usecase for this: in a later PR I intend to introduce a generic
"ssh.target" that is supposed to be activated when SSH becomes available
on a host. A supervisor (i.e. a VMM/hypervisor/container mgr/…) can
watch for that, and know two things:

1. that SSH is generally available in the system
2. when it is available

In order to not flood the supervisor with events I only send these out
for target units. We could open this up later, in theory, but I think it
makes sense to tell people instead to define clear milestone target
units if they want a supervisor to be able to track system state.
2024-03-14 17:23:10 +01:00
Yu Watanabe d70dfe1b27 core: constify PidRef arguments 2024-01-24 14:43:18 +09:00
Lennart Poettering 8a69bf0c57 manager: order idle jobs
Let's put the run queue really the last spot, as we should only start
doing more work if we really have nothing else to do anymore.

Let's move the service watchdog after the rewatch PID logic for similar
logic: it will possibly result in new jobs being enqueued to stop
things, and we should really have done all other work first.
2024-01-19 16:46:28 +01:00
Lennart Poettering 90c40ea4bf manager: renumber priorities
no actual change, let's just make sure the priorities are densely
defined without "holes". Just to make this prettier and less surprising.
2024-01-19 16:46:28 +01:00
Lennart Poettering f3a269a935 manager: process exec_fd (i.e. Type=exec) events before SIGCHLD events
We want to make sure we don't confuse the case "process started
successfully but then failed quickly" from the case "process failed to
start". Hence we need to make sure we take notice of Type=exec before we
bother with SIGCHLD.

Hence move EVENT_PRIORITY_EXEC_FD to the front. In fact, let's move it
even further up than SIGCHLD, i.e. before sd_notify() handling, so that
we don't end up processing service state change notifications before we
even considered that the service is properly started.

This also gives the cgroup OOM handling and the exec_fd handling
different priorities, to improve robustness of the system, we should act
quickly on OOM, and it doesn't matter if a service started succcessfully
if we have to act on OOM anyway.

This is based on Andrew Onyshchuk <andryk.rv@gmail.com> work here:

See: #30799
Fixes: #28304
2024-01-19 16:46:28 +01:00
Lennart Poettering d42b61d279 core: maintain a single table with event source priorities
It's hard to oversee the assigned processing priorities of the various
event sources we have. Let's unify them in a table (an enum), where we
can have a single consisten look at them, and then reference the table
entries by expressive symbols.

This doesn#t change behaviour in any way, it just gives each priority a
nice label, but doesn't change any of the priorities.

Prompted by: #30799
2024-01-19 16:46:28 +01:00
Luca Boccassi 9e615fa3aa core: add WantsMountsFor=
This is the equivalent of RequiresMountsFor=, but adds Wants= instead
of Requires=. It will be useful for example for the autogenerated
systemd-cryptsetup units.

Fixes https://github.com/systemd/systemd/issues/11646
2023-11-29 11:04:59 +00:00
Daan De Meyer cc156539d9 manager: Introduce manager_get_progress() helper 2023-10-20 14:09:32 +02:00
Lennart Poettering 06044356de manager: move idle_pipe allocation to manager.c and make it atomic
Let's make sure it either fails or suceeds, but never fails half-way
leaving a half-initialized array around.
2023-10-18 16:07:41 +01:00
Luca Boccassi bb5232b6a3 core: add systemd-executor binary
Currently we spawn services by forking a child process, doing a bunch
of work, and then exec'ing the service executable.

There are some advantages to this approach:

- quick: we immediately have access to all the enourmous amount of
  state simply by virtue of sharing the memory with the parent
- easy to refactor and add features
- part of the same binary, will never be out of sync

There are however significant drawbacks:

- doing work after fork and before exec is against glibc's supported
  case for several APIs we call
- copy-on-write trap: anytime any memory is touched in either parent
  or child, a copy of that page will be triggered
- memory footprint of the child process will be memory footprint of
  PID1, but using the cgroup memory limits of the unit

The last issue is especially problematic on resource constrained
systems where hard memory caps are enforced and swap is not allowed.
As soon as PID1 is under load, with no page out due to no swap, and a
service with a low MemoryMax= tries to start, hilarity ensues.

Add a new systemd-executor binary, that is able to receive all the
required state via memfd, deserialize it, prepare the appropriate
data structures and call exec_child.

Use posix_spawn which uses CLONE_VM + CLONE_VFORK, to ensure there is
no copy-on-write (same address space will be used, and parent process
will be frozen, until exec).
The sd-executor binary is pinned by FD on startup, so that we can
guarantee there will be no incompatibilities during upgrades.
2023-10-12 15:01:51 +01:00
Luca Boccassi b646fc324a core: ensure execute/spawn functions can work without Unit object
When switching to serialization later, the Unit object will not be
serialized, move parameters around instead
2023-10-12 13:37:22 +01:00
Lennart Poettering 94f0b13b16 cgroup: rename TasksMax structure to CGroupTasksMax
Almost all our enums/structs/funcs carry the CGroup prefix if they are
defined in cgroup.h, TasksMax so far does not, even though it is
exclusively used in cgroup context.

Change that.
2023-10-06 18:13:16 +02:00
Lennart Poettering 495e75ed5c core: move pid watch/unwatch logic of the service manager to pidfd
This makes sure unit_watch_pid() and unit_unwatch_pid() will track
processes by pidfd if supported. Also ports over some related code.
Should not really change behaviour.

Note that this does *not* add support waiting for POLLIN on the pidfds
as additional exit notification. This is left for a later commit (this
commit is already large enough), in particular as that would add new
logic and not just convert existing logic.
2023-09-28 23:22:58 +02:00
Mike Yuan a82b8b3dc8 core: mark units as need daemon-reload if unit file operations are
performed

systemctl would issue daemon-reload after unit file operations
(enable/disable/preset/...) succeed. However, such operations
are not atomic, meaning that the unit file state could still change
even if the operation generally fails, and the unit_file_state
cached by manager becomes outdated.

Fixes #29341
2023-09-28 15:19:24 +01:00
Topi Miettinen dc7d69b3c1 core: firewall integration of cgroups with NFTSet=
New directive `NFTSet=` provides a method for integrating dynamic cgroup IDs
into firewall rules with NFT sets. The benefit of using this setting is to be
able to use control group as a selector in firewall rules easily and this in
turn allows more fine grained filtering. Also, NFT rules for cgroup matching
use numeric cgroup IDs, which change every time a service is restarted, making
them hard to use in systemd environment.

This option expects a whitespace separated list of NFT set definitions. Each
definition consists of a colon-separated tuple of source type (only "cgroup"),
NFT address family (one of "arp", "bridge", "inet", "ip", "ip6", or "netdev"),
table name and set name. The names of tables and sets must conform to lexical
restrictions of NFT table names. The type of the element used in the NFT filter
must be "cgroupsv2". When a control group for a unit is realized, the cgroup ID
will be appended to the NFT sets and it will be be removed when the control
group is removed.  systemd only inserts elements to (or removes from) the sets,
so the related NFT rules, tables and sets must be prepared elsewhere in
advance.  Failures to manage the sets will be ignored.

If the firewall rules are reinstalled so that the contents of NFT sets are
destroyed, command systemctl daemon-reload can be used to refill the sets.

Example:

```
table inet filter {
...
        set timesyncd {
                type cgroupsv2
        }

        chain ntp_output {
                socket cgroupv2 != @timesyncd counter drop
                accept
        }
...
}
```

/etc/systemd/system/systemd-timesyncd.service.d/override.conf
```
[Service]
NFTSet=cgroup:inet:filter:timesyncd
```

```
$ sudo nft list set inet filter timesyncd
table inet filter {
        set timesyncd {
                type cgroupsv2
                elements = { "system.slice/systemd-timesyncd.service" }
        }
}
```
2023-09-27 18:10:11 +00:00
Luca Boccassi 0112c37ce4 core: dump jobs list on sigrtmin+18 with 0x500 2023-09-11 12:24:23 +01:00
Lennart Poettering ea09a416ed core: introduce unit_defaults_init() common initialization helper
THis adds a helper for initializing UnitDefaults to our default values.
Previously we'd do that differently in two different locations. Let's
unify this in one, and apply the exact same settings at both as
defaults.
2023-09-08 15:25:05 +02:00
Lennart Poettering bfb27b06da manager: add manager_set_unit_defaults() call that sets all unit defaults in one go
No change in behaviour. Just some refactoring.
2023-09-08 15:25:05 +02:00
Lennart Poettering c9e120e06f manager: move various fields that declare unit defaults into a new structure UnitDefaults
This adds a new structure UnitDefaults which embedds the various default
settings for units we maintain. We so far maintained two sets of
variables for this, one in main.c as static variables and one in the
Manager structure. This moves them into a common structure.

This is most just search/replace, i.e. very dumb refactoring.

The fact that we now use a common structure for this allows us further
refactorings later.

Inspired by the discussions on #27890
2023-09-08 14:19:45 +02:00
Luca Boccassi b0d3095fd6 Drop split-usr and unmerged-usr support
As previously announced, execute order 66:

https://lists.freedesktop.org/archives/systemd-devel/2022-September/048352.html

The meson options split-usr, rootlibdir and rootprefix become no-ops
that print a warning if they are set to anything other than the
default values. We can remove them in a future release.
2023-07-28 19:34:03 +01:00
Lennart Poettering 13ffc60749 pid1: add "soft-reboot" reboot method
This adds a new mechanism for rebooting, a form of "userspace reboot"
hereby dubbed "soft-reboot". It will stop all services as in a usual
shutdown, possibly transition into a new root fs and then issue a fresh
initial transaction. The kernel is not replaced.

File descriptors can be passed over, thus opening the door for leaving
certain resources around between such reboots.

Usecase: this is an extremely quick way to reset userspace fully when
updating image based systems, without going through a full
hardware/firmware/boot loader/kernel/initrd cycle. It minimizes "grayout time"
for OS updates. (In particular when combined with kernel live patching)
2023-06-02 16:49:38 +02:00
Luca Boccassi d936595672 manager: restrict Dump*() to privileged callers or ratelimit
Dump*() methods can take quite some time due to the amount of data to
serialize, so they can potentially stall the manager. Make them
privileged, as they are debugging tools anyway. Use a new 'dump'
capability for polkit, and the 'reload' capability for SELinux, as
that's also non-destructive but slow.

If the caller is not privileged, allow it but rate limited to 10 calls
every 10 minutes.
2023-05-19 15:18:23 +01:00
Mike Yuan 2b680534c9 Revert "core/manager: export manager_dbus_is_running" and partially "core: refuse dbus activation if dbus is not running"
This reverts commit e886315065
and partially 53964fd26b.

Specifically, changes to signal_activation_request()
is not desired.
2023-05-12 16:21:44 +08:00
Mike Yuan e886315065 core/manager: export manager_dbus_is_running 2023-05-09 01:42:25 +08:00
Lennart Poettering 6ac62d61db service: release resources from a seperate queue, not unit_check_gc()
The per-unit-type release_resources() hook (most prominent use: to
release a service unit's fdstore once a unit is entirely dead and has no
jobs more) was currently invoked as part of unit_check_gc(), whose
primary purpose is to determine if a unit should be GC'ed. This was
always a bit ugly, as release_resources() changes state of the unit,
while unit_check_gc() is otherwise (and was before release_resources()
was added) a "passive" function that just checks for a couple of
conditions.

unit_check_gc() is called at various places, including when we wonder if
we should add a unit to the gc queue, and then again when we take it out
of the gc queue to dtermine whether to really gc it now. The fact that
these checks have side effects so far wasn't too problematic, as the
state changes (primarily: that services would empty their fdstores) were
relatively limited and scope.

A later patch in this series is supposed to extend the service state
engine with a separate state distinct from SERVICE_DEAD that is very
much like it but indicates that the service still has active resources
(specifically the fdstore). For cases like that the releasing of the
fdstore would result in state changes (as we'd then return to a classic
SERVICE_DEAD state).  And this is where the fact that the
release_resources() is called as side-effect becomes problematic: it
would mean that unit state changes would instantly propagate to state
changes elsewhere, though we usually want this to be done through the
run queue for coalescing and avoidance of recursion.

Hence, let's clean this up: let's move the release_resources() logic
into a queue of its own, and then enqueue items into it from the general
state change notification handle in unit_notify().
2023-04-13 06:44:27 +02:00
Daan De Meyer e76506b748 execute: Rename ExecRuntime to ExecSharedRuntime
Preparation for next commit
2023-03-27 14:05:30 +02:00
Lennart Poettering 4870133bfa basic: add RuntimeScope enum
In various tools and services we have a per-system and per-user concept.
So far we sometimes used a boolean indicating whether we are in system
mode, or a reversed boolean indicating whether we are in user mode, or
the LookupScope enum used by the lookup path logic.

Let's address that, in introduce a common enum for this, we can use all
across the board.

This is mostly just search/replace, no actual code changes.
2023-03-10 09:47:39 +01:00
Lennart Poettering 6bb0084204 pid1: add unit file settings to control memory pressure logic 2023-03-01 09:43:23 +01:00
Lennart Poettering 29e6b0c171 pid1: also process memory pressure events (and SIGRTMIN+18) 2023-03-01 09:43:23 +01:00
Zbigniew Jędrzejewski-Szmek e4c7b5f517 core: split system/user job timeouts and make them configurable
Config options are -Ddefault-timeout-sec= and -Ddefault-user-timeout-sec=.
Existing -Dupdate-helper-user-timeout= is renamed to -Dupdate-helper-user-timeout-sec=
for consistency. All three options take an integer value in seconds. The
renaming and type-change of the option is a small compat break, but it's just
at compile time and result in a clear error message. I also doubt that anyone was
actually using the option.

This commit separates the user manager timeouts, but keeps them unchanged at 90 s.
The timeout for the user manager is set to 4/3*user-timeout, which means that it
is still 120 s.

Fedora wants to experiment with lower timeouts, but doing this via a patch would
be annoying and more work than necessary. Let's make this easy to configure.
2023-02-01 11:52:29 +00:00
Lennart Poettering dd0ab174c3 pid1: make sure we send our calling service manager RELOADING=1 when reloading
And send READY=1 again when we are done with it.

We do this not only for "daemon-reload" but also for "daemon-reexec" and
"switch-root", since from the perspective of an encapsulating service
manager these three operations are not that different.
2023-01-10 18:28:38 +01:00
Luca Boccassi 856bfaeb05 manager: add option to rate limit daemon-reload
Reloading is a heavy-weight operation, and currently it is not
possible to stop an orchestrator from spamming reload requests.
Add configuration options to allow rate-limiting.
2022-12-13 18:13:10 +00:00
Zbigniew Jędrzejewski-Szmek 4b6a2b3f58 core: modernize style of return param naming 2022-10-17 13:50:16 +02:00
Lennart Poettering d096265708 Merge pull request #24044 from dtardon/default-device-timeout
Add a configuration option for setting default device timeout
2022-08-08 15:32:55 +02:00
Franck Bui 7870de03c5 core: replace m->honor_device_enumeration with MANAGER_IS_SWITCHING_ROOT() 2022-08-05 22:13:47 +09:00
Franck Bui d35fe8c0af core: introduce MANAGER_IS_SWITCHING_ROOT() helper function
Will be used by the following commit.
2022-08-05 22:13:43 +09:00
David Tardon a0fe19f9f7 core: allow to set default timeout for devices
Fixes: #19879
2022-08-05 13:20:00 +02:00
Łukasz Stelmach aa5ae9711e smack: Add DefaultSmackProcessLabel to user.conf and system.conf
DefaultSmackProcessLabel tells systemd what label to assign to its child
process in case SmackProcessLabel is not set in the service file. By
default, when DefaultSmackProcessLabel is not set child processes inherit
label from systemd.

If DefaultSmackProcessLabel is set to "/" (which is an invalid character
for a SMACK label) the DEFAULT_SMACK_PROCESS_LABEL set during compilation
is ignored and systemd act as if the option was unset.
2022-07-12 22:47:32 +01:00
Lennart Poettering 2ad591a3a3 pid1: search for creds in LoadCredential=/LoadCredentialEncrypted=
This adds support for searching for credentials more comprehensively.

Specifically, unless an absolute source path is specified we'll now
search for the credentials in the system credentials first, and then in
/etc/credstore/, /run/credstore/, and /usr/lib/credstore, making these
dirs hence the recommended place for credentials to leave in the system.

For LoadCredentialEncrypted= we'll also look into
/etc/credstore.encrypted/, /run/credstore.encrypted/, …. These dirs are
hence suitable for credentials whose provenience isn't trusted (e.g.
UEFI creds from systemd-stub), and thus require to be authenticated
before use.
2022-04-28 18:12:00 +02:00
Zbigniew Jędrzejewski-Szmek 83fe5d8a78 manager: rework manager_taint_string()
When I see stpcpy, my brain bleeds. This function was too complicated
for it's own good.
2022-04-06 12:55:57 +02:00