shared/specifier: provide proper error messages when specifiers fail to read files
ENOENT is easily confused with the file that we're working on not being
present, e.g. when the file contains %o or something else that requires
os-release to be present. Let's use -EUNATCH instead to reduce that chances of
confusion if the context of the error is lost.
And once we have pinpointed the reason, let's provide a proper error message:
+ build/systemctl --root=/tmp/systemctl-test.TO7Mcb enable some-some-link6@.socket
/tmp/systemctl-test.TO7Mcb/etc/systemd/system/some-some-link6@.socket: Failed to resolve alias "target@A:%A.socket": Protocol driver not attached
Failed to enable unit, cannot resolve specifiers in "target@A:%A.socket".
shared/specifier: clarify and add test for missing data
In systemd.unit we document that unset fields resolve to "". But we didn't
directly test this, so let's do that. Also, we return -ENOENT if the file
is missing, which we didn't document or test.
man/os-release: add a note about repeating entries
We didn't actually say that keys should not be repeated. At least the
examples in docs (both python and shell) would do that, and any simple
parser that builds a dictionary would most likely behave the same way.
But let's document this expectation, but also say how to deal with malformed
files.
basic: add new variable $SYSTEMD_OS_RELEASE to override location of os-release
The test for the variable is added in test-systemctl-enable because there we
can do it almost for free, and the variable is most likely to be used with
'systemctl enable --root' anyway.
This test has overlap with test-install-root, but it tests things at a
different level, so I think it's useful to add. It immediately shows various
bugs which will be fixed in later patches.
When we are printing a valid unit name, quoting isn't necessary, because
unit names cannot contain whitespace or other confusing characters. In particular
if the unit name is prefixed by " unit " or something else that clearly
identifies the string as a unit name, quoting would just add unnecessary
noise. But when we're printing paths or invalid names, it's better to add
quotes for clarity.
shared/install: reuse the standard symlink verification subroutine
We save a few lines, but the important thing is that we don't have two
different implementations with slightly different rules used for enablement
and loading. Fixes #22000.
Tested with:
- the report in #22000, it now says:
$ SYSTEMD_LOG_LEVEL=debug systemctl --root=/ enable test.service
Suspicious symlink /etc/systemd/system/test.service→/etc/systemd/system/myown.d/test.service, treating as alias.
unit_file_resolve_symlink: self-alias: /etc/systemd/system/test.service → test.service, ignoring.
running_in_chroot(): Permission denied
Suspicious symlink /etc/systemd/system/test.service→/etc/systemd/system/myown.d/test.service, treating as alias.
unit_file_resolve_symlink: self-alias: /etc/systemd/system/test.service → test.service, ignoring.
Failed to enable unit, refusing to operate on linked unit file test.service
- a symlink to /dev/null:
...
unit_file_resolve_symlink: linked unit file: /etc/systemd/system/test3.service → /dev/null
Failed to enable unit, unit /etc/systemd/system/test3.service is masked.
- the same from the host:
...
unit_file_resolve_symlink: linked unit file: /var/lib/machines/rawhide/etc/systemd/system/test3.service → /var/lib/machines/rawhide/dev/null
Failed to enable unit, unit /var/lib/machines/rawhide/etc/systemd/system/test3.service is masked.
- through the manager:
$ sudo systemctl enable test.service
Failed to enable unit: Refusing to operate on alias name or linked unit file: test.service
$ sudo systemctl enable test3.service
Failed to enable unit: Unit file /etc/systemd/system/test3.service is masked.
As seen in the first example, the warning is repeated. This is because we call
the lookup logic twice: first for sysv-compat, and then again for real. I think
that since this is only for broken setups, and when sysv-compat is enabled, and
in an infrequent manual operation, at debug level, this is OK.
basic/unit-file: split out the subroutine for symlink verification
The old logs used __func__, but this doesn't make sense now, because the
low-level function will be used in other places. So those are adjusted to be
more generic.
No functional change intended. The type of the iterator is generally changed to
be 'const char*' instead of 'char*'. Despite the type commonly used, modifying
the string was not allowed.
I adjusted the naming of some short variables for clarity and reduced the scope
of some variable declarations in code that was being touched anyway.
meson: replace sh+find with an internal glob in the python helper
As suggested in https://github.com/systemd/systemd/pull/22810#discussion_r831708052
This makes the whole thing simpler. A glob is passed to helper which then resolves
it on its own. This way it's trivial to call the helper with a different
set of files for testing.
tools/dbus_exporter: deblackify and shorten code a bit
When we do mkdir, we should just use 0o777 and let the umask take care of the
rest. Specifying an explicit mode is inappropriate. And when touching the code,
let's replace black madness with normal python style.
Nishal Kulkarni [Sun, 13 Mar 2022 19:05:18 +0000 (00:35 +0530)]
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.
random-util: use correct minimum pool size constant
The actual minimum size of the pool across supported kernel versions is
32 bytes. So adjust this minimum.
I've audited every single usage of random_pool_size(), and cannot see
anywhere that this would have any impact at all on anything. We could
actually just not change the constant and everything would be fine, or
we could change it here and that's fine too. From both a functionality
and crypto perspective, it doesn't really seem to make a substantive
difference any which way, so long as the value is ≥32. However, it's
better to be correct and have the function do what it says, so clamp it
to the right minimum.
systemd-udev-trigger.service by default triggeres all devices regardless
of whether they were already recognized by systemd-udevd.
There are machines (especially in embedded environments) where
systemd-udev-trigger.service is configured to run at a later stage of
the boot sequence, which can lead to quite a lot of devices being
triggered although they were already recognized by systemd-udevd.
Re-triggering a lot of devices is a relatively expensive operation and
therefore should be avoided if unnecessary.
Therefore this patch introduces --initialized-nomatch, which filters out
devices that are already present in the udev database. For consistance
reasons --initialized-match is implemented as well, which filters out devices
that are *not* already present in the udev database.
Yu Watanabe [Sat, 19 Mar 2022 00:35:32 +0000 (09:35 +0900)]
sd-device-enumerator: drop /sys/subsystem support
This addresses the comment by Lennart
https://github.com/systemd/systemd/pull/22662#discussion_r829799863:
> /sys/subsystem is preparation for a future that never came.
> And given that the main proponent of this left Linux kernel
> development (Kay), I doubt this will ever come. So maybe we
> should start dropping references to /sys/subsystem/ given it's
> unlikely to materialize anytime soon.
docs: add /loader/entries.srel to the boot loader spec
This new file is supposed to address conflicts with Fedora/Grub's
frankenbootloaderspec implementation, that squatted the /loader/entries/
dir, but place incompatible files in them (that do variable expansion?).
A simple text file /loader/entries.srel shall indicate which spec is
implemented. If it contains the string "type1\n" then the
/loader/entries/ directory implements our standard spec, otherwise
something else.
man: also install systemd-stub man page as sd-stub
So, typically systemd-boot is referenced as sd-boot, due to te usual
shorter naming in ESP resources. systemd-stub didnt do that so far,
since it never appears as separate files in the ESP. However it's super
annoying that you can find "man sd-boot", but not the very closely
related "man sd-stub". Let's fix that, and also add an "sd-stub" alias
to the "systemd-stub" man page.
man: clarify where the settings in type #1 entries are documented
So (maybe weirdly) loader.conf(5) documents both loader.conf and type #1
entries (because they share a similar syntax). But it then only lists
the options of loader.conf. Let's add an explicit hint where to find
the documentation of the type #1 entries.
NEWS: try to fix old entry regarding KERNEL_INSTALL_LAYOUT
The old text was simply wrong, we used to read $layout from
/etc/kernel/install.conf and the machine ID from
$KERNEL_INSTALL_MACHINE_ID from /etc/machine-info. Correct that.
Apparently KERNEL_INSTALL_MACHINE_ID was already known back in v235
times, hence don't mention it anymore.
it's kinda weird retro-fixing these NEWS entries, given we deprecate
them again, but I couldn't let this really incorrect stuff be.
bootctl: load /etc/kernel/install.conf's $layout field, too
bootctl so far tried to determine the layout from /etc/machine-info, but
that's obsolete, and the kernel-install script never looked there. Let's
read the setting from /etc/kernel/install.conf instead, where
kernel-install actually looks.
Support for reading the field from /etc/machine-info is retained for
compat.
This means we'll now read /etc/machine-id, /etc/machine-info and
/etc/kernel/install.conf, and read the machine ID from the former too
and the layout setting from the latter two.
journal-file: port journal_file_open() to openat_report_new()
We so far had some magic logic in place that files we open for write
with size zero are freshly created. That of course is a bogus
assumption, in particular as this code deals with corrupted file systems
which oftentimes contain zero size inodes from left-over runs.
Let's fix this properly, and actually let the kernel tell us whether it
create the file or not.
fs-util: add openat_report_new() wrapper around openat()
This is a wrapper around openat(). It works mostly the same, except for
one thing: it race-freely reports whether we just created the indicated
file in case O_CREAT is passed without O_EXCL.
basic/strv: avoid potential UB with references to array[-1]
"""
Given an array a[N] of N elements of type T:
- Forming a pointer &a[i] (or a + i) with 0 ≤ i ≤ N is safe.
- Forming a pointer &a[i] with i < 0 or i > N causes undefined behavior.
- Dereferencing a pointer &a[i] with 0 ≤ i < N is safe.
- Dereferencing a pointer &a[i] with i < 0 or i ≥ N causes undefined behavior.
"""
As pointed by by @medhefgo, here we were forming a pointer to a[-1]. a itself
wasn't NULL, so a > 0, and a-1 was also >= 0, and this didn't seem to cause any
problems. But it's better to be formally correct, especially if we move the
code to src/fundamental/ later on and compile it differently.
Compilation shows no size change (with -O0 -g) on build/systemd, so this should
have no effect whatsoever.
With my crappy home network the test takes 29.5s usually. But with any
tiny slowdown, it goes above the 30s limit and fails. Let's bump the
timeout to avoid spurious failures.
"meson test" uses a test name generated from the file name and those long names
cause the test log output to exceed terminal width which looks bad. Let's replace
some long names with more-meaningful names that actually say something about
the tests.