Commit Graph
932 Commits
Author SHA1 Message Date
Mike Yuan 9984a35d65 core/execute: stop looking at ExecSharedRuntime to determine PrivateTmp= state
The only reason why ExecSharedRuntime.(var_)tmp_dir might
be suppressed is when (/var)/tmp/ is listed in InaccessiblePaths=,
in which case mount namespace is needed anyways. Moreover,
the current logic imposes a chicken-and-egg problem:
at various places in pid1 we'd need to check whether
the unit runs in a mountns, but the ExecSharedRuntime
may not be allocated for it just yet.
2026-02-25 12:38:11 +01:00
Lennart Poettering e93fd71094 core: introduce PinnedResource
This introduces PinnedResources as a structure combining pinned
references to a root directory, root image, or root mstack. This is not
only easier to work with, but essential to make certain unpriv things
work, as we need some mechanism to pin resources before we drop into a
userns which might possibly not provide access anymore to those
resources.

Hence this does two things: introduce the new structure, and immediately
hook it up so that we pin things properly before dropping into userns,
and then makes use of this after dropping the right way, and enables
unpriv userns operation.

The concept is generic enough to eventually implement extension images +
mount images with the same structure, but in order to keep the changes
managable this is left for another time.

(This also makes one further clean-up: client-side verity-reuse checks
are moved server side if we are unpriv. Previously we'd do them client
side, but they were doomed to fail because of lack of privs. Hence let's
drop the client side if we are unpriv and purely do them server-side in
that case.)
2026-02-19 15:08:20 +01:00
Lennart Poettering 32b88dd25a pid1: introduce RootMStack= for using an mstack as root dir for a service 2026-02-19 15:05:15 +01:00
Mike Yuan b1cd249a69 core/service: correct desc for first-level credential refreshing process
It doesn't join the unit namespace. It would fork again to do so
if needed.
2026-02-13 14:51:44 +01:00
Mike Yuan d800432156 core/service: fix typo
Addresses https://github.com/systemd/systemd/pull/40093#discussion_r2803104490
2026-02-13 14:51:44 +01:00
Mike Yuan 21292677f6 core/service: if RefreshOnReload= is explicitly enabled, allow reload even without exec/notify-reload
This was originally brought up by @poettering. If the process
loads stuff on demand and flushes them out after each use,
or actively monitors file changes, they can be reloaded
by merely refreshing the resources.
2026-02-10 21:54:13 +01:00
Mike Yuan f385b3f3dd core/service: pass credentials to ExecReload*= if refreshed
Closes #35227
2026-02-10 21:54:13 +01:00
Mike Yuan fff07be411 core/service: support credential refreshing on reload
Closes #21099
2026-02-10 21:54:12 +01:00
Mike Yuan a43bc1aed8 core/service: introduce RefreshOnReload= setting
This allows controlling resources to be refreshed before performing
reload, with one extra benefit that in the future we can permit
"seemless reload"s, i.e. no active signaling is done to the main process
after refreshing get updated. This could come in handy for programs
that loads stuff on demand or watches changes via inotify.
2026-02-10 21:54:12 +01:00
Mike Yuan 4a6e5b0ae9 core: various cleanups for setup_input/output (#39860) 2025-12-18 15:56:42 +01:00
Mike Yuan 8619c65fcf core/service: const and pure'ify service_restart_usec_next() 2025-12-18 00:39:59 +01:00
Mike Yuan e04382384d core/execute: introduce exec_input_is_inheritable() helper 2025-12-17 23:23:22 +00:00
Luca Boccassi 90f4c0473a core: set Result=start-limit-hit when a unit is rate limited
There is currently no way to figure out a rate limit was hit on a unit,
as the last result is stripped in order to keep reporting the first
result, which is useful in case of a watchdog failure, which is the
reason why it was changed as such.

But rate limiting is also an important information to provide to
users, so allow the Result property to reflect it when it
happens.
2025-12-18 00:19:09 +01:00
Mike Yuan 4d136f1462 core: dlopen() libcryptsetup in extensions refreshing
Follow-up for a08f2ea02d

This fixes extensions refreshing + verity-protected DDIs.
TEST-50-DISSECT previously passed because confext refreshing
is tested after live mount, the latter of which used to
load libcryptsetup in pid1.
2025-12-16 22:11:45 +01:00
Mike Yuan 12df39fadf core/service: defer cryptsetup dlopen to helper process
This should still be safe, as we block dlopen() in namespace_fork().

Partially reverts 9252e26f4c.
2025-12-16 21:57:37 +01:00
Mike Yuan 552822992c core/service: do not honor SuccessExitStatus= for our own helpers
They're exclusively under our control, hence errors should not be
suppressed based on external user input.
2025-12-17 04:04:02 +09:00
Mike Yuan 4f25248b6e core/service: set unit log context in helper processes that bypass cgroup
Since these helper processes aren't spawned in the unit cgroup,
let's explicitly attach unit log context so that all logging gets
attributed to the unit, including the ones done in library calls.
2025-12-16 12:49:06 +01:00
Yu Watanabe 93378148d4 tree-wide: normalize comment style 2025-12-15 08:50:13 +09:00
Daan De Meyer 5eb0639faa namespace: Clone root dir descriptor before use
Before doing anything with the root directory file descriptor, let's
make sure we clone it first so that the caller can't mess with mount fd
attributes via mount_setattr() anymore.

We clone during parsing instead of in executor so that the caller can't
mess with the mount fd between invocations.
2025-12-14 11:32:06 +01:00
Daan De Meyer 27217200f6 core: Rename error sd_bus_error parameters to reterr_error 2025-11-26 16:22:50 +09:00
Lennart Poettering 9252e26f4c core: load libcryptsetup before forking off child that might need it 2025-11-24 11:56:47 +01:00
Daan De Meyer 87fbd33372 clang-tidy: Fix all remaining misc-include-cleaner violations
- Remove unused includes
- Add common false positive headers to misc-include-cleaner.IgnoreHeaders
- Add IWYU pragma keep for uncommon false positive headers
2025-11-22 10:19:41 +01:00
Yu Watanabe 5d397dc7f4 cgroup-util: drop 'controller' argument from cg_get_keyed_attribute() and cg_is_empty()
The argument is completely unused. Let's drop it.
2025-11-17 21:31:50 +09:00
Maximilian Bosch 4dabc30050 service: setup credentials for ExecCondition
Closes #35788

This gives access to credentials within ExecCondition=. As described in
ticket #35788, I do have a use-case for this and as noted in the
commit that dropped this[1], this is OK to be revisited if there are
use-cases.

[1] a145623bc4
2025-11-10 05:27:00 +09:00
Mike Yuan 675a4841cc core/service: do not pass $MANAGERPID and friends if pidns is employed 2025-11-05 17:28:44 +01:00
Mike Yuan b03e1b09af core/service: rework ExecReload= + Type=notify-reload interaction, add ExecReloadPost=
When Type=notify-reload got introduced, it wasn't intended to be
mutually exclusive with ExecReload=. However, currently ExecReload=
is immediately forked off after the service main process is signaled,
leaving states in between essentially undefined. Given so broken
it is I doubt any sane user is using this setup, hence I took a stab
to rework everything:

1.  Extensions are refreshed (unchanged)
2.  ExecReload= is forked off without signaling the process
3a. If RELOADING=1 is sent during the ExecReload= invocation,
    we'd refrain from signaling the process again, instead
    just transition to SERVICE_RELOAD_NOTIFY directly and
    wait for READY=1
3b. If not, signal the process after ExecReload= finishes
    (from now on the same as Type=notify-reload w/o ExecReload=)
4.  To accomodate the use case of performing post-reload tasks,
    ExecReloadPost= is introduced which executes after READY=1

The new model greatly simplifies things, as no control processes
will be around in SERVICE_RELOAD_SIGNAL and SERVICE_RELOAD_NOTIFY
states.

See also: https://github.com/systemd/systemd/issues/37515#issuecomment-2891229652
2025-11-04 12:18:33 +01:00
Mike Yuan 1b4cf02ada core/service: fix missing error handling for refresh-extensions control process 2025-11-04 12:17:33 +01:00
Mike Yuan 5fb8387c67 core/service: reset all reload-related states once a cycle completes
Fixes #37515
2025-11-04 12:17:33 +01:00
Mike Yuan 584e89f26e core/service: consolidate where to initialize reload_result 2025-11-04 12:17:32 +01:00
Mike Yuan 98734ac74d core/service: forbid reverting STOPPING=1
We don't permit state transition from STOPPING back to RUNNING,
hence refrain from resetting notify_state too.
2025-11-04 12:17:32 +01:00
Mike Yuan ed834f11cb core/service: split out service_notify_message_process_state()
No functional change, preparation for later changes.
2025-11-04 12:17:32 +01:00
Mike Yuan 3d888e2dad core/service: add missing serialization for notify_state
This really should be persisted across daemon-reload since
it might contain deferred state transitions.
2025-11-04 12:17:32 +01:00
Mike Yuan 38ea58a907 core/service: remove effectively unused NOTIFY_UNKNOWN state
We usually use _INVALID enum value as placeholder.

While at it, reset notify_state in service_enter_dead() for consistency.
2025-11-04 12:17:31 +01:00
Mike Yuan 1b5a9a7d56 core/service: avoid duplicate unit_add_to_dbus_queue() call
If we're changing state anyways, service_set_state() -> unit_notify()
will take care of dbus signaling for us.
2025-11-04 12:17:31 +01:00
Mike Yuan 1b272d778a core/service: introduce SERVICE_STATE_WITH_WATCHDOG 2025-11-04 12:17:31 +01:00
Mike Yuan 1773d2a207 core: drop redundant pidref_done() calls
{service,socket}_unwatch_control_pid() -> unit_unwatch_pidref_done()
is unconditionally called everywhere.
2025-11-04 12:17:31 +01:00
Mike Yuan 16a0cbe915 core/service: merge service_enter_reload_mounting() into _refresh_extensions() 2025-11-04 12:17:31 +01:00
Mike Yuan 2e43eee666 core/service: restore spuriously changed comment
Not sure why dfdeb0b1cb
touched it at all.
2025-11-04 12:17:30 +01:00
Mike Yuan aebe553db3 core/service: do not set reload_begin_usec when refreshing confexts
reload_begin_usec is a barrier for determining whether RELOADING=1
came after the main process got signaled, unrelated to refreshing.
2025-11-04 12:17:30 +01:00
Mike Yuan af3a197515 core/service: no need for STATUS_TEXT_MAX to reside in header 2025-11-04 12:17:30 +01:00
Daan De Meyer 9e26ced980 core: Add RootDirectoryFileDescriptor=
RootDirectory= but via a open_tree() file descriptor. This allows
setting up the execution environment for a service by the client in
a mount namespace and then starting a transient unit in that execution
environment using the new property.

We also add --root-directory= and --same-root-dir= to systemd-run to
have it run services within the given root directory. As systemd-run
might be invoked from a different mount namespace than what systemd is
running in, systemd-run opens the given path with open_tree() and then
sends it to systemd using the new RootDirectoryFileDescriptor= property.
2025-10-31 13:09:51 +01:00
Mike Yuan d93fff5c0c core/service: also pass sockets to control processes when stdio is named fd 2025-10-30 17:47:30 +01:00
Mike Yuan c954830fa9 core/service: only pass socket fds to control processes
If socket is used as stdio, we'd currently imply EXEC_PASS_FDS
and dump the whole set of fds to the control processes. This is
pretty much unexpected and unnecessary though, instead let's
pass only the socket fds.

Yes, this is a compat break, but a relatively minor one I'd
argue. And we can always revisit things if users do complain.
2025-10-30 17:47:29 +01:00
Mike Yuan d85d98f406 core/execute: merge n_storage_fds and n_extra_fds into stashed_fds
The distinction between fdstore and extra fds is only meaningful
to struct Service. As far as executor is concerned they're just
some fds to pass to the service. Let's just merge it hence,
for the sake of simplicity.
2025-10-30 17:47:29 +01:00
Yu Watanabe 8eefd0f4de core: increment start limit counter only when we can start the unit
Otherwise, e.g. requesting to start a unit that is under stopping may
enter the failed state.

This makes
- rename .can_start() -> .test_startable(), and make it allow to return
  boolean and refuse to start units when it returns false,
- refuse earlier to start units that are in the deactivating state, so
  several redundant conditions in .start() can be dropped,
- move checks for unit states mapped to UNIT_ACTIVATING from .start() to
  .test_startable().

Fixes #39247.
2025-10-23 15:51:28 +02:00
Mike Yuan 4f07ec2b65 core/service: properly handle freezer action -> watchdog propagation
Follow-up for 25178aadb2
2025-10-06 02:40:01 +02:00
Mike Yuan b5381d76d5 core/service: drop "cgroup" part of service_cgroup_freezer_action()
This operates on more than cgroup, hence use generic naming,
which also aligns with slice_freezer_action().
2025-10-06 02:40:01 +02:00
Mike Yuan 1cbbb05bc7 unit-def: introduce freezer_state_objective()
No functional change, preparation for later commits.
2025-10-06 02:40:01 +02:00
Yu WatanabeandLuca Boccassi 4279336618 chase: trigger automount only when explicitly requested
Since c5de7b14ae
file searching implies a new mount api syscall by default,
to trigger automounts.

But, this is not necessary in most cases, e.g. when chasing
syspath in sd-device (actually this causes regression in umockdev,
see https://github.com/martinpitt/umockdev/issues/271).
Another example is reading unit files, especially .network files,
as automount may trigger mounting network filesystems...

Also, when this is used in NSS plugins, programs that load the
plugins may fail because of spuriously configured seccomp. See #38565.

Let's not trigger automount by default, and do only when explicitly
requested.

This introduces CHASE_TRIGGER_AUTOFS, and use it in
- service manager,
- bootctl and finding ESP/xbootldr,
- sysupdate,
- mountfsd,
- systemd-mount.

There may be several more places we should trigger automount, but let's
do that later.

Follow-up for c5de7b14ae.
Fixes #38565.
Replaces #38569.

Co-authored-by: Luca Boccassi <luca.boccassi@gmail.com>
2025-08-20 02:32:02 +09:00
Yu Watanabe 2e7d7e929e Revert "chase: invert CHASE_NO_AUTOFS and only set it where needed"
This reverts commit 490aa05ca1.

As commented https://github.com/systemd/systemd/pull/38569#discussion_r2284978273,
the commit makes autofs check bypassed. Before the commit, when
CHASE_NO_AUTOFS is set, we did not shortcut chasing paths, and refused
any autofs mount points in the path. However, with the commit, the flag
was swapped but even when CHASE_AUTOFS is unset, the autofs check may be
skipped.

To fix the issue, rather than swapping the flag, we should introduce
another flag, say CHASE_TRIGGER_AUTOFS. This revert the commit, and in a
later commit, the new flag will be introduced.
2025-08-20 02:15:36 +09:00