Commit Graph
100 Commits
Author SHA1 Message Date
Michal Koutný 3a4aa7f5b2 update TODO 2025-04-25 06:14:42 +09:00
Michal Koutný b67a45841f test-cgroup-util: Ignore LXC group
LXC helper processes hide themselve in .lxc cgroup, we don't have to
deal with the inside tests (and the error in conversion to unit is handled).
Skip those but keep iterating over remaining processes to detect what
can be created around us.
2025-03-12 11:46:19 +01:00
Michal Koutný b78003c793 test-cgroup-util: Skip procs analysis without cgroupfs
cg_pidref_get_path() cannot work (current implementaion) without
cgroupfs (when it checks unified or not setup). Similarly,
cg_pidref_get_unit() assumes all processes are part of a unit. So carry
out the test only when running on a systemd setup.
2025-03-12 10:31:23 +01:00
Michal Koutný ca82f0cbe2 test-cgroup-util: Check return values
The test is supposed to check a battery of cgroup helpers on each
process found but it doesn't literally check anything besides presence
of procfs. (One can visually check printed output only. Introduction in
aff38e74bd ("nspawn: suffix the nspawn cgroups with ".nspawn"").)

Make some assumptions about visible processes and turn the test into
testing that systemd helpers can deal with whatever process they find on
the SUT.

Reported by Coverity and
Fixes CID#1587767
2025-03-12 10:31:23 +01:00
Michal Koutný 6c5703f9bc cgroup-util: Handle capsule@ paths like user@ paths
The capsule instances are related to user instances, so treat them
equally to user@.service when handling cgroup paths. This also saves us
from polluting public libsystemd API with variant for capsules too.

Fix: #36098
2025-03-11 10:37:19 +01:00
Michal Koutný afffd9ee26 capsule-util: Move from shared/ to basic/
...so that other code in basic can use it too (basic ⊆ shared).
2025-03-07 18:07:51 +01:00
Michal Koutný cf62e00295 path: Close inotify FD asynchronously
inotify FD may take several milliseconds to close.  We measured
daemon-reload

        default: (0.427 ± 0.05) s
        async:   (0.323 ± 0.02) s

with 5 path units out of 422 units. I.e. ~1% of units cause ~25% of
delay, hence this fix seems like low-hanging fruit on the daemon-reload
critical path.

Particular inotify slowness pointed out by @fbuihuu.
2025-03-04 21:37:58 +01:00
Michal Koutný c4b7596607 TEST-13-NSPAWN.nss-mymachines: Use negative matching switch
The test expects _not_ to find the patterns but the run_and_grep would
still print 'FAIL:' message. Use the dedicated -n option that inverts
the semantics cleaner than shell's !.
2025-03-03 19:27:17 +01:00
Michal Koutný 75e2d70eef user-record: Make user and group matching functions total
Since we can evaluate even the case with invalid ids (non-matching) we
can switch the function to pure boolean with no error cases and simpler
(none) return error handling.
2025-03-03 19:27:12 +01:00
Michal Koutný eaeb96125a userdb: Fix return value of groupdb_by_name()
The commit 7419291670 ("userdb: move UserDBMatch handling from userdbctl
into generic userdb code to allow it to be done server side")
unintentionally passes return value from group_record_match() as its
return value and thus diverges from other search functions that return 0
on success. Align that by returning 0 instead of 1, all existing callers
are invariant to this change.
2025-03-03 19:26:52 +01:00
Michal Koutný 5eceb5a7a2 user-record: Handle invalid uid/gid case
I'm not that familiar with outer code to guide Coverity with an
assert(), so consider invalid uid/gid as non-matching in order to avoid
-EINVAL for bit shifts calculation.

Fixes: CID#1590746
2025-03-03 19:14:56 +01:00
Michal Koutný 1644724a4d sd-event: Fix sd_event_source leak
Hinted by CID#1591563 but the issue is different -- when
sd_event_source_set_destroy_callback() fails, we would use the old
n_sources value and possibly missing sd_event_source_unref() of the last
added source.
2025-02-28 15:16:53 +01:00
Michal Koutný 4c9f242a54 mkosi: Fix tools image package name 2024-12-18 11:08:06 +01:00
Michal Koutný 64f173324e core/manager: Deprecate StartAuxiliaryScope() method
The method was added with migration of resources in mind (e.g. process's
allocated memory will follow it to the new scope), however, such a
resource migration is not in cgroup semantics. The method may thus have
the intended users and others could be guided to StartTransientUnit().

Since this API was advertised in a regular release, start the removal
with a deprecation message to callers.
Eventually, the goal is to remove the method to clean up DBus API and
simplify code (removal of cgroup_context_copy()).

Part of DBus docs is retained to satisfy build checks.
2024-10-08 17:49:13 +02:00
Michal Koutný 3216377433 test: Add test for per-device cgroup properties
Reported in #34126
2024-10-04 22:04:46 +02:00
Michal Koutný 0fa0dfa044 core/cgroup: Apply IODevice*= directives in configured order
Different device paths may resolve to same device node
(lookup_block_device()), e.g.
        IOReadBandwidthMax=/dev/sda1 18879
        IOReadBandwidthMax=/dev/sda2 18878
where both partitions resolve to /dev/sda and when these values are
applied (they are associated with original paths, i.e. as if applied for
different device) in the order from io_device_limits.

The parsing code prepends, so they end up in reverse order wrt config
file. Switch the direction so that the order of application matches the
order of configuration -- i.e. semantics in all other unit file
directives.

Apply same change to all directives that use per-device lists. (The
question whether partitions should be resolved to base device is
independent.)

And apply the changes equally to DBus properties write handlers.

Fixes #34126
2024-09-24 15:00:41 +02:00
Michal Koutný 3e6e3e6d40 test: Fail cgroup delegation test when user cannot be created
It means: a) user cannot be created, something's wrong in the
test environment -> fail the test; b) user already exists, we shall not
continue and delete (foreign) user.
2024-07-26 10:44:10 +02:00
Michal Koutný 4f0541dc59 test: Reorganize testcase of cgroup delegation
There are multiple subtests, just move them around into functions
(leveraging the testcase_* convention) to make space for new related
subtests.
2024-07-25 17:29:42 +02:00
Michal Koutný 307abfc83a Revert "TEST-19-CGROUP: Skip on opensuse"
This reverts commit 60d064d3fd.

The logged test failure was because of missing memory controller in
testing cgroup. With the test fixed in previous commit, memory
attributes are delegated as expected.

Ref: #32439
2024-05-23 18:05:25 +02:00
Michal Koutný 8fd755ffe6 test: Ensure delegation test unit has memory controller
When the test used to be run on distro that doesn't enable memory
accounting by default (such as openSUSE TW), there is no guarantee that
testing unit has memory.* cgroup attributes and delegation test would
fail if they are missing.

Require memory controller explicitly inside the unit so that test can
work in any environment.
2024-05-23 18:05:25 +02:00
Michal Koutný 3a51e31be9 timedated: Respond on org.freedesktop.timedate1.SetNTP only when really finished
The method returns prematurely (before jobs it triggers terminate). This
is externally visible because other methods may fail if jobs did not
finish.
Postpone the DBus method response until we collect all signals for
finished jobs.
systemd-timedated keeps track of in-flight DBus requests and answers
them all in unspecified order when jobs finish. The capacity of requests
in systemd-timedated is limited.

Fixes: #17739
2024-03-27 17:28:24 +00:00
Michal Koutný 5734d5d04c service: Demote log level of NotifyAccess= messages to debug
The situation is a service like

        Type=notify
        NotifyAccess=main

and the service uses some of the systemd helper utilities, e.g.
coredumpctl. The service process will pass NOTIFY_SOCKET to the helper
child (accidentally) and the result is a spurious notification and
the warning message:

> Jan 18 09:38:01 host systemd[1]: sdnotify.service: Got notification message from PID 13736, but reception only permitted for main PID 13549

Notification from helpers seem like an unintentional composition of the
commit c118b577fa ("coredumpctl: define main through macro") and commit
6b636c2d27 ("main-func: send main exit code to parent via sd_notify() on
exit"). The former used the handy macro for a main function, the latter
equipped any main function with the notification. (Further extended in
the commit 623a00020f ("notify: Add EXIT_STATUS field").)

Since notification from systemd utitilities are meant to extend
rudimentary exit()/wait() pair generally, they may happen to land into
service's NOTIFY_SOCKET. Tone down messages of notification that won't
match NotifyAccess=.
2024-02-12 12:20:39 +01:00
Michal Koutný 8ad614890b cgroup: Rename effective limits internal table
Post-merge fixup of commit 4fb0d2dc14 ("cgroup: Add EffectiveMemoryMax=,
EffectiveMemoryHigh= and EffectiveTasksMax= properties"), no functional
change intended.
2024-01-22 22:02:37 +00:00
Michal Koutný 93f8e88d23 cgroup: Restrict effective limits with global resource provision
Global resource (whole system or root cg's (e.g. in a container)) is
also a well-defined limit for memory and tasks, take it into account
when calculating effective limits.
2024-01-03 13:43:04 +01:00
Michal Koutný ce35bb95c7 test: Add effective cgroup limits testing 2024-01-03 13:37:58 +01:00
Michal Koutný 834ca54624 test: Convert rlimit test to subtest of generic limit testing
No functional change intended. Preparation for new tests.
2024-01-03 13:37:58 +01:00
Michal Koutný 4fb0d2dc14 cgroup: Add EffectiveMemoryMax=, EffectiveMemoryHigh= and EffectiveTasksMax= properties
Users become perplexed when they run their workload in a unit with no
explicit limits configured (moreover, listing the limit property would
even show it's infinity) but they experience unexpected resource
limitation.

The memory and pid limits come as the most visible, therefore add new
unit read-only properties:
- EffectiveMemoryMax=,
- EffectiveMemoryHigh=,
- EffectiveTasksMax=.

These properties represent the most stringent limit systemd is aware of
for the given unit -- and that is typically(*) the effective value.

Implement the properties by simply traversing all parents in the
leaf-slice tree and picking the minimum value. Note that effective
limits are thus defined even for units that don't enable explicit
accounting (because of the hierarchy).

(*) The evasive case is when systemd runs in a cgroupns and cannot
reason about outer setup. Complete solution would need kernel support.
2024-01-03 13:37:08 +01:00
Michal Koutný 788b7e7630 man: Add remarks about StandardInput=socket and sd_listen_fds()
It confuses users when they cannot find respective environment variables
with config that is supposes for (x)inetd activated service only.

Fix: #29670
2023-10-31 13:08:45 +01:00
Michal Koutný 761791bcf8 sysctl.d: Fix pid_max comment
The actual default is 2^15 and that is also 32b kernels default.
Fix the value, mention 32b and do not talk about default which may
depend on nr_cpus.

Fix: #29607
2023-10-31 13:07:49 +01:00
Michal Koutný 055665d596 dbus: Document org.freedesktop.systemd1.Service.MemoryAvailable property
The value is an optimistic estimate, make it clear in the docs.
2023-09-09 10:42:38 +02:00
Michal Koutný 8db929a1e2 cgroup: Estimate MemoryAvailable= when DefaultMemoryAccounting=no
Without memory accounting explicitly disabled, we may not obtain current
consumption from all units on the ancestry path.
Use a descendant value as lower bound estimate for ancestors if
ancestor's consumption cannot be directly queried.

This makes MemoryAvailable= an upper bound of available values.
2023-09-08 19:07:12 +02:00
Michal Koutný 727cea7652 cgroup: Refactor MemoryAvailable= evaluation
unit_get_memory_available() duplicates similar logic contained in
unit_get_memory_current(). Instead, it can call it for each unit it
needs data for.
Additionally, simplify the flow by treating all units from leaf to root
uniformly in one loop.

Functional change when a queried unit does not have MemoryAccounting=yes
(or cgroup_path), we will try getting an estimate from ancestors.
2023-09-08 19:07:12 +02:00
Michal Koutný 3565c709f5 cgroup: Fix MemoryAvailable= by considering physical memory
Currently, querying a unit's available memory would result in infinity
if there are no limits set on the unit or ancestors.
That undermines semantics implied by the name, so look at the physical
memory if the search propagates up to the -.slice.
This makes sense even in systemd user instances, limits of -.slice are
still looked at too.

Also change printed representation of infinite MemoryAvailable which
means we could not figure out a good estimate.
2023-09-08 19:05:52 +02:00
Michal Koutný 9e42433ff9 mkosi: Copy sources under /usr in the image
Originally, the source code was copied under /root/src.
This home directory is part of root FS and the new mkosi building
paradigm has only ephemeral root FS that is generated lazily.
Any files placed on the root FS in the build environment are that
excluded from the final image.

It is useful to have source codes available in the image's runtime (not
build time) environment for debugging.

ExtraTrees= as used currently are ineffective, so change the destination
to copy files under /usr to achieve the intention.

gdb sees source files as:
> 1354	../src/src/systemctl/systemctl.c: No such file or directory.

Modify gdb configration in the built image accordingly (that file cannot
be in /root neither) to resolve to the moved sources.

(Commit fdecbf7 ("Enable unprivileged image builds") envisions bind
mounting or virtiofsd for nspawn or qemu containers respectively.)
2023-08-10 19:14:40 +01:00
Michal Koutný edd84b8e4b meson: Copy files with git only in true git repository
When mkosi is run from git-worktree(1), the .git is not a repository
directory but a textfile pointing to the real git dir
(e.g. /home/user/systemd/.git/worktrees/systemd-worktree). This git dir
is not bind mounted into build environment and it fails with:

> fatal: not a git repository: /home/user/systemd/.git/worktrees/systemd-worktree
> test/meson.build:190:16: ERROR: Command `/usr/bin/env -u GIT_WORK_TREE /usr/bin/git --git-dir=/root/src/.git ls-files ':/test/dmidecode-dumps/*.bin'` failed with status 128.

There is already a fallback to use shell globbing instead of ls-files,
use it with git worktrees as well.
2023-03-02 15:04:40 +00:00
Michal Koutný b9f976fb45 core: mount namespaces: Remove auxiliary bind mounts directory after unit termination
Unit that requires its own mount namespace creates a temporary directory
to implement dynamic bind mounts (org.freedesktop.systemd1.Manager.BindMountUnit).
However, this directory is never removed and they will accumulate for
each unique unit (e.g. templated units of systemd-coredump@).

Attach the auxiliary runtime directory existence to lifetime of other
"runtime" only per-unit directories.
2023-01-19 21:58:10 +01:00
Michal Koutný b7a41491ed cgroup: Do not emit compat message without memory limit
Previously mere MemoryLow= directive would lead to emitting the compat
message 'Applying MemoryMax=18446744073709551615 as MemoryLimit=' even
though it carries little information.
2023-01-13 10:48:03 +09:00
Michal Koutný 862be54d57 cgtop: Update code comments 2022-11-30 09:40:56 +09:00
Michal Koutný d4e32838e8 test: Add tests for systemd-cgtop args parsing 2022-11-28 14:29:49 +01:00
Michal Koutný 48600b3524 cgtop: Do not rewrite -P or -k options
--recursive=no will overwrite possible -P or -k option hence making the
recursive disabling impossible.

Check what counting types the system supports (encoded in the ordering
of our enum) of and pick whatever user requests but is also supported.

Fixes: #25248
2022-11-28 14:29:49 +01:00
Michal Koutný f38e89c23c logind: Properly unescape names of lingering users
Filenames to store user linger requests are created with C-escaping.
When we enumerate the files to acquire ligering users, we use the
filenames verbatim. In the case C-escaping is not an identity map (such
as "DOMAIN\User"), we won't be able to start user instances of
such mangled users.

Unescape filenames when we treat them as usernames again.

Fixes: #25448
2022-11-26 08:27:16 +09:00
Michal Koutný 7e343b530e meson: Generate fuzzer inputs with directives
The lists of directives for fuzzer tests are maintained manually in the
repo. There is a tools/check-directives.sh script that runs during test
phase and reports stale directive lists.
Let's rework the script into a generator so that these directive files
are created on-the-flight and needn't be updated whenever a unit file
directives change. The scripts is rewritten in Python to get rid of gawk
dependency and each generated file is a separate meson target so that
incremental builds refresh what is just necessary (and parallelize
(negligible)).

Note: test/fuzz/fuzz-unit-file/directives-all.slice is kept since there
is not automated way to generate it (it is not covered by the check
script neither).
2022-10-20 14:43:50 +02:00
Michal Koutný 7db5761dda meson: Store fuzz tests in structured way
Put fuzzer tests into dictionary that maps `fuzzer->list of inputs`
instead of the flat list.
This is just refactoring with no intentional .
2022-10-11 09:48:05 +02:00
Michal Koutný 3286770daa meson: Require TPM2 for measuring utilities
I happened to run build with openssl but no tpm2 and ran into issues
like:

        [313/1382] Compiling C object systemd-measure.p/src_boot_measure.c.o
        FAILED: systemd-measure.p/src_boot_measure.c.o
        cc -Isystemd-measure.p -I. -I.. -Isrc/basic -I../src/basic -Isrc/fundamental -I../src/fundamental -Isrc/systemd -I../src/systemd -I../src/libsystemd/sd-bus -I../src/libsystemd/sd-device -I../src/libsystemd/sd-event -I../src/libsystemd/sd-hwdb -I../src/libsystemd/sd-id128 -I../src/libsystemd/sd-journal -I../src/libsystemd/sd-netlink -I../src/libsystemd/sd-network -I../src/libsystemd/sd-resolve -Isrc/shared -I../src/shared -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -std=gnu11 -O0 -g -Wno-missing-field-initializers -Wno-unused-parameter -Wdate-time -Wendif-labels -Werror=format=2 -Werror=format-signedness -Werror=implicit-function-declaration -Werror=incompatible-pointer-types -Werror=int-conversion -Werror=overflow -Werror=override-init -Werror=return-type -Werror=shift-count-overflow -Werror=shift-overflow=2 -Werror=undef -Wfloat-equal -Wimplicit-fallthrough=5 -Winit-self -Wlogical-op -Wmissing-include-dirs -Wmissing-noreturn -Wnested-externs -Wold-style-definition -Wpointer-arith -Wredundant-decls -Wshadow -Wstrict-aliasing=2 -Wstrict-prototypes -Wsuggest-attribute=noreturn -Wunused-function -Wwrite-strings -Wno-unused-result -Werror=missing-declarations -Werror=missing-prototypes -fdiagnostics-show-option -fno-common -fno-strict-aliasing -fstack-protector -fstack-protector-strong -fvisibility=hidden --param=ssp-buffer-size=4 -fno-omit-frame-pointer -Werror=shadow -include config.h -DOPENSSL_LOAD_CONF -MD -MQ systemd-measure.p/src_boot_measure.c.o -MF systemd-measure.p/src_boot_measure.c.o.d -o systemd-measure.p/src_boot_measure.c.o -c ../src/boot/measure.c
        ../src/boot/measure.c: In function ‘verb_sign’:
        ../src/boot/measure.c:710:48: error: variable ‘c’ has initializer but incomplete type
          710 |         _cleanup_(tpm2_context_destroy) struct tpm2_context c = {};

        [308/1382] Compiling C object systemd-pcrphase.p/src_boot_pcrphase.c.o
        FAILED: systemd-pcrphase.p/src_boot_pcrphase.c.o
        cc -Isystemd-pcrphase.p -I. -I.. -Isrc/basic -I../src/basic -Isrc/fundamental -I../src/fundamental -Isrc/systemd -I../src/systemd -I../src/libsystemd/sd-bus -I../src/libsystemd/sd-device -I../src/libsystemd/sd-event -I../src/libsystemd/sd-hwdb -I../src/libsystemd/sd-id128 -I../src/libsystemd/sd-journal -I../src/libsystemd/sd-netlink -I../src/libsystemd/sd-network -I../src/libsystemd/sd-resolve -Isrc/shared -I../src/shared -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -std=gnu11 -O0 -g -Wno-missing-field-initializers -Wno-unused-parameter -Wdate-time -Wendif-labels -Werror=format=2 -Werror=format-signedness -Werror=implicit-function-declaration -Werror=incompatible-pointer-types -Werror=int-conversion -Werror=overflow -Werror=override-init -Werror=return-type -Werror=shift-count-overflow -Werror=shift-overflow=2 -Werror=undef -Wfloat-equal -Wimplicit-fallthrough=5 -Winit-self -Wlogical-op -Wmissing-include-dirs -Wmissing-noreturn -Wnested-externs -Wold-style-definition -Wpointer-arith -Wredundant-decls -Wshadow -Wstrict-aliasing=2 -Wstrict-prototypes -Wsuggest-attribute=noreturn -Wunused-function -Wwrite-strings -Wno-unused-result -Werror=missing-declarations -Werror=missing-prototypes -fdiagnostics-show-option -fno-common -fno-strict-aliasing -fstack-protector -fstack-protector-strong -fvisibility=hidden --param=ssp-buffer-size=4 -fno-omit-frame-pointer -Werror=shadow -include config.h -DOPENSSL_LOAD_CONF -MD -MQ systemd-pcrphase.p/src_boot_pcrphase.c.o -MF systemd-pcrphase.p/src_boot_pcrphase.c.o.d -o systemd-pcrphase.p/src_boot_pcrphase.c.o -c ../src/boot/pcrphase.c
        ../src/boot/pcrphase.c: In function ‘determine_banks’:
        ../src/boot/pcrphase.c:117:24: error: unknown type name ‘TPMI_ALG_HASH’
          117 |         _cleanup_free_ TPMI_ALG_HASH *algs = NULL;

Guarding the utilites with HAVE_TPM2 fixes the issue for me.

This complements #24811.
2022-10-06 22:57:45 +09:00
Michal Koutný 3e6eafddbf core/cgroup: Silence IODeviceWeight= exclusive policy warnings
A single device cannot have more than a single proportional control
policy at the same time. So either io.bfq.weight or io.weight will
always fail. Process the resulting values and emit a warning message
only when none was really configured.

This patch also drops warnings when setting [blk]io.bfq.weight fails,
the code would be too convoluted otherwise.
2022-03-29 18:06:40 +02:00
Michal Koutný 8d75f60e3a core/cgroup: Silence warnings IODeviceWeigth= on old kernels
Old kernels (795fe54c2a82 ("bfq: Add per-device weight") v5.4) won't
allow io.bfq.weight per-device configuration, don't get too excited
about it but give the user one warning message to be aware this settings
don't apply.
2022-03-29 18:06:08 +02:00
Michal Koutný 1cf4a685ad core/cgroup: Refactor device weight property name
Use arithmetic over explicit list of existing property names.
2022-03-29 17:46:11 +02:00
Michal Koutný 9f0c0c4e15 core/cgroup: Apply IODeviceWeight= through BFQ attributes as well
There are two possible IO control mechanisms (io.cost and BFQ) that
expose separate weights APIs. In systemd units we configure only a
single device weight value so we need to write it to both attribute
files.
This patch extends to devices what is already done for default cgroup IO
weight in commit 2dbc45aea7 ("cgroup: Also set io.bfq.weight"). This
is possible with kernels >= v5.4 with commit 795fe54c2a82 ("bfq: Add
per-device weight"). A warning is logged if the write fails on older kernels.

Since per-device weight of a particular device cannot use both io.cost
policy and BFQ scheduler, at least one warning is always expected with
this approach (the method that is unconfigured).
2022-03-23 19:20:51 +01:00
Michal Koutný bec17e801a core/cgroup: Factor out BFQ weight setting
No functional change.
2022-01-10 18:23:20 +01:00
Michal Koutný d2bd0bfa36 cgroup-util: Move macros to macros and tests to tests
Friends to friends to be consistent with the other macros and make tests
separate from main code.
2022-01-10 18:22:41 +01:00
Michal Koutný d43ffcac84 core/cgroup: Provide information about applied BFQ scaling
The BFQ weights are not passed verbatim to the kernel, provide that
information in a form of debug message so that users are not
surprised/confused when IOWeight != io.bfq.weight.
2022-01-10 18:22:27 +01:00
Michal Koutný 7a0895c2eb Revert "CI: disable opensuse mkosi CI"
This reverts commit ab6df52083.

The image build failed during kernel RPM installation (bug in %post
scriptlet). This has been fixed in the package suse-module-tools 16.0.13
[1]. The fix is in openSUSE Tumbleweed repos so the tests can be enabled
again.

[1] https://github.com/openSUSE/suse-module-tools/pull/53

Fixes: #21019
2021-11-09 10:57:03 +00:00
Michal Koutný 13e721036b core: Make sure cgroup_oom_queue is flushed on manager exit
The unit queues are not serialized/deserialized (they are recreated
after reexec/reload instead). The destroyed units are not removed from
the cgroup_oom_queue. That means the queue may contain possibly invalid
pointers to released units.

Fix this by removing the units from cgroup_oom_queue as we do for
others. When at it, sync assert checks with currently existing queues
and put them in order in the manager cleanup code.
2021-08-05 10:35:20 -04:00
Michal Koutný 3ec4fccb37 ci: Add openSUSE Tumbleweed among tested distros 2021-08-04 11:16:48 +02:00
Michal Koutný 7e5e604393 ci: Detect shell prompt with higher specificity
The current pattern '#' triggers on the openSUSE kernel version that is
printed early during boot when no actual prompt is ready
> [    0.000000] Linux version 5.12.10-1-default (geeko@buildhost) (gcc (SUSE Linux) 11.1.1 20210510 [revision 23855a176609fe8dda6abaf2b21846b4517966eb], GNU ld (GNU Binutils; openSUSE Tumbleweed) 2.36.1.20210326-4) #1 SMP Fri Jun 11 05:05:06 UTC 2021 (b92eaf7)

Instead wait for pattern that: a) should have fewer false positives, b)
still be with working on distro shells:

openSUSE (red color)
^[[1m^[[31mimage:~ #^[[m^O

arch
[root@image ~]#

debian
root@image:~#

ubuntu
root@image:~#

fedora
[root@image ~]#
2021-08-04 11:16:48 +02:00
Michal Koutný 2e9055ab6a ci: Do not require network in test images
The current boot test relies on terminal login, therefore network setup
inside image is unnecessary. This opens up possibility to test images
that don't support the network setup via veth devices.
2021-08-04 11:16:48 +02:00
Michal Koutný 7c87fb219e ci: Bump mkosi version to v10
Use mkosi GH action that includes fixes for openSUSE builds. This
enables testing openSUSE builds in CI.
2021-08-04 11:16:48 +02:00
Michal Koutný ed802c44da mkosi: Fix openSUSE Jinja2 package name
Dare to be different ¯\_(ツ)_/¯
2021-07-09 10:49:30 +02:00
Michal Koutný f2bb8857cd mkosi: openSUSE update --bootable=no dependencies
Since we can build --bootable=no images without dracut->systemd, we need
to add systemd runtime dependencies explicitely.
2021-07-09 10:49:30 +02:00
Michal Koutný cc815b7fea core: Avoid spurious realization of unit cgroups
Cgroups may be unnecessarily realized when they are not needed. This
happens, e.g. for mount units parsed from /proc/$PID/mountinfo, check

        touch /run/ns_mount
        unshare -n sh -c "mount --bind /proc/self/ns/net /run/ns_mount"
        # no cgroup exists
        file /sys/fs/cgroup/system.slice/run-ns_mount.mount
        systemctl daemon-reload
        # the vain cgroup exists
        file /sys/fs/cgroup/system.slice/run-ns_mount.mount

. (Such cgroups can account to a large number with many similar mounts.)

The code already accounts for "lazy" realization (see various checks for
Unit.cgroup_realized) but the unit_deserialize() in the reload/reexec
path performs unconditional realization.

Invalidate (and queue) the units for realization only if we know that
they were already realized in the past. This is a safe thing to do even
in the case the reload brings some new cgroup setting (controllers, BPF)
because units that aren't realized will use the updated setting when the
time for their realization comes. (It's not even needed to add a code
comment because the current formulation suggests the changed behavior.)
2021-06-11 10:34:22 +01:00
Michal Koutný 873446f2e4 Revert "Silence cgroups v1 read-only filesystem warning"
PID 1 will now check upfront which v1 controller hiearchies are
available and modifiable and therefore it will not attempt to touch
them. If we get an EROFS failure then, it points to another
inconsistency so we will report it again. The revert also simplifies the
code a bit.
2021-02-11 16:59:50 +01:00
Michal Koutný 0fa7b50053 core: Make (user) instance aware of delegated cgroup controllers
systemd user instance assumed same controllers are available to it as to
PID 1. That is not true generally, in v1 (legacy, hybrid) we don't delegate any
controllers to anyone and in v2 (unified) we may delegate only subset of
controllers.
The user instance would fail silently when the controller cgroup cannot
be created or the controller cannot be enabled on the unified hierarchy.

The changes in 7b63961415 ("cgroup: Swap cgroup v1 deletion and
migration") caused some attempts of operating on non-delegated
controllers to be logged.

Make the user instance first check what controllers are availble to it
and narrow operations only to these controllers. The original checks are
kept in place.

Note that daemon-reexec needs to be invoked in order to update the set
of unabled controllers after a change.

Fixes: #18047
Fixes: #17862
2021-02-11 16:58:34 +01:00
Michal Koutný 81504017f4 cgroup: Simplify cg_get_path_and_check
The function controller_is_accessible() doesn't do really much in case
of the unified hierarchy. Move common parts into cg_get_path_and_check
and make controller check v1 specific. This is refactoring only.
2021-02-11 11:51:59 +01:00
Michal Koutný 0bc2f071e1 meson: Fix missing libseccomp dependencies
The builds with HAVE_SECCOMP fail on missing include paths:

FAILED: src/basic/libbasic.a.p/parse-util.c.o
cc -Isrc/basic/libbasic.a.p -Isrc/basic -I../src/basic -Isrc/boot -I../src/boot -Isrc/home -I../src/home -Isrc/shared -I../src/shared -Isrc/systemd -I../src/systemd -Isrc/journal -I../src/journal -Isrc/journal-remote -I../src/journal-remote -Isrc/nspawn -I../src/nspawn -Isrc/resolve -I../src/resolve -Isrc/timesync -I../src/timesync -I../src/time-wait-sync -Isrc/login -I../src/login -Isrc/udev -I../src/udev -Isrc/libudev -I../src/libudev -Isrc/core -I../src/core -Isrc/shutdown -I../src/shutdown -I../src/xdg-autostart-generator -I../src/libsystemd/sd-bus -I../src/libsystemd/sd-device -I../src/libsystemd/sd-event -I../src/libsystemd/sd-hwdb -I../src/libsystemd/sd-id128 -I../src/libsystemd/sd-netlink -I../src/libsystemd/sd-network -I../src/libsystemd/sd-resolve -Isrc/libsystemd-network -I../src/libsystemd-network -I. -I.. -fdiagnostics-color=always -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -std=gnu99 -g -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Werror=undef -Wlogical-op -Wmissing-include-dirs -Wold-style-definition -Wpointer-arith -Winit-self -Wfloat-equal -Wsuggest-attribute=noreturn -Werror=missing-prototypes -Werror=implicit-function-declaration -Werror=missing-declarations -Werror=return-type -Werror=incompatible-pointer-types -Werror=format=2 -Wstrict-prototypes -Wredundant-decls -Wmissing-noreturn -Wimplicit-fallthrough=5 -Wshadow -Wendif-labels -Wstrict-aliasing=2 -Wwrite-strings -Werror=overflow -Werror=shift-count-overflow -Werror=shift-overflow=2 -Wdate-time -Wnested-externs -Wno-maybe-uninitialized -ffast-math -fno-common -fdiagnostics-show-option -fno-strict-aliasing -fvisibility=hidden -fstack-protector -fstack-protector-strong --param=ssp-buffer-size=4 -Werror=shadow -include config.h -fPIC -pthread -fvisibility=default -MD -MQ src/basic/libbasic.a.p/parse-util.c.o -MF src/basic/libbasic.a.p/parse-util.c.o.d -o src/basic/libbasic.a.p/parse-util.c.o -c ../src/basic/parse-util.c
In file included from ../src/basic/parse-util.c:20:
../src/shared/seccomp-util.h:4:10: fatal error: seccomp.h: No such file or directory
    4 | #include <seccomp.h>
      |          ^~~~~~~~~~~
compilation terminated.

FAILED: test-parse-util.p/src_test_test-parse-util.c.o
cc -Itest-parse-util.p -I. -I.. -Isrc/basic -I../src/basic -Isrc/boot -I../src/boot -Isrc/home -I../src/home -Isrc/shared -I../src/shared -Isrc/systemd -I../src/systemd -Isrc/journal -I../src/journal -Isrc/journal-remote -I../src/journal-remote -Isrc/nspawn -I../src/nspawn -Isrc/resolve -I../src/resolve -Isrc/timesync -I../src/timesync -I../src/time-wait-sync -Isrc/login -I../src/login -Isrc/udev -I../src/udev -Isrc/libudev -I../src/libudev -Isrc/core -I../src/core -Isrc/shutdown -I../src/shutdown -I../src/xdg-autostart-generator -I../src/libsystemd/sd-bus -I../src/libsystemd/sd-device -I../src/libsystemd/sd-event -I../src/libsystemd/sd-hwdb -I../src/libsystemd/sd-id128 -I../src/libsystemd/sd-netlink -I../src/libsystemd/sd-network -I../src/libsystemd/sd-resolve -Isrc/libsystemd-network -I../src/libsystemd-network -fdiagnostics-color=always -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -std=gnu99 -g -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Werror=undef -Wlogical-op -Wmissing-include-dirs -Wold-style-definition -Wpointer-arith -Winit-self -Wfloat-equal -Wsuggest-attribute=noreturn -Werror=missing-prototypes -Werror=implicit-function-declaration -Werror=missing-declarations -Werror=return-type -Werror=incompatible-pointer-types -Werror=format=2 -Wstrict-prototypes -Wredundant-decls -Wmissing-noreturn -Wimplicit-fallthrough=5 -Wshadow -Wendif-labels -Wstrict-aliasing=2 -Wwrite-strings -Werror=overflow -Werror=shift-count-overflow -Werror=shift-overflow=2 -Wdate-time -Wnested-externs -Wno-maybe-uninitialized -ffast-math -fno-common -fdiagnostics-show-option -fno-strict-aliasing -fvisibility=hidden -fstack-protector -fstack-protector-strong --param=ssp-buffer-size=4 -Werror=shadow -include config.h -MD -MQ test-parse-util.p/src_test_test-parse-util.c.o -MF test-parse-util.p/src_test_test-parse-util.c.o.d -o test-parse-util.p/src_test_test-parse-util.c.o -c ../src/test/test-parse-util.c
In file included from ../src/test/test-parse-util.c:14:
../src/shared/seccomp-util.h:4:10: fatal error: seccomp.h: No such file or directory
    4 | #include <seccomp.h>
      |          ^~~~~~~~~~~
compilation terminated.

Add the respective deps.

Fixes: 005bfaf118 ("exec: Add kill action to system call filters")
2020-10-16 12:30:24 +09:00
Michal Koutný 94d21c2ef6 missing: Add new Linux capability
Yet another new capability coming in Linux kernel v5.9.
Make sure we can recongize them even when built with older kernel headers.
2020-08-27 16:13:09 +02:00
Michal Koutný d9ef594454 cgroup: Cleanup function usage
Some masks shouldn't be needed externally, so keep their functions in
the module (others would fit there too but they're used in tests) to
think twice if something would depend on them.

Drop unused function cg_attach_many_everywhere.

Use cgroup_realized instead of cgroup_path when we actually ask for
realized.

This should not cause any functional changes.
2020-08-19 11:41:53 +02:00
Michal Koutný 12b975e065 cgroup: Reduce unit_get_ancestor_disable_mask use
The usage in unit_get_own_mask is redundant, we only need apply
disable_mask at the end befor application, i.e. calculating enable or
target mask.

(IOW, we allow all configurations, but disabling affects effective
controls.)

Modify tests accordingly and add testing of enable mask.

This is intended as cleanup, with no effect but changing unit_dump
output.
2020-08-19 11:41:53 +02:00
Michal Koutný 4c591f3996 cgroup: Introduce family queueing instead of siblings
The unit_add_siblings_to_cgroup_realize_queue does more than mere
siblings queueing, hence define a family of a unit as (immediate)
children of the unit and immediate children of all ancestors.

Working with this abstraction simplifies the queuing calls and it
shouldn't change the functionality.
2020-08-19 11:41:53 +02:00
Michal Koutný f23ba94db3 cgroup: Implicit unit_invalidate_cgroup_members_masks
Merge members mask invalidation into
unit_add_siblings_to_cgroup_realize_queue, this way unit_realize_cgroup
needn't be called with members mask invalidation.

We have to retain the members mask invalidation in unit_load -- although
active units would have cgroups (re)realized (unit_load queues for
realization), the realization would happen with potentially stale mask.
2020-08-19 11:41:53 +02:00
Michal Koutný fb46fca7e0 cgroup: Eager realization in unit_free
unit_free(u) realizes direct parent and invalidates members mask of all
ancestors. This isn't sufficient in v1 controller hierarchies since
siblings of the freed unit may have existed only because of the removed
unit.

We cannot be lazy about the siblings because if parent(u) is also
removed, it'd migrate and rmdir cgroups for siblings(u). However,
realized masks of siblings(u) won't reflect this change.

This was a non-issue earlier, because we weren't removing cgroup
directories properly (effectively matching the stale realized mask),
removal failed because of tasks left by missing migration (see previous
commit).

Therefore, ensure realization of all units necessary to clean up after
the free'd unit.

Fixes: #14149
2020-08-19 11:41:53 +02:00
Michal Koutný 7b63961415 cgroup: Swap cgroup v1 deletion and migration
When we are about to derealize a controller on v1 cgroup, we first
attempt to delete the controller cgroup and migrate afterwards. This
doesn't work in practice because populated cgroup cannot be deleted.
Furthermore, we leave out slices from migration completely, so
(un)setting a control value on them won't realize their controller
cgroup.

Rework actual realization, unit_create_cgroup() becomes
unit_update_cgroup() and make sure that controller hierarchies are
reduced when given controller cgroup ceased to be needed.

Note that with this we introduce slight deviation between v1 and v2 code
-- when a descendant unit turns off a delegated controller, we attempt
to disable it in ancestor slices. On v2 this may fail (kernel enforced,
because of child cgroups using the controller), on v1 we'll migrate
whole subtree and trim the subhierachy. (Previously, we wouldn't take
away delegated controller, however, derealization was broken anyway.)

Fixes: #14149
2020-08-19 11:41:53 +02:00
Michal Koutný 30ad3ca086 cgroup: Add root slice to cgroup realization queue
When we're disabling controller on a direct child of root cgroup, we
forgot to add root slice into cgroup realization queue, which prevented
proper disabling of the controller (on unified hierarchy).

The mechanism relying on "bounce from bottom and propagate up" in
unit_create_cgroup doesn't work on unified hierarchy (leaves needn't be
enabled). Drop it as we rely on the ancestors to be queued -- that's now
intentional but was artifact of combining the two patches:

cb5e3bc37d ("cgroup: Don't explicitly check for member in UNIT_BEFORE") v240~78
65f6b6bdcb ("core: fix re-realization of cgroup siblings") v245-rc1~153^2

Fixes: #14917
2020-07-28 15:49:24 +02:00
Michal Koutný a479c21ed2 cgroup: Make realize_queue behave FIFO
The current implementation is LIFO, which is a) confusing b) prevents
some ordered operations on the cgroup tree (e.g. removing children
before parents).

Fix it quickly. Current list implementation turns this from O(1) to O(n)
operation. Rework the lists later.
2020-07-28 15:49:24 +02:00
Michal Koutný e41de5e491 missing: Add new Linux capabilities
Linux kernel v5.8 adds two new capabilities. Make sure we can recongize
them even when built with older kernel.
2020-06-25 09:02:43 +02:00
Michal Koutný d184fb39b6 test: Test memory limit parsing
This covers parsing from configuration files only. Properties set via
DBus have separate code path whose testing would require DBus setup.
2020-06-24 23:16:11 +02:00
Michal Koutný 67e2baff6b cgroup: Parse infinity properly for memory protections
This fixes commit db2b8d2e28 that
rectified parsing empty values but broke parsing explicit infinity.
Intended parsing semantics will be captured in a testcase in a follow up
commit.

Ref: #16248
2020-06-24 23:16:06 +02:00
Michal Koutný 53aa85af24 cgroup: Allow empty assignments of Memory{Low,Min}=
Currently, an empty assignment of Memory{Low,Min}= directives would be
interpretted as setting it to global default, i.e. zero. However, if we
set a runtime protection value on a unit that inherits parent's
DefaultMemory{Low,Min}=, it is not possible to revert it back to the
state where the DefaultMemory{Low,Min}= is propagated from parent
slice(s).

This patch changes the semantics of the empty assignments to explicitly
nullify any value set by the user previously. Since DBus API uses
uint64_t where 0 is a valid configuration, the patch modifies DBus API
by exploiting the variant type of property value to pass the NULL value.
2020-06-02 18:59:47 +02:00
Michal Koutný db2b8d2e28 cgroup: Make empty assignments reset to default
When MemoryLow= or MemoryMin= is set, it is interpretted as setting the
values to infinity. This is inconsistent with the default initialization
to 0.
It'd be nice to interpret the empty assignment as fallback to
DefaultMemory* of parent slice, however, current DBus API cannot convey
such a NULL value, so stick to simply interpretting that as hard-wired
default.
2020-06-02 18:59:47 +02:00
Michal Koutný 21c8397694 tests: Fix description of test units
Corrected reference to non-existent unit.
2020-06-02 18:59:47 +02:00
Michal Koutný 38fee61952 systemctl: Fix frozen state coloring
When unit is in an unhighlighted state, freezer coloring won't be turned off
(active_off is empty) until the end of the TTY output.
2020-05-19 19:35:36 +02:00
Michal Koutný a840ad5ae8 mkosi: Add explicit --bootable=no openSUSE dependencies
Many dependencies were pulled via dracut->systemd. Since we can build
stripped images without initrd and dracut, we need to add systemd
runtime dependencies explicitely.
2020-05-19 13:14:19 +02:00
Michal Koutný 498115c2b6 mkosi: Add openSUSE Tumbleweed packages
patterns-base-minimal_base is a moving target, so dependencies need to
be as explicit as possible.
2020-05-18 23:06:22 +02:00
Michal Koutný 05d9125ece mkosi: Fix openSUSE image declaration
User accounts of given names are necessary for the build script and
tests to succeed.

(Fixup of #15527, too keen cleaning of dependencies and cached image
caused this.)
2020-05-04 22:12:58 +02:00
Michal Koutný 2e4086060b test: Fix build with !HAVE_LZ4 && HAVE_XZ
HUGE_SIZE was defined inconsistently.

> In file included from ../src/basic/alloc-util.h:9,
>                  from ../src/journal/test-compress.c:9:
> ../src/journal/test-compress.c: In function ‘main’:
> ../src/journal/test-compress.c:280:33: error: ‘HUGE_SIZE’ undeclared (first use in this function)
>   280 |         assert_se(huge = malloc(HUGE_SIZE));
2020-05-02 20:04:36 +00:00
Michal Koutný 69d95d6468 mkosi: Add openSUSE params file
The setup is meant to run against openSUSE Tumbleweed and install
minimum packages necessary for successful build and passing tests.

To speed up incremental build an external build directory is used.
2020-04-23 10:28:03 +02:00
Michal Koutný ff5499824f mkosi: Unify environment for unit tests
Some testcases in test-execute rely on existence of user groups with
certain gids. However, their existence is not universally granted [1].
Although the test could be skipped in their absence and give up testing
some code paths, different approach was chosen -- create dummy groups in
the testing image.

[1] See how systemd-sysusers allocates gids (e.g.
src/test/test-uid-range.c).
2020-04-22 10:35:12 +02:00
Michal Koutný 9acb2964d7 test: Simplify hostname checking
Both hostname and uname utilities boil down to uname(2) syscall. Reduce
tests dependency footprint by using uname for checking hostname too.
2020-04-22 10:35:12 +02:00
Michal Koutný bac567a53b mkosi: Use distro-invariant rootprefix
Distributions may be build with various configs, e.g. customized
rootprefix. It'd be unmaintanable to have specific mkosi.build for each
supported distro. Hence, make the build script flexible yet distro
oblivious.
2020-04-22 10:35:12 +02:00
Michal Koutný 8b51950f4c docs: Correct resource weight range 2020-02-05 16:58:07 +00:00
Michal Koutný 594057fd99 tests: Check trivial loop between two jobs
job_compare return value is undefined in case the jobs have a loop
between them, so better make a test to make sure transaction cycle
detection catches it.
2019-06-26 23:16:31 +02:00
Michal Koutný 804cdabc31 tests: Check job ordering on execution cycles
The test-engine Test2 tests the cycle detection when units a, b and d
all start at once

    ,-------------------after-----------------,
    v                                         |
    a/start ---after---> d/start ---after---> b/start

Extend the test with Test11 that adds i.service which causes a and d
stop (by unordered Conflicts=) while starting b. Because stops precede
starts, we effectively eliminate the job cycle and all transaction jobs
should be applicable.

    ,-------------------after-----------------,
    v                                         |
    a/stop <---after--- d/stop <---after--- b/start
    .                   .                     ^
    .                   .                     |
     '. . . . . . . . . i/start ---after------'
2019-06-26 23:16:31 +02:00
Michal Koutný dfd79eca55 core: Check transaction against execution cycles
When we are validating a transaction, we take into account declared
ordering between job units. However, since JOB_STOP goes always first
regardless of the ordering constraint between respective units, we may
detect some false cycles in the transaction which would not prevent the
execution though.

Use the same logic in transaction checking as we use for job execution.
2019-06-26 23:16:31 +02:00
Michal Koutný e602f15282 core: Extract job ordering logic
The job ordering logic is spread at multiple places of the code, making
it hard to maintain and also a bit to understand. The actual execution
order of two jobs always depends on their types and the ordering
contraint between their units. Extract this logic to a new function
job_compare. The second change is simplification of the order
evaluation, JOB_STOP takes always precedence (as documented), unless two
units are both stopping, then the ordering constraint is taken into
account.
2019-06-26 00:00:43 +02:00
Michal Koutný d3340e6f95 analyze: Fix build without seccomp (#10899) 2018-11-24 02:40:32 +09:00
Michal Koutný aa1f95d264 core: Detect initial timer state from serialized data
We keep a mark whether a single-shot timer was triggered in the caller's
variable initial. When such a timer elapses while we are
serializing/deserializing the inner state, we consider the timer
incorrectly as elapsed and don't trigger it later.

This patch exploits last_trigger timestamp that we already serialize,
hence we can eliminate the argument initial completely.

A reproducer for OnBootSec= timers:
        cat >repro.c <<EOD
        /*
         * Compile:	gcc repro.c -o repro
         * Run:		./repro
         */
        #include <errno.h>
        #include <fcntl.h>
        #include <stdio.h>
        #include <stdlib.h>
        #include <sys/stat.h>
        #include <sys/types.h>
        #include <time.h>
        #include <unistd.h>

        int main(int argc, char *argv[]) {
        	char command[1024];
        	int pause;

        	struct timespec now;

        	while (1) {
        		usleep(rand() % 200000); // prevent periodic repeats
               		clock_gettime(CLOCK_MONOTONIC, &now);
        		printf("%i\n", now.tv_sec);

        		system("rm -f $PWD/mark");
        		snprintf(command, 1024, "systemd-run --user --on-boot=%i --timer-property=AccuracySec=100ms "
        					"touch $PWD/mark", now.tv_sec + 1);
        		system(command);
        		system("systemctl --user list-timers");
        		pause = (1000000000 - now.tv_nsec)/1000 - 70000; // fiddle to hit the middle of reloading
        		usleep(pause > 0 ? pause : 0);
        		system("systemctl --user daemon-reload");
        		sync();
        		sleep(2);
        		if (open("./mark", 0) < 0)
        			if (errno == ENOENT) {
        				printf("mark file does not exist\n");
        				break;
        			}
        	}

        	return 0;
        }
        EOD
2018-11-21 11:28:33 +01:00
Michal Koutný 1e75824cb0 core/manager: Make sure jobs statistics are not double after daemon-reload
We add n_installed_jobs and n_failed_jobs to our inner state after
deserialization. This is fine during daemon-reexec when we start with clear
Manager (and some jobs possibly queued before deserialization), however,
daemon-reload works with the same manager and adding the values would
effectively double the counters. Reset the counters before we deserialize and
add their values again.
2018-06-25 11:18:44 +02:00
Michal Koutný 1a0d353b44 man: SystemMaxUse= clarification in journald.conf(5)
Similar semantics applies to {System,Runtime}MaxUse= as to
{System,Runtime}MaxFiles=, i.e. active files aren't vacuumed and the limit
is not thus strictly honored.
2018-06-25 11:18:20 +02:00
Michal Koutný c7f7e859f0 man: Correct value of default KillUserProcesses= 2018-03-09 18:29:25 +01:00
Michal Koutný 7f672e865a man: Unify values of boolean configuration values with sample config 2018-03-09 18:29:05 +01:00
Michal Koutný 204d140c4d core/timer: Prevent timer looping when unit cannot start
When a unit job finishes early (e.g. when fork(2) fails) triggered unit goes
through states
        stopped->failed (or failed->failed),
in case a ExecStart= command fails unit passes through
        stopped->starting->failed.

The former transition doesn't result in unit active/inactive timestamp being
updated and timer (OnUnitActiveSec= or OnUnitInactiveSec=) would use an expired
timestamp triggering immediately again (repeatedly).

This patch exploits timer's last trigger timestamp to ensure the timer isn't
triggered more frequently than OnUnitActiveSec=/OnUnitInactiveSec= period.

Steps to reproduce:

0) Create sample units:

cat >~/.config/systemd/user/looper.service <<EOD
[Service]
ExecStart=/usr/bin/sleep 2
EOD

cat >~/.config/systemd/user/looper.timer <<EOD
[Timer]
AccuracySec=5
OnUnitActiveSec=5
EOD

1) systemctl --user daemon-reload

2) systemctl --user start looper.timer
   # to have first activation timestamp/sentinel
   systemctl --user start looper.service

o  Observe the service is being regularly triggered.

3) systemctl set-property user@$UID.service TasksMax=2

o  Observe the tight looping as long as the looper.service cannot be started.

Ref: #5969
2018-01-22 17:13:00 +01:00