Commit Graph
253 Commits
Author SHA1 Message Date
Ł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
Zbigniew Jędrzejewski-Szmek b380b64383 Rename UnitFileScope to LookupScope
As suggested in
https://github.com/systemd/systemd/pull/22649/commits/8b3ad3983f5440eef812b34e5ed862ca59fdf7f7#r837345892

The define is generalized and moved to path-lookup.h, where it seems to fit
better. This allows a recursive include to be removed and in general makes
things simpler.
2022-03-29 16:17:57 +02: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 ec75e8e07a sd-event: add a single implementation of an event source that runs on clock changes
We basically had the same code in three places. Let's unify it in a
common helper function.

event_add_time_change() might be something we should add to the official
sd-event API sooner or later, given its general usefulness.
2022-03-18 23:53:34 +01:00
Luca Boccassi aff3a9e1fa watchdog: add setting to configure pretimeout governor 2022-02-22 17:19:54 +00:00
Curtis Klein 5717062e93 watchdog: Add watchdog pretimeout support
Add support for managing and configuring watchdog pretimeout values if
the watchdog hardware supports it. The ping interval is adjusted to
account for a pretimeout so that it will still ping at half the timeout
interval before a pretimeout event would be triggered. By default the
pretimeout defaults to 0s or disabled.

The RuntimeWatchdogPreSec config option is added to allow the pretimeout
to be specified (similar to RuntimeWatchdogSec). The
RuntimeWatchdogPreUSec dbus property is added to override the pretimeout
value at runtime (similar to RuntimeWatchdogUSec). Setting the
pretimeout to 0s will disable the pretimeout.
2022-02-22 17:19:54 +00:00
Yu Watanabe aac470326e pid1: voidify manager_override_watchdog()
As it always returns 0.
2022-01-07 09:44:32 +01:00
Zbigniew Jędrzejewski-Szmek f333ed27fa Merge pull request #20476 from jamacku/new-feature-reloaded-stamp
core: indicate the time when units were loaded
2021-12-07 18:47:25 +01:00
Jan Macku 49fbe940a4 core: Add new DBUS properties UnitsReloadStartTimestamp and UnitsLoadTimestampMontonic 2021-12-07 16:02:46 +01:00
Emily Gonyer be7148ebed Change gendered terms to be gender-neutral (#21325)
Some typos are also fixed.
2021-11-12 16:09:56 +01:00
Lennart Poettering b0c4b28246 pid1: add a manager_trigger_run_queue() helper
We have two different places where we re-trigger the run queue now.
let's unify it under a common function, that is part of the Manager
code.

Follow-up for #20953
2021-11-12 15:52:37 +01:00
Iago Lopez Galeiras 184b4f78cf core: add BPF LSM functions
This adds 6 functions to implement RestrictFileSystems=

* lsm_bpf_supported() checks if LSM BPF is supported. It checks that
  cgroupv2 is used, that BPF LSM is enabled, and tries to load the BPF
  LSM program which makes sure BTF and hash of maps are supported, and
  BPF LSM programs can be loaded.
* lsm_bpf_setup() loads and attaches the LSM BPF program.
* lsm_bpf_unit_restrict_filesystems() populates the hash of maps BPF map with the
  cgroupID and the set of allowed or denied filesystems.
* lsm_bpf_cleanup() removes a cgroupID entry from the hash of maps.
* lsm_bpf_map_restrict_fs_fd() is a helper function to get the file
  descriptor of the BPF map.
* lsm_bpf_destroy() is a wrapper around the destroy function of the BPF
  skeleton file.
2021-10-06 10:52:14 +02:00
Lennart Poettering d4a402e4f6 core: add a new setting DefaultOOMScoreAdjust= and set it to 100 above service manager's by default
Let's make our service managers slightly less likely to be killed by the
OOM killer by adjusting our services' OOM score adjustment to 100 above
ours. Do this conservatively, i.e. only for regular user sessions.
2021-10-04 16:27:10 +02:00
Luca Boccassi 71a80dcc0b Merge pull request #20690 from DaanDeMeyer/oomd-user-services
oom: Support for user services
2021-09-21 15:39:48 +01:00
Daan De Meyer 064a5c1438 oom: Add support for user unit ManagedOOM property updates
Compared to PID1 where systemd-oomd has to be the client to PID1
because PID1 is a more privileged process than systemd-oomd, systemd-oomd
is the more privileged process compared to a user manager so we have
user managers be the client whereas systemd-oomd is now the server.

The same varlink protocol is used between user managers and systemd-oomd
to deliver ManagedOOM property updates. systemd-oomd now sets up a varlink
server that user managers connect to to send ManagedOOM property updates.

We also add extra validation to make sure that non-root senders don't
send updates for cgroups they don't own.

The integration test was extended to repeat the chill/bloat test using
a user manager instead of PID1.
2021-09-20 13:53:11 +01:00
Luca Boccassi 8f8e9ad7cb Merge pull request #20650 from fbuihuu/watchdog-rework
Watchdog rework
2021-09-15 14:44:49 +01:00
Franck Bui ae4a0ec45c core: call watchdog_ping() unconditionally
This basically reverts commit 61927b9f11 and
relies on the fact that watchdog_ping() will open and setup the watchdog for us
in case the device appears later on.

Also unlike what is said in comment
https://github.com/systemd/systemd/pull/17460#pullrequestreview-517434377, both
m->watchdog[] and m->overriden_watchdog[] are not supposed to store the actual
timeout used by the watchdog device but stores the value defined by the user.

If the HW timeout value is really needed by the manager then it's probably
better to read it via an helper defined in watchdog.c instead. However the HW
timeout value is currently only needed by the watchdog code itself mainly when
it calculates the time for the next ping.
2021-09-15 10:54:24 +02:00
Yu Watanabe 84ebe6f013 core: replace IPAddressAccessItem with struct in_addr_prefix
Previously, if a unit file which contains n IPAddressAllow/Deny= lines,
then the computational order of parsing the file was O(n^3), as
ip_address_access_reduce(), whose order is O(n^2), is called for each line.

By replacing in_addr_prefix related functions, now the computational
order is O(n log n).

Fixes #20680.
2021-09-14 20:30:09 +09:00
Maanya Goenka f14d6810e0 manager: add a test flag to ignore dependencies
The MANAGER_TEST_RUN_IGNORE_DEPENDENCIES flag was added in order to allow the caller
to skip the recursive loading of dependency units when loading specific
unit files. This includes the default dependencies, the specified dependencies, the slice.
This will be used by systemd-analyze to allow checking individual unit files in isolation.
2021-08-12 07:22:15 -07:00
Maanya Goenka 2a7cf953e1 systemd-analyze: add --root option for 'verify' verb and allow path parsing
-------------------------------------------------------------------------------
Example Run:

foobar.service created below is a service unit file that has a non-existing key-value
pairing (foo = bar) and is thus, syntactically invalid.

maanya-goenka@debian:~/systemd (img-support)$ cat <<EOF>img/usr/lib/systemd/system/foobar.service
> [Unit]
> foo = bar
>
> [Service]
> ExecStart = /opt/script0.sh
> EOF

The failure to create foobar.service because of the recursive dependency searching and verification has been addressed
in a different PR: systemd-analyze: add option to return an error value when unit verification fails #20233

maanya-goenka@debian:~/systemd (img-support)$ sudo build/systemd-analyze verify --root=img/ foobar.service
/home/maanya-goenka/systemd/img/usr/lib/systemd/system/foobar.service:2: Unknown key name 'foo' in section 'Unit', ignoring.
foobar.service: Failed to create foobar.service/start: Unit sysinit.target not found.
2021-08-10 02:41:12 -07:00
Zbigniew Jędrzejewski-Szmek 6d93265955 manager: rework sending of STATUS=
We would send READY=1,STATUS="Startup finished in …" once after finishing
boot. This changes the message to just "Ready.". The time used to reach
readiness is not part of the ongoing status — it's just a bit of debug
information that it useful in some scenarious, but completely uninteresting
most of the time. Also, when we start sending status about other things in
subsequent patches, we can't really go back to showing "Startup finished in …"
later on. So let's just show "Ready." whenever we're in the steady state.

In manager_check_finished(), more steps are skipped if MANAGER_IS_FINISHED().
Those steps are idempotent, but no need to waste cycles trying to do them
more than once.

We'll now also check whether to send the status message whenever the job queue
runs empty. If we already sent the exact same message already, we'll not send
again.
2021-07-19 11:36:25 +02:00
Zbigniew Jędrzejewski-Szmek a01ba4b2b8 core: split out manager-serialize.[ch]
The file is super long, so let's split this out one subject to a new file.
2021-07-19 11:27:11 +02:00
Zbigniew Jędrzejewski-Szmek 2a341bb9d2 core: split out core/manager-dump.[ch]
This is a fairly specialized topic, let's create a separate file for it.
2021-06-02 09:22:08 +02:00
Lennart Poettering 56c5959202 core: change BoundBy= dependency handling to be processed by a deferred work queue
So far StopWhenUnneeded= handling and UpheldBy= handling was already
processed by a queue that is dispatched in a deferred mode of operation
instead of instantly. This changes BoundBy= handling to be processed the
same way.

This should ensure that all *event*-to-job propagation is done directly
from unit_notify(), while all *state*-to-job propagation is done from a
deferred work queue, quite systematically. The work queue is submitted
to by unit_notify() too.

Key really is the difference between event and state: some jobs shall be
queued one-time on events (think: OnFailure= + OnSuccess= and similar),
others shall be queued continuously when a specific state is in effect
(think: UpheldBy=).  The latter cases are usually effect of the
combination of states of a few units (e.g. StopWhenUnneeded= checks
wether any of the Wants=/Requires=/… deps are still up before acting),
and hence it makes sense to trigger them to be run after an individual
unit's state changed, but process them on a queue that runs whenever
there's nothing else to do that ensures the decision on them is only
taken after all jobs/queued IO events are dispatched, and things
settled, so that it makes sense to come to a combined conclusion. If
we'd dispatch this work immediately inside of unit_notify() we'd always
act instantly, even though another event from another unit that is
already queued might make the work unnecessary or invalid.

This is mostly a commit to make things philosophically clean. It does
not add features, but it should make corner cases more robust.
2021-05-25 16:03:03 +02:00
Lennart Poettering 0bc488c99a core: implement Uphold= dependency type
This is like a really strong version of Wants=, that keeps starting the
specified unit if it is ever found inactive.

This is an alternative to Restart= inside a unit, acknowledging the fact
that whether to keep restarting the unit is sometimes not a property of
the unit itself but the state of the system.

This implements a part of what #4263 requests. i.e. there's no
distinction between "always" and "opportunistic". We just dumbly
implement "always" and become active whenever we see no job queued for
an inactive unit that is supposed to be upheld.
2021-05-25 16:03:03 +02:00
Yu Watanabe 01e3d04ee6 Merge pull request #18536 from poettering/uid-refs-simplify
dynamic uid/gid reference handling simplifications
2021-02-11 03:18:15 +09:00
Lennart Poettering 2571aafbd8 core: fix manager_ref_gid() parameter name in header
It should match what we do for manager_ref_uid() and in the .c file.
2021-02-10 15:48:39 +01: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
Zbigniew Jędrzejewski-Szmek ec08f27069 core: drop bitfields in Manager object
Every bitfield may make the object a little smaller, but requires additional
code when accessing the field. So it only makes sense in objects that are
created in many many copies. The Manager is pretty much a singleton.

-rwxrwxr-x 1 zbyszek zbyszek 4443840 Feb  9 16:14 build/systemd
-rwxrwxr-x 1 zbyszek zbyszek 4442552 Feb  9 16:42 build/systemd

We save 1288 bytes of code by "wasting" a few bytes on storage. (The speed
advantages are probably more important, but harder to measure…)
2021-02-10 14:43:10 +01:00
Michael MarleyandDan Callaghan 61927b9f11 manager: Fix HW watchdog when systemd starts before driver loaded
When manager_{set|override}_watchdog is called, set the watchdog timeout
regardless of whether the hardware watchdog was successfully initialized.  If
the watchdog was requested but could not be initialized, then instead of
pinging it, attempt to initialize it again.  This ensures that the hardware
watchdog is initialized even if the kernel module for it isn't loaded when
systemd starts (which is quite likely, unless it is compiled in).

This builds on work by @danc86 in https://github.com/systemd/systemd/pull/17460,
but fixes the issue of not updating the watchdog timeout with the actual value
from the hardware.

Fixes https://github.com/systemd/systemd/issues/17838

Co-authored-by: Dan Callaghan <djc@djc.id.au>
Co-authored-by: Michael Marley <michael@michaelmarley.com>
2020-12-09 11:47:22 +00:00
Yu Watanabe db9ecf0501 license: LGPL-2.1+ -> LGPL-2.1-or-later 2020-11-09 13:23:58 +09:00
Anita Zhang e30bbc90c9 core: add varlink call to get cgroup paths of units using ManagedOOM*= 2020-10-07 16:17:23 -07:00
Zbigniew Jędrzejewski-Szmek c2911d48ff Rework how we cache mtime to figure out if units changed
Instead of assuming that more-recently modified directories have higher mtime,
just look for any mtime changes, up or down. Since we don't want to remember
individual mtimes, hash them to obtain a single value.

This should help us behave properly in the case when the time jumps backwards
during boot: various files might have mtimes that in the future, but we won't
care. This fixes the following scenario:

We have /etc/systemd/system with T1. T1 is initially far in the past.
We have /run/systemd/generator with time T2.
The time is adjusted backwards, so T2 will be always in the future for a while.
Now the user writes new files to /etc/systemd/system, and T1 is updated to T1'.
Nevertheless, T1 < T1' << T2.
We would consider our cache to be up-to-date, falsely.
2020-08-31 20:53:38 +02:00
Zbigniew Jędrzejewski-Szmek 81be23886d core: rename manager_unit_file_maybe_loadable_from_cache()
The name is misleading, since we aren't really loading the unit from cache — if
this function returns true, we'll try to load the unit from disk, updating the
cache in the process.
2020-08-31 20:53:38 +02:00
Lennart Poettering bb0c0d6f29 core: add credentials logic
Fixes: #15778 #16060
2020-08-25 19:45:35 +02:00
Luca Boccassi cda667722c core: refresh unit cache when building a transaction if UNIT_NOT_FOUND
When a command asks to load a unit directly and it is in state
UNIT_NOT_FOUND, and the cache is outdated, we refresh it and
attempto to load again.
Use the same logic when building up a transaction and a dependency in
UNIT_NOT_FOUND state is encountered.
Update the unit test to exercise this code path.
2020-07-07 10:09:24 +02:00
Franck Bui 43bba15ac8 pid1: rename manager_set_{show_status,watchdog}_overridden() into manager_override_(show_status,watchdog}
No functional change.
2020-06-11 12:00:32 +02:00
Franck Bui 44a419540e pid1: rework handling of m->show_status
The fact that m->show_status was serialized/deserialized made impossible any
further customisation of this setting via system.conf. IOW the value was
basically always locked unless it was changed via signals.

This patch reworks the handling of m->show_status but also makes sure that if a
new value was changed via the signal API then this value is kept and preserved
accross PID1 reexecuting or reloading.

Note: this effectively means that once the value is set via the signal
interface, it can be changed again only through the signal API.
2020-06-09 09:16:54 +02:00
Franck Bui b406c6d128 pid1: make manager_deserialize_{uid,gid}_refs() static
No functional change.
2020-05-19 15:48:54 +02:00
Franck Bui 80f605c807 pid1: make manager_serialize_{uid,gid}_refs() static
No functional change.
2020-05-19 15:48:54 +02:00
Franck Bui 06a4eb0737 pid1: make manager_vacuum_{uid,gid}_refs() static
No functional change.
2020-05-19 15:48:54 +02:00
Franck Bui 1addc46c8c pid1: make manager_flip_auto_status() static
No functional change.
2020-05-19 15:48:54 +02:00
Franck Bui 986935cf6a pid1: update manager settings on reload too
Most complexity of this patch is due to the fact that some manager settings
(basically the watchdog properties) can be set at runtime and in this case the
runtime values must be retained over daemon-reload or daemon-reexec.

For consistency sake, all watchdog properties behaves now the same way, that
is:

  - Values defined by config files can be overridden by writing the new value
    through their respective D-BUS properties. In this case, these values are
    preserved over reload/reexec until the special value '0' or USEC_INFINITY
    is written, which will then restore the last values loaded from the config
    files. If the restored value is '0' or 'USEC_INFINITY', the watchdogs will
    be disabled and the corresponding device will be closed.

  - Reading the properties from a user instance will return the USEC_INFINITY
    value as these properties are only meaningful for PID1.

  - Writing to one of the watchdog properties of a user instance's will be a
    NOP.

Fixes: #15453
2020-05-19 15:31:55 +02:00
Zbigniew Jędrzejewski-Szmek 5bcf34ebf3 pid1: when showing error status, do not switch to status=temporary
We would flip to status=temporary mode on the first error, and then switch back
to status=auto after the initial transaction was done. This isn't very useful,
because usually all the messages about successfully started units and not
related to the original failure. In fact, all those messages most likely cause
the information about the prime error to scroll off screen. And if the user
requested quiet boot, there's no reason to think that they care about those
success messages.

Also, when logging about dependency cycles, treat this similarly to a unit
error and show the message even if the status is "soft disabled" (before we
wouldn't show it in that case).
2020-03-01 11:42:42 +01:00
Zbigniew Jędrzejewski-Szmek 7365a29670 pid1: when printing status message status, give reason 2020-03-01 11:42:19 +01:00
Lennart Poettering 19d22d433d core: add user/group resolution varlink interface to PID 1 2020-01-15 15:28:55 +01:00
Lennart Poettering fc67a943d9 core: drop initial ListNames() bus call from PID 1
Previously, when first connecting to the bus after connecting to it we'd
issue a ListNames() bus call to the driver to figure out which bus names
are currently active. This information was then used to initialize the
initial state for services that use BusName=.

This change removes the whole code for this and replaces it with
something vastly simpler.

First of all, the ListNames() call was issues synchronosuly, which meant
if dbus was for some reason synchronously calling into PID1 for some
reason we'd deadlock. As it turns out there's now a good chance it does:
the nss-systemd userdb hookup means that any user dbus-daemon resolves
might result in a varlink call into PID 1, and dbus resolves quite a lot
of users while parsing its policy. My original goal was to fix this
deadlock.

But as it turns out we don't need the ListNames() call at all anymore,
since #12957 has been merged. That PR was supposed to fix a race where
asynchronous installation of bus matches would cause us missing the
initial owner of a bus name when a service is first started. It fixed it
(correctly) by enquiring with GetOwnerName() who currently owns the
name, right after installing the match. But this means whenever we start watching a bus name we anyway
issue a GetOwnerName() for it, and that means also when first connecting
to the bus we don't need to issue ListNames() anymore since that just
tells us the same info: which names are currently owned.

hence, let's drop ListNames() and instead make better use of the
GetOwnerName() result: if it failed the name is not owned.

Also, while we are at it, let's simplify the unit's owner_name_changed()
callback(): let's drop the "old_owner" argument. We never used that
besides logging, and it's hard to synthesize from just the return of a
GetOwnerName(), hence don't bother.
2020-01-06 15:21:47 +01:00
Zbigniew Jędrzejewski-Szmek 3a0f06c41a core: make TasksMax a partially dynamic property
TasksMax= and DefaultTasksMax= can be specified as percentages. We don't
actually document of what the percentage is relative to, but the implementation
uses the smallest of /proc/sys/kernel/pid_max, /proc/sys/kernel/threads-max,
and /sys/fs/cgroup/pids.max (when present). When the value is a percentage,
we immediately convert it to an absolute value. If the limit later changes
(which can happen e.g. when systemd-sysctl runs), the absolute value becomes
outdated.

So let's store either the percentage or absolute value, whatever was specified,
and only convert to an absolute value when the value is used. For example, when
starting a unit, the absolute value will be calculated when the cgroup for
the unit is created.

Fixes #13419.
2019-11-14 18:41:54 +01:00