Commit Graph
9757 Commits
Author SHA1 Message Date
Lennart Poettering e735bc49ac unit: don't bother determining unit install state for transient or perpetual units
I noticed that we keep querying the preset database for transient units,
which makes little sense, since transient units are well, transient, and
hence not suject to enablement/disablement. Hence, let's shortcut things
and simply not check the preset database for them.

While we are at it, shortcut unit file state checks for transient units,
too.  We know they are transient already, we can return that directly,
no need to go to disk.

Finally, treat perpetual units like transient units for the the preset
case: also bypass the preset database. (But keep checking for the unit
file state for them, since it *is* relevant to know whether they were
generated or not.)
2025-04-01 16:44:20 +02:00
Yu Watanabe 566b8f4d46 core/manager: update comment 2025-03-31 23:22:38 +09:00
Mike Yuan 0cba5bdcf1 core/namespace: remove wonky fallback in mount_private_apivfs()
Let's avoid dropping opts willy-nilly, especially that we already
carry the logic of determining availability prior to mount (but
make sure we respect the result though, and don't assume things
are available if the check fails).
2025-03-30 18:57:18 +02:00
Mike Yuan 1614d0c451 core/namespace: stop applying mount options on private cgroupfs mount
We always unshare cgroup ns for ProtectControlGroups=private/strict,
while the mount options only apply to the cgroupfs instance
in initial cgns (c.f.
https://github.com/torvalds/linux/blob/b69bb476dee99d564d65d418e9a20acca6f32c3f/kernel/cgroup/cgroup.c#L1984)
Hence let's drop the thing wholesale.

Also, as noted in the comment already, mount_private_apivfs()
internally enforces nosuid/noexec, so drop explicit flags too.
2025-03-30 18:57:18 +02:00
Mike Yuan 32b69b190b core: delegate mountns implicitly when any of pidns/cgns/netns is in use 2025-03-30 18:57:18 +02:00
Mike Yuan 2b4cfbf91f core/execute: drop unused function param and cg unified check for cgns
While at it, remove TODO about assuming availability of cgns.
We generally want to keep that optional still.
2025-03-30 18:54:34 +02:00
Yu Watanabe e2c801e767 core: drop manager_get_unit_by_pid() and friends (#36872)
Except for one place, they are only used by test-watch-pid. Let's also
use manager_get_unit_by_pidref() and friends in the test, and drop the
_pid() variants.
2025-03-27 06:10:53 +09:00
msizanoen 85d00912c0 core/cgroup: Properly handle aborting a pending freeze operation
We must thaw the cgroup even if cgroup.events/frozen=0 if a freeze
operation is in flight as it means the cgroup is already partially
frozen.
2025-03-26 21:39:50 +01:00
Yu Watanabe eb3554666e core: drop unused wrappers of manager_get_unit_by_pidref() and friends 2025-03-27 04:15:43 +09:00
Zbigniew Jędrzejewski-Szmek c4876f604b Ratelimit attempts to open watchdog, increase logging (#35708) 2025-03-24 21:06:57 +01:00
Luca Boccassi 5aee5bda1a tree-wide: introduce LOG_ITEM() macro for verifying format string (#36780)
This introduce `LOG_ITEM()` macro that checks format strings in
log_struct() and friends.

Hopefully, this silences false-positive warnings by Coverity.
2025-03-24 12:58:14 +00:00
Zbigniew Jędrzejewski-Szmek a9cee8f4de core/manager: do not exclude watchdog logic from busy-loop protection
As reported in https://github.com/systemd/systemd/issues/35405, if the watchdog
ping failed, we effectively started a busy loop here. The previous commits
should fix this, but in general, the protection here is intended as a safety
net in case the logic is broken somewhere else. We shouldn't exclude the
watchdog stuff from this.
2025-03-24 10:45:49 +01:00
Zbigniew Jędrzejewski-Szmek ab596e4cde shared/watchdog: give up after a few failed pings
Closes https://github.com/systemd/systemd/issues/35405. Apparently some
watchdog devices can be opened, but then the pings start failing after some
time. Since the timestamp of the last successful ping is not updated, we try to
ping again immediately, causing a busy loop and excessive logging.

After trying a few different approaches to fit this into the existing framework
without changing the logic too much, I settled on an approach with a second
timestamp. In particular, the timestamp of the last successful ping is public,
exposed as WatchdogLastPingTimestamp over dbus. It'd be wrong to redefine this
to mean the last ping *attempt*. So we need a second timestamp in some form.

Also, if we give up on pinging, we probably should attempt to disarm the
watchdog. It's possible that the pinging fails, but the watchdog would still
fire. I don't think we want that, since it seems that our internal loop is
working, it's just the watchdog that is broken.

Structured message with SD_MESSAGE_WATCHDOG_PING_FAILED is logged if we fail
to ping.

I tested this by attaching gdb to pid 1 and calling close(watchdog_fd).
We get a bunch of warning messages and then an attempt to close the watchdog:
Mar 21 15:46:17 fedora systemd[1]: Failed to ping hardware watchdog /dev/watchdog0: Bad file descriptor
Mar 21 15:46:20 fedora systemd[1]: Failed to ping hardware watchdog /dev/watchdog0: Bad file descriptor
Mar 21 15:46:23 fedora systemd[1]: Failed to ping hardware watchdog /dev/watchdog0: Bad file descriptor
Mar 21 15:46:26 fedora systemd[1]: Failed to ping hardware watchdog /dev/watchdog0: Bad file descriptor
Mar 21 15:46:29 fedora systemd[1]: Failed to ping hardware watchdog /dev/watchdog0: Bad file descriptor
Mar 21 15:46:32 fedora systemd[1]: Failed to ping hardware watchdog /dev/watchdog0: Bad file descriptor
Mar 21 15:46:35 fedora systemd[1]: Failed to ping hardware watchdog /dev/watchdog0: Bad file descriptor
Mar 21 15:46:37 fedora systemd[1]: Failed to ping hardware watchdog /dev/watchdog0: Bad file descriptor
Mar 21 15:46:40 fedora systemd[1]: Failed to ping hardware watchdog /dev/watchdog0: Bad file descriptor
Mar 21 15:46:43 fedora systemd[1]: Failed to ping hardware watchdog /dev/watchdog0: Bad file descriptor
Mar 21 15:46:46 fedora systemd[1]: Failed to ping hardware watchdog /dev/watchdog0: Bad file descriptor
Mar 21 15:46:49 fedora systemd[1]: Failed to ping hardware watchdog /dev/watchdog0: Bad file descriptor
Mar 21 15:46:52 fedora systemd[1]: Failed to ping hardware watchdog /dev/watchdog0: Bad file descriptor
Mar 21 15:46:55 fedora systemd[1]: Failed to ping hardware watchdog /dev/watchdog0: Bad file descriptor
Mar 21 15:46:58 fedora systemd[1]: Failed to ping hardware watchdog /dev/watchdog0, closing watchdog after 15 attempts: Bad file descriptor
Mar 21 15:46:58 fedora systemd[1]: Failed to disable hardware watchdog, ignoring: Bad file descriptor
Mar 21 15:46:58 fedora systemd[1]: Failed to disarm watchdog timer, ignoring: Bad file descriptor
2025-03-24 10:45:49 +01:00
Lennart Poettering ed13622bc8 core: not sure why but TTYRows/TTYColumns property is 16bit towards outside, 32bit inside, handle that properly 2025-03-22 12:51:25 +01:00
Lennart Poettering 0b0cb6f33d core: fix C type handler for ExitCode property 2025-03-22 12:47:48 +01:00
Zbigniew Jędrzejewski-Szmek 2c6397d1c2 pid1: log if we failed to find a watchdog device
I think we need to log at some point if the user configured a watchdog device,
but no devices were found. We can't log ENOENT immediately, because the device
may likely appear during boot. So wait until the end of the initial transaction
and log then.
2025-03-21 11:38:43 +01:00
Zbigniew Jędrzejewski-Szmek 18284f5a1b core: drop duplicated check in manager_{set,override}_watchdog
Those functions call watchdog_setup() and watchdog_setup_pretimeout(), which
internally do a similar check against the static variables watchdog_timeout and
watchdog_pretimeout. The second check is not useful.
2025-03-21 11:30:26 +01:00
Mike Yuan 551d4c91e8 core/meson: libcore doesn't depend on PAM
It's only used by sd-executor.
2025-03-20 21:34:31 +00:00
Lennart Poettering 9d37b8f690 namespace: use EBADF where appropriate 2025-03-20 12:26:06 +01:00
Yu Watanabe db4b4e0cd3 core: Make DelegateNamespaces= work for user managers with CAP_SYS_ADMIN (#36771)
Currently DelegateNamespaces= only works for services spawned by the
system manager. User managers will always unshare the user namespace
first even if they're running with CAP_SYS_ADMIN.

Let's add support for DelegateNamespaces= for user managers if they're
running with CAP_SYS_ADMIN. By default, we'll still delegate all
namespaces
for user managers, but this can now be overridden by explicitly passing
DelegateNamespaces=.

If a user manager is running without CAP_SYS_ADMIN, the user manager is
still always unshared first just like before.
2025-03-20 06:28:18 +09:00
Yu Watanabe bb8c74d7f2 Introduce ConditionVersion (#36468)
Add a new condition which can check against systemd version.

        $ systemctl --version
        systemd 258 (258~devel-g53ca5f6)

        $ systemd-analyze condition 'ConditionVersion=systemd>255'
        test.service: ConditionVersion=>255 succeeded.

        $ systemd-analyze condition 'ConditionVersion=systemd>260'
        test.service: ConditionVersion=>260 failed.

        $ systemd-analyze condition 'ConditionVersion=systemd>=258'
        test.service: ConditionVersion=>=258 succeeded.

        $ systemd-analyze condition 'ConditionVersion=systemd>=257.1'
        test.service: ConditionVersion=>=257.1 succeeded.

        $ uname -r
        6.12.13-200.fc41.aarch64

        $ systemd-analyze condition 'ConditionVersion=kernel > 4.4'
        test.service: ConditionVersion=kernel > 4.4 succeeded.

        $ systemd-analyze condition 'ConditionVersion=kernel > 6.20'
        test.service: ConditionVersion=kernel > 6.20 failed.

        $ systemd-analyze condition 'ConditionVersion=kernel < 9.0'
        test.service: ConditionVersion=kernel < 9.0 succeeded.
2025-03-20 06:15:35 +09:00
Lennart Poettering bb160976b0 cgroup: whenever we migrate a PID to a unit, explicitly drop unit from empty notification queue
A unit might be pending in the empty queue still when we add a PID to
the cgroup. At that point, let's explicitly remove the unit from that
queue.

Fixes: #36781
2025-03-19 21:40:33 +01:00
Daan De Meyer 38748596f0 core: Make DelegateNamespaces= work for user managers with CAP_SYS_ADMIN
Currently DelegateNamespaces= only works for services spawned by the
system manager. User managers will always unshare the user namespace
first even if they're running with CAP_SYS_ADMIN.

Let's add support for DelegateNamespaces= for user managers if they're
running with CAP_SYS_ADMIN. By default, we'll still delegate all namespaces
for user managers, but this can now be overridden by explicitly passing
DelegateNamespaces=.

If a user manager is running without CAP_SYS_ADMIN, the user manager is
still always unshared first just like before.
2025-03-19 10:01:19 +01:00
Daan De Meyer 918a188fda core: Also check if we can mount /proc if pid namespace is delegated
If the pid namespace is delegated, it doesn't matter if we have CAP_SYS_ADMIN,
we'll still fail to mount /proc if part of it is masked on the host so also
check if we can mount /proc if the pid namespace is delegated.
2025-03-19 10:00:45 +01:00
Daan De Meyer af6a8b6969 exec-invoke: Rename various variables from has_ to have_
All of these encode information of the current process, so have_ is
more approriate than has_, which refers to something else.
2025-03-19 10:00:45 +01:00
Yu Watanabe 3cf6a3a3d4 tree-wide: check more log message format in log_struct() and friends
This introduce LOG_ITEM() macro that checks arbitrary formats in
log_struct().
Then, drop _printf_ attribute from log_struct_internal(), as it does not
help so much, and compiler checked only the first format string.

Hopefully, this silences false-positive warnings by Coverity.
2025-03-19 01:56:48 +09:00
Matteo Croce c154bb65ad condition: introduce ConditionVersion=/AssertVersion=
Add a new condition wich checks against systemd version.
Change condition_test_kernel_version() into a generic condition_test_version()
so most of the code can be reused.

    $ systemctl --version
    systemd 258 (258~devel-g53ca5f6)

    $ systemd-analyze condition 'ConditionVersion=systemd>255'
    test.service: ConditionVersion=>255 succeeded.

    $ systemd-analyze condition 'ConditionVersion=systemd>260'
    test.service: ConditionVersion=>260 failed.

    $ systemd-analyze condition 'ConditionVersion=systemd>=258'
    test.service: ConditionVersion=>=258 succeeded.

    $ systemd-analyze condition 'ConditionVersion=systemd>=257.1'
    test.service: ConditionVersion=>=257.1 succeeded.

    $ uname -r
    6.12.13-200.fc41.aarch64

    $ systemd-analyze condition 'ConditionVersion=kernel > 4.4'
    test.service: ConditionVersion=kernel > 4.4 succeeded.

    $ systemd-analyze condition 'ConditionVersion=kernel > 6.20'
    test.service: ConditionVersion=kernel > 6.20 failed.

    $ systemd-analyze condition 'ConditionVersion=kernel < 9.0'
    test.service: ConditionVersion=kernel < 9.0 succeeded.
2025-03-18 18:36:59 +09:00
Lennart Poettering 33cbda04eb xattr-util: rework getxattr_at_malloc()
Let's return the size in a return parameter instead of the return value.
And if NULL is specified this tells us the caller doesn't care about the
size and expects a NUL terminated string. In that case look for an
embedded NUL byte, and refuse in that case.

This should lock things down a bit, as we'll systematically refuse
embedded NUL strings now when we expect strings.
2025-03-18 07:17:10 +01:00
Lennart Poettering 5c9327e353 namespace: simplify apply_one_mount() a bit
Drop a bunch of unnecessary casts, format strings, and {} blocks.
2025-03-17 16:03:18 +01:00
Lennart Poettering 6431c34b8a namespace-util: make "setgroups" users property writable via userns_acquire()
Unprivileged namespaces are only allowed if the "setgroups" file is set
to "deny" for processes. And we need to write it before writing the
gidmap. Hence add a parameter for that.

Then, also patch all current users to actually enable this. The usecase
generally don't need it (because they don't care about unprivileged
userns), but it doesn't hurt to enable the concept anyway in all current
users (none of them actually runs complex userspace in them, but they
mostly use userns_acquire() for idmapped mounts and similar).

Let's anyway make this option explicit in the function call, to indicate
that the concept exists and is applied.
2025-03-17 16:03:18 +01:00
Lennart Poettering 19aff5f775 main: explicitly pick up $COLORTERM + $NO_COLOR from kernel cmdline where we pick up $TERM
I think we should work towards always picking up the triplet of $TERM +
$COLORTERM + $NO_COLOR where we so far picked up $TERM only. I think
it's safe to say that at this time, $TERM is not enough anymore to
clearly communicate terminal feature support. Hence, teach PID 1 to pick
$COLORTERM + $NO_COLOR wherever we pick up $TERM.
2025-03-17 10:17:51 +01:00
Lennart Poettering 728dbaeffb exec: when we have no $TERM configuration, and we default to vt220, also set $COLORTERM
When we configure a serial or VM terminal and have no $TERM
configuration, then we default to vt220 as a fallback. This is a pretty
safe bet, since the termcap/terminfo definitions for vt220 are
relatively widely available (much like vt100), and (in contrast to
vt100) it supports pageup/pagedown keys. vt220 is a terminal without
color support however, but we do want color support, because in 2025
there's really no terminal emulator without color in this world.

The $COLORTERM env var is used my many emulators and tools to
communicate that ANSI color support is available, despite what $TERM
says. Hence, let's tweak systemd's logic to also set $COLORTERM in case
we set the vt220 $TERM fallback.

This means we define an ahistoric frankenterminal: a vt220 (that
historically definitely didn't have color) that is explicitly configured
to have color.

One effect of this is that coreutils' dircolors command will start to
output color sequences in systemd's serial or VM terminals. (Since it
actually honours $COLORTERM).

Also note that systemd itself checks $COLORTERM since a long time, hence
it makes sense for us to also set it.

Note that this unfortunately doesn't have the desired effect of
propagating $COLORTERM into any getty shell sessions yet. That's because
util-linux' login package currently fiters $COLORTERM (but lets $TERM
though). I filed a bug about that here:

https://github.com/util-linux/util-linux/issues/3463
2025-03-17 10:15:51 +01:00
Mike Yuan 399791eaf0 core/taint: we know we're always running on cgv2 now 2025-03-16 18:02:07 +01:00
Mike Yuan 2b61489e5a core/main: refuse bootup with legacy cgroup hierarchy
First step towards a unified-only future (rework of internals
coming soon (TM))
2025-03-16 15:30:39 +01:00
Mike Yuan 36dad381a2 mount-setup: remove cgroup v1 hierarchy mounting 2025-03-16 15:30:38 +01:00
Mike Yuan 64db06c421 mount-setup: generalize cgroupfs_recursiveprot_supported() 2025-03-16 15:22:13 +01:00
Zbigniew Jędrzejewski-Szmek 1ae9b0cfa8 basic/glyph-util: rename "special glyph" to just "glyph"
Admittedly, some of our glyphs _are_ special, e.g. "O=" for SPECIAL_GLYPH_TOUCH ;)
But we don't need this in the name. The very long names make some invocations
very wordy, e.g. special_glyph(SPECIAL_GLYPH_SLIGHTLY_UNHAPPY_SMILEY).
Also, I want to add GLYPH_SPACE, which is not special at all.
2025-03-15 14:40:39 +01:00
Lennart Poettering e707d0459c analyze: don't connect to bus from analyze test run (#36719)
This thing should not be "live", hence don't try to connect to the bus,
or bind the private bus socket.

Fixes: #36540
2025-03-13 17:51:45 +01:00
Lennart Poettering 96a0cfbf47 emergency-action: sleep 5s before rebooting in various cases
This adds a new EMERGENCY_ACTION_SLEEP_5S flag, which when set will
delay the emergency action for 5s. This is supposed to be used together
with EMERGENCY_ACTION_WARN so that users can actually read the message
we output.

We enable this with all emergency action requests that already set
EMERGENCY_ACTION_WARN, except for the 7x ctrl-alt-del burst reboot,
where the user knows what they do and there's no real reason to wait,
they don't need to be informed.

This also enables both EMERGENCY_ACTION_WARN + EMERGENCY_ACTION_SLEEP_5S
for FailureAction= processing of regular units, where these were so far
off. (it leaves this off for SuccessAction= however!). This is a good
thing to make things more debuggable: if something fails and we reboot
this really deserves notification of the user.

(For SuccessAction= this logic does not apply, since the shutdown action
induced here is apparently intended part of the codeflow, for example in
systemd-reboot.service or a similar unit, where the shutdown is goal and
not exception and derserves no additional noisy reporting).

Inspired by: https://github.com/systemd/systemd/pull/36705#issuecomment-2717014120
2025-03-13 17:03:42 +01:00
Lennart Poettering 2544075c0b execute: add some minor debug logging 2025-03-13 14:22:13 +01:00
Lennart Poettering ec5bcf0b69 pid1: don't connect to oomd in test runs 2025-03-13 14:22:13 +01:00
Lennart Poettering 71a737d68d analyze: don't connect to bus from analyze test run
This thing should not be "live", hence don't try to connect to the bus,
or bind the private bus socket.

Fixes: #36540
2025-03-13 14:22:13 +01:00
Lennart Poettering e75fbee624 manager: explicitly create our private runtime directory
So far /run/systemd/ was created as side-effect of initializing the
D-Bus client/server. But in one of the next commits we'll suppress
connecting to D-Bus in test runs, hence let's move the logic our of the
D-Bus code and into manager_startup().

Then, also drop creating it again and again in PID 1 at various places,
and just rely on it to exist.
2025-03-13 14:22:13 +01:00
Lennart Poettering af9c45d5b6 hostname: support that /etc/hostname contains ??? as wildcards to be replaced by hash value from /etc/machine-id 2025-03-11 18:01:42 +01:00
Lennart Poettering f8a09ace1d core/service: introduce sd_notify() RESTART_RESET=1 for resetting restart counter (#36698) 2025-03-11 12:03:12 +01:00
Mike Yuan fce19eb67f core/main: fix logging of /sbin/init exec failure
Follow-up for 93e19483dc

While at it, avoid duplicate manager_status_printf()
(error_message will be shown in main()).
2025-03-11 12:02:57 +01:00
Mike Yuan 406aeb5da6 core/service: introduce sd_notify() RESTART_RESET=1 for resetting restart counter
We have RestartMaxDelaySec= + RestartSteps= to exponentially increase
auto restart durations, but it currently cannot be reset by the service
itself, which makes it sometimes awkward to use. A typical pattern
in real life is that a service was once down (e.g. due to temporary
network interruption) and multiple restarts were attempted. Then,
future restarts would always wait for increated amount of time based on
RestartMaxDelaySec=, even after the original problem got resolved.
Such "persistence" could result in longer unavailablity than there
should be for failures that come later.
(C.f. https://utcc.utoronto.ca/~cks/space/blog/linux/SystemdResettingUnitBackoff)

Let's introduce a new sd_notify() notification for resetting the restart
counter. There were discussions about making this timer-based, but I think
it's more flexible to leave the decision-making to the service. This enables
them to do a combination of N successful requests + uptime check for instance.
2025-03-11 00:44:44 +01:00
Mike Yuan a364ebd46d core/unit: disable unit debug invocation in generic unit_reset_failed() 2025-03-10 23:59:31 +01:00
Yu Watanabe c0cc01de8a meson: use install_symlink() where applicable
Now our baseline of meson is 0.62, hence install_symlink() can be used.

Note, install_symlink() implies install_emptydir() for specified
install_dir. Hence, this also drops several unnecessary
install_emptydir() calls.

Note, the function currently does not support 'relative' and 'force' flags,
so several 'ln -frsT' inline calls cannot be replaced.
2025-03-10 02:41:40 +09:00
Mike Yuan 590e0e3bac core/main: correct retval for reexec/switch-root/soft-reboot
For these objectives we ought to execve() at the end, i.e. if we
ever hit the return path something went wrong in do_reexecute().
Let's properly report that via retval.
2025-03-08 20:49:30 +01:00