Commit Graph
333 Commits
Author SHA1 Message Date
Yu Watanabe 223a67e572 tree-wide: replace reallocarray() with GREEDY_REALLOC() 2024-10-08 19:56:09 +09:00
Zbigniew Jędrzejewski-Szmek 8dc40c25a4 shared: adjust whitespace and formatting 2024-09-27 20:19:58 +02:00
Daan De Meyer fa693fdc7e core: Add support for PrivateUsers=identity
This configures an indentity mapping similar to
systemd-nspawn --private-users=identity.
2024-09-09 18:31:01 +02:00
Mike Yuan 7a9f0125bb core: rename BindJournalSockets= to BindLogSockets=
Addresses https://github.com/systemd/systemd/pull/32487#issuecomment-2328465309
2024-09-04 21:44:25 +02:00
Mike Yuan 368a3071e9 core: introduce BindJournalSockets=
Closes #32478
2024-09-03 21:04:50 +02:00
Daan De Meyer 831f208783 core: Add support for renaming credentials with ImportCredential=
This allows for "per-instance" credentials for units. The use case
is best explained with an example. Currently all our getty units
have the following stanzas in their unit file:

"""
ImportCredential=agetty.*
ImportCredential=login.*
"""

This means that setting agetty.autologin=root as a system credential
will make every instance of our all our getty units autologin as the
root user. This prevents us from doing autologin on /dev/hvc0 while
still requiring manual login on all other ttys.

To solve the issue, we introduce support for renaming credentials with
ImportCredential=. This will allow us to add the following to e.g.
serial-getty@.service:

"""
ImportCredential=tty.serial.%I.agetty.*:agetty.
ImportCredential=tty.serial.%I.login.*:login.
"""

which for serial-getty@hvc0.service will make the service manager read
all credentials of the form "tty.serial.hvc0.agetty.xxx" and pass them
to the service in the form "agetty.xxx" (same goes for login). We can
apply the same to each of the getty units to allow setting agetty and
login credentials for individual ttys instead of globally.
2024-07-31 15:52:27 +02:00
Mike Yuan b1ed7e6749 sleep,home: always initialize UnitFreezer if used
Previously, unit_freezer_new_freeze() would only return
UnitFreezer object if FreezeUnit() succeeds. This is not
ideal though, as a failed bus call doesn't mean the action
actually failed. E.g. a timeout might occur because pid1
is waiting for cgroup event from kernel, while the bus call
timeout was exceeded (#33269). In such a case, ThawUnit()
will never be called, resulting in frozen units remain that
way after resuming from sleep.

Therefore, let's get rid of unit_freezer_new_freeze(),
and make sure as long as unit freezer is involved, we'll
call ThawUnit() when we're done. This should make things
a lot more robust.
2024-07-17 18:14:33 +02:00
Mike Yuan eb37c0c078 bus-unit-util: add PrivateTmpEx to bus_append_execute_property()
Follow-up for 9d50d053f3
2024-06-23 06:43:14 +09:00
Zbigniew Jędrzejewski-Szmek 835fbe5f75 bus-unit-util: extend the bus call timeout for UnitFreezer
Follow-up for 1d617b35fe.
Should fix https://github.com/systemd/systemd/issues/33269.

From the logs in the bug:
Jun 10 22:55:37 systemd-logind[909]: The system will suspend now!
Jun 10 22:55:37 ModemManager[996]: <msg> [sleep-monitor-systemd] system is about to suspend
...
Jun 10 22:55:48 systemd-sleep[422408]: Failed to freeze unit 'user.slice': Connection timed out
Jun 10 22:55:48 systemd-sleep[422408]: Performing sleep operation 'suspend'...

The delay is ~11 s, consistent with the patch that set the timeout to 10 s.
Looks like this is not enough. It's the freeze operation that fails, but
thawing might be slow too, so just bump the timeout again.
2024-06-11 14:56:00 +01:00
Mike Yuan 1d617b35fe bus-unit-util: extend the bus call timeout for UnitFreezer
Might fix #33083

There's another report available on Mastodon:
https://m.otter.homes/@kaixin/112510783502516607
https://m.otter.homes/@kaixin/112510803023469180
2024-05-30 21:51:48 +08:00
Mike Yuan 12904d5387 bus-unit-util: rework UnitFreezer, explicitly thaw unit
Currently, we don't explicitly call unit_freezer_thaw(),
but rely on the destructor to thaw the frozen unit on
return. This has several problems though, one of them
being that we ignore the return value of ThawUnit(),
which is something we really shouldn't do here,
since such failure can easily leave the whole system
in unusable state. Moreover, the logging is kinda messy,
e.g. homed might log "Everything completed" yet immediately
followed by "Failed to thaw unit". Instead, we should log
consistently and at higher level, to make things more
debuggable.

Therefore, let's step away from the practice. Plus,
make UnitFreezer object heap-allocated, to match
with existing unit_freezer_new() and allow us to
use NULL to denote that the freezer is disabled.
2024-05-30 21:51:48 +08:00
Yu Watanabe 4e494e6aac tree-wise: several cleanups for logging
- drop unnecessary SYNTHETIC_ERRNO() when the logger does not propagate
  error code,
- drop unnecessary '%m' in error message when the error code is
  specified with SYNTHETIC_ERRNO(),
- add missing full stop at the end of log message,
- use RET_GATHER(),
- add missing ", ignoring.",
- upeercase the first letter, etc., etc...
2024-05-01 04:41:06 +09:00
Jakub Sitnicki 97df75d7bd socket: pass socket FDs to all ExecXYZ= commands but ExecStartPre=
Today listen file descriptors created by socket unit don't get passed to
commands in Exec{Start,Stop}{Pre,Post}= socket options.

This prevents ExecXYZ= commands from accessing the created socket FDs to do
any kind of system setup which involves the socket but is not covered by
existing socket unit options.

One concrete example is to insert a socket FD into a BPF map capable of
holding socket references, such as BPF sockmap/sockhash [1] or
reuseport_sockarray [2]. Or, similarly, send the file descriptor with
SCM_RIGHTS to another process, which has access to a BPF map for storing
sockets.

To unblock this use case, pass ListenXYZ= file descriptors to ExecXYZ=
commands as listen FDs [4]. As an exception, ExecStartPre= command does not
inherit any file descriptors because it gets invoked before the listen FDs
are created.

This new behavior can potentially break existing configurations. Commands
invoked from ExecXYZ= might not expect to inherit file descriptors through
sd_listen_fds protocol.

To prevent breakage, add a new socket unit parameter,
PassFileDescriptorsToExec=, to control whether ExecXYZ= programs inherit
listen FDs.

[1] https://docs.kernel.org/bpf/map_sockmap.html
[2] https://lore.kernel.org/r/20180808075917.3009181-1-kafai@fb.com
[3] https://man.archlinux.org/man/socket.7#SO_INCOMING_CPU
[4] https://www.freedesktop.org/software/systemd/man/latest/sd_listen_fds.html
2024-03-27 01:41:26 +08:00
Daan De Meyer 66b574b0a2 tree-wide: Add allow_pidfd argument to bus_append_scope_pidref() 2024-03-22 17:03:35 +01:00
Mike Yuan 1ea275f119 core/cgroup: introduce MemoryZSwapWriteback setting
Added in
https://github.com/torvalds/linux/commit/501a06fe8e4c185bbda371b8cedbdf1b23a633d8
2024-03-13 23:36:25 +00:00
Mike Yuan dc35af47df bus-unit-util: trivial follow-up for UnitFreezer
Follow-up for 7483708131

Make sure that function param names match between
source and header. Also, place UnitFreezer params
in front.
2024-03-08 01:10:09 +08:00
Mike Yuan 5ba6321d86 bus-unit-util: define FREEZE_BUS_CALL_TIMEOUT locally
Follow-up for f274f8bf25

We define *_SLOW_BUS_CALL_TIMEOUT in each component's
own file too. This one is no different and doesn't need
to be in constants.h IMO.
2024-03-08 01:09:01 +08:00
Adrian Vovk 7483708131 bus-unit-util: Add utility to freeze/thaw units
This utility lets us freeze units, and then automatically thaw them
when via a _cleanup_ handler. For example, you can now write something
like:

```
_cleanup_(unit_freezer_thaw) UnitFreezer freezer = UNIT_FREEZER_NULL;
r = unit_freezer_freeze("myunit.service", &freezer);
if (r < 0)
    return r;
// Freeze is thawed once this scope ends
```

Aside from the basic _freeze and _thaw methods, there's also
_cancel and _restore. Cancel destroys the UnitFreezer without
thawing the unit. Restore creates a UnitFreezer without freezing it.
The idea of these two methods is that it allows the freeze/thaw to
be separated from each other (i.e. done in response to two separate
DBus method calls). For example:

```
_cleanup_(unit_freezer_thaw) UnitFreezer freezer = UNIT_FREEZER_NULL;
r = unit_freezer_freeze("myunit.service", &freezer);
if (r < 0)
    return r;
// Freeze is thawed once this scope ends

r = do_something()
if (r < 0)
    return r; // Freeze is thawed

unit_freezer_cancel(&freezer); // Thaw is canceled.
```

Then in another scope:
```
// Bring back a UnitFreezer object for the already-frozen service
_cleanup_(unit_freezer_thaw) UnitFreezer freezer = UNIT_FREEZER_NULL;
r = unit_freezer_restore("myunit.service", &freezer);
if (r < 0)
    return r;
// Freeze is thawed once this scope ends
```
2024-03-05 12:12:34 -05:00
Mike Yuan 4f49512695 extract-word: modernize extract_many_words 2024-03-03 19:01:00 +08:00
Lennart Poettering 04a3af3c6d tree-wide: be more careful when passing literal integers to "t" bus message fields
Since we use varargs for sd_message_append() we need to make sure the
parameters we pass are actually 64bit wide, if "t" is used. Hence cast
appropriately if necessary.

I went through the whole tree, and in most cases we got it right, but
there are some cases we missed so far.

Inspired by: #31420
2024-02-22 04:31:50 +09:00
Mike Yuan bdd2036e81 hexdecoct: make unbase64mem and unhexmem always use SIZE_MAX 2024-01-09 03:59:15 +09: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
Nick Rosbrook 6cf96ab456 core: add CoredumpReceive= setting
This setting indicates that the given unit wants to receive coredumps
for processes that crash within the cgroup of this unit. This setting
requires that Delegate= is also true, and therefore is only available
where Delegate= is available.

This will be used by systemd-coredump to support forwarding coredumps to
containers.
2023-10-13 15:13:11 -04:00
Mike Yuan 854eca4a95 core/execute: always set $USER and introduce SetLoginEnvironment=
Before this commit, $USER, $HOME, $LOGNAME and $SHELL are only
set when User= is set for the unit. For system service, this
results in different behaviors depending on whether User=root is set.

$USER always makes sense on its own, so let's set it unconditionally.
Ideally $HOME should be set too, but it causes trouble when e.g. getty
passes '-p' to login(1), which then doesn't override $HOME. $LOGNAME and
$SHELL are more like "login environments", and are generally not
suitable for system services. Therefore, a new option SetLoginEnvironment=
is also added to control the latter three variables.

Fixes #23438

Replaces #8227
2023-10-10 00:00:26 +08:00
Lennart Poettering 7eda208ffe tree-wide: prefer sending pifds over pids when creating scope units 2023-10-05 17:10:00 +02:00
Luca Boccassi 559214cbbd pid1: add SurviveFinalKillSignal= to skip units on final sigterm/sigkill spree
Add a new boolean for units, SurviveFinalKillSignal=yes/no. Units that
set it will not have their process receive the final sigterm/sigkill in
the shutdown phase.

This is implemented by checking if a process is part of a cgroup marked
with a user.survive_final_kill_signal xattr (or a trusted xattr if we
can't set a user one, which were added only in kernel v5.7 and are not
supported in CentOS 8).
2023-09-28 13:48:14 +01:00
Topi Miettinen 3bb48b19bd core: add user and group to NFTSet=
The benefit of using this setting is that user and group IDs, especially dynamic and random
IDs used by DynamicUser=, can be used in firewall configuration easily.

Example:

```
[Service]
NFTSet=user:inet:filter:serviceuser
```

Corresponding NFT rules:

```
table inet filter {
        set serviceuser {
                typeof meta skuid
        }
        chain service_output {
                meta skuid @serviceuser accept
                drop
        }
}
```

```
$ cat /etc/systemd/system/dunft.service
[Service]
DynamicUser=yes
NFTSet=user:inet:filter:serviceuser
ExecStart=/bin/sleep 1000

[Install]
WantedBy=multi-user.target
$ sudo nft list set inet filter serviceuser
table inet filter {
        set serviceuser {
                typeof meta skuid
                elements = { 64864 }
        }
}
$ ps -n --format user,group,pid,command -p `systemctl show dunft.service -P MainPID`
    USER    GROUP     PID COMMAND
   64864    64864   55158 /bin/sleep 1000
```
2023-09-27 18:10:11 +00: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
Lennart Poettering 2bec84e7a5 core: add new "PollLimit" settings to .socket units
This adds a new "PollLimit" pair of settings to .socket units, very
similar to existing "TriggerLimit" logic. The differences are:

* PollLimit focusses on the polling on the sockets, and pauses that
  temporarily if a ratelimit on that is reached. TriggerLimit otoh
  focusses on the triggering effect of socket units, and stops
  triggering once the ratelimit is hit.

* While the trigger limit being hit is an action that causes the socket
  unit to fail the polling limit being reached will just temporarily
  disable polling on the socket fd, and it is resumed once the ratelimit
  interval is over.

* When a socket unit operates on multiple socket fds (e,g, ListenStream=
  on both some ipv6 and an ipv4 address or so). Then the PollLimit will
  be specific to each fd, while the trigger limit is specific to the
  whole unit.

Implementation-wise this is mostly a wrapper around sd-event's
sd_event_source_set_ratelimit(), which exposes the desired behaviour
directly.

Usecase for all of this: socket services which when overloaded with
connections should just slow down reception of it, but not fail
persistently.
2023-09-18 18:55:19 +02:00
Lennart Poettering e2fc0a7222 tree-wide: don't ifdef seccomp-util.h, drop seccomp.h inclusion everywhere
seccomp-util.h doesn't need ifdeffing, hence don't. It has worked since
quite a while with HAVE_SECCOMP is off, hence use it everywhere.

Also drop explicit seccomp.h inclusion everywhere (which needs
HAVE_SECCOMP ifdeffery everywhere). seccomp-util.h includes it anyway,
automatically, which we can just rely on, and it deals with HAVE_SECCOMP
at one central place.
2023-08-21 18:50:29 +02:00
Lennart Poettering 65a57927ad seccomp: move seccomp_parse_errno_or_action() into common definitions
Let's remove some HAVE_SECCOMP ifdeffery by simply defining the funcion
in question (seccomp_parse_errno_or_action() + related calls) into
common code that is also compiled if HAVE_SECCOMP is off.

This is generally the better approach anyway, since we want as much as
possible and easily feasible parsers work even if the code implementing
them is disabled. THis is easy to achieve here, hence do.
2023-08-21 18:50:29 +02:00
Luca Boccassi 3835b9aa4b Revert "core: add IgnoreOnSoftReboot= unit option"
The feature is not ready, postpone it

This reverts commit b80fc61e89.
2023-07-22 23:27:27 +01:00
Luca Boccassi b80fc61e89 core: add IgnoreOnSoftReboot= unit option
As it says on the tin, configures the unit to survive a soft reboot.
Currently all the following options have to be set by hand:

Conflicts=reboot.target kexec.target poweroff.target halt.target
Before=reboot.target kexec.target poweroff.target halt.target
After=sysinit.target basic.target
DefaultDependencies=no
IgnoreOnIsolate=yes

This is not very user friendly. If new default dependencies are added,
or new shutdown/reboot types, they also have to be added manually.

The new option is much simpler, easy to find, and does the right thing
by default.
2023-07-21 18:05:41 +02:00
Lennart Poettering a93993584d bus-unit-util: add common code for reloading PID 1
We have this very similar code in various places, and it#s not entirely
obvious (since we want a prolonged timeout for the reload), hence unify
this at one place.
2023-07-10 16:39:16 +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
Daan De Meyer 9c0c670125 core: Add RootEphemeral= setting
This setting allows services to run in an ephemeral copy of the root
directory or root image. To make sure the ephemeral copies are always
cleaned up, we add a tmpfiles snippet to unconditionally clean up
/var/lib/systemd/ephemeral. To prevent in use ephemeral copies from
being cleaned up by tmpfiles, we use the newly added COPY_LOCK_BSD
and BTRFS_SNAPSHOT_LOCK_BSD flags to take a BSD lock on the ephemeral
copies which instruct tmpfiles to not touch those ephemeral copies as
long as the BSD lock is held.
2023-06-21 12:48:46 +02:00
Daan De Meyer bbfb25f4b9 creds: Add ImportCredential=
ImportCredential= takes a credential name and searches for a matching
credential in all the credential stores we know about it. It supports
globs which are expanded so that all matching credentials are loaded.
2023-06-08 14:09:18 +02:00
Stefan Roesch 85614c6e2f add support for KSM
This adds support for KSM (kernel samepage merging). It adds a new
boolean parameter called MemoryKSM to enable the feature. The feature
can only be enabled with newer kernels.
2023-06-05 11:22:43 +02:00
Mike Yuan a559ea1535 bus-unit-util: add missing RestartSteps and RestartMaxDelaySec to bus_append_service_property
Follow-up for be1adc27fc
2023-05-18 00:23:49 +08:00
Lennart Poettering a8b993dc11 core: add DelegateSubgroup= setting
This implements a minimal subset of #24961, but in a lot more
restrictive way: we only allow one level of subcgroup (as that's enough
to address the no-processes in inner cgroups rule), and does not change
anything about threaded cgroup logic or similar, or make any of this new
behaviour mandatory.

All this does is this: all non-control processes we invoke for a unit
we'll invoke in a subgroup by the specified name.

We'll later port all our current services that use cgroup delegation
over to this, i.e. user@.service, systemd-nspawn@.service and
systemd-udevd.service.
2023-04-27 12:18:32 +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
Lennart Poettering 3af48a86d9 Merge pull request #25608 from poettering/dissect-moar
dissect: add dissection policies
2023-04-12 13:46:08 +02:00
David Tardon 5e891cbb5c tree-wide: drop unneeded output params
Neither of the callers of bus_deserialize_and_dump_unit_file_changes()
touches the changes array, so let's simplify things and keep it internal
to the function.
2023-04-12 09:53:55 +02:00
Lennart Poettering 84be0c710d tree-wide: hook up image dissection policy logic everywhere 2023-04-05 20:45:30 +02:00
Jan Engelhardt 18fe76eba5 doc: correct wrong use "'s" contractions 2023-03-07 13:39:31 +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 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
Yu Watanabe b3f1afc089 Merge pull request #24058 from qdeslandes/journald_regex_filtering
Allow for journald logs filtering on a per-unit basis
2022-12-15 22:03:33 +09:00
Quentin Deslandes 523ea1237a journal: log filtering options support in PID1
Define new unit parameter (LogFilterPatterns) to filter logs processed by
journald.

This option is used to store a regular expression which is carried from
PID1 to systemd-journald through a cgroup xattrs:
`user.journald_log_filter_patterns`.
2022-12-15 09:57:39 +00:00