112cfb1814 tried to improve handling of
paths when root is specified. It said:
> To avoid answering what a relative path means when called with a root
> prefix path_strv_canonicalize is now path_strv_canonicalize_absolute
> and only considers absolute paths. Fortunately all users of already call
> path_strv_canonicalize with a list of absolute paths.
Of course, other users were added later and for example now
SYSTEMD_HOSTNAME_WORDLIST_PATH=build/hostname-wordlist/ ... doesn't
work as expected. If root is not specified, there is really no reason
to ignore relative paths. They work relative to CWD per the usual convention.
It's up to the user to not use relative paths in a context where they
should not be used. When root is specified, continue to ignore the relative
paths, since there is no clear interpreation what they mean, but emit
a debug message.
This is useful to check if how fast the code is (painfully slow) and whether
worlds indeed are selected with a flat distribution probability (they are).
The code is slow because the hashing and because chaseat is exteremely
inefficient :(
Unfortunately udevadm is special, so some more infra extensions turned
out to be necessary.
Retroactively, we might want to apply some of the new functionality in
other places too, but I'm leaving that for later.
The petnames wordlist added in [1] is Apache-2.0 and this
causes problems with the distribution of systemd as the
GPL-2 and Apache-2.0 are considered incompatible by the FSF.
So this commit replaces the previous wordlist with
a new one:
- weather (basic english weather adjectives)
- colors (basic english color names)
- worlds (planets, moons, minor bodies of the solar system)
All common vocabulary and compiled for this project, not taken
from anywhere.
An example with the new list:
- wintry-rust-dione-9393
- warm-yellow-saturn-39f9
The "worlds" are picked on the following principles:
- well-known
- memorable
- short(ish)
- cool
This is why e.g. we have "thetis" (an astroid) instead of
"tethys" (a moon): easier to spell and more well known.
[1] https://github.com/systemd/systemd/pull/42566
The previous commit uses `parse_source_date_epoch()` for creating FAT
time stamps. Do the same in `mtools_exec()`, `mkfs.*`, and
`$E2FSPROGS_FAKE_TIME` instead of passing the raw environment variable.
That avoids these programs creating time stamps from a value we would
have rejected ourselves (unparsable, overflowing), read differently
(e.g. octal numbers), or from one that `secure_getenv()` declines to
look at under AT_SECURE.
Note: mtools derives file and directory timestamps from
$SOURCE_DATE_EPOCH since v4.0.20 (2018).
Use the new copy timestamp clamping mechanism from the previous commit
to fix unreproducible wall-clock files in the generated images.
That covers both modes: online mode writes through the kernel, and
offline mode stages the tree in a temporary directory before handing it
to mkfs or mcopy. `mcopy -m` then carries the clamped mtimes into the
FAT.
This complements commit 34c3d57474 (directory times) and commit
f191ca982c (FAT insertion order).
Cover all combinations (online/offline, with and without epoch) in the
new `testcase_vfat_reproducibility()`. Update `testcase_make_symlinks()`
to cover the symlink creation/re-fix their parent directory code paths.
Sadly, images are still not reproducible byte for byte. Document
systemd-repart's $SOURCE_DATE_EPOCH handling and remaining
reproducibility issues in the manpage.
Add a `ts_clamp` argument to `copy_tree_at_full()` and
`copy_times_full()` that clamps copied inodes to a given time stamp.
This is the recommended `$SOURCE_DATE_EPOCH` semantics [1] for
reproducible builds. Their non-`_full` APIs keep existing behaviour by
clamping to `USEC_INFINITY`.
atime and mtime are clamped separately: a file that was merely read
after the epoch has to keep its mtime and still lose its atime. E.g. FAT
(EFI partition) stores an access date.
[1] https://reproducible-builds.org/specs/source-date-epoch/
systemd-udevd is the same binary as udevadm, so the introspection data
describes both commands, from either name. The COMMAND intentionally
owns no verbs — all of udevadm's verbs are defined in udevadm.c right
after its own COMMAND, so that they are attributed to it.
The -V/--version output (GIT_VERSION) is preserved.
The custom help() is replaced by the common verb help, which derives the
synopsis, abstract, and option list from the verb declaration in
udevadm.c and the "udevadm-wait" option namespace. The verb's one-line
description from the abstract is retained, I think it is good enough
but shorter.
The custom help() is replaced by the common verb help, which derives the
synopsis, abstract, and option list from the verb declaration in
udevadm.c and the "udevadm-verify" option namespace.
The custom help() is replaced by the common verb help, which derives the
synopsis, abstract, and option list from the verb declaration in
udevadm.c and the "udevadm-trigger" option namespace.
The custom help() is replaced by the common verb help, which derives the
synopsis, abstract, and option list from the verb declaration in
udevadm.c and the "udevadm-test-builtin" option namespace. The list of
built-in commands is appended after the generic help. The man page
reference is now printed before the command list. It'd be somewhat
nicer to have it _after_, but that'd require a lot of plumbing to
split the help generated in two and just doesn't seem worth effort.
The list of commands is now printed to stdout (it went to stderr before),
arguably a backportable bugfix.
The custom help() is replaced by the common verb help, which derives the
synopsis, abstract, and option list from the verb declaration in
udevadm.c and the "udevadm-test" option namespace.
The custom help() is replaced by the common verb help, which derives the
synopsis, abstract, and option list from the verb declaration in
udevadm.c and the "udevadm-settle" option namespace.
The custom help() is replaced by the common verb help, which derives the
synopsis, abstract, and option list from the verb declaration in
udevadm.c and the "udevadm-monitor" option namespace.
The custom help() is replaced by the common verb help, which derives the
synopsis, abstract, and option list from the verb declaration in
udevadm.c and the "udevadm-control" option namespace. The synopsis
makes use of the new nulstr-argspec functionality:
> udevadm [OPTION…] lock [OPTION…] COMMAND
> udevadm [OPTION…] lock [OPTION…] --print
The arg_no_pager variable is lifted to udevadm, so that it can be
referenced in the command structure. It's only used for 'udevadm info',
but that's OK. We can later generalize it if wanted.
The custom help() is replaced by the common verb help, which derives the
synopsis, abstract, and option list from the verb declaration in udevadm.c
and the "udevadm-info" option namespace. --help now goes through the
pager, like other commands with --no-pager.
The custom help() is replaced by the common verb help, which derives the
synopsis, abstract, and option list from the verb declaration in udevadm.c
and the "udevadm-control" option namespace. The new VERB_DEPRECATED flag
is used.
The custom help() is replaced by the common verb help, which derives the
synopsis, abstract, and option list from the verb declaration in
udevadm.c and the "udevadm-control" option namespace. The synopsis
is now "udevadm [OPTION…] control OPTION…".
The custom help() is replaced by the common verb help, which derives the
synopsis, abstract, and option list from the verb declaration in
udevadm.c and the "udevadm-cat" option namespace.
The verbs declare their subcommand option namespaces, so the
introspection data describes the options of every subcommand, nested in
the verb objects.
The bare version number output (a dracut compatibility requirement) is
preserved for --version/-V and the "version" verb.
The "lock" verb's argument specification is simplified to "COMMAND" --
other verbs do not mention their options in the argspec either, and the
subcommand help states where the options may go.
Previously, verbs were skipped in --help automatically when their
.help field was nil. But this doesn't work in two ways:
- in introspection data we want to show the option, but marked as
deprecated
- in udevadm (and maybe other programs with verbs with own options in
the future), we need to show help for the verb.
So add an explicit flag to mark verbs as deprecated and skip them in
help even if .help is set. If there's a footer, print it highlighted
in red automatically.
A helper to print the help of a single verb, derived entirely from the
data in the SYSTEMD_VERBS and SYSTEMD_OPTIONS sections: the synopsis is
built from the verb name and argspec, the one-line verb help serves as
the abstract, the options come from the verb's option namespace, and the
man page links from the command the verb belongs to. A flag allows
suppressing the man page links for callers which append custom sections.
Like the command-level CommandDescription.argspec, a verb's argspec is now
a nulstr, so that a verb may declare multiple alternative usage lines. The
verbs help table renders one synopsis line per nulstr entry in the
synopsis cell.
All verb argument specifications must gain an explicit NUL suffix. This
is a lot of churn, but I think this needs to be done. For now, there'll
be only one user of the new functionality (i.e. a verb with more than
one argspec), but I think we'll eventually want to use this in other
places too.
Verbs like udevadm's subcommands parse their own options from a dedicated
option namespace. Allow the namespace to be declared in the verb
definition (via the new VERB_SCOPE_NS* macros), and report the options of
that namespace in the verb's CLI introspection object.
This is conformant with the CLI-Introspection Specification: verbs are
represented as nested command objects, which may carry their own "options"
array just like the top-level command object.
`r` at that point holds the return value of `pidref_safe_fork_full()`,
which is 0 in the child, so a failing `setenv()` was reported as
"Success".
Also, fix a stray "°".
Previously we just wrote /etc/hostname and returned. The kernel hostname
was left at whatever PID 1 sethostname()'d very early in boot (before
/etc/hostname existed), which meant hostnamectl reported the transient
hostname instead of the static one until the next reboot.
Call io.systemd.Hostname.SetStaticHostname on the running system so
hostnamed writes /etc/hostname and updates the kernel hostname in one
step. If hostnamed is unreachable (masked or absent on minimal images)
fall back to writing /etc/hostname directly. --root=/--image= also keeps
writing the file directly, since hostnamed only manages the running
system.
As mentioned in a05fe6684a, glibc provides two
wrappers for epoll_pwait2() on 32-bit architectures, and sys/epoll.h,
together with features-time64.h, selects the appropriate one.
To avoid depending on symbols introduced in newer glibc releases, that
commit relied on the glibc internal macro __USE_TIME_BITS64 to determine
which wrapper to use. However, that is incorrect on some architectures.
See:
https://sourceware.org/git/?p=glibc.git;a=commit;h=a4ed0471d71739928a0d0fa3258b3ff3b158e9b9
The above glibc commit introduces a new internal macro,
__USE_TIME64_REDIRECTS, which correctly describes whether the time64
wrapper should be used. However, we cannot rely on it because it was
introduced in glibc 2.40, while our baseline remains glibc 2.34.
Moreover, even after raising the baseline, relying on glibc internal
implementation details is undesirable.
Instead, call the epoll_pwait2 syscall directly. This avoids any
dependency on glibc wrapper selection logic while preserving the original
goal of avoiding newer glibc symbols.
As a side effect, this also enables epoll_pwait2() on musl, which does not
currently provide a libc wrapper for it.
Currently, epoll_pwait2() is only used by sd-event, so this is also the
simplest solution.
Otherwise, test-dlopen-note.py fails when libarchive support is disabled
but libacl support is enabled.
Also, log the dlopen_libarchive() failure at LOG_ERR level, matching how
the other failures are already logged.
Fixes#43530.
The final enablement pieces needed for coco tests in systemd CI. Runners
will be incus containers, these two commits enable running coco tests
with mkosi boot (where image is a directory), then start a confidential
guest with vmspawn as part of the test.
The calculator key (Fn + numpad =) emits a press event but never a
release, leaving KEY_CALC permanently held down. Desktop environments
then repeatedly spawn the calculator.
Before:
MSC_SCAN a1 / KEY_CALC value 1
(no release for the remaining 24s of the capture)
After:
MSC_SCAN a1 / KEY_CALC value 1
MSC_SCAN a1 / KEY_CALC value 0 (14us later)
Scancode 0xd7 (Fn+F4) is an atkbd echo of the mic mute key that
ideapad-laptop already reports as KEY_MICMUTE with a proper
press/release pair. Mapping it to unknown silences the repeated
"Unknown key pressed" kernel messages without affecting the working
key.
Tested on Fedora 44, kernel 7.1.10, BIOS P5CN31WW.
The NitroSense button on the Acer Nitro V 15 (ANV15-52) emits atkbd
scancode 0xf5, the same as its sibling ANV15-51 (#38415). Map it to
prog1 so it is usable out of the box.
Verified on hardware:
dmi:bvnINSYDECorp.:bvrV1.31:bd06/27/2025:br1.31:efr1.7:svnAcer:pnNitroANV15-52:pvrV1.31:rvnRPL:rnSportage_RTH
evdev capture on "AT Translated Set 2 keyboard":
EV_MSC MSC_SCAN f5
EV_KEY KEY_PRESENTATION 425 (via the generic Acer f5 rule)
Add a TEST_MKOSI_ARGS environment variable whose contents are appended
to the mkosi invocation launching the test image, without affecting the
image build. This lets the environment adapt how tests are run, e.g.
pass --format=directory --output-dir=... to boot the test container
from a directory format output in environments that cannot dissect disk
images, such as unprivileged containers, where loop devices and udev
are not available.
Signed-off-by: Paul Meyer <katexochen0@gmail.com>
In a mount namespace owned by a non-initial user namespace, the kernel
only allows mounting a fresh proc or sysfs if the namespace already
contains a fully visible mount of the same filesystem type
(mount_too_revealing()). systemd-nspawn's pivoted root contains no such
mount, so booting the test container inside an unprivileged container
(e.g. a containerized CI runner) fails with EPERM when mounting /proc.
When running in a non-initial user namespace, satisfy the check by
binding a read-only instance of each into the container under /work.
Skipping the binds on regular privileged runs keeps the container
isolated from the host's proc and sysfs. Binding non-recursively keeps
foreign submounts (e.g. lxcfs overmounts) out, which would spoil full
visibility where they end up locked, and which read-only would not
cover.
Signed-off-by: Paul Meyer <katexochen0@gmail.com>