1
0
mirror of https://github.com/systemd/systemd synced 2026-03-29 19:24:50 +02:00

Compare commits

..

35 Commits

Author SHA1 Message Date
Lennart Poettering
3a5d9ee980 discover-image: use _SD_PATH_INVALID where appropriate
The enum definition only exists for cases like this, use it, instead of
its literal value.

This doesn't effectively change anything, but cleans up the code a bit.
2025-11-24 17:42:04 +00:00
Lennart Poettering
b26e6207cb dissect-image: make verity params for mountfsd_mount_image() optional 2025-11-24 17:41:06 +00:00
Chris Down
e45f2aede9
Revert "nspawn: Fix broken host links for container journals" (#39879)
Reverts systemd/systemd#39727
2025-11-25 01:13:43 +08:00
Daan De Meyer
8c22cb264d
core: Make libmount optional (#39878) 2025-11-24 17:19:26 +01:00
Antonio Alvarez Feijoo
7599d26436 run: fix two minor memory leaks
```
==19541== 8 bytes in 1 blocks are still reachable in loss record 1 of 3
==19541==    at 0x4841744: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==19541==    by 0x50125C9: strdup (strdup.c:42)
==19541==    by 0x4C55925: getusername_malloc (user-util.c:154)
==19541==    by 0x1121D6: parse_argv_sudo_mode (run.c:1098)
==19541==    by 0x123B13: run (run.c:3032)
==19541==    by 0x124198: main (run.c:3100)
==19541==
==19541== 11 bytes in 1 blocks are still reachable in loss record 2 of 3
==19541==    at 0x4841744: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==19541==    by 0x50125C9: strdup (strdup.c:42)
==19541==    by 0x112A9C: parse_argv_sudo_mode (run.c:1182)
==19541==    by 0x123B13: run (run.c:3032)
==19541==    by 0x124198: main (run.c:3100)
```
2025-11-24 16:03:34 +00:00
Lennart Poettering
77a1e2dec6
Revert "nspawn: Fix broken host links for container journals" 2025-11-24 16:34:00 +01:00
Daan De Meyer
5df44d0f6a core: Make libmount optional
Instead of skipping libcore entirely when libmount is not available,
let's only compile out the pieces that need libmount. This makes the
meson logic much less complex and allows systemd-analyze to be built
when libmount is not available.
2025-11-24 16:23:10 +01:00
Daan De Meyer
9c2cd09420 test: Skip protect_kernel_logs test if libmount is missing
libmount is required for setup_namespace() so skip the test if it
is not available.
2025-11-24 16:10:31 +01:00
Lennart Poettering
39c343daa6 nspawn: fix CI 2025-11-24 15:53:47 +01:00
Yu Watanabe
da22ccf48f openssl-util: introduce openssl_extract_public_key() helper function
This splits out common logic in keyutil and systemd-measure.

Note, previously d2i_PUBKEY_fp() was used, but now it is replaced with
d2i_PUBKEY(), as musl seems to not support reading from memstream.
2025-11-24 22:49:55 +09:00
Daan De Meyer
4f6ef13f43 run0: Stay in cwd if --empower is specified without a user
If we run "run0 --empower", the expectation is to stay in the
current working directory, not switch to ~.
2025-11-24 14:39:34 +01:00
Lennart Poettering
c746488537
block dlopen() once we transition into some foreign namespace (#39824)
Let's make sure we never accidentally end up loading code from a foreign
namespace.
2025-11-24 14:14:16 +01:00
Daan De Meyer
d60206c49a
meson: Still build libshared even if libmount is disabled (#39871)
Currently, if the libmount feature is disabled, we don't build libshared
and as a result skip building every other executable as well. Among
other things, this makes our nodeps CI builds kind of pointless since
hardly any code will be compiled.

Let's improve on the situation by making libmount properly optional in
libshared. Then, we only skip building the executables that actually
need libmount.
2025-11-24 14:05:29 +01:00
Yu Watanabe
0cc96fc213 test: use log_tests_skipped_errno() at one more place
Follow-up for 12d2abe0827ad62652d0cb1791c89f3d2adbb280.
2025-11-24 21:16:39 +09:00
Daan De Meyer
7336f2c748 meson: Still build libshared even if libmount is disabled
Currently, if the libmount feature is disabled, we don't build
libshared and as a result skip building every other executable as
well. Among other things, this makes our nodeps CI builds kind of
pointless since hardly any code will be compiled.

Let's improve on the situation by making libmount properly optional
in libshared. Then, we only skip building the executables that
actually need libmount.
2025-11-24 13:09:41 +01:00
Daan De Meyer
e910f9bc63 test-reread-partition-table: Don't keep open fds around
Avoids EBUSY from BLKRRPART when built without libblkid support.
2025-11-24 13:09:41 +01:00
Daan De Meyer
dee7dfea1d test-reread-partition-table: Only check for CAP_SYS_ADMIN
We might have CAP_SYS_ADMIN even without being root.
2025-11-24 13:09:41 +01:00
Daan De Meyer
43687c22ab tests: Assume we're running in a chroot if check fails
running_in_chroot() will fail when a test is executed as a non-root
user without CAP_DAC_READ_SEARCH as it won't be able to access
/proc/1/root.

Let's make things more robust by skipping tests if we can't detect
if we're in a chroot or not, since if we can't even detect if we're
in a chroot or not, chances are we're missing the required privileges
to execute the test anyway.
2025-11-24 13:09:41 +01:00
Yu Watanabe
f866ff3df8 tree-wide: replace tab with space, adjust missing or duplicated space 2025-11-24 12:45:06 +01:00
Yu Watanabe
332bce5bd7 oomd: move check if processes can be killed into oomd_cgroup_kill()
This also adds a debuuging log if the check failed.
Addresses https://github.com/systemd/systemd/pull/39773#discussion_r2549439336.

Follow-up for 38e9d40c8097363b1e8fa025ef06865dadb0a3ac.
2025-11-24 12:40:13 +01:00
Luca Boccassi
5da6a8ee6e
man,doc: add uapi spec numbers to all links to uapi specs (#39867) 2025-11-24 11:15:09 +00:00
Lennart Poettering
ed3fcaae11 crash-handler: also disable dlopen(), just in case 2025-11-24 11:56:47 +01:00
Lennart Poettering
a08f2ea02d process-util: also disable dlopen() in safe_fork() 2025-11-24 11:56:47 +01:00
Lennart Poettering
9252e26f4c core: load libcryptsetup before forking off child that might need it 2025-11-24 11:56:47 +01:00
Lennart Poettering
c64a486058 sysext: load libraries before forking off worker child 2025-11-24 11:56:47 +01:00
Lennart Poettering
09596e7d1a repart: load libraries before forking off child 2025-11-24 11:56:47 +01:00
Lennart Poettering
52594c3184 udev: load a bunch of libs before we fork off worker processes 2025-11-24 11:56:47 +01:00
Lennart Poettering
5b2f52814b dissect-image: load library before we fork off metadata extractor child process 2025-11-24 11:56:47 +01:00
Lennart Poettering
e683dce1f1 portabled: load a bunch of libs before we fork off a dissector child processes 2025-11-24 11:56:47 +01:00
Lennart Poettering
6069de1ed3 pid1: pull in libmount unconditionally 2025-11-24 11:56:47 +01:00
Lennart Poettering
efaf5a763d execute: load a bunch of libs before we disable dlopen() 2025-11-24 11:56:35 +01:00
Lennart Poettering
800d11c36c nspawn: load three libraries we'll need later before we fork() a child 2025-11-24 11:49:44 +01:00
Lennart Poettering
2c7bdaf9f1 dlfcn-util: let's make our dlopen() code fail if we enter a container namespace
Now that we dlopen() so many deps, it might happen by accident that we
end up dlopen()ening stuff when we entered a container, which we should
really avoid, to not mix host and container libraries.

Let's add a global variable we can set when we want to block dlopen() to
ever succeed. This is then checked primarily in
dlopen_many_sym_or_warn(), where we'll generate EPERM plus a log
message.

There are a couple of other places we invoke dlopen(), without going
through dlopen_many_sym_or_warn(). This adds the same check there.
2025-11-24 09:19:33 +01:00
Lennart Poettering
fc3adbbbcb man: always prefix links to uapi specs with their UAPI.XY spec number
Let's try to establish the spec numbers, by mentioning them in most doc
links.

Follow-up for: https://github.com/uapi-group/specifications/pull/187
2025-11-23 18:09:11 +01:00
Lennart Poettering
81b52a013c docs: reference UAPI specs by their number when linked 2025-11-23 17:16:09 +01:00
108 changed files with 673 additions and 539 deletions

View File

@ -9,7 +9,7 @@ SPDX-License-Identifier: LGPL-2.1-or-later
systemd provides support for automatically reverting back to the previous systemd provides support for automatically reverting back to the previous
version of the OS or kernel in case the system consistently fails to boot. The version of the OS or kernel in case the system consistently fails to boot. The
[Boot Loader Specification](https://uapi-group.org/specifications/specs/boot_loader_specification/#boot-counting) [UAPI.1 Boot Loader Specification](https://uapi-group.org/specifications/specs/boot_loader_specification/#boot-counting)
describes how to annotate boot loader entries with a counter that specifies how describes how to annotate boot loader entries with a counter that specifies how
many attempts should be made to boot it. This document describes how systemd many attempts should be made to boot it. This document describes how systemd
implements this scheme. implements this scheme.
@ -28,7 +28,7 @@ Here's a brief overview of the complete set of components:
* The * The
[`systemd-boot(7)`](https://www.freedesktop.org/software/systemd/man/systemd-boot.html) [`systemd-boot(7)`](https://www.freedesktop.org/software/systemd/man/systemd-boot.html)
boot loader optionally maintains a per-boot-loader-entry counter described by boot loader optionally maintains a per-boot-loader-entry counter described by
the [Boot Loader Specification](https://uapi-group.org/specifications/specs/boot_loader_specification/#boot-counting) the [UAPI.1 Boot Loader Specification](https://uapi-group.org/specifications/specs/boot_loader_specification/#boot-counting)
that is decreased by one on each attempt to boot the entry, prioritizing that is decreased by one on each attempt to boot the entry, prioritizing
entries that have non-zero counters over those which already reached a entries that have non-zero counters over those which already reached a
counter of zero when choosing the entry to boot. counter of zero when choosing the entry to boot.
@ -61,7 +61,7 @@ Here's a brief overview of the complete set of components:
## Details ## Details
As described in the As described in the
[Boot Loader Specification](https://uapi-group.org/specifications/specs/boot_loader_specification/#boot-counting), [UAPI.1 Boot Loader Specification](https://uapi-group.org/specifications/specs/boot_loader_specification/#boot-counting),
the boot counting data is stored in the file name of the boot loader entries as the boot counting data is stored in the file name of the boot loader entries as
a plus (`+`), followed by a number, optionally followed by `-` and another a plus (`+`), followed by a number, optionally followed by `-` and another
number, right before the file name suffix (`.conf` or `.efi`). number, right before the file name suffix (`.conf` or `.efi`).

View File

@ -136,7 +136,7 @@ the identifiers as passed in `LoaderEntries`, `LoaderEntryDefault`,
names for them in UIs. names for them in UIs.
1. When boot loader entries are defined through the 1. When boot loader entries are defined through the
[Boot Loader Specification](https://uapi-group.org/specifications/specs/boot_loader_specification/) [BOOT.1 Boot Loader Specification](https://uapi-group.org/specifications/specs/boot_loader_specification/)
files, the identifier should be derived directly from the file name, files, the identifier should be derived directly from the file name,
but with the `.conf` (Type #1 snippets) or `.efi` (Type #2 images) but with the `.conf` (Type #1 snippets) or `.efi` (Type #2 images)
suffix removed. suffix removed.
@ -167,8 +167,8 @@ names for them in UIs.
## Links ## Links
[Boot Loader Specification](https://uapi-group.org/specifications/specs/boot_loader_specification)<br> [UAPI.1 Boot Loader Specification](https://uapi-group.org/specifications/specs/boot_loader_specification)<br>
[Discoverable Partitions Specification](https://uapi-group.org/specifications/specs/discoverable_partitions_specification)<br> [UAPI.2 Discoverable Partitions Specification](https://uapi-group.org/specifications/specs/discoverable_partitions_specification)<br>
[`systemd-boot(7)`](https://www.freedesktop.org/software/systemd/man/systemd-boot.html)<br> [`systemd-boot(7)`](https://www.freedesktop.org/software/systemd/man/systemd-boot.html)<br>
[`bootctl(1)`](https://www.freedesktop.org/software/systemd/man/bootctl.html)<br> [`bootctl(1)`](https://www.freedesktop.org/software/systemd/man/bootctl.html)<br>
[`systemd-gpt-auto-generator(8)`](https://www.freedesktop.org/software/systemd/man/systemd-gpt-auto-generator.html) [`systemd-gpt-auto-generator(8)`](https://www.freedesktop.org/software/systemd/man/systemd-gpt-auto-generator.html)

View File

@ -66,7 +66,7 @@ boot. For that it's essential to:
The The
[`kernel-install(8)`](https://www.freedesktop.org/software/systemd/man/kernel-install.html) [`kernel-install(8)`](https://www.freedesktop.org/software/systemd/man/kernel-install.html)
logic used to generate logic used to generate
[Boot Loader Specification Type #1](https://uapi-group.org/specifications/specs/boot_loader_specification/#type-1-boot-loader-specification-entries) [UAPI.1 Boot Loader Specification Type #1](https://uapi-group.org/specifications/specs/boot_loader_specification/#type-1-boot-loader-specification-entries)
entries by default uses the machine ID as stored in `/etc/machine-id` for entries by default uses the machine ID as stored in `/etc/machine-id` for
naming boot menu entries and the directories in the ESP to place kernel images in. naming boot menu entries and the directories in the ESP to place kernel images in.
This is done in order to allow multiple installations of the same OS on the This is done in order to allow multiple installations of the same OS on the
@ -207,7 +207,7 @@ it, then format it.
in. The `x-systemd.growfs` mount option in `/etc/fstab` is sufficient to in. The `x-systemd.growfs` mount option in `/etc/fstab` is sufficient to
enable this logic for specific mounts. Alternatively appropriately set up enable this logic for specific mounts. Alternatively appropriately set up
partitions can set GPT partition flag 59 to request this behaviour, see the partitions can set GPT partition flag 59 to request this behaviour, see the
[Discoverable Partitions Specification](https://uapi-group.org/specifications/specs/discoverable_partitions_specification) [UAPI.2 Discoverable Partitions Specification](https://uapi-group.org/specifications/specs/discoverable_partitions_specification)
for details. If the file system is already grown it executes no operation. for details. If the file system is already grown it executes no operation.
3. Similar, the `systemd-makefs@.service` and `systemd-makeswap@.service` 3. Similar, the `systemd-makefs@.service` and `systemd-makeswap@.service`
@ -268,8 +268,8 @@ fields.
[`machine-id(5)`](https://www.freedesktop.org/software/systemd/man/machine-id.html)<br> [`machine-id(5)`](https://www.freedesktop.org/software/systemd/man/machine-id.html)<br>
[`systemd-random-seed(8)`](https://www.freedesktop.org/software/systemd/man/systemd-random-seed.service.html)<br> [`systemd-random-seed(8)`](https://www.freedesktop.org/software/systemd/man/systemd-random-seed.service.html)<br>
[`os-release(5)`](https://www.freedesktop.org/software/systemd/man/os-release.html)<br> [`os-release(5)`](https://www.freedesktop.org/software/systemd/man/os-release.html)<br>
[Boot Loader Specification](https://uapi-group.org/specifications/specs/boot_loader_specification)<br> [UAPI.1 Boot Loader Specification](https://uapi-group.org/specifications/specs/boot_loader_specification)<br>
[Discoverable Partitions Specification](https://uapi-group.org/specifications/specs/discoverable_partitions_specification)<br> [UAPI.2 Discoverable Partitions Specification](https://uapi-group.org/specifications/specs/discoverable_partitions_specification)<br>
[`mkosi`](https://github.com/systemd/mkosi)<br> [`mkosi`](https://github.com/systemd/mkosi)<br>
[`systemd-boot(7)`](https://www.freedesktop.org/software/systemd/man/systemd-boot.html)<br> [`systemd-boot(7)`](https://www.freedesktop.org/software/systemd/man/systemd-boot.html)<br>
[`systemd-repart(8)`](https://www.freedesktop.org/software/systemd/man/systemd-repart.service.html)<br> [`systemd-repart(8)`](https://www.freedesktop.org/software/systemd/man/systemd-repart.service.html)<br>

View File

@ -234,7 +234,7 @@ All tools:
file may be checked for by services run during system shutdown in order to file may be checked for by services run during system shutdown in order to
request the appropriate operation from the boot loader in an alternative request the appropriate operation from the boot loader in an alternative
fashion. Note that by default only boot loader entries which follow the fashion. Note that by default only boot loader entries which follow the
[Boot Loader Specification](https://uapi-group.org/specifications/specs/boot_loader_specification) [UAPI.1 Boot Loader Specification](https://uapi-group.org/specifications/specs/boot_loader_specification)
and are placed in the ESP or the Extended Boot Loader partition may be and are placed in the ESP or the Extended Boot Loader partition may be
selected this way. However, if a directory `/run/boot-loader-entries/` selected this way. However, if a directory `/run/boot-loader-entries/`
exists, the entries are loaded from there instead. The directory should exists, the entries are loaded from there instead. The directory should
@ -518,7 +518,7 @@ disk images with `--image=` or similar:
to load the embedded Verity signature data. If enabled (which is the to load the embedded Verity signature data. If enabled (which is the
default), Verity root hash information and a suitable signature is default), Verity root hash information and a suitable signature is
automatically acquired from a signature partition, following the automatically acquired from a signature partition, following the
[Discoverable Partitions Specification](https://uapi-group.org/specifications/specs/discoverable_partitions_specification). [UAPI.2 Discoverable Partitions Specification](https://uapi-group.org/specifications/specs/discoverable_partitions_specification).
If disabled any such partition is ignored. Note that this only disables If disabled any such partition is ignored. Note that this only disables
discovery of the root hash and its signature, the Verity data partition discovery of the root hash and its signature, the Verity data partition
itself is still searched in the GPT image. itself is still searched in the GPT image.
@ -540,7 +540,7 @@ disk images with `--image=` or similar:
* `$SYSTEMD_DISSECT_FSTYPE_<DESIGNATOR>=` overrides the file system time to * `$SYSTEMD_DISSECT_FSTYPE_<DESIGNATOR>=` overrides the file system time to
use when mounting the partition of the indicated designator. The use when mounting the partition of the indicated designator. The
`<DESIGNATOR>` string shall be one of `ROOT`, `USR`, `HOME`, `SRV`, `ESP`, `<DESIGNATOR>` string shall be one of `ROOT`, `USR`, `HOME`, `SRV`, `ESP`,
`XBOOTLDR`, `TMP`, `VAR` as per the [Discoverable Partitions `XBOOTLDR`, `TMP`, `VAR` as per the [UAPI.2 Discoverable Partitions
Specification](https://uapi-group.org/specifications/specs/discoverable_partitions_specification/). If Specification](https://uapi-group.org/specifications/specs/discoverable_partitions_specification/). If
unspecified the image dissection logic will automatically probe the file unspecified the image dissection logic will automatically probe the file
system type (subject to `$SYSTEMD_DISSECT_FILE_SYSTEMS`, see above), except system type (subject to `$SYSTEMD_DISSECT_FILE_SYSTEMS`, see above), except
@ -560,8 +560,8 @@ disk images with `--image=` or similar:
* `$SYSTEMD_DISSECT_VERITY_GUESS` takes a boolean. Controls whether to guess * `$SYSTEMD_DISSECT_VERITY_GUESS` takes a boolean. Controls whether to guess
the Verity root hash from the partition UUIDs of a suitable pair of data the Verity root hash from the partition UUIDs of a suitable pair of data
partition and matching Verity partition: the UUIDs two are simply joined and partition and matching Verity partition: the UUIDs two are simply joined and
used as root hash, in accordance with the recommendations in [Discoverable used as root hash, in accordance with the recommendations in [UAPI.2
Partitions Discoverable Partitions
Specification](https://uapi-group.org/specifications/specs/discoverable_partitions_specification). Defaults Specification](https://uapi-group.org/specifications/specs/discoverable_partitions_specification). Defaults
to true. to true.

View File

@ -11,7 +11,7 @@ This document describes the requirements placed by systemd
on the time when various parts of the file system hierarchy on the time when various parts of the file system hierarchy
must be available and mounted during boot. must be available and mounted during boot.
This document should be read in conjunction with This document should be read in conjunction with
[Linux File System Hierarchy](https://uapi-group.org/specifications/specs/linux_file_system_hierarchy/), [UAPI.9 Linux File System Hierarchy](https://uapi-group.org/specifications/specs/linux_file_system_hierarchy/),
which describes the role of the mount points discussed here. which describes the role of the mount points discussed here.
If the file system backing a mount point is located on external or remote media If the file system backing a mount point is located on external or remote media

View File

@ -162,7 +162,7 @@ Specifically, the following requirements are made for an image that can be attac
an image with a partition table understood by the Linux kernel with only a an image with a partition table understood by the Linux kernel with only a
single partition defined, or alternatively, a GPT partition table with a set single partition defined, or alternatively, a GPT partition table with a set
of properly marked partitions following the of properly marked partitions following the
[Discoverable Partitions Specification](https://uapi-group.org/specifications/specs/discoverable_partitions_specification). [UAPI.2 Discoverable Partitions Specification](https://uapi-group.org/specifications/specs/discoverable_partitions_specification).
3. The image must at least contain one matching unit file, with the right name 3. The image must at least contain one matching unit file, with the right name
prefix and suffix (see above). prefix and suffix (see above).

View File

@ -27,7 +27,7 @@ architecture.
partitions. Use `systemd-id128 new -p` to generate new suitable UUIDs you partitions. Use `systemd-id128 new -p` to generate new suitable UUIDs you
can use for this. Make sure to register your new types in the various can use for this. Make sure to register your new types in the various
functions in `gpt.c`. Also make sure to update the tables in functions in `gpt.c`. Also make sure to update the tables in
[Discoverable Partitions Specification](https://uapi-group.org/specifications/specs/discoverable_partitions_specification) [UAPI.2 Discoverable Partitions Specification](https://uapi-group.org/specifications/specs/discoverable_partitions_specification)
and `man/systemd-gpt-auto-generator.xml` accordingly. and `man/systemd-gpt-auto-generator.xml` accordingly.
3. If your architecture supports UEFI, make sure to update the `efi_arch` 3. If your architecture supports UEFI, make sure to update the `efi_arch`

View File

@ -13,7 +13,7 @@ SPDX-License-Identifier: LGPL-2.1-or-later
4. Update hwdb (`ninja -C build update-hwdb`, `ninja -C build update-hwdb-autosuspend`, commit separately). 4. Update hwdb (`ninja -C build update-hwdb`, `ninja -C build update-hwdb-autosuspend`, commit separately).
5. Update syscall numbers (`ninja -C build update-syscall-tables update-syscall-header`). 5. Update syscall numbers (`ninja -C build update-syscall-tables update-syscall-header`).
6. [RC1] Update library numbers in `meson.build` 6. [RC1] Update library numbers in `meson.build`
7. Update version number in `meson.version` (e.g. from `256~devel` to `256~rc1` or from `256~rc3` to `256`). Note that this uses a tilde (\~) instead of a hyphen (-) because tildes sort lower in version comparisons according to the [version format specification](https://uapi-group.org/specifications/specs/version_format_specification/), and we want `255~rc1` to sort lower than `255`. 7. Update version number in `meson.version` (e.g. from `256~devel` to `256~rc1` or from `256~rc3` to `256`). Note that this uses a tilde (\~) instead of a hyphen (-) because tildes sort lower in version comparisons according to the [UAPI.10 Version Format Specification](https://uapi-group.org/specifications/specs/version_format_specification/), and we want `255~rc1` to sort lower than `255`.
8. Check dbus docs with `ninja -C build update-dbus-docs` 8. Check dbus docs with `ninja -C build update-dbus-docs`
9. Check manpages list with `ninja -C build update-man-rules` 9. Check manpages list with `ninja -C build update-man-rules`
10. Update translation strings (`ninja -C build systemd-pot`, `ninja -C build systemd-update-po`) - drop the header comments from `systemd.pot` + re-add SPDX before committing. If the only change in a file is the 'POT-Creation-Date' field, then ignore that file. 10. Update translation strings (`ninja -C build systemd-pot`, `ninja -C build systemd-update-po`) - drop the header comments from `systemd.pot` + re-add SPDX before committing. If the only change in a file is the 'POT-Creation-Date' field, then ignore that file.

View File

@ -15,13 +15,13 @@ components:
i.e. [`systemd-boot`](https://www.freedesktop.org/software/systemd/man/latest/systemd-boot.html) i.e. [`systemd-boot`](https://www.freedesktop.org/software/systemd/man/latest/systemd-boot.html)
that provides interactive and programmatic control of what precisely to that provides interactive and programmatic control of what precisely to
boot. It takes care of enumerating all possible boot targets (implementing boot. It takes care of enumerating all possible boot targets (implementing
the [Boot Loader the [UAPI.1 Boot Loader
Specification](https://uapi-group.org/specifications/specs/boot_loader_specification/)), Specification](https://uapi-group.org/specifications/specs/boot_loader_specification/)),
potentially presenting it to the user in a menu, but otherwise picking an potentially presenting it to the user in a menu, but otherwise picking an
item automatically, implementing boot counting and automatic rollback if item automatically, implementing boot counting and automatic rollback if
desired. desired.
2. A [unified kernel image 2. A [UAPI.5 Unified Kernel Image
("UKI")](https://uapi-group.org/specifications/specs/unified_kernel_image/), ("UKI")](https://uapi-group.org/specifications/specs/unified_kernel_image/),
i.e. an UEFI PE executable that combines i.e. an UEFI PE executable that combines
[`systemd-stub`](https://www.freedesktop.org/software/systemd/man/latest/systemd-stub.html), [`systemd-stub`](https://www.freedesktop.org/software/systemd/man/latest/systemd-stub.html),
@ -133,7 +133,7 @@ the same disk. Specifically:
ESP as well, in particular below the `/loader/` subdirectory. ESP as well, in particular below the `/loader/` subdirectory.
2. The UKIs may either be placed in the ESP (below the `/EFI/Linux/` 2. The UKIs may either be placed in the ESP (below the `/EFI/Linux/`
subdirectory), or in the [Extended Boot Loader subdirectory), or in the [UAPI.1 Extended Boot Loader
Partition](https://uapi-group.org/specifications/specs/boot_loader_specification/#the-partitions) Partition](https://uapi-group.org/specifications/specs/boot_loader_specification/#the-partitions)
("XBOOTLDR"), which can be placed on the same disk as the ESP and is also ("XBOOTLDR"), which can be placed on the same disk as the ESP and is also
VFAT. XBOOTLDR is an optional concept and it's only *raison d'être* is that VFAT. XBOOTLDR is an optional concept and it's only *raison d'être* is that
@ -146,7 +146,7 @@ the same disk. Specifically:
3. The `rootfs` is placed on the same disk as the ESP/XBOOTLDR, in a partition 3. The `rootfs` is placed on the same disk as the ESP/XBOOTLDR, in a partition
marked with a special GPT partition type. Various other well-known types of marked with a special GPT partition type. Various other well-known types of
partitions can be placed next to the `rootfs` and are automatically partitions can be placed next to the `rootfs` and are automatically
discovered and mounted, see the [Discoverable Partitions discovered and mounted, see the [UAPI.2 Discoverable Partitions
Specification](https://uapi-group.org/specifications/specs/discoverable_partitions_specification/) Specification](https://uapi-group.org/specifications/specs/discoverable_partitions_specification/)
for details. for details.
@ -179,8 +179,8 @@ each of these resources:
[`bootctl`](https://www.freedesktop.org/software/systemd/man/latest/bootctl.html), [`bootctl`](https://www.freedesktop.org/software/systemd/man/latest/bootctl.html),
`efibootmgr` or `kernel-bootcfg`. `efibootmgr` or `kernel-bootcfg`.
2. The `systemd-boot` boot loader may be configured via [`Boot Loader 2. The `systemd-boot` boot loader may be configured via [UAPI.1 Boot Loader
Specification Type #1`](https://uapi-group.org/specifications/specs/boot_loader_specification/) Specification Type #1](https://uapi-group.org/specifications/specs/boot_loader_specification/)
entries to acquire UKIs or similar from other locations. entries to acquire UKIs or similar from other locations.
3. The `initrd` part of the UKI understands the `root=` (and `mount.usr=`) 3. The `initrd` part of the UKI understands the `root=` (and `mount.usr=`)
@ -220,7 +220,7 @@ local disk. This can happen at each of these three components:
`rootfs` from HTTP `rootfs` from HTTP
sources](https://www.freedesktop.org/software/systemd/man/latest/systemd-import-generator.html), sources](https://www.freedesktop.org/software/systemd/man/latest/systemd-import-generator.html),
either in a GPT disk image (specifically: either in a GPT disk image (specifically:
[DDIs](https://uapi-group.org/specifications/specs/discoverable_disk_image/), [UAPI.3 DDIs](https://uapi-group.org/specifications/specs/discoverable_disk_image/),
with `.raw` suffix) or in a `.tar` file, which are placed in system RAM and with `.raw` suffix) or in a `.tar` file, which are placed in system RAM and
then booted into (these downloads can be downloaded in compressed form and then booted into (these downloads can be downloaded in compressed form and
are automatically decompressed on-the-fly). This of course requires are automatically decompressed on-the-fly). This of course requires

View File

@ -17,7 +17,7 @@ to systemd's UEFI-mode measurements, and if the latter are not done the former
aren't made either. aren't made either.
See See
[Linux TPM PCR Registry](https://uapi-group.org/specifications/specs/linux_tpm_pcr_registry/) [UAPI.7 Linux TPM PCR Registry](https://uapi-group.org/specifications/specs/linux_tpm_pcr_registry/)
for an overview of PCRs. for an overview of PCRs.
systemd will measure to PCRs 5 (`boot-loader-config`), 11 (`kernel-boot`), systemd will measure to PCRs 5 (`boot-loader-config`), 11 (`kernel-boot`),
@ -108,8 +108,8 @@ trailing NUL bytes).
### PCR 11, `EV_IPL`, PE section name ### PCR 11, `EV_IPL`, PE section name
A measurement is made for each PE section of the UKI that is defined by the A measurement is made for each PE section of the UKI that is defined by the
[UKI [UAPI.5 UKI
specification](https://uapi-group.org/specifications/specs/unified_kernel_image/), Specification](https://uapi-group.org/specifications/specs/unified_kernel_image/),
in the canonical order described in the specification. in the canonical order described in the specification.
Happens once for each UKI-defined PE section of the UKI, in the canonical UKI Happens once for each UKI-defined PE section of the UKI, in the canonical UKI

View File

@ -81,7 +81,7 @@
<para>These commands are available for all boot loaders that <para>These commands are available for all boot loaders that
implement the <ulink implement the <ulink
url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot
Loader Specification</ulink>, such as Loader Specification</ulink>, such as
<command>systemd-boot</command>.</para> <command>systemd-boot</command>.</para>
@ -90,7 +90,7 @@
<term><option>list</option></term> <term><option>list</option></term>
<listitem><para>Shows all available boot loader entries implementing the <ulink <listitem><para>Shows all available boot loader entries implementing the <ulink
url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader Specification</ulink>, as well as any url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader Specification</ulink>, as well as any
other entries discovered or automatically generated by a boot loader implementing the <ulink other entries discovered or automatically generated by a boot loader implementing the <ulink
url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader Interface</ulink>. url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader Interface</ulink>.
JSON output may be requested with <option>--json=</option>.</para> JSON output may be requested with <option>--json=</option>.</para>
@ -126,7 +126,7 @@
<title>Boot Loader Interface Commands</title> <title>Boot Loader Interface Commands</title>
<para>These commands are available for all boot loaders that implement the <ulink <para>These commands are available for all boot loaders that implement the <ulink
url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader Specification</ulink> and the <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader Specification</ulink> and the <ulink
url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader Interface</ulink>, such as url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader Interface</ulink>, such as
<command>systemd-boot</command>.</para> <command>systemd-boot</command>.</para>
@ -152,7 +152,7 @@
boot loader entry. These special IDs are resolved to the current values of the EFI variables boot loader entry. These special IDs are resolved to the current values of the EFI variables
<varname>LoaderEntryDefault</varname>, <varname>LoaderEntrySysFail</varname>, <varname>LoaderEntryOneShot</varname> <varname>LoaderEntryDefault</varname>, <varname>LoaderEntrySysFail</varname>, <varname>LoaderEntryOneShot</varname>
and <varname>LoaderEntrySelected</varname>, see <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification"> and <varname>LoaderEntrySelected</varname>, see <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">
Boot Loader Specification</ulink> for details. UAPI.1 Boot Loader Specification</ulink> for details.
These special IDs are primarily useful as a quick way to persistently make the currently booted boot loader These special IDs are primarily useful as a quick way to persistently make the currently booted boot loader
entry the default choice, or to upgrade the default boot loader entry for the next boot to the default boot entry the default choice, or to upgrade the default boot loader entry for the next boot to the default boot
loader entry for all future boots, but may be used for other operations too.</para> loader entry for all future boots, but may be used for other operations too.</para>
@ -314,7 +314,7 @@
are applied to file system in the indicated disk image. This option is similar to are applied to file system in the indicated disk image. This option is similar to
<option>--root=</option>, but operates on file systems stored in disk images or block devices. The <option>--root=</option>, but operates on file systems stored in disk images or block devices. The
disk image should either contain just a file system or a set of file systems within a GPT partition disk image should either contain just a file system or a set of file systems within a GPT partition
table, following the <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable Partitions table, following the <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2 Discoverable Partitions
Specification</ulink>. For further information on supported disk images, see Specification</ulink>. For further information on supported disk images, see
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s <citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
switch of the same name.</para> switch of the same name.</para>
@ -444,7 +444,7 @@
<varlistentry> <varlistentry>
<term><option>--make-entry-directory=yes|no</option></term> <term><option>--make-entry-directory=yes|no</option></term>
<listitem><para>Controls creation and deletion of the <ulink <listitem><para>Controls creation and deletion of the <ulink
url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader Specification</ulink> Type #1 entry url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader Specification</ulink> Type #1 entry
directory on the file system containing resources such as kernel and initrd images during directory on the file system containing resources such as kernel and initrd images during
<option>install</option> and <option>remove</option>, respectively. The directory is named after the <option>install</option> and <option>remove</option>, respectively. The directory is named after the
entry token, as specified with <option>--entry-token=</option> parameter described below, and is entry token, as specified with <option>--entry-token=</option> parameter described below, and is
@ -705,7 +705,7 @@ Boot Loader Entries:
<title>See Also</title> <title>See Also</title>
<para><simplelist type="inline"> <para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
<member><ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader Specification</ulink></member> <member><ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader Specification</ulink></member>
<member><ulink url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader Interface</ulink></member> <member><ulink url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader Interface</ulink></member>
<member><citerefentry><refentrytitle>systemd-boot-random-seed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd-boot-random-seed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
</simplelist></para> </simplelist></para>

View File

@ -306,8 +306,9 @@
are applied to file system in the indicated disk image. This option is similar to are applied to file system in the indicated disk image. This option is similar to
<option>--root=</option>, but operates on file systems stored in disk images or block devices. The <option>--root=</option>, but operates on file systems stored in disk images or block devices. The
disk image should either contain just a file system or a set of file systems within a GPT partition disk image should either contain just a file system or a set of file systems within a GPT partition
table, following the <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable Partitions table, following the <ulink
Specification</ulink>. For further information on supported disk images, see url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2
Discoverable Partitions Specification</ulink>. For further information on supported disk images, see
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s <citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
switch of the same name.</para> switch of the same name.</para>

View File

@ -25,12 +25,11 @@
<para>Operating systems using the <para>Operating systems using the
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry> system and <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry> system and
service manager are organized based on a file system hierarchy inspired by UNIX, service manager are organized based on a file system hierarchy inspired by UNIX, as described in <ulink
as described in <ulink url="https://uapi-group.org/specifications/specs/linux_file_system_hierarchy/"> url="https://uapi-group.org/specifications/specs/linux_file_system_hierarchy/"> UAPI.9 Linux File System
Linux File System Hierarchy</ulink>. Hierarchy</ulink>. Additional requirements on <emphasis>when</emphasis> given parts of the hierarchy
Additional requirements on <emphasis>when</emphasis> given parts of the hierarchy must be available during boot are listed in <ulink url="https://systemd.io/MOUNT_REQUIREMENTS/">Mount
must be available during boot are listed in Requirements</ulink>.</para>
<ulink url="https://systemd.io/MOUNT_REQUIREMENTS/">Mount Requirements</ulink>.</para>
<para>Many of the paths described here can be queried <para>Many of the paths described here can be queried
with the with the

View File

@ -193,7 +193,7 @@
option is similar to <option>--root=</option>, but operates on file systems stored in disk images or option is similar to <option>--root=</option>, but operates on file systems stored in disk images or
block devices, thus providing an easy way to extract log data from disk images. The disk image should block devices, thus providing an easy way to extract log data from disk images. The disk image should
either contain just a file system or a set of file systems within a GPT partition table, following either contain just a file system or a set of file systems within a GPT partition table, following
the <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable Partitions the <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2 Discoverable Partitions
Specification</ulink>. For further information on supported disk images, see Specification</ulink>. For further information on supported disk images, see
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s <citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
switch of the same name.</para> switch of the same name.</para>

View File

@ -109,7 +109,7 @@
<para>The third argument directly refers to the path where to place kernel images, initrd <para>The third argument directly refers to the path where to place kernel images, initrd
images and other resources for images and other resources for
<ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot
Loader Specification</ulink> Type #1 entries (the "entry directory"). If other boot loader schemes Loader Specification</ulink> Type #1 entries (the "entry directory"). If other boot loader schemes
are used the parameter may be ignored.</para> are used the parameter may be ignored.</para>
@ -141,7 +141,7 @@
<filename>$BOOT/<replaceable>ENTRY-TOKEN</replaceable>/<replaceable>KERNEL_VERSION</replaceable>/<replaceable>INITRD-FILE</replaceable></filename>. <filename>$BOOT/<replaceable>ENTRY-TOKEN</replaceable>/<replaceable>KERNEL_VERSION</replaceable>/<replaceable>INITRD-FILE</replaceable></filename>.
This can also be used to prepend microcode before the actual initrd. It also creates a boot This can also be used to prepend microcode before the actual initrd. It also creates a boot
loader entry according to the loader entry according to the
<ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader Specification</ulink> <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader Specification</ulink>
(Type #1) in (Type #1) in
<filename>$BOOT/loader/entries/<replaceable>ENTRY-TOKEN</replaceable>-<replaceable>KERNEL-VERSION</replaceable>.conf</filename>. <filename>$BOOT/loader/entries/<replaceable>ENTRY-TOKEN</replaceable>-<replaceable>KERNEL-VERSION</replaceable>.conf</filename>.
The title of the entry is the <replaceable>PRETTY_NAME</replaceable> parameter specified in The title of the entry is the <replaceable>PRETTY_NAME</replaceable> parameter specified in
@ -290,7 +290,7 @@
<refsect1> <refsect1>
<title>The <varname>$BOOT</varname> partition</title> <title>The <varname>$BOOT</varname> partition</title>
<para>The partition where the kernels and <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot <para>The partition where the kernels and <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot
Loader Specification</ulink> snippets are located is called <varname>$BOOT</varname>. Loader Specification</ulink> snippets are located is called <varname>$BOOT</varname>.
<command>kernel-install</command> determines the location of this partition by checking <command>kernel-install</command> determines the location of this partition by checking
<filename>/efi/</filename>, <filename>/boot/</filename>, and <filename>/boot/efi/</filename> in turn. The <filename>/efi/</filename>, <filename>/boot/</filename>, and <filename>/boot/efi/</filename> in turn. The
@ -310,7 +310,7 @@
<term><option>--make-entry-directory=yes|no|auto</option></term> <term><option>--make-entry-directory=yes|no|auto</option></term>
<listitem> <listitem>
<para>Controls creation and deletion of the <para>Controls creation and deletion of the
<ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader Specification</ulink> <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader Specification</ulink>
Type #1 entry directory on the file system containing resources such as kernel and initrd images Type #1 entry directory on the file system containing resources such as kernel and initrd images
during <option>add</option> and <option>remove</option>, respectively. The directory is named after during <option>add</option> and <option>remove</option>, respectively. The directory is named after
the entry token, and is placed immediately below the boot root directory. When the entry token, and is placed immediately below the boot root directory. When
@ -410,7 +410,7 @@
are applied to the file system in the indicated disk image. This option is similar to are applied to the file system in the indicated disk image. This option is similar to
<option>--root=</option>, but operates on file systems stored in disk images or block devices. The <option>--root=</option>, but operates on file systems stored in disk images or block devices. The
disk image should either contain just a file system or a set of file systems within a GPT partition disk image should either contain just a file system or a set of file systems within a GPT partition
table, following the <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable Partitions table, following the <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2 Discoverable Partitions
Specification</ulink>. For further information on supported disk images, see Specification</ulink>. For further information on supported disk images, see
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s <citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
switch of the same name.</para> switch of the same name.</para>
@ -504,7 +504,7 @@
<varlistentry> <varlistentry>
<term>bls</term> <term>bls</term>
<listitem> <listitem>
<para>Standard <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader <para>Standard <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader
Specification</ulink> Type #1 layout, compatible with Specification</ulink> Type #1 layout, compatible with
<citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>: <citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>:
entries in entries in
@ -520,7 +520,7 @@
<term>uki</term> <term>uki</term>
<listitem> <listitem>
<para>Standard <ulink <para>Standard <ulink
url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader
Specification</ulink> Type #2 layout, compatible with Specification</ulink> Type #2 layout, compatible with
<citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>: <citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>:
unified kernel images under <filename>$BOOT/EFI/Linux</filename> as unified kernel images under <filename>$BOOT/EFI/Linux</filename> as
@ -787,7 +787,7 @@
<member><citerefentry project='man-pages'><refentrytitle>depmod</refentrytitle><manvolnum>8</manvolnum></citerefentry></member> <member><citerefentry project='man-pages'><refentrytitle>depmod</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>ukify</refentrytitle><manvolnum>1</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>ukify</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader Specification</ulink></member> <member><ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader Specification</ulink></member>
</simplelist></para> </simplelist></para>
</refsect1> </refsect1>

View File

@ -51,7 +51,7 @@
and type #2 (<filename><replaceable>ESP</replaceable>/EFI/Linux/*.uki</filename> and type #2 (<filename><replaceable>ESP</replaceable>/EFI/Linux/*.uki</filename>
and <filename><replaceable>XBOOTLDR</replaceable>/EFI/Linux/*.uki</filename>). and <filename><replaceable>XBOOTLDR</replaceable>/EFI/Linux/*.uki</filename>).
Those files are described by the Those files are described by the
<ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader
Specification</ulink>.</para> Specification</ulink>.</para>
<para>Note: the behaviour of <command>systemd-boot</command> is also influenced by EFI variables. Some of <para>Note: the behaviour of <command>systemd-boot</command> is also influenced by EFI variables. Some of

View File

@ -238,7 +238,7 @@
<constant>x86</constant> (32-bit, aka i386) and <constant>x86-64</constant> (64-bit, aka amd64).</para> <constant>x86</constant> (32-bit, aka i386) and <constant>x86-64</constant> (64-bit, aka amd64).</para>
<para>Most of the partition type UUIDs listed above are defined in the <ulink <para>Most of the partition type UUIDs listed above are defined in the <ulink
url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable Partitions url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2 Discoverable Partitions
Specification</ulink>.</para> Specification</ulink>.</para>
<xi:include href="version-info.xml" xpointer="v245"/></listitem> <xi:include href="version-info.xml" xpointer="v245"/></listitem>
@ -780,7 +780,7 @@
<listitem><para>Configures the No-Auto, Read-Only and Grow-File-System partition flags (bit 63, 60 <listitem><para>Configures the No-Auto, Read-Only and Grow-File-System partition flags (bit 63, 60
and 59) of the partition table entry, as defined by the <ulink and 59) of the partition table entry, as defined by the <ulink
url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable Partitions Specification</ulink>. Only url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2 Discoverable Partitions Specification</ulink>. Only
available for partition types supported by the specification. This option is a friendly way to set available for partition types supported by the specification. This option is a friendly way to set
bits 63, 60 and 59 of the partition flags value without setting any of the other bits, and may be set bits 63, 60 and 59 of the partition flags value without setting any of the other bits, and may be set
via <varname>Flags=</varname> too, see above.</para> via <varname>Flags=</varname> too, see above.</para>
@ -1007,7 +1007,7 @@
associated with it.</para> associated with it.</para>
<para>For example, distributions can use this to implement <varname>$BOOT</varname> as defined in the <para>For example, distributions can use this to implement <varname>$BOOT</varname> as defined in the
<ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification/">Boot Loader <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification/">UAPI.1 Boot Loader
Specification</ulink>. Distributions may prefer to use the ESP as <varname>$BOOT</varname> whenever Specification</ulink>. Distributions may prefer to use the ESP as <varname>$BOOT</varname> whenever
possible, but to adhere to the spec XBOOTLDR must sometimes be used instead. So, they should create possible, but to adhere to the spec XBOOTLDR must sometimes be used instead. So, they should create
two definitions: the first defining an ESP big enough to hold just the bootloader, and a second for two definitions: the first defining an ESP big enough to hold just the bootloader, and a second for

View File

@ -137,7 +137,7 @@
<listitem> <listitem>
<para>Path to the Extended Boot Loader partition, as defined in the <para>Path to the Extended Boot Loader partition, as defined in the
<ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader Specification</ulink>. <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader Specification</ulink>.
If not specified, <filename>/boot/</filename> is checked. It is recommended to mount the Extended Boot If not specified, <filename>/boot/</filename> is checked. It is recommended to mount the Extended Boot
Loader partition to <filename>/boot/</filename>, if possible.</para> Loader partition to <filename>/boot/</filename>, if possible.</para>
</listitem> </listitem>

View File

@ -1755,7 +1755,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
</para> </para>
<para>To load a kernel, an enumeration is performed following the <para>To load a kernel, an enumeration is performed following the
<ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader Specification</ulink>, <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader Specification</ulink>,
and the default boot entry is loaded. For this step to succeed, the system must be using UEFI and the default boot entry is loaded. For this step to succeed, the system must be using UEFI
and the boot loader entries must be configured appropriately. <command>bootctl list</command> and the boot loader entries must be configured appropriately. <command>bootctl list</command>
may be used to list boot entries, see may be used to list boot entries, see
@ -2646,7 +2646,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
are applied to file system in the indicated disk image. This option is similar to are applied to file system in the indicated disk image. This option is similar to
<option>--root=</option>, but operates on file systems stored in disk images or block devices. The <option>--root=</option>, but operates on file systems stored in disk images or block devices. The
disk image should either contain just a file system or a set of file systems within a GPT partition disk image should either contain just a file system or a set of file systems within a GPT partition
table, following the <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable Partitions table, following the <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2 Discoverable Partitions
Specification</ulink>. For further information on supported disk images, see Specification</ulink>. For further information on supported disk images, see
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s <citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
switch of the same name.</para> switch of the same name.</para>

View File

@ -966,7 +966,7 @@ stored sock 0:8 4213190 - socket:[4213190] ro
<para>This command analyzes the specified image policy string, as per <para>This command analyzes the specified image policy string, as per
<citerefentry><refentrytitle>systemd.image-policy</refentrytitle><manvolnum>7</manvolnum></citerefentry>. The <citerefentry><refentrytitle>systemd.image-policy</refentrytitle><manvolnum>7</manvolnum></citerefentry>. The
policy is normalized and simplified. For each currently defined partition identifier (as per the <ulink policy is normalized and simplified. For each currently defined partition identifier (as per the <ulink
url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2 Discoverable
Partitions Specification</ulink>) the effect of the image policy string is shown in tabular form.</para> Partitions Specification</ulink>) the effect of the image policy string is shown in tabular form.</para>
<example> <example>

View File

@ -36,15 +36,15 @@
detects that <citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry> style detects that <citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry> style
boot counting is used.</para> boot counting is used.</para>
<para>Internally, the service operates based on the <varname>LoaderBootCountPath</varname> EFI variable (of the <para>Internally, the service operates based on the <varname>LoaderBootCountPath</varname> EFI variable
vendor UUID <constant>4a67b082-0a4c-41cf-b6c7-440b29bb8c4f</constant>), which is passed from the boot loader to the (of the vendor UUID <constant>4a67b082-0a4c-41cf-b6c7-440b29bb8c4f</constant>), which is passed from the
OS. It contains a file system path (relative to the EFI system partition) of the <ulink boot loader to the OS. It contains a file system path (relative to the EFI system partition) of the
url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader Specification</ulink> compliant boot loader entry <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader
file or unified kernel image file that was used to boot up the Specification</ulink> compliant boot loader entry file or unified kernel image file that was used to boot
system. <command>systemd-bless-boot.service</command> removes the two "tries done" and "tries left" numeric boot up the system. <command>systemd-bless-boot.service</command> removes the two "tries done" and "tries
counters from the filename, which indicates to future invocations of the boot loader that the entry has completed left" numeric boot counters from the filename, which indicates to future invocations of the boot loader
booting successfully at least once. (This service will hence rename the boot loader entry file or unified kernel that the entry has completed booting successfully at least once. (This service will hence rename the boot
image file on the first successful boot.)</para> loader entry file or unified kernel image file on the first successful boot.)</para>
</refsect1> </refsect1>
<refsect1> <refsect1>

View File

@ -39,12 +39,12 @@
<itemizedlist> <itemizedlist>
<listitem><para>Boot entries defined with <ulink <listitem><para>Boot entries defined with <ulink
url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader Specification</ulink> Type #1 url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader Specification</ulink> Type #1
description files located in <filename>/loader/entries/</filename> on the ESP and the Extended Boot description files located in <filename>/loader/entries/</filename> on the ESP and the Extended Boot
Loader Partition. These usually describe Linux kernel images with associated initrd images, but Loader Partition. These usually describe Linux kernel images with associated initrd images, but
alternatively may also describe other arbitrary EFI executables.</para></listitem> alternatively may also describe other arbitrary EFI executables.</para></listitem>
<listitem><para>Unified kernel images, <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot <listitem><para>Unified kernel images, <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot
Loader Specification</ulink> Type #2, which are executable EFI binaries in Loader Specification</ulink> Type #2, which are executable EFI binaries in
<filename>/EFI/Linux/</filename> on the ESP and the Extended Boot Loader Partition.</para></listitem> <filename>/EFI/Linux/</filename> on the ESP and the Extended Boot Loader Partition.</para></listitem>
@ -373,11 +373,11 @@
<citerefentry><refentrytitle>loader.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para> <citerefentry><refentrytitle>loader.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
<para>Boot entry description files following the <ulink <para>Boot entry description files following the <ulink
url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader Specification</ulink> are read from url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader Specification</ulink> are read from
<filename>/loader/entries/</filename> on the ESP and the Extended Boot Loader partition.</para> <filename>/loader/entries/</filename> on the ESP and the Extended Boot Loader partition.</para>
<para>Unified kernel boot entries following the <ulink <para>Unified kernel boot entries following the <ulink
url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader Specification</ulink> are read from url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader Specification</ulink> are read from
<filename>/EFI/Linux/</filename> on the ESP and the Extended Boot Loader partition.</para> <filename>/EFI/Linux/</filename> on the ESP and the Extended Boot Loader partition.</para>
<para>Optionally, a random seed for early boot entropy pool provisioning is stored in <para>Optionally, a random seed for early boot entropy pool provisioning is stored in
@ -657,7 +657,7 @@ uki-url http://example.com/somedir/fooos.efi</programlisting>
<title>Boot Counting</title> <title>Boot Counting</title>
<para><command>systemd-boot</command> implements a simple boot counting mechanism on top of the <ulink <para><command>systemd-boot</command> implements a simple boot counting mechanism on top of the <ulink
url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader Specification</ulink>, for automatic and unattended url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader Specification</ulink>, for automatic and unattended
fallback to older kernel versions/boot loader entries when a specific entry continuously fails. Any boot loader fallback to older kernel versions/boot loader entries when a specific entry continuously fails. Any boot loader
entry file and unified kernel image file that contains a <literal>+</literal> followed by one or two numbers (if entry file and unified kernel image file that contains a <literal>+</literal> followed by one or two numbers (if
two they need to be separated by a <literal>-</literal>), before the <filename>.conf</filename> or two they need to be separated by a <literal>-</literal>), before the <filename>.conf</filename> or
@ -742,7 +742,7 @@ uki-url http://example.com/somedir/fooos.efi</programlisting>
<member><citerefentry><refentrytitle>systemd-boot-random-seed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd-boot-random-seed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>kernel-install</refentrytitle><manvolnum>8</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>kernel-install</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
<member><ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader Specification</ulink></member> <member><ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader Specification</ulink></member>
<member><ulink url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader Interface</ulink></member> <member><ulink url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader Interface</ulink></member>
<member><ulink url="https://systemd.io/TPM2_PCR_MEASUREMENTS">TPM2 PCR Measurements Made by systemd</ulink></member> <member><ulink url="https://systemd.io/TPM2_PCR_MEASUREMENTS">TPM2 PCR Measurements Made by systemd</ulink></member>
</simplelist></para> </simplelist></para>

View File

@ -84,8 +84,8 @@
<option>--tpm2-public-key-pcrs=</option>, <option>--tpm2-signature=</option> described below. <option>--tpm2-public-key-pcrs=</option>, <option>--tpm2-signature=</option> described below.
</para> </para>
<para>See <ulink url="https://uapi-group.org/specifications/specs/linux_tpm_pcr_registry/">Linux TPM <para>See <ulink url="https://uapi-group.org/specifications/specs/linux_tpm_pcr_registry/">UAPI.7 Linux
PCR Registry</ulink> for an authoritative list of PCRs and how they are updated. The table below TPM PCR Registry</ulink> for an authoritative list of PCRs and how they are updated. The table below
contains a quick reference, describing in particular the PCRs modified by systemd.</para> contains a quick reference, describing in particular the PCRs modified by systemd.</para>
<table> <table>
@ -218,7 +218,7 @@
through the certificates measured into PCR 7. Validation through certificates hashes is typically through the certificates measured into PCR 7. Validation through certificates hashes is typically
preferable over validation through direct measurements as it is less brittle in context of OS/firmware preferable over validation through direct measurements as it is less brittle in context of OS/firmware
updates: the measurements will change on every update, but signatures should remain unchanged. See the updates: the measurements will change on every update, but signatures should remain unchanged. See the
<ulink url="https://uapi-group.org/specifications/specs/linux_tpm_pcr_registry/">Linux TPM PCR <ulink url="https://uapi-group.org/specifications/specs/linux_tpm_pcr_registry/">UAPI.7 Linux TPM PCR
Registry</ulink> for more discussion.</para> Registry</ulink> for more discussion.</para>
</refsect2> </refsect2>
</refsect1> </refsect1>

View File

@ -93,7 +93,7 @@
<orderedlist> <orderedlist>
<listitem><para>OS disk images containing a GPT partition table envelope, with partitions marked <listitem><para>OS disk images containing a GPT partition table envelope, with partitions marked
according to the <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable Partitions according to the <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2 Discoverable Partitions
Specification</ulink>.</para></listitem> Specification</ulink>.</para></listitem>
<listitem><para>OS disk images containing just a plain file-system without an enveloping partition <listitem><para>OS disk images containing just a plain file-system without an enveloping partition
@ -144,7 +144,7 @@
<listitem><para>Mount the specified OS image to the specified directory. This will dissect the image, <listitem><para>Mount the specified OS image to the specified directory. This will dissect the image,
determine the OS root file system — as well as possibly other partitions — and mount them to the determine the OS root file system — as well as possibly other partitions — and mount them to the
specified directory. If the OS image contains multiple partitions marked with the <ulink specified directory. If the OS image contains multiple partitions marked with the <ulink
url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable Partitions Specification</ulink> url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2 Discoverable Partitions Specification</ulink>
multiple nested mounts are established. This command expects two arguments: a path to an image file multiple nested mounts are established. This command expects two arguments: a path to an image file
and a path to a directory where to mount the image.</para> and a path to a directory where to mount the image.</para>
@ -421,7 +421,7 @@
<option>--mount</option> or <option>--copy-to</option>) the file systems contained in the OS image <option>--mount</option> or <option>--copy-to</option>) the file systems contained in the OS image
are automatically grown to their partition sizes, if bit 59 in the GPT partition flags is set for are automatically grown to their partition sizes, if bit 59 in the GPT partition flags is set for
partition types that are defined by the <ulink partition types that are defined by the <ulink
url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable Partitions Specification</ulink>. This url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2 Discoverable Partitions Specification</ulink>. This
behavior may be switched off using <option>--growfs=no</option>. File systems are grown automatically behavior may be switched off using <option>--growfs=no</option>. File systems are grown automatically
on access if all of the following conditions are met:</para> on access if all of the following conditions are met:</para>
<orderedlist> <orderedlist>
@ -492,7 +492,7 @@
<option>--verity-data=</option> specifies a path to a file with the Verity data to use for the OS <option>--verity-data=</option> specifies a path to a file with the Verity data to use for the OS
image, in case it is stored in a detached file. It is recommended to embed the Verity data directly image, in case it is stored in a detached file. It is recommended to embed the Verity data directly
in the image, using the Verity mechanisms in the <ulink in the image, using the Verity mechanisms in the <ulink
url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable Partitions Specification</ulink>. url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2 Discoverable Partitions Specification</ulink>.
</para> </para>
<xi:include href="version-info.xml" xpointer="v247"/></listitem> <xi:include href="version-info.xml" xpointer="v247"/></listitem>
@ -651,7 +651,7 @@
<member><citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd.v</refentrytitle><manvolnum>7</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd.v</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
<member><ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable Partitions Specification</ulink></member> <member><ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2 Discoverable Partitions Specification</ulink></member>
<member><citerefentry project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry></member> <member><citerefentry project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry project='man-pages'><refentrytitle>umount</refentrytitle><manvolnum>8</manvolnum></citerefentry></member> <member><citerefentry project='man-pages'><refentrytitle>umount</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry project='man-pages'><refentrytitle>fdisk</refentrytitle><manvolnum>8</manvolnum></citerefentry></member> <member><citerefentry project='man-pages'><refentrytitle>fdisk</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>

View File

@ -117,7 +117,7 @@
are applied to file system in the indicated disk image. This is similar to <option>--root=</option> are applied to file system in the indicated disk image. This is similar to <option>--root=</option>
but operates on file systems stored in disk images or block devices. The disk image should either but operates on file systems stored in disk images or block devices. The disk image should either
contain just a file system or a set of file systems within a GPT partition table, following the contain just a file system or a set of file systems within a GPT partition table, following the
<ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable Partitions <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2 Discoverable Partitions
Specification</ulink>. For further information on supported disk images, see Specification</ulink>. For further information on supported disk images, see
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s <citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
switch of the same name.</para> switch of the same name.</para>

View File

@ -36,7 +36,7 @@
(XBOOTLDR), and swap partitions and creates mount and swap units for them, based on the partition type (XBOOTLDR), and swap partitions and creates mount and swap units for them, based on the partition type
GUIDs of GUID partition tables (GPT). See <ulink url="https://uefi.org/specifications">UEFI GUIDs of GUID partition tables (GPT). See <ulink url="https://uefi.org/specifications">UEFI
Specification</ulink>, chapter 5 for more details. It implements the <ulink Specification</ulink>, chapter 5 for more details. It implements the <ulink
url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2 Discoverable
Partitions Specification</ulink>.</para> Partitions Specification</ulink>.</para>
<para>Note that this generator has no effect on non-GPT systems. It will also not create mount point <para>Note that this generator has no effect on non-GPT systems. It will also not create mount point
@ -138,7 +138,7 @@
<entry></entry> <entry></entry>
<entry>Root partitions for other architectures</entry> <entry>Root partitions for other architectures</entry>
<entry><filename>/</filename></entry> <entry><filename>/</filename></entry>
<entry>The first partition with the type UUID matching the architecture, located on the same disk as the ESP used for booting, is used as the root file system <filename>/</filename>. For the full list and constant values, see <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable Partitions Specification</ulink>.</entry> <entry>The first partition with the type UUID matching the architecture, located on the same disk as the ESP used for booting, is used as the root file system <filename>/</filename>. For the full list and constant values, see <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2 Discoverable Partitions Specification</ulink>.</entry>
</row> </row>
<row> <row>
<entry><constant>SD_GPT_HOME</constant></entry> <entry><constant>SD_GPT_HOME</constant></entry>
@ -252,7 +252,7 @@
<para>Mount and automount units for the EFI System Partition (ESP) and Extended Boot Loader Partition <para>Mount and automount units for the EFI System Partition (ESP) and Extended Boot Loader Partition
(XBOOTLDR) are generated on EFI systems. If the disk contains an XBOOTLDR partition, as defined in the (XBOOTLDR) are generated on EFI systems. If the disk contains an XBOOTLDR partition, as defined in the
<ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader
Specification</ulink>, it is made available at <filename>/boot/</filename>. This generator creates an Specification</ulink>, it is made available at <filename>/boot/</filename>. This generator creates an
automount unit; the mount will only be activated on-demand when accessed. The mount point will be created automount unit; the mount will only be activated on-demand when accessed. The mount point will be created
if necessary.</para> if necessary.</para>
@ -354,7 +354,7 @@
automatic discovery of the root partition based on GPT partition information is enabled. This is a automatic discovery of the root partition based on GPT partition information is enabled. This is a
superset of <varname>root=gpt-auto</varname>, as it automatically configures Verity partitions superset of <varname>root=gpt-auto</varname>, as it automatically configures Verity partitions
(including signature-based setup) following the logic defined for that in the <ulink (including signature-based setup) following the logic defined for that in the <ulink
url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification/">Discoverable url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification/">UAPI.2 Discoverable
Partitions Specification</ulink>. Moreover it takes the configured image policy and image filter into Partitions Specification</ulink>. Moreover it takes the configured image policy and image filter into
account for all partition types, including the root file system. <literal>root=dissect</literal> will account for all partition types, including the root file system. <literal>root=dissect</literal> will
wait for the factory reset phase to be completed if it is in effect before activating the root file wait for the factory reset phase to be completed if it is in effect before activating the root file

View File

@ -96,7 +96,7 @@
version 255.</para> version 255.</para>
<para><command>var-partition-uuid</command> prints a UUID which, following the <ulink <para><command>var-partition-uuid</command> prints a UUID which, following the <ulink
url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2 Discoverable
Partitions Specification</ulink>, should be used as the GPT partition UUID for Partitions Specification</ulink>, should be used as the GPT partition UUID for
<filename>/var/</filename>, being derived from the GPT partition type, keyed by the local <filename>/var/</filename>, being derived from the GPT partition type, keyed by the local
<filename>/etc/machine-id</filename>. Added in version 257.</para> <filename>/etc/machine-id</filename>. Added in version 257.</para>

View File

@ -128,7 +128,7 @@
from downloaded disk images. This is only supported for <literal>raw</literal> disk images.</para> from downloaded disk images. This is only supported for <literal>raw</literal> disk images.</para>
<para>Note when this option is used with the purpose of mounting a disk image conforming to the <para>Note when this option is used with the purpose of mounting a disk image conforming to the
<ulink url="https://uapi-group.org/specifications/specs/discoverable_disk_image/">Discoverable <ulink url="https://uapi-group.org/specifications/specs/discoverable_disk_image/">UAPI.3 Discoverable
Disk Image Specification</ulink> as root file system, and the automatic GPT partition discovery Disk Image Specification</ulink> as root file system, and the automatic GPT partition discovery
logic as implemented by logic as implemented by
<citerefentry><refentrytitle>systemd-gpt-auto-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry> <citerefentry><refentrytitle>systemd-gpt-auto-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>

View File

@ -34,7 +34,7 @@
<para><command>systemd-measure</command> is a tool that may be used to pre-calculate and sign the <para><command>systemd-measure</command> is a tool that may be used to pre-calculate and sign the
expected TPM2 PCR 11 values that should be seen when a Linux <ulink expected TPM2 PCR 11 values that should be seen when a Linux <ulink
url="https://uapi-group.org/specifications/specs/unified_kernel_image/">Unified Kernel Image url="https://uapi-group.org/specifications/specs/unified_kernel_image/">UAPI.5 Unified Kernel Image
(UKI)</ulink> based on (UKI)</ulink> based on
<citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry> is <citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry> is
booted up. It accepts paths to the ELF kernel image file, initrd image file, devicetree file, kernel booted up. It accepts paths to the ELF kernel image file, initrd image file, devicetree file, kernel

View File

@ -33,7 +33,7 @@
file descriptors for the file systems contained therein to clients, via a Varlink IPC API.</para> file descriptors for the file systems contained therein to clients, via a Varlink IPC API.</para>
<para>The disk images provided must contain a raw file system image or must follow the <ulink <para>The disk images provided must contain a raw file system image or must follow the <ulink
url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification/">Discoverable url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification/">UAPI.2 Discoverable
Partitions Specification</ulink>. Before mounting any file systems authenticity of the disk image is Partitions Specification</ulink>. Before mounting any file systems authenticity of the disk image is
established in one or a combination of the following ways:</para> established in one or a combination of the following ways:</para>

View File

@ -327,14 +327,12 @@
partition of type partition of type
0fc63daf-8483-4772-8e79-3d69d8477de4.</para></listitem> 0fc63daf-8483-4772-8e79-3d69d8477de4.</para></listitem>
<listitem><para>A GUID partition table (GPT) with a marked <listitem><para>A GUID partition table (GPT) with a marked root partition which is mounted as the
root partition which is mounted as the root directory of the root directory of the container. Optionally, GPT images may contain a home and/or a server data
container. Optionally, GPT images may contain a home and/or partition which are mounted to the appropriate places in the container. All these partitions must
a server data partition which are mounted to the appropriate be identified by the partition types defined by the <ulink
places in the container. All these partitions must be url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2
identified by the partition types defined by the <ulink Discoverable Partitions Specification</ulink>.</para></listitem>
url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable
Partitions Specification</ulink>.</para></listitem>
<listitem><para>No partition table, and a single file system spanning the whole image.</para></listitem> <listitem><para>No partition table, and a single file system spanning the whole image.</para></listitem>
</itemizedlist> </itemizedlist>

View File

@ -170,7 +170,7 @@
or credentials) or bind encryption to booted kernels.</para> or credentials) or bind encryption to booted kernels.</para>
<para>For further details about the UKI concept, see the <ulink <para>For further details about the UKI concept, see the <ulink
url="https://uapi-group.org/specifications/specs/unified_kernel_image/">UKI specification</ulink>.</para> url="https://uapi-group.org/specifications/specs/unified_kernel_image/">UAPI.5 UKI specification</ulink>.</para>
</refsect1> </refsect1>
<refsect1> <refsect1>
@ -806,7 +806,7 @@
<member><citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-creds</refentrytitle><manvolnum>1</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd-creds</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-sysext</refentrytitle><manvolnum>8</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd-sysext</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader Specification</ulink></member> <member><ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader Specification</ulink></member>
<member><ulink url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader Interface</ulink></member> <member><ulink url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader Interface</ulink></member>
<member><citerefentry><refentrytitle>ukify</refentrytitle><manvolnum>1</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>ukify</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-measure</refentrytitle><manvolnum>1</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd-measure</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>

View File

@ -90,7 +90,7 @@
<orderedlist> <orderedlist>
<listitem><para>Plain directories or btrfs subvolumes containing the OS tree</para></listitem> <listitem><para>Plain directories or btrfs subvolumes containing the OS tree</para></listitem>
<listitem><para>Disk images with a GPT disk label, following the <ulink <listitem><para>Disk images with a GPT disk label, following the <ulink
url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable Partitions Specification</ulink></para></listitem> url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2 Discoverable Partitions Specification</ulink></para></listitem>
<listitem><para>Disk images lacking a partition table, with a naked Linux file system (e.g. erofs, <listitem><para>Disk images lacking a partition table, with a naked Linux file system (e.g. erofs,
squashfs or ext4)</para></listitem> squashfs or ext4)</para></listitem>
</orderedlist> </orderedlist>

View File

@ -76,8 +76,8 @@
are applied to file system in the indicated disk image. This is similar to <option>--root=</option> are applied to file system in the indicated disk image. This is similar to <option>--root=</option>
but operates on file systems stored in disk images or block devices. The disk image should either but operates on file systems stored in disk images or block devices. The disk image should either
contain just a file system or a set of file systems within a GPT partition table, following the contain just a file system or a set of file systems within a GPT partition table, following the
<ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable Partitions <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2
Specification</ulink>. For further information on supported disk images, see Discoverable Partitions Specification</ulink>. For further information on supported disk images, see
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s <citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
switch of the same name.</para> switch of the same name.</para>

View File

@ -264,7 +264,7 @@
are applied to file system in the indicated disk image. This is similar to <option>--root=</option> are applied to file system in the indicated disk image. This is similar to <option>--root=</option>
but operates on file systems stored in disk images or block devices. The disk image should either but operates on file systems stored in disk images or block devices. The disk image should either
contain just a file system or a set of file systems within a GPT partition table, following the contain just a file system or a set of file systems within a GPT partition table, following the
<ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable Partitions <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2 Discoverable Partitions
Specification</ulink>. For further information on supported disk images, see Specification</ulink>. For further information on supported disk images, see
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s <citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
switch of the same name.</para> switch of the same name.</para>

View File

@ -196,7 +196,7 @@
<para>Set the linux kernel image to use for direct kernel boot. <para>Set the linux kernel image to use for direct kernel boot.
If a directory type image is used and <option>--linux=</option> was omitted, vmspawn will search for boot loader entries If a directory type image is used and <option>--linux=</option> was omitted, vmspawn will search for boot loader entries
according to the according to the
<ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader Specification</ulink> assuming <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader Specification</ulink> assuming
XBOOTLDR to be located at /boot and ESP to be /efi respectively. XBOOTLDR to be located at /boot and ESP to be /efi respectively.
If no kernel was installed into the image then the image will fail to boot.</para> If no kernel was installed into the image then the image will fail to boot.</para>
@ -210,7 +210,7 @@
<listitem> <listitem>
<para>Set the initrd to use for direct kernel boot. <para>Set the initrd to use for direct kernel boot.
If the <option>--linux=</option> supplied is a If the <option>--linux=</option> supplied is a
<ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader Specification</ulink> <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader Specification</ulink>
Type #2 entry, then this argument is not required. Type #2 entry, then this argument is not required.
If no initrd was installed into the image then the image will fail to boot.</para> If no initrd was installed into the image then the image will fail to boot.</para>
@ -739,7 +739,7 @@ $ ssh root@vsock/$my_vsock_cid -i /run/user/$UID/systemd/vmspawn/machine-*-syste
<member><citerefentry project='debian'><refentrytitle>mkosi</refentrytitle><manvolnum>1</manvolnum></citerefentry></member> <member><citerefentry project='debian'><refentrytitle>mkosi</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>importctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>importctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader Specification</ulink></member> <member><ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader Specification</ulink></member>
</simplelist></para> </simplelist></para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -174,8 +174,8 @@
or loopback file instead of a directory. The device node or file system image file needs to contain a or loopback file instead of a directory. The device node or file system image file needs to contain a
file system without a partition table, or a file system within an MBR/MS-DOS or GPT partition table file system without a partition table, or a file system within an MBR/MS-DOS or GPT partition table
with only a single Linux-compatible partition, or a set of file systems within a GPT partition table with only a single Linux-compatible partition, or a set of file systems within a GPT partition table
that follows the that follows the <ulink
<ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification"> url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2
Discoverable Partitions Specification</ulink>.</para> Discoverable Partitions Specification</ulink>.</para>
<para>When <varname>DevicePolicy=</varname> is set to <literal>closed</literal> or <para>When <varname>DevicePolicy=</varname> is set to <literal>closed</literal> or

View File

@ -24,7 +24,7 @@
<title>Description</title> <title>Description</title>
<para>In systemd, whenever a disk image (DDI) implementing the <ulink <para>In systemd, whenever a disk image (DDI) implementing the <ulink
url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2 Discoverable
Partitions Specification</ulink> is activated, a filter may be specified controlling which partitions to Partitions Specification</ulink> is activated, a filter may be specified controlling which partitions to
consider for mounting. Such a disk image dissection filter is a string that contains per-partition-type consider for mounting. Such a disk image dissection filter is a string that contains per-partition-type
patterns, separated by colons (<literal>:</literal>). The individual rules consist of a partition patterns, separated by colons (<literal>:</literal>). The individual rules consist of a partition

View File

@ -24,13 +24,13 @@
<title>Description</title> <title>Description</title>
<para>In systemd, whenever a disk image (DDI) implementing the <ulink <para>In systemd, whenever a disk image (DDI) implementing the <ulink
url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2
Partitions Specification</ulink> is activated, a policy may be specified controlling which partitions to Discoverable Partitions Specification</ulink> is activated, a policy may be specified controlling which
mount and what kind of cryptographic protection to require. Such a disk image dissection policy is a partitions to mount and what kind of cryptographic protection to require. Such a disk image dissection
string that contains per-partition-type rules, separated by colons (<literal>:</literal>). The individual policy is a string that contains per-partition-type rules, separated by colons
rules consist of a partition identifier, an equal sign (<literal>=</literal>), and one or more flags (<literal>:</literal>). The individual rules consist of a partition identifier, an equal sign
which may be set per partition. If multiple flags are specified per partition they are separated by a (<literal>=</literal>), and one or more flags which may be set per partition. If multiple flags are
plus sign (<literal>+</literal>).</para> specified per partition they are separated by a plus sign (<literal>+</literal>).</para>
<para>The partition identifiers currently defined are: <option>root</option>, <option>usr</option>, <para>The partition identifiers currently defined are: <option>root</option>, <option>usr</option>,
<option>home</option>, <option>srv</option>, <option>esp</option>, <option>xbootldr</option>, <option>home</option>, <option>srv</option>, <option>esp</option>, <option>xbootldr</option>,

View File

@ -81,7 +81,7 @@
<para>The variable part of the filenames in the <literal>.v/</literal> directories are filtered and <para>The variable part of the filenames in the <literal>.v/</literal> directories are filtered and
compared primarily with a version comparison, implementing <ulink compared primarily with a version comparison, implementing <ulink
url="https://uapi-group.org/specifications/specs/version_format_specification/">Version Format url="https://uapi-group.org/specifications/specs/version_format_specification/">UAPI.10 Version Format
Specification</ulink>. However, additional rules apply:</para> Specification</ulink>. However, additional rules apply:</para>
<itemizedlist> <itemizedlist>

View File

@ -84,8 +84,8 @@
<listitem><para>A file <literal>https://download.example.com/foobarOS_47.root.xz</literal> should be <listitem><para>A file <literal>https://download.example.com/foobarOS_47.root.xz</literal> should be
downloaded, decompressed and written to a previously unused partition with GPT partition type UUID downloaded, decompressed and written to a previously unused partition with GPT partition type UUID
4f68bce3-e8cd-4db1-96e7-fbcaf984b709 for x86-64, as per <ulink 4f68bce3-e8cd-4db1-96e7-fbcaf984b709 for x86-64, as per <ulink
url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable Partitions url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2
Specification</ulink>.</para></listitem> Discoverable Partitions Specification</ulink>.</para></listitem>
<listitem><para>Similarly, a file <literal>https://download.example.com/foobarOS_47.verity.xz</literal> <listitem><para>Similarly, a file <literal>https://download.example.com/foobarOS_47.verity.xz</literal>
should be downloaded, decompressed and written to a previously empty partition with GPT partition type should be downloaded, decompressed and written to a previously empty partition with GPT partition type
@ -93,7 +93,7 @@
for x86-64 root file systems).</para></listitem> for x86-64 root file systems).</para></listitem>
<listitem><para>Finally, a file <literal>https://download.example.com/foobarOS_47.efi</literal> (a <listitem><para>Finally, a file <literal>https://download.example.com/foobarOS_47.efi</literal> (a
unified kernel, as per <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader unified kernel, as per <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader
Specification</ulink> Type #2) should be downloaded, decompressed and written to the $BOOT file system, Specification</ulink> Type #2) should be downloaded, decompressed and written to the $BOOT file system,
i.e. to <filename>EFI/Linux/foobarOS_47.efi</filename> in the ESP or XBOOTLDR partition.</para></listitem> i.e. to <filename>EFI/Linux/foobarOS_47.efi</filename> in the ESP or XBOOTLDR partition.</para></listitem>
</orderedlist> </orderedlist>
@ -368,21 +368,21 @@
<entry><literal>@a</literal></entry> <entry><literal>@a</literal></entry>
<entry>GPT partition flag NoAuto</entry> <entry>GPT partition flag NoAuto</entry>
<entry>Either <literal>0</literal> or <literal>1</literal></entry> <entry>Either <literal>0</literal> or <literal>1</literal></entry>
<entry>Controls NoAuto bit of the GPT partition flags, as per <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable Partitions Specification</ulink>; only relevant if target resource type chosen as <constant>partition</constant></entry> <entry>Controls NoAuto bit of the GPT partition flags, as per <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2 Discoverable Partitions Specification</ulink>; only relevant if target resource type chosen as <constant>partition</constant></entry>
</row> </row>
<row> <row>
<entry><literal>@g</literal></entry> <entry><literal>@g</literal></entry>
<entry>GPT partition flag GrowFileSystem</entry> <entry>GPT partition flag GrowFileSystem</entry>
<entry>Either <literal>0</literal> or <literal>1</literal></entry> <entry>Either <literal>0</literal> or <literal>1</literal></entry>
<entry>Controls GrowFileSystem bit of the GPT partition flags, as per <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable Partitions Specification</ulink>; only relevant if target resource type chosen as <constant>partition</constant></entry> <entry>Controls GrowFileSystem bit of the GPT partition flags, as per <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2 Discoverable Partitions Specification</ulink>; only relevant if target resource type chosen as <constant>partition</constant></entry>
</row> </row>
<row> <row>
<entry><literal>@r</literal></entry> <entry><literal>@r</literal></entry>
<entry>Read-only flag</entry> <entry>Read-only flag</entry>
<entry>Either <literal>0</literal> or <literal>1</literal></entry> <entry>Either <literal>0</literal> or <literal>1</literal></entry>
<entry>Controls ReadOnly bit of the GPT partition flags, as per <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable Partitions Specification</ulink> and other output read-only flags, see <varname>ReadOnly=</varname> below</entry> <entry>Controls ReadOnly bit of the GPT partition flags, as per <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2 Discoverable Partitions Specification</ulink> and other output read-only flags, see <varname>ReadOnly=</varname> below</entry>
</row> </row>
<row> <row>
@ -681,12 +681,12 @@
<para>If set to <constant>root</constant>, <constant>esp</constant>, <constant>xbootldr</constant>, <para>If set to <constant>root</constant>, <constant>esp</constant>, <constant>xbootldr</constant>,
the specified <varname>Path=</varname> will be resolved relative to the mount point of the the specified <varname>Path=</varname> will be resolved relative to the mount point of the
corresponding partition, as defined by the corresponding partition, as defined by the
<ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader
Specification</ulink>.</para> Specification</ulink>.</para>
<para>If set to <constant>boot</constant>, the specified <varname>Path=</varname> will be resolved <para>If set to <constant>boot</constant>, the specified <varname>Path=</varname> will be resolved
relative to the mount point of the $BOOT partition (i.e. the ESP or XBOOTLDR), as defined by the relative to the mount point of the $BOOT partition (i.e. the ESP or XBOOTLDR), as defined by the
<ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader
Specification</ulink>.</para> Specification</ulink>.</para>
<para>If set to <constant>explicit</constant>, the specified <varname>Path=</varname> will be <para>If set to <constant>explicit</constant>, the specified <varname>Path=</varname> will be
@ -753,7 +753,7 @@
overall <varname>PartitionFlags=</varname> flags setting and the individual flag settings overall <varname>PartitionFlags=</varname> flags setting and the individual flag settings
<varname>PartitionNoAuto=</varname> and <varname>PartitionGrowFileSystem=</varname> are used (or the <varname>PartitionNoAuto=</varname> and <varname>PartitionGrowFileSystem=</varname> are used (or the
wildcards for them), then the latter override the former, i.e. the individual flag bit overrides the wildcards for them), then the latter override the former, i.e. the individual flag bit overrides the
overall flags value. See <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable overall flags value. See <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2 Discoverable
Partitions Specification</ulink> for details about these flags.</para> Partitions Specification</ulink> for details about these flags.</para>
<para>Note that these settings are not used for matching, they only have effect on newly written <para>Note that these settings are not used for matching, they only have effect on newly written
@ -767,7 +767,7 @@
<listitem><para>Controls whether to mark the resulting file, subvolume or partition read-only. If the <listitem><para>Controls whether to mark the resulting file, subvolume or partition read-only. If the
target type is <constant>partition</constant> this controls the ReadOnly partition flag, as per target type is <constant>partition</constant> this controls the ReadOnly partition flag, as per
<ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">Discoverable Partitions <ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">UAPI.2 Discoverable Partitions
Specification</ulink>, similar to the <varname>PartitionNoAuto=</varname> and Specification</ulink>, similar to the <varname>PartitionNoAuto=</varname> and
<varname>PartitionGrowFileSystem=</varname> flags described above. If the target type is <varname>PartitionGrowFileSystem=</varname> flags described above. If the target type is
<constant>regular-file</constant>, the writable bit is removed from the access mode. If the <constant>regular-file</constant>, the writable bit is removed from the access mode. If the
@ -987,7 +987,7 @@ TriesDone=0
InstancesMax=2</programlisting></para> InstancesMax=2</programlisting></para>
<para>The above installs a unified kernel image into the $BOOT partition, as per <para>The above installs a unified kernel image into the $BOOT partition, as per
<ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">UAPI.1 Boot Loader
Specification</ulink> Type #2. This defines three possible patterns for the names of the kernel Specification</ulink> Type #2. This defines three possible patterns for the names of the kernel
images, as per <ulink url="https://systemd.io/AUTOMATIC_BOOT_ASSESSMENT">Automatic Boot Assessment</ulink>, images, as per <ulink url="https://systemd.io/AUTOMATIC_BOOT_ASSESSMENT">Automatic Boot Assessment</ulink>,
and ensures when installing new kernels, they are set up with 3 tries left. No more than two parallel and ensures when installing new kernels, they are set up with 3 tries left. No more than two parallel

View File

@ -47,7 +47,7 @@
<para><command>ukify</command> is a tool whose primary purpose is to combine components (usually a <para><command>ukify</command> is a tool whose primary purpose is to combine components (usually a
kernel, an initrd, and the kernel, an initrd, and the
<citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry> UEFI <citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry> UEFI
stub) to create a <ulink url="https://uapi-group.org/specifications/specs/unified_kernel_image/">Unified stub) to create a <ulink url="https://uapi-group.org/specifications/specs/unified_kernel_image/">UAPI.5 Unified
Kernel Image (UKI)</ulink> — a single PE binary that boots the system. When the UKI is executed, the stub Kernel Image (UKI)</ulink> — a single PE binary that boots the system. When the UKI is executed, the stub
extracts and boots the embedded linux kernel. The UKI can be started directly by the firmware or through extracts and boots the embedded linux kernel. The UKI can be started directly by the firmware or through
a boot loader. When used with <ulink url="https://www.qemu.org/docs/master/">qemu</ulink>, a UKI can also a boot loader. When used with <ulink url="https://www.qemu.org/docs/master/">qemu</ulink>, a UKI can also

View File

@ -1163,8 +1163,9 @@ endif
libmount = dependency('mount', libmount = dependency('mount',
version : fuzzer_build ? '>= 0' : '>= 2.30', version : fuzzer_build ? '>= 0' : '>= 2.30',
disabler : true,
required : get_option('libmount')) required : get_option('libmount'))
have = libmount.found()
conf.set10('HAVE_LIBMOUNT', have)
libmount_cflags = libmount.partial_dependency(includes: true, compile_args: true) libmount_cflags = libmount.partial_dependency(includes: true, compile_args: true)
libfdisk = dependency('fdisk', libfdisk = dependency('fdisk',

View File

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "dlfcn-util.h" #include "dlfcn-util.h"
#include "errno-util.h"
#include "log.h" #include "log.h"
void* safe_dlclose(void *dl) { void* safe_dlclose(void *dl) {
@ -47,18 +48,20 @@ int dlsym_many_or_warn_sentinel(void *dl, int log_level, ...) {
} }
int dlopen_many_sym_or_warn_sentinel(void **dlp, const char *filename, int log_level, ...) { int dlopen_many_sym_or_warn_sentinel(void **dlp, const char *filename, int log_level, ...) {
_cleanup_(dlclosep) void *dl = NULL;
int r; int r;
if (*dlp) if (*dlp)
return 0; /* Already loaded */ return 0; /* Already loaded */
dl = dlopen(filename, RTLD_NOW|RTLD_NODELETE); _cleanup_(dlclosep) void *dl = NULL;
if (!dl) const char *dle = NULL;
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), r = dlopen_safe(filename, &dl, &dle);
"%s is not installed: %s", filename, dlerror()); if (r < 0) {
log_debug_errno(r, "Shared library '%s' is not available: %s", filename, dle ?: STRERROR(r));
return -EOPNOTSUPP; /* Turn into recognizable error */
}
log_debug("Loaded '%s' via dlopen()", filename); log_debug("Loaded shared library '%s' via dlopen().", filename);
va_list ap; va_list ap;
va_start(ap, log_level); va_start(ap, log_level);
@ -73,3 +76,52 @@ int dlopen_many_sym_or_warn_sentinel(void **dlp, const char *filename, int log_l
*dlp = TAKE_PTR(dl); *dlp = TAKE_PTR(dl);
return 1; return 1;
} }
static bool dlopen_blocked = false;
void block_dlopen(void) {
dlopen_blocked = true;
}
int dlopen_safe(const char *filename, void **ret, const char **reterr_dlerror) {
int r;
assert(filename);
/* A wrapper around dlopen(), that takes dlopen_blocked into account, and tries to normalize the
* error reporting a bit. */
int flags = RTLD_NOW|RTLD_NODELETE; /* Always set RTLD_NOW + RTLD_NODELETE, for security reasons */
/* If dlopen() is blocked we'll still try it, but set RTLD_NOLOAD, so that it will still work if
* already loaded (for example because the binary linked to things regularly), but fail if not. */
if (dlopen_blocked)
flags |= RTLD_NOLOAD;
errno = 0;
void *p = dlopen(filename, flags);
if (!p) {
if (dlopen_blocked) {
(void) dlerror(); /* consume error, so that no later call will return it */
if (reterr_dlerror)
*reterr_dlerror = NULL;
return log_debug_errno(SYNTHETIC_ERRNO(EPERM), "Refusing loading of '%s', as loading further dlopen() modules has been blocked.", filename);
}
r = errno_or_else(ENOPKG);
if (reterr_dlerror)
*reterr_dlerror = dlerror();
else
(void) dlerror(); /* consume error, so that no later call will return it */
return r;
}
if (ret)
*ret = TAKE_PTR(p);
return 0;
}

View File

@ -72,3 +72,11 @@ int dlopen_many_sym_or_warn_sentinel(void **dlp, const char *filename, int log_l
* _SONAME_ARRAY<X+1> will need to be added). */ * _SONAME_ARRAY<X+1> will need to be added). */
#define ELF_NOTE_DLOPEN(feature, description, priority, ...) \ #define ELF_NOTE_DLOPEN(feature, description, priority, ...) \
_ELF_NOTE_DLOPEN("[{\"feature\":\"" feature "\",\"description\":\"" description "\",\"priority\":\"" priority "\",\"soname\":" _SONAME_ARRAY(__VA_ARGS__) "}]", UNIQ_T(s, UNIQ)) _ELF_NOTE_DLOPEN("[{\"feature\":\"" feature "\",\"description\":\"" description "\",\"priority\":\"" priority "\",\"soname\":" _SONAME_ARRAY(__VA_ARGS__) "}]", UNIQ_T(s, UNIQ))
/* If called dlopen_many_sym_or_warn() will fail with EPERM. This can be used to block lazy loading of shared
* libs, if we transfer a process into a different namespace. Note that this does not work for all calls of
* dlopen(), just those through our dlopen_safe() wrapper (which we use comprehensively in our
* codebase). This hence has *no* effect on NSS. (Would be great if we could change that...) */
void block_dlopen(void);
int dlopen_safe(const char *filename, void **ret, const char **reterr_dlerror);

View File

@ -22,6 +22,7 @@
#include "argv-util.h" #include "argv-util.h"
#include "cgroup-util.h" #include "cgroup-util.h"
#include "dirent-util.h" #include "dirent-util.h"
#include "dlfcn-util.h"
#include "env-file.h" #include "env-file.h"
#include "errno-util.h" #include "errno-util.h"
#include "escape.h" #include "escape.h"
@ -1695,6 +1696,15 @@ int pidref_safe_fork_full(
r, "Failed to rename process, ignoring: %m"); r, "Failed to rename process, ignoring: %m");
} }
/* let's disable dlopen() in the child, as a paranoia safety precaution: children should not live for
* long and only do minimal work before exiting or exec()ing. Doing dlopen() is not either. If people
* want dlopen() they should do it before forking. This is a safety precuation in particular for
* cases where the child does namespace shenanigans: we should never end up loading a module from a
* foreign environment. Note that this has no effect on NSS! (i.e. it only has effect on uses of our
* dlopen_safe(), which we use comprehensively in our codebase, but glibc NSS doesn't bother, of
* course.) */
block_dlopen();
if (flags & (FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGINT|FORK_DEATHSIG_SIGKILL)) if (flags & (FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGINT|FORK_DEATHSIG_SIGKILL))
if (prctl(PR_SET_PDEATHSIG, fork_flags_to_signal(flags)) < 0) { if (prctl(PR_SET_PDEATHSIG, fork_flags_to_signal(flags)) < 0) {
log_full_errno(prio, errno, "Failed to set death signal: %m"); log_full_errno(prio, errno, "Failed to set death signal: %m");

View File

@ -7,6 +7,7 @@
#include "constants.h" #include "constants.h"
#include "crash-handler.h" #include "crash-handler.h"
#include "dlfcn-util.h"
#include "exit-status.h" #include "exit-status.h"
#include "format-util.h" #include "format-util.h"
#include "log.h" #include "log.h"
@ -70,6 +71,9 @@ _noreturn_ static void crash(int sig, siginfo_t *siginfo, void *context) {
* memory allocation is not async-signal-safe anyway see signal-safety(7) for details , and thus * memory allocation is not async-signal-safe anyway see signal-safety(7) for details , and thus
* is not permissible in signal handlers.) */ * is not permissible in signal handlers.) */
block_dlopen(); /* paranoia: never end up doing dlopen() as side-effect from some call anymore from
* here */
if (getpid_cached() != 1) if (getpid_cached() != 1)
/* Pass this on immediately, if this is not PID 1 */ /* Pass this on immediately, if this is not PID 1 */
propagate_signal(sig, siginfo); propagate_signal(sig, siginfo);

View File

@ -32,6 +32,7 @@
#include "constants.h" #include "constants.h"
#include "copy.h" #include "copy.h"
#include "coredump-util.h" #include "coredump-util.h"
#include "cryptsetup-util.h"
#include "dissect-image.h" #include "dissect-image.h"
#include "dynamic-user.h" #include "dynamic-user.h"
#include "env-util.h" #include "env-util.h"
@ -48,6 +49,7 @@
#include "io-util.h" #include "io-util.h"
#include "iovec-util.h" #include "iovec-util.h"
#include "journal-send.h" #include "journal-send.h"
#include "libmount-util.h"
#include "manager.h" #include "manager.h"
#include "memfd-util.h" #include "memfd-util.h"
#include "mkdir-label.h" #include "mkdir-label.h"
@ -5818,6 +5820,16 @@ int exec_invoke(
} }
} }
/* Load a bunch of libraries we'll possibly need later, before we turn off dlopen() */
(void) dlopen_bpf();
(void) dlopen_cryptsetup();
(void) dlopen_libmount();
(void) dlopen_libseccomp();
/* Let's now disable further dlopen()ing of libraries, since we are about to do namespace
* shenanigans, and do not want to mix resources from host and namespace */
block_dlopen();
if (needs_sandboxing && !have_cap_sys_admin && exec_needs_cap_sys_admin(context, params)) { if (needs_sandboxing && !have_cap_sys_admin && exec_needs_cap_sys_admin(context, params)) {
/* If we're unprivileged, set up the user namespace first to enable use of the other namespaces. /* If we're unprivileged, set up the user namespace first to enable use of the other namespaces.
* Users with CAP_SYS_ADMIN can set up user namespaces last because they will be able to * Users with CAP_SYS_ADMIN can set up user namespaces last because they will be able to

View File

@ -2622,7 +2622,7 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) {
return r; return r;
} else if ((val = startswith(l, "exec-context-root-hash-sig="))) { } else if ((val = startswith(l, "exec-context-root-hash-sig="))) {
iovec_done(&c->root_hash_sig); iovec_done(&c->root_hash_sig);
r= unbase64mem(val, &c->root_hash_sig.iov_base, &c->root_hash_sig.iov_len); r = unbase64mem(val, &c->root_hash_sig.iov_base, &c->root_hash_sig.iov_len);
if (r < 0) if (r < 0)
return r; return r;
} else if ((val = startswith(l, "exec-context-root-ephemeral="))) { } else if ((val = startswith(l, "exec-context-root-ephemeral="))) {

View File

@ -59,6 +59,7 @@
#include "killall.h" #include "killall.h"
#include "kmod-setup.h" #include "kmod-setup.h"
#include "label-util.h" #include "label-util.h"
#include "libmount-util.h"
#include "limits-util.h" #include "limits-util.h"
#include "load-fragment.h" #include "load-fragment.h"
#include "log.h" #include "log.h"
@ -3310,6 +3311,12 @@ int main(int argc, char *argv[]) {
goto finish; goto finish;
} }
r = dlopen_libmount();
if (r < 0) {
error_message = "Failed to load libmount.so";
goto finish;
}
r = initialize_runtime(skip_setup, r = initialize_runtime(skip_setup,
first_boot, first_boot,
&saved_rlimit_nofile, &saved_rlimit_nofile,

View File

@ -133,6 +133,8 @@ libcore_static = static_library(
implicit_include_directories : false, implicit_include_directories : false,
c_args : ['-fvisibility=default'], c_args : ['-fvisibility=default'],
dependencies : [libaudit_cflags, dependencies : [libaudit_cflags,
libbpf_cflags,
libcryptsetup_cflags,
libdl, libdl,
libm, libm,
libmount_cflags, libmount_cflags,
@ -200,6 +202,7 @@ executables += [
'dependencies' : [ 'dependencies' : [
libapparmor_cflags, libapparmor_cflags,
libkmod_cflags, libkmod_cflags,
libmount_cflags,
libseccomp_cflags, libseccomp_cflags,
libselinux_cflags, libselinux_cflags,
], ],
@ -212,6 +215,9 @@ executables += [
'link_with' : executor_libs, 'link_with' : executor_libs,
'dependencies' : [ 'dependencies' : [
libapparmor_cflags, libapparmor_cflags,
libbpf_cflags,
libcryptsetup_cflags,
libmount_cflags,
libpam_cflags, libpam_cflags,
libseccomp_cflags, libseccomp_cflags,
libselinux_cflags, libselinux_cflags,

View File

@ -60,7 +60,9 @@ static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = {
}; };
static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata); static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
#if HAVE_LIBMOUNT
static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata); static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
#endif
static void mount_enter_dead(Mount *m, MountResult f, bool flush_result); static void mount_enter_dead(Mount *m, MountResult f, bool flush_result);
static void mount_enter_mounted(Mount *m, MountResult f); static void mount_enter_mounted(Mount *m, MountResult f);
static void mount_cycle_clear(Mount *m); static void mount_cycle_clear(Mount *m);
@ -1744,6 +1746,7 @@ static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *user
return 0; return 0;
} }
#if HAVE_LIBMOUNT
static int mount_setup_new_unit( static int mount_setup_new_unit(
Manager *m, Manager *m,
const char *name, const char *name,
@ -1924,8 +1927,10 @@ static int mount_setup_unit(
return 0; return 0;
} }
#endif
static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
#if HAVE_LIBMOUNT
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
_cleanup_set_free_ Set *devices = NULL; _cleanup_set_free_ Set *devices = NULL;
@ -1965,6 +1970,9 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
} }
return 0; return 0;
#else
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in");
#endif
} }
static void mount_shutdown(Manager *m) { static void mount_shutdown(Manager *m) {
@ -2042,6 +2050,7 @@ static bool mount_is_mounted(Mount *m) {
return UNIT(m)->perpetual || FLAGS_SET(m->proc_flags, MOUNT_PROC_IS_MOUNTED); return UNIT(m)->perpetual || FLAGS_SET(m->proc_flags, MOUNT_PROC_IS_MOUNTED);
} }
#if HAVE_LIBMOUNT
static int mount_on_ratelimit_expire(sd_event_source *s, void *userdata) { static int mount_on_ratelimit_expire(sd_event_source *s, void *userdata) {
Manager *m = ASSERT_PTR(userdata); Manager *m = ASSERT_PTR(userdata);
Job *j; Job *j;
@ -2060,8 +2069,10 @@ static int mount_on_ratelimit_expire(sd_event_source *s, void *userdata) {
return 0; return 0;
} }
#endif
static void mount_enumerate(Manager *m) { static void mount_enumerate(Manager *m) {
#if HAVE_LIBMOUNT
int r; int r;
assert(m); assert(m);
@ -2154,9 +2165,14 @@ static void mount_enumerate(Manager *m) {
fail: fail:
mount_shutdown(m); mount_shutdown(m);
#else
log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Cannot enumerate mounts, as libmount support is not compiled in");
mount_shutdown(m);
#endif
} }
static int drain_libmount(Manager *m) { static int drain_libmount(Manager *m) {
#if HAVE_LIBMOUNT
bool rescan = false; bool rescan = false;
int r; int r;
@ -2180,6 +2196,9 @@ static int drain_libmount(Manager *m) {
} while (r == 0); } while (r == 0);
return rescan; return rescan;
#else
return 0;
#endif
} }
static int mount_process_proc_self_mountinfo(Manager *m) { static int mount_process_proc_self_mountinfo(Manager *m) {
@ -2294,6 +2313,7 @@ static int mount_process_proc_self_mountinfo(Manager *m) {
return 0; return 0;
} }
#if HAVE_LIBMOUNT
static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) { static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
Manager *m = ASSERT_PTR(userdata); Manager *m = ASSERT_PTR(userdata);
@ -2301,6 +2321,7 @@ static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents,
return mount_process_proc_self_mountinfo(m); return mount_process_proc_self_mountinfo(m);
} }
#endif
static void mount_reset_failed(Unit *u) { static void mount_reset_failed(Unit *u) {
Mount *m = MOUNT(u); Mount *m = MOUNT(u);

View File

@ -14,6 +14,7 @@
#include "bus-error.h" #include "bus-error.h"
#include "bus-util.h" #include "bus-util.h"
#include "chase.h" #include "chase.h"
#include "cryptsetup-util.h"
#include "dbus-service.h" #include "dbus-service.h"
#include "dbus-unit.h" #include "dbus-unit.h"
#include "devnum-util.h" #include "devnum-util.h"
@ -5552,6 +5553,8 @@ static int service_live_mount(
u->id); u->id);
} }
(void) dlopen_cryptsetup();
service_unwatch_control_pid(s); service_unwatch_control_pid(s);
s->live_mount_result = SERVICE_SUCCESS; s->live_mount_result = SERVICE_SUCCESS;
s->control_command = NULL; s->control_command = NULL;

View File

@ -1,5 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('HAVE_LIBMOUNT') != 1
subdir_done()
endif
executables += [ executables += [
executable_template + { executable_template + {
'name' : 'systemd-creds', 'name' : 'systemd-creds',

View File

@ -1,6 +1,6 @@
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('HAVE_LIBCRYPTSETUP') != 1 if conf.get('HAVE_LIBCRYPTSETUP') != 1 or conf.get('HAVE_LIBMOUNT') != 1
subdir_done() subdir_done()
endif endif

View File

@ -1,5 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('HAVE_LIBMOUNT') != 1
subdir_done()
endif
executables += [ executables += [
generator_template + { generator_template + {
'name' : 'systemd-fstab-generator', 'name' : 'systemd-fstab-generator',

View File

@ -10,7 +10,6 @@
#include "fs-util.h" #include "fs-util.h"
#include "log.h" #include "log.h"
#include "main-func.h" #include "main-func.h"
#include "memstream-util.h"
#include "openssl-util.h" #include "openssl-util.h"
#include "parse-argument.h" #include "parse-argument.h"
#include "pretty-print.h" #include "pretty-print.h"
@ -303,21 +302,9 @@ static int verb_public(int argc, char *argv[], void *userdata) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to load private key from %s: %m", arg_private_key); return log_error_errno(r, "Failed to load private key from %s: %m", arg_private_key);
_cleanup_(memstream_done) MemStream m = {}; r = openssl_extract_public_key(private_key, &public_key);
FILE *tf = memstream_init(&m); if (r < 0)
if (!tf) return log_error_errno(r, "Failed to extract public key from private key file '%s': %m", arg_private_key);
return log_oom();
if (i2d_PUBKEY_fp(tf, private_key) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EIO),
"Failed to extract public key from private key file '%s'.", arg_private_key);
fflush(tf);
rewind(tf);
if (!d2i_PUBKEY_fp(tf, &public_key))
return log_error_errno(SYNTHETIC_ERRNO(EIO),
"Failed to parse extracted public key of private key file '%s'.", arg_private_key);
} else } else
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "One of --certificate=, or --private-key= must be specified"); return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "One of --certificate=, or --private-key= must be specified");

View File

@ -203,7 +203,6 @@ simple_tests += files(
'sd-bus/test-bus-vtable.c', 'sd-bus/test-bus-vtable.c',
'sd-device/test-device-util.c', 'sd-device/test-device-util.c',
'sd-device/test-sd-device-monitor.c', 'sd-device/test-sd-device-monitor.c',
'sd-device/test-sd-device.c',
'sd-journal/test-journal-flush.c', 'sd-journal/test-journal-flush.c',
'sd-journal/test-journal-interleaving.c', 'sd-journal/test-journal-interleaving.c',
'sd-journal/test-journal-stream.c', 'sd-journal/test-journal-stream.c',
@ -214,6 +213,10 @@ simple_tests += files(
) )
libsystemd_tests += [ libsystemd_tests += [
{
'sources' : files('sd-device/test-sd-device.c'),
'dependencies' : [ threads, libmount_cflags ],
},
{ {
'sources' : files('sd-bus/test-bus-address.c'), 'sources' : files('sd-bus/test-bus-address.c'),
'dependencies' : threads 'dependencies' : threads

View File

@ -13,6 +13,7 @@
#include "fd-util.h" #include "fd-util.h"
#include "fs-util.h" #include "fs-util.h"
#include "hashmap.h" #include "hashmap.h"
#include "libmount-util.h"
#include "mkdir.h" #include "mkdir.h"
#include "mount-util.h" #include "mount-util.h"
#include "mountpoint-util.h" #include "mountpoint-util.h"
@ -833,8 +834,14 @@ TEST(devname_from_devnum) {
} }
static int intro(void) { static int intro(void) {
int r;
if (path_is_mount_point("/sys") <= 0) if (path_is_mount_point("/sys") <= 0)
return log_tests_skipped("/sys is not mounted"); return log_tests_skipped("/sys/ is not mounted");
r = dlopen_libmount();
if (r < 0)
return log_tests_skipped("libmount not available.");
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -15,7 +15,6 @@
#include "hexdecoct.h" #include "hexdecoct.h"
#include "log.h" #include "log.h"
#include "main-func.h" #include "main-func.h"
#include "memstream-util.h"
#include "openssl-util.h" #include "openssl-util.h"
#include "pager.h" #include "pager.h"
#include "parse-argument.h" #include "parse-argument.h"
@ -890,25 +889,10 @@ static int build_policy_digest(bool sign) {
"Failed to extract public key from certificate %s.", "Failed to extract public key from certificate %s.",
arg_certificate); arg_certificate);
} else if (sign) { } else if (sign) {
_cleanup_(memstream_done) MemStream m = {};
FILE *tf;
/* No public key was specified, let's derive it automatically, if we can, when signing */ /* No public key was specified, let's derive it automatically, if we can, when signing */
r = openssl_extract_public_key(privkey, &pubkey);
tf = memstream_init(&m); if (r < 0)
if (!tf) return log_error_errno(r, "Failed to extract public key from private key file '%s': %m", arg_private_key);
return log_oom();
if (i2d_PUBKEY_fp(tf, privkey) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EIO),
"Failed to extract public key from private key file '%s'.", arg_private_key);
fflush(tf);
rewind(tf);
if (!d2i_PUBKEY_fp(tf, &pubkey))
return log_error_errno(SYNTHETIC_ERRNO(EIO),
"Failed to parse extracted public key of private key file '%s'.", arg_private_key);
} }
r = pcr_states_allocate(&pcr_states); r = pcr_states_allocate(&pcr_states);

View File

@ -1,5 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('HAVE_LIBMOUNT') != 1
subdir_done()
endif
executables += [ executables += [
executable_template + { executable_template + {
'name' : 'systemd-mount', 'name' : 'systemd-mount',

View File

@ -47,6 +47,7 @@ executables += [
include_directories('.') include_directories('.')
], ],
'dependencies' : [ 'dependencies' : [
libmount_cflags,
libseccomp_cflags, libseccomp_cflags,
libselinux_cflags, libselinux_cflags,
], ],

View File

@ -41,6 +41,7 @@
#include "devnum-util.h" #include "devnum-util.h"
#include "discover-image.h" #include "discover-image.h"
#include "dissect-image.h" #include "dissect-image.h"
#include "dlfcn-util.h"
#include "env-util.h" #include "env-util.h"
#include "escape.h" #include "escape.h"
#include "ether-addr-util.h" #include "ether-addr-util.h"
@ -58,6 +59,7 @@
#include "image-policy.h" #include "image-policy.h"
#include "in-addr-util.h" #include "in-addr-util.h"
#include "io-util.h" #include "io-util.h"
#include "libmount-util.h"
#include "log.h" #include "log.h"
#include "loop-util.h" #include "loop-util.h"
#include "loopback-setup.h" #include "loopback-setup.h"
@ -2551,14 +2553,12 @@ static int setup_hostname(void) {
return 0; return 0;
} }
static int setup_journal(const char *root_dir, const char *persistent_path, uid_t chown_uid, uid_t chown_range) { static int setup_journal(const char *directory, uid_t uid_shift, uid_t uid_range) {
_cleanup_free_ char *d = NULL; _cleanup_free_ char *d = NULL;
sd_id128_t this_id; sd_id128_t this_id;
bool try; bool try;
int r; int r;
assert(root_dir);
/* Don't link journals in ephemeral mode */ /* Don't link journals in ephemeral mode */
if (arg_ephemeral) if (arg_ephemeral)
return 0; return 0;
@ -2568,17 +2568,6 @@ static int setup_journal(const char *root_dir, const char *persistent_path, uid_
try = arg_link_journal_try || arg_link_journal == LINK_AUTO; try = arg_link_journal_try || arg_link_journal == LINK_AUTO;
if (!persistent_path) {
if (try) {
log_debug("No persistent path available, skipping journal linking.");
return 0;
} else
return log_error_errno(
SYNTHETIC_ERRNO(ENOENT),
"Journal linking requested but no persistent directory available. "
"Use --directory, or --link-journal=auto/try-guest/try-host for optional linking.");
}
r = sd_id128_get_machine(&this_id); r = sd_id128_get_machine(&this_id);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to retrieve machine ID: %m"); return log_error_errno(r, "Failed to retrieve machine ID: %m");
@ -2592,7 +2581,7 @@ static int setup_journal(const char *root_dir, const char *persistent_path, uid_
} }
FOREACH_STRING(dirname, "/var", "/var/log", "/var/log/journal") { FOREACH_STRING(dirname, "/var", "/var/log", "/var/log/journal") {
r = userns_mkdir(root_dir, dirname, 0755, 0, 0); r = userns_mkdir(directory, dirname, 0755, 0, 0);
if (r < 0) { if (r < 0) {
bool ignore = r == -EROFS && try; bool ignore = r == -EROFS && try;
log_full_errno(ignore ? LOG_DEBUG : LOG_ERR, r, log_full_errno(ignore ? LOG_DEBUG : LOG_ERR, r,
@ -2605,14 +2594,10 @@ static int setup_journal(const char *root_dir, const char *persistent_path, uid_
if (!p) if (!p)
return log_oom(); return log_oom();
_cleanup_free_ char *q = path_join(persistent_path, p); _cleanup_free_ char *q = path_join(directory, p);
if (!q) if (!q)
return log_oom(); return log_oom();
_cleanup_free_ char *container_path = path_join(root_dir, p);
if (!container_path)
return log_oom();
if (path_is_mount_point(p) > 0) { if (path_is_mount_point(p) > 0) {
if (try) if (try)
return 0; return 0;
@ -2621,14 +2606,12 @@ static int setup_journal(const char *root_dir, const char *persistent_path, uid_
"%s: already a mount point, refusing to use for journal", p); "%s: already a mount point, refusing to use for journal", p);
} }
if (path_is_mount_point(container_path) > 0) { if (path_is_mount_point(q) > 0) {
if (try) if (try)
return 0; return 0;
return log_error_errno( return log_error_errno(SYNTHETIC_ERRNO(EEXIST),
SYNTHETIC_ERRNO(EEXIST), "%s: already a mount point, refusing to use for journal", q);
"%s: already a mount point, refusing to use for journal",
container_path);
} }
r = readlink_and_make_absolute(p, &d); r = readlink_and_make_absolute(p, &d);
@ -2636,9 +2619,9 @@ static int setup_journal(const char *root_dir, const char *persistent_path, uid_
if (IN_SET(arg_link_journal, LINK_GUEST, LINK_AUTO) && if (IN_SET(arg_link_journal, LINK_GUEST, LINK_AUTO) &&
path_equal(d, q)) { path_equal(d, q)) {
r = userns_mkdir(root_dir, p, 0755, 0, 0); r = userns_mkdir(directory, p, 0755, 0, 0);
if (r < 0) if (r < 0)
log_warning_errno(r, "Failed to create directory %s: %m", container_path); log_warning_errno(r, "Failed to create directory %s: %m", q);
return 0; return 0;
} }
@ -2668,9 +2651,9 @@ static int setup_journal(const char *root_dir, const char *persistent_path, uid_
return log_error_errno(errno, "Failed to symlink %s to %s: %m", q, p); return log_error_errno(errno, "Failed to symlink %s to %s: %m", q, p);
} }
r = userns_mkdir(root_dir, p, 0755, 0, 0); r = userns_mkdir(directory, p, 0755, 0, 0);
if (r < 0) if (r < 0)
log_warning_errno(r, "Failed to create directory %s: %m", container_path); log_warning_errno(r, "Failed to create directory %s: %m", q);
return 0; return 0;
} }
@ -2690,25 +2673,25 @@ static int setup_journal(const char *root_dir, const char *persistent_path, uid_
} else if (access(p, F_OK) < 0) } else if (access(p, F_OK) < 0)
return 0; return 0;
if (dir_is_empty(container_path, /* ignore_hidden_or_backup= */ false) == 0) if (dir_is_empty(q, /* ignore_hidden_or_backup= */ false) == 0)
log_warning("%s is not empty, proceeding anyway.", container_path); log_warning("%s is not empty, proceeding anyway.", q);
r = userns_mkdir(root_dir, p, 0755, 0, 0); r = userns_mkdir(directory, p, 0755, 0, 0);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to create %s: %m", container_path); return log_error_errno(r, "Failed to create %s: %m", q);
return mount_custom( return mount_custom(
root_dir, directory,
&(CustomMount) { &(CustomMount) {
.type = CUSTOM_MOUNT_BIND, .type = CUSTOM_MOUNT_BIND,
.options = (char*) (uid_is_valid(chown_uid) ? "rootidmap" : NULL), .options = (char*) (uid_is_valid(uid_shift) ? "rootidmap" : NULL),
.source = p, .source = p,
.destination = p, .destination = p,
.destination_uid = UID_INVALID, .destination_uid = UID_INVALID,
}, },
/* n = */ 1, /* n = */ 1,
chown_uid, uid_shift,
chown_range, uid_range,
arg_selinux_apifs_context, arg_selinux_apifs_context,
MOUNT_NON_ROOT_ONLY); MOUNT_NON_ROOT_ONLY);
} }
@ -3880,7 +3863,6 @@ static DissectImageFlags determine_dissect_image_flags(void) {
static int outer_child( static int outer_child(
Barrier *barrier, Barrier *barrier,
const char *directory, const char *directory,
const char *persistent_path,
int mount_fd, int mount_fd,
DissectedImage *dissected_image, DissectedImage *dissected_image,
int fd_outer_socket, int fd_outer_socket,
@ -4287,7 +4269,7 @@ static int outer_child(
if (r < 0) if (r < 0)
return r; return r;
r = setup_journal(directory, persistent_path, chown_uid, chown_range); r = setup_journal(directory, chown_uid, chown_range);
if (r < 0) if (r < 0)
return r; return r;
@ -4372,6 +4354,9 @@ static int outer_child(
if (pid == 0) { if (pid == 0) {
fd_outer_socket = safe_close(fd_outer_socket); fd_outer_socket = safe_close(fd_outer_socket);
/* In the child refuse dlopen(), so that we never mix shared libraries from payload and parent */
block_dlopen();
/* The inner child has all namespaces that are requested, so that we all are owned by the /* The inner child has all namespaces that are requested, so that we all are owned by the
* user if user namespaces are turned on. */ * user if user namespaces are turned on. */
@ -5085,7 +5070,6 @@ static int load_oci_bundle(void) {
static int run_container( static int run_container(
const char *directory, const char *directory,
const char *persistent_path,
int mount_fd, int mount_fd,
DissectedImage *dissected_image, DissectedImage *dissected_image,
int userns_fd, int userns_fd,
@ -5236,7 +5220,6 @@ static int run_container(
r = outer_child(&barrier, r = outer_child(&barrier,
directory, directory,
persistent_path,
mount_fd, mount_fd,
dissected_image, dissected_image,
fd_outer_socket_pair[1], fd_outer_socket_pair[1],
@ -5949,7 +5932,6 @@ static int run(int argc, char *argv[]) {
_cleanup_(dissected_image_unrefp) DissectedImage *dissected_image = NULL; _cleanup_(dissected_image_unrefp) DissectedImage *dissected_image = NULL;
_cleanup_(sd_netlink_unrefp) sd_netlink *nfnl = NULL; _cleanup_(sd_netlink_unrefp) sd_netlink *nfnl = NULL;
_cleanup_(pidref_done) PidRef pid = PIDREF_NULL; _cleanup_(pidref_done) PidRef pid = PIDREF_NULL;
_cleanup_free_ char *persistent_path_storage = NULL;
log_setup(); log_setup();
@ -5962,6 +5944,10 @@ static int run(int argc, char *argv[]) {
if (arg_cleanup) if (arg_cleanup)
return do_cleanup(); return do_cleanup();
(void) dlopen_libmount();
(void) dlopen_libseccomp();
(void) dlopen_libselinux();
r = cg_has_legacy(); r = cg_has_legacy();
if (r < 0) if (r < 0)
goto finish; goto finish;
@ -6411,47 +6397,6 @@ static int run(int argc, char *argv[]) {
arg_architecture = dissected_image_architecture(dissected_image); arg_architecture = dissected_image_architecture(dissected_image);
} }
/* Journal linking creates symlinks from the host's /var/log/journal/<uuid> to a persistent directory
* that survives container restarts, allowing journalctl -M to read container logs. But where that
* persistent directory is can be quite different depending on the mode:
*
* For --directory: The directory itself is the persistent location.
* For --image: Use /var/lib/machines/<machine-name> if it exists as a directory.
*
* Otherwise, we skip journal linking.
*/
const char *persistent_path;
if (arg_directory)
persistent_path = arg_directory;
else if (arg_image) {
persistent_path_storage = path_join("/var/lib/machines", arg_machine);
if (!persistent_path_storage) {
r = log_oom();
goto finish;
}
/* Validate that the persistent path exists and is actually a directory. We cannot create it
* ourselves as that would conflict with image management. */
struct stat st;
if (stat(persistent_path_storage, &st) < 0) {
if (errno == ENOENT)
log_debug("Persistent directory %s does not exist, skipping journal linking.",
persistent_path_storage);
else
log_warning_errno(
errno,
"Failed to access persistent directory %s, skipping journal linking: %m",
persistent_path_storage);
persistent_path = NULL;
} else if (!S_ISDIR(st.st_mode)) {
log_warning("%s exists but is not a directory, skipping journal linking.",
persistent_path_storage);
persistent_path = NULL;
} else
persistent_path = persistent_path_storage;
} else
assert_not_reached();
/* Create a temporary place to mount stuff. */ /* Create a temporary place to mount stuff. */
r = mkdtemp_malloc("/tmp/nspawn-root-XXXXXX", &rootdir); r = mkdtemp_malloc("/tmp/nspawn-root-XXXXXX", &rootdir);
if (r < 0) { if (r < 0) {
@ -6498,7 +6443,6 @@ static int run(int argc, char *argv[]) {
for (;;) { for (;;) {
r = run_container( r = run_container(
rootdir, rootdir,
persistent_path,
mount_fd, mount_fd,
dissected_image, dissected_image,
userns_fd, userns_fd,

View File

@ -237,6 +237,16 @@ int oomd_cgroup_kill(const char *path, bool recurse, bool dry_run) {
assert(path); assert(path);
/* First try to send SIG0 recursively to ensure all child cgroups can be killed. */
if (recurse)
r = cg_kill_recursive(path, /* sig= */ 0, CGROUP_IGNORE_SELF,
/* killed_pids= */ NULL, /* log_kill= */ NULL, /* userdata= */ NULL);
else
r = cg_kill(path, /* sig= */ 0, CGROUP_IGNORE_SELF,
/* killed_pids= */ NULL, /* log_kill= */ NULL, /* userdata= */ NULL);
if (r < 0)
return log_debug_errno(r, "Failed to send SIG0 to processes in cgroup '%s': %m", path);
if (dry_run) { if (dry_run) {
_cleanup_free_ char *cg_path = NULL; _cleanup_free_ char *cg_path = NULL;
@ -337,12 +347,6 @@ int oomd_kill_by_pgscan_rate(Hashmap *h, const char *prefix, bool dry_run, char
if (c->pgscan == 0 && c->current_memory_usage == 0) if (c->pgscan == 0 && c->current_memory_usage == 0)
continue; continue;
/* First try killing recursively to ensure all child cgroups can be killed. */
r = cg_kill_recursive(c->path, /* sig= */ 0, CGROUP_IGNORE_SELF, /* killed_pids= */ NULL,
/* log_kill= */ NULL, /* userdata= */ NULL);
if (r < 0)
continue;
r = oomd_cgroup_kill(c->path, /* recurse= */ true, /* dry_run= */ dry_run); r = oomd_cgroup_kill(c->path, /* recurse= */ true, /* dry_run= */ dry_run);
if (r == -ENOMEM) if (r == -ENOMEM)
return r; /* Treat oom as a hard error */ return r; /* Treat oom as a hard error */
@ -387,12 +391,6 @@ int oomd_kill_by_swap_usage(Hashmap *h, uint64_t threshold_usage, bool dry_run,
if (c->swap_usage <= threshold_usage) if (c->swap_usage <= threshold_usage)
continue; continue;
/* First try killing recursively to ensure all child cgroups can be killed. */
r = cg_kill_recursive(c->path, /* sig= */ 0, CGROUP_IGNORE_SELF, /* killed_pids= */ NULL,
/* log_kill= */ NULL, /* userdata= */ NULL);
if (r < 0)
continue;
r = oomd_cgroup_kill(c->path, /* recurse= */ true, /* dry_run= */ dry_run); r = oomd_cgroup_kill(c->path, /* recurse= */ true, /* dry_run= */ dry_run);
if (r == -ENOMEM) if (r == -ENOMEM)
return r; /* Treat oom as a hard error */ return r; /* Treat oom as a hard error */

View File

@ -29,6 +29,8 @@ executables += [
'sources' : systemd_portabled_sources, 'sources' : systemd_portabled_sources,
'link_with' : portabled_link_with, 'link_with' : portabled_link_with,
'dependencies' : [ 'dependencies' : [
libcryptsetup_cflags,
libmount_cflags,
libselinux_cflags, libselinux_cflags,
threads, threads,
], ],

View File

@ -12,6 +12,7 @@
#include "chase.h" #include "chase.h"
#include "conf-files.h" #include "conf-files.h"
#include "copy.h" #include "copy.h"
#include "cryptsetup-util.h"
#include "data-fd-util.h" #include "data-fd-util.h"
#include "dirent-util.h" #include "dirent-util.h"
#include "discover-image.h" #include "discover-image.h"
@ -28,6 +29,7 @@
#include "glyph-util.h" #include "glyph-util.h"
#include "install.h" #include "install.h"
#include "iovec-util.h" #include "iovec-util.h"
#include "libmount-util.h"
#include "log-context.h" #include "log-context.h"
#include "log.h" #include "log.h"
#include "loop-util.h" #include "loop-util.h"
@ -420,6 +422,10 @@ static int portable_extract_by_path(
BLOCK_SIGNALS(SIGCHLD); BLOCK_SIGNALS(SIGCHLD);
/* Load some libraries before we fork workers off that want to use them */
(void) dlopen_cryptsetup();
(void) dlopen_libmount();
r = mkdtemp_malloc("/tmp/inspect-XXXXXX", &tmpdir); r = mkdtemp_malloc("/tmp/inspect-XXXXXX", &tmpdir);
if (r < 0) if (r < 0)
return log_debug_errno(r, "Failed to create temporary directory: %m"); return log_debug_errno(r, "Failed to create temporary directory: %m");

View File

@ -1,5 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('HAVE_LIBMOUNT') != 1
subdir_done()
endif
executables += [ executables += [
libexec_template + { libexec_template + {
'name' : 'systemd-remount-fs', 'name' : 'systemd-remount-fs',

View File

@ -16,6 +16,7 @@ executables += [
'dependencies' : [ 'dependencies' : [
libblkid_cflags, libblkid_cflags,
libfdisk, libfdisk,
libmount_cflags,
libopenssl, libopenssl,
threads, threads,
], ],
@ -35,6 +36,7 @@ executables += [
'dependencies' : [ 'dependencies' : [
libblkid_cflags, libblkid_cflags,
libfdisk, libfdisk,
libmount_cflags,
libopenssl, libopenssl,
threads, threads,
], ],

View File

@ -50,6 +50,7 @@
#include "initrd-util.h" #include "initrd-util.h"
#include "io-util.h" #include "io-util.h"
#include "json-util.h" #include "json-util.h"
#include "libmount-util.h"
#include "list.h" #include "list.h"
#include "loop-util.h" #include "loop-util.h"
#include "main-func.h" #include "main-func.h"
@ -6616,6 +6617,8 @@ static int partition_populate_filesystem(Context *context, Partition *p, const c
* appear in the host namespace. Hence we fork a child that has its own file system namespace and * appear in the host namespace. Hence we fork a child that has its own file system namespace and
* detached mount propagation. */ * detached mount propagation. */
(void) dlopen_libmount();
r = safe_fork("(sd-copy)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, NULL); r = safe_fork("(sd-copy)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, NULL);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -73,7 +73,7 @@ static bool arg_no_block = false;
static bool arg_wait = false; static bool arg_wait = false;
static const char *arg_unit = NULL; static const char *arg_unit = NULL;
static char *arg_description = NULL; static char *arg_description = NULL;
static const char *arg_slice = NULL; static char *arg_slice = NULL;
static bool arg_slice_inherit = false; static bool arg_slice_inherit = false;
static bool arg_expand_environment = true; static bool arg_expand_environment = true;
static bool arg_send_sighup = false; static bool arg_send_sighup = false;
@ -81,7 +81,7 @@ static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
static const char *arg_host = NULL; static const char *arg_host = NULL;
static RuntimeScope arg_runtime_scope = RUNTIME_SCOPE_SYSTEM; static RuntimeScope arg_runtime_scope = RUNTIME_SCOPE_SYSTEM;
static const char *arg_service_type = NULL; static const char *arg_service_type = NULL;
static const char *arg_exec_user = NULL; static char *arg_exec_user = NULL;
static const char *arg_exec_group = NULL; static const char *arg_exec_group = NULL;
static int arg_nice = 0; static int arg_nice = 0;
static bool arg_nice_set = false; static bool arg_nice_set = false;
@ -123,6 +123,8 @@ static bool arg_via_shell = false;
static bool arg_empower = false; static bool arg_empower = false;
STATIC_DESTRUCTOR_REGISTER(arg_description, freep); STATIC_DESTRUCTOR_REGISTER(arg_description, freep);
STATIC_DESTRUCTOR_REGISTER(arg_slice, freep);
STATIC_DESTRUCTOR_REGISTER(arg_exec_user, freep);
STATIC_DESTRUCTOR_REGISTER(arg_environment, strv_freep); STATIC_DESTRUCTOR_REGISTER(arg_environment, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_property, strv_freep); STATIC_DESTRUCTOR_REGISTER(arg_property, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_path_property, strv_freep); STATIC_DESTRUCTOR_REGISTER(arg_path_property, strv_freep);
@ -453,7 +455,9 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_SLICE: case ARG_SLICE:
arg_slice = optarg; r = free_and_strdup_warn(&arg_slice, optarg);
if (r < 0)
return r;
break; break;
case ARG_SLICE_INHERIT: case ARG_SLICE_INHERIT:
@ -490,7 +494,9 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_EXEC_USER: case ARG_EXEC_USER:
arg_exec_user = optarg; r = free_and_strdup_warn(&arg_exec_user, optarg);
if (r < 0)
return r;
break; break;
case ARG_EXEC_GROUP: case ARG_EXEC_GROUP:
@ -979,7 +985,9 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) {
break; break;
case ARG_SLICE: case ARG_SLICE:
arg_slice = optarg; r = free_and_strdup_warn(&arg_slice, optarg);
if (r < 0)
return r;
break; break;
case ARG_SLICE_INHERIT: case ARG_SLICE_INHERIT:
@ -987,7 +995,9 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) {
break; break;
case 'u': case 'u':
arg_exec_user = optarg; r = free_and_strdup_warn(&arg_exec_user, optarg);
if (r < 0)
return r;
break; break;
case 'g': case 'g':
@ -1098,6 +1108,12 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) {
arg_exec_user = getusername_malloc(); arg_exec_user = getusername_malloc();
if (!arg_exec_user) if (!arg_exec_user)
return log_oom(); return log_oom();
if (arg_empower && !arg_working_directory) {
r = safe_getcwd(&arg_working_directory);
if (r < 0)
return log_error_errno(r, "Failed to get current working directory: %m");
}
} }
if (!arg_working_directory) { if (!arg_working_directory) {
@ -2756,16 +2772,20 @@ static int start_transient_scope(sd_bus *bus) {
} }
if (arg_exec_user) { if (arg_exec_user) {
const char *home, *shell; const char *un = arg_exec_user, *home, *shell;
uid_t uid; uid_t uid;
gid_t gid; gid_t gid;
r = get_user_creds(&arg_exec_user, &uid, &gid, &home, &shell, r = get_user_creds(&un, &uid, &gid, &home, &shell,
USER_CREDS_CLEAN|USER_CREDS_SUPPRESS_PLACEHOLDER|USER_CREDS_PREFER_NSS); USER_CREDS_CLEAN|USER_CREDS_SUPPRESS_PLACEHOLDER|USER_CREDS_PREFER_NSS);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to resolve user '%s': %s", return log_error_errno(r, "Failed to resolve user '%s': %s",
arg_exec_user, STRERROR_USER(r)); arg_exec_user, STRERROR_USER(r));
r = free_and_strdup_warn(&arg_exec_user, un);
if (r < 0)
return r;
if (home) { if (home) {
r = strv_extendf(&user_env, "HOME=%s", home); r = strv_extendf(&user_env, "HOME=%s", home);
if (r < 0) if (r < 0)

View File

@ -2,6 +2,7 @@
#include "bpf-dlopen.h" #include "bpf-dlopen.h"
#include "dlfcn-util.h" #include "dlfcn-util.h"
#include "errno-util.h"
#include "initrd-util.h" #include "initrd-util.h"
#include "log.h" #include "log.h"
@ -73,7 +74,6 @@ static int bpf_print_func(enum libbpf_print_level level, const char *fmt, va_lis
} }
int dlopen_bpf_full(int log_level) { int dlopen_bpf_full(int log_level) {
_cleanup_(dlclosep) void *dl = NULL;
static int cached = 0; static int cached = 0;
int r; int r;
@ -87,17 +87,20 @@ int dlopen_bpf_full(int log_level) {
DISABLE_WARNING_DEPRECATED_DECLARATIONS; DISABLE_WARNING_DEPRECATED_DECLARATIONS;
dl = dlopen("libbpf.so.1", RTLD_NOW|RTLD_NODELETE); _cleanup_(dlclosep) void *dl = NULL;
if (!dl) { r = dlopen_safe("libbpf.so.1", &dl, /* reterr_dlerror= */ NULL);
if (r < 0) {
/* libbpf < 1.0.0 (we rely on 0.1.0+) provide most symbols we care about, but /* libbpf < 1.0.0 (we rely on 0.1.0+) provide most symbols we care about, but
* unfortunately not all until 0.7.0. See bpf-compat.h for more details. * unfortunately not all until 0.7.0. See bpf-compat.h for more details.
* Once we consider we can assume 0.7+ is present we can just use the same symbol * Once we consider we can assume 0.7+ is present we can just use the same symbol
* list for both files, and when we assume 1.0+ is present we can remove this dlopen */ * list for both files, and when we assume 1.0+ is present we can remove this dlopen */
dl = dlopen("libbpf.so.0", RTLD_NOW|RTLD_NODELETE); const char *dle = NULL;
if (!dl) r = dlopen_safe("libbpf.so.0", &dl, &dle);
return cached = log_full_errno(in_initrd() ? LOG_DEBUG : log_level, SYNTHETIC_ERRNO(EOPNOTSUPP), if (r < 0) {
"Neither libbpf.so.1 nor libbpf.so.0 are installed, cgroup BPF features disabled: %s", log_full_errno(in_initrd() ? LOG_DEBUG : log_level, r,
dlerror()); "Neither libbpf.so.1 nor libbpf.so.0 are installed, cgroup BPF features disabled: %s", dle ?: STRERROR(r));
return (cached = -EOPNOTSUPP); /* turn into recognizable error */
}
log_debug("Loaded 'libbpf.so.0' via dlopen()"); log_debug("Loaded 'libbpf.so.0' via dlopen()");

View File

@ -171,13 +171,13 @@ static char** image_settings_path(Image *image, RuntimeScope scope) {
SD_PATH_SYSTEM_CONFIGURATION, SD_PATH_SYSTEM_CONFIGURATION,
SD_PATH_SYSTEM_RUNTIME, SD_PATH_SYSTEM_RUNTIME,
SD_PATH_SYSTEM_LIBRARY_PRIVATE, SD_PATH_SYSTEM_LIBRARY_PRIVATE,
UINT64_MAX _SD_PATH_INVALID
}; };
static const uint64_t user_locations[] = { static const uint64_t user_locations[] = {
SD_PATH_USER_CONFIGURATION, SD_PATH_USER_CONFIGURATION,
SD_PATH_USER_RUNTIME, SD_PATH_USER_RUNTIME,
SD_PATH_USER_LIBRARY_PRIVATE, SD_PATH_USER_LIBRARY_PRIVATE,
UINT64_MAX _SD_PATH_INVALID
}; };
const uint64_t *locations; const uint64_t *locations;
@ -194,7 +194,7 @@ static char** image_settings_path(Image *image, RuntimeScope scope) {
assert_not_reached(); assert_not_reached();
} }
for (size_t k = 0; locations[k] != UINT64_MAX; k++) { for (size_t k = 0; locations[k] != _SD_PATH_INVALID; k++) {
_cleanup_free_ char *s = NULL; _cleanup_free_ char *s = NULL;
r = sd_path_lookup(locations[k], "systemd/nspawn", &s); r = sd_path_lookup(locations[k], "systemd/nspawn", &s);
if (r == -ENXIO) if (r == -ENXIO)

View File

@ -49,6 +49,7 @@
#include "io-util.h" #include "io-util.h"
#include "iovec-util.h" #include "iovec-util.h"
#include "json-util.h" #include "json-util.h"
#include "libmount-util.h"
#include "loop-util.h" #include "loop-util.h"
#include "mkdir-label.h" #include "mkdir-label.h"
#include "mount-util.h" #include "mount-util.h"
@ -3907,6 +3908,10 @@ int dissected_image_acquire_metadata(
assert(m); assert(m);
r = dlopen_libmount();
if (r < 0)
return r;
for (; n_meta_initialized < _META_MAX; n_meta_initialized++) { for (; n_meta_initialized < _META_MAX; n_meta_initialized++) {
assert(paths[n_meta_initialized]); assert(paths[n_meta_initialized]);
@ -4756,7 +4761,6 @@ int mountfsd_mount_image(
int r; int r;
assert(path); assert(path);
assert(verity);
assert(ret); assert(ret);
r = sd_varlink_connect_address(&vl, "/run/systemd/io.systemd.MountFileSystem"); r = sd_varlink_connect_address(&vl, "/run/systemd/io.systemd.MountFileSystem");
@ -4791,7 +4795,7 @@ int mountfsd_mount_image(
return log_error_errno(r, "Failed to format image policy to string: %m"); return log_error_errno(r, "Failed to format image policy to string: %m");
} }
if (verity->data_path) { if (verity && verity->data_path) {
verity_data_fd = open(verity->data_path, O_RDONLY|O_CLOEXEC); verity_data_fd = open(verity->data_path, O_RDONLY|O_CLOEXEC);
if (verity_data_fd < 0) if (verity_data_fd < 0)
return log_error_errno(errno, "Failed to open verity data file '%s': %m", verity->data_path); return log_error_errno(errno, "Failed to open verity data file '%s': %m", verity->data_path);
@ -4814,8 +4818,8 @@ int mountfsd_mount_image(
SD_JSON_BUILD_PAIR_CONDITION(!!ps, "imagePolicy", SD_JSON_BUILD_STRING(ps)), SD_JSON_BUILD_PAIR_CONDITION(!!ps, "imagePolicy", SD_JSON_BUILD_STRING(ps)),
SD_JSON_BUILD_PAIR_BOOLEAN("veritySharing", FLAGS_SET(flags, DISSECT_IMAGE_VERITY_SHARE)), SD_JSON_BUILD_PAIR_BOOLEAN("veritySharing", FLAGS_SET(flags, DISSECT_IMAGE_VERITY_SHARE)),
SD_JSON_BUILD_PAIR_CONDITION(verity_data_fd >= 0, "verityDataFileDescriptor", SD_JSON_BUILD_UNSIGNED(userns_fd >= 0 ? 2 : 1)), SD_JSON_BUILD_PAIR_CONDITION(verity_data_fd >= 0, "verityDataFileDescriptor", SD_JSON_BUILD_UNSIGNED(userns_fd >= 0 ? 2 : 1)),
JSON_BUILD_PAIR_IOVEC_HEX("verityRootHash", &verity->root_hash), SD_JSON_BUILD_PAIR_CONDITION(verity && iovec_is_set(&verity->root_hash), "verityRootHash", JSON_BUILD_IOVEC_HEX(&verity->root_hash)),
JSON_BUILD_PAIR_IOVEC_BASE64("verityRootHashSignature", &verity->root_hash_sig), SD_JSON_BUILD_PAIR_CONDITION(verity && iovec_is_set(&verity->root_hash_sig), "verityRootHashSignature", JSON_BUILD_IOVEC_BASE64(&verity->root_hash_sig)),
SD_JSON_BUILD_PAIR_BOOLEAN("allowInteractiveAuthentication", FLAGS_SET(flags, DISSECT_IMAGE_ALLOW_INTERACTIVE_AUTH))); SD_JSON_BUILD_PAIR_BOOLEAN("allowInteractiveAuthentication", FLAGS_SET(flags, DISSECT_IMAGE_ALLOW_INTERACTIVE_AUTH)));
if (r < 0) if (r < 0)
return r; return r;

View File

@ -38,6 +38,7 @@ bool fstab_enabled_full(int enabled) {
} }
int fstab_has_fstype(const char *fstype) { int fstab_has_fstype(const char *fstype) {
#if HAVE_LIBMOUNT
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
int r; int r;
@ -65,6 +66,9 @@ int fstab_has_fstype(const char *fstype) {
if (streq_ptr(sym_mnt_fs_get_fstype(fs), fstype)) if (streq_ptr(sym_mnt_fs_get_fstype(fs), fstype))
return true; return true;
} }
#else
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in");
#endif
} }
bool fstab_is_extrinsic(const char *mount, const char *opts) { bool fstab_is_extrinsic(const char *mount, const char *opts) {
@ -92,6 +96,7 @@ bool fstab_is_extrinsic(const char *mount, const char *opts) {
return false; return false;
} }
#if HAVE_LIBMOUNT
static int fstab_is_same_node(const char *what_fstab, const char *path) { static int fstab_is_same_node(const char *what_fstab, const char *path) {
_cleanup_free_ char *node = NULL; _cleanup_free_ char *node = NULL;
@ -110,8 +115,10 @@ static int fstab_is_same_node(const char *what_fstab, const char *path) {
return false; return false;
} }
#endif
int fstab_has_mount_point_prefix_strv(char * const *prefixes) { int fstab_has_mount_point_prefix_strv(char * const *prefixes) {
#if HAVE_LIBMOUNT
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
int r; int r;
@ -147,9 +154,13 @@ int fstab_has_mount_point_prefix_strv(char * const *prefixes) {
if (path_startswith_strv(path, prefixes)) if (path_startswith_strv(path, prefixes))
return true; return true;
} }
#else
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in");
#endif
} }
int fstab_is_mount_point_full(const char *where, const char *path) { int fstab_is_mount_point_full(const char *where, const char *path) {
#if HAVE_LIBMOUNT
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
int r; int r;
@ -184,6 +195,9 @@ int fstab_is_mount_point_full(const char *where, const char *path) {
if (r > 0 || (r < 0 && !ERRNO_IS_DEVICE_ABSENT(r))) if (r > 0 || (r < 0 && !ERRNO_IS_DEVICE_ABSENT(r)))
return r; return r;
} }
#else
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in");
#endif
} }
int fstab_filter_options( int fstab_filter_options(

View File

@ -41,7 +41,6 @@ DLSYM_PROTOTYPE(stringprep_ucs4_to_utf8) = NULL;
DLSYM_PROTOTYPE(stringprep_utf8_to_ucs4) = NULL; DLSYM_PROTOTYPE(stringprep_utf8_to_ucs4) = NULL;
int dlopen_idn(void) { int dlopen_idn(void) {
_cleanup_(dlclosep) void *dl = NULL;
int r; int r;
ELF_NOTE_DLOPEN("idn", ELF_NOTE_DLOPEN("idn",
@ -52,14 +51,21 @@ int dlopen_idn(void) {
if (idn_dl) if (idn_dl)
return 0; /* Already loaded */ return 0; /* Already loaded */
dl = dlopen("libidn.so.12", RTLD_NOW|RTLD_NODELETE); r = check_dlopen_blocked("libidn.so.12");
if (!dl) { if (r < 0)
return r;
_cleanup_(dlclosep) void *dl = NULL;
r = dlopen_safe("libidn.so.12", &dl, /* reterr_dlerror= */ NULL);
if (r < 0) {
/* libidn broke ABI in 1.34, but not in a way we care about (a new field got added to an /* libidn broke ABI in 1.34, but not in a way we care about (a new field got added to an
* open-coded struct we do not use), hence support both versions. */ * open-coded struct we do not use), hence support both versions. */
dl = dlopen("libidn.so.11", RTLD_NOW|RTLD_NODELETE); const char *dle = NULL;
if (!dl) r = dlopen_safe("libidn.so.11", &dl, &dle);
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), if (r < 0) {
"libidn support is not installed: %s", dlerror()); log_debug_errno(r, "libidn support is not available: %s", dle ?: STRERROR(r));
return -EOPNOTSUPP; /* turn into recognizable error */
}
log_debug("Loaded 'libidn.so.11' via dlopen()"); log_debug("Loaded 'libidn.so.11' via dlopen()");
} else } else
log_debug("Loaded 'libidn.so.12' via dlopen()"); log_debug("Loaded 'libidn.so.12' via dlopen()");

View File

@ -1,9 +1,11 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "libmount-util.h"
#if HAVE_LIBMOUNT
#include <stdio.h> #include <stdio.h>
#include "fstab-util.h" #include "fstab-util.h"
#include "libmount-util.h"
#include "log.h" #include "log.h"
static void *libmount_dl = NULL; static void *libmount_dl = NULL;
@ -39,8 +41,10 @@ DLSYM_PROTOTYPE(mnt_table_parse_mtab) = NULL;
DLSYM_PROTOTYPE(mnt_table_parse_stream) = NULL; DLSYM_PROTOTYPE(mnt_table_parse_stream) = NULL;
DLSYM_PROTOTYPE(mnt_table_parse_swaps) = NULL; DLSYM_PROTOTYPE(mnt_table_parse_swaps) = NULL;
DLSYM_PROTOTYPE(mnt_unref_monitor) = NULL; DLSYM_PROTOTYPE(mnt_unref_monitor) = NULL;
#endif
int dlopen_libmount(void) { int dlopen_libmount(void) {
#if HAVE_LIBMOUNT
ELF_NOTE_DLOPEN("mount", ELF_NOTE_DLOPEN("mount",
"Support for mount enumeration", "Support for mount enumeration",
ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED, ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED,
@ -81,8 +85,12 @@ int dlopen_libmount(void) {
DLSYM_ARG(mnt_table_parse_stream), DLSYM_ARG(mnt_table_parse_stream),
DLSYM_ARG(mnt_table_parse_swaps), DLSYM_ARG(mnt_table_parse_swaps),
DLSYM_ARG(mnt_unref_monitor)); DLSYM_ARG(mnt_unref_monitor));
#else
return -EOPNOTSUPP;
#endif
} }
#if HAVE_LIBMOUNT
int libmount_parse_full( int libmount_parse_full(
const char *path, const char *path,
FILE *source, FILE *source,
@ -151,3 +159,4 @@ int libmount_is_leaf(
return r == 1; return r == 1;
} }
#endif

View File

@ -1,11 +1,14 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once #pragma once
#include "shared-forward.h"
#if HAVE_LIBMOUNT
/* This needs to be after sys/mount.h */ /* This needs to be after sys/mount.h */
#include <libmount.h> /* IWYU pragma: export */ #include <libmount.h> /* IWYU pragma: export */
#include "dlfcn-util.h" #include "dlfcn-util.h"
#include "shared-forward.h"
extern DLSYM_PROTOTYPE(mnt_free_iter); extern DLSYM_PROTOTYPE(mnt_free_iter);
extern DLSYM_PROTOTYPE(mnt_free_table); extern DLSYM_PROTOTYPE(mnt_free_table);
@ -39,8 +42,6 @@ extern DLSYM_PROTOTYPE(mnt_table_parse_stream);
extern DLSYM_PROTOTYPE(mnt_table_parse_swaps); extern DLSYM_PROTOTYPE(mnt_table_parse_swaps);
extern DLSYM_PROTOTYPE(mnt_unref_monitor); extern DLSYM_PROTOTYPE(mnt_unref_monitor);
int dlopen_libmount(void);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(struct libmnt_table*, sym_mnt_free_table, mnt_free_tablep, NULL); DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(struct libmnt_table*, sym_mnt_free_table, mnt_free_tablep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(struct libmnt_iter*, sym_mnt_free_iter, mnt_free_iterp, NULL); DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(struct libmnt_iter*, sym_mnt_free_iter, mnt_free_iterp, NULL);
@ -55,14 +56,12 @@ static inline int libmount_parse_mountinfo(
FILE *source, FILE *source,
struct libmnt_table **ret_table, struct libmnt_table **ret_table,
struct libmnt_iter **ret_iter) { struct libmnt_iter **ret_iter) {
return libmount_parse_full("/proc/self/mountinfo", source, MNT_ITER_FORWARD, ret_table, ret_iter); return libmount_parse_full("/proc/self/mountinfo", source, MNT_ITER_FORWARD, ret_table, ret_iter);
} }
static inline int libmount_parse_with_utab( static inline int libmount_parse_with_utab(
struct libmnt_table **ret_table, struct libmnt_table **ret_table,
struct libmnt_iter **ret_iter) { struct libmnt_iter **ret_iter) {
return libmount_parse_full(NULL, NULL, MNT_ITER_FORWARD, ret_table, ret_iter); return libmount_parse_full(NULL, NULL, MNT_ITER_FORWARD, ret_table, ret_iter);
} }
@ -71,3 +70,15 @@ int libmount_parse_fstab(struct libmnt_table **ret_table, struct libmnt_iter **r
int libmount_is_leaf( int libmount_is_leaf(
struct libmnt_table *table, struct libmnt_table *table,
struct libmnt_fs *fs); struct libmnt_fs *fs);
#else
struct libmnt_monitor;
static inline void *sym_mnt_unref_monitor(struct libmnt_monitor *p) {
assert(p == NULL);
return NULL;
}
#endif
int dlopen_libmount(void);

View File

@ -38,6 +38,7 @@
#include "user-util.h" #include "user-util.h"
int umount_recursive_full(const char *prefix, int flags, char **keep) { int umount_recursive_full(const char *prefix, int flags, char **keep) {
#if HAVE_LIBMOUNT
_cleanup_fclose_ FILE *f = NULL; _cleanup_fclose_ FILE *f = NULL;
int n = 0, r; int n = 0, r;
@ -110,6 +111,9 @@ int umount_recursive_full(const char *prefix, int flags, char **keep) {
} }
return n; return n;
#else
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in");
#endif
} }
#define MS_CONVERTIBLE_FLAGS (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_NOSYMFOLLOW|MS_RELATIME|MS_NOATIME|MS_STRICTATIME|MS_NODIRATIME) #define MS_CONVERTIBLE_FLAGS (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_NOSYMFOLLOW|MS_RELATIME|MS_NOATIME|MS_STRICTATIME|MS_NODIRATIME)
@ -175,11 +179,6 @@ int bind_remount_recursive_with_mountinfo(
char **deny_list, char **deny_list,
FILE *proc_self_mountinfo) { FILE *proc_self_mountinfo) {
_cleanup_fclose_ FILE *proc_self_mountinfo_opened = NULL;
_cleanup_set_free_ Set *done = NULL;
unsigned n_tries = 0;
int r;
assert(prefix); assert(prefix);
if ((flags_mask & ~MS_CONVERTIBLE_FLAGS) == 0 && strv_isempty(deny_list) && !skip_mount_set_attr) { if ((flags_mask & ~MS_CONVERTIBLE_FLAGS) == 0 && strv_isempty(deny_list) && !skip_mount_set_attr) {
@ -206,6 +205,12 @@ int bind_remount_recursive_with_mountinfo(
return 0; /* Nice, this worked! */ return 0; /* Nice, this worked! */
} }
#if HAVE_LIBMOUNT
_cleanup_fclose_ FILE *proc_self_mountinfo_opened = NULL;
_cleanup_set_free_ Set *done = NULL;
unsigned n_tries = 0;
int r;
if (!proc_self_mountinfo) { if (!proc_self_mountinfo) {
r = fopen_unlocked("/proc/self/mountinfo", "re", &proc_self_mountinfo_opened); r = fopen_unlocked("/proc/self/mountinfo", "re", &proc_self_mountinfo_opened);
if (r < 0) if (r < 0)
@ -404,6 +409,9 @@ int bind_remount_recursive_with_mountinfo(
log_trace("Remounted %s.", x); log_trace("Remounted %s.", x);
} }
} }
#else
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in");
#endif
} }
int bind_remount_one_with_mountinfo( int bind_remount_one_with_mountinfo(
@ -412,12 +420,6 @@ int bind_remount_one_with_mountinfo(
unsigned long flags_mask, unsigned long flags_mask,
FILE *proc_self_mountinfo) { FILE *proc_self_mountinfo) {
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
unsigned long flags = 0;
struct libmnt_fs *fs;
const char *opts;
int r;
assert(path); assert(path);
assert(proc_self_mountinfo); assert(proc_self_mountinfo);
@ -438,6 +440,13 @@ int bind_remount_one_with_mountinfo(
return 0; /* Nice, this worked! */ return 0; /* Nice, this worked! */
} }
#if HAVE_LIBMOUNT
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
unsigned long flags = 0;
struct libmnt_fs *fs;
const char *opts;
int r;
rewind(proc_self_mountinfo); rewind(proc_self_mountinfo);
r = dlopen_libmount(); r = dlopen_libmount();
@ -481,6 +490,9 @@ int bind_remount_one_with_mountinfo(
} }
return 0; return 0;
#else
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in");
#endif
} }
int bind_remount_one(const char *path, unsigned long new_flags, unsigned long flags_mask) { int bind_remount_one(const char *path, unsigned long new_flags, unsigned long flags_mask) {
@ -859,6 +871,16 @@ int mount_option_mangle(
unsigned long *ret_mount_flags, unsigned long *ret_mount_flags,
char **ret_remaining_options) { char **ret_remaining_options) {
assert(ret_mount_flags);
assert(ret_remaining_options);
if (!options) {
*ret_mount_flags = mount_flags;
*ret_remaining_options = NULL;
return 0;
}
#if HAVE_LIBMOUNT
const struct libmnt_optmap *map; const struct libmnt_optmap *map;
_cleanup_free_ char *ret = NULL; _cleanup_free_ char *ret = NULL;
int r; int r;
@ -876,9 +898,6 @@ int mount_option_mangle(
* The validity of options stored in '*ret_remaining_options' is not checked. * The validity of options stored in '*ret_remaining_options' is not checked.
* If 'options' is NULL, this just copies 'mount_flags' to *ret_mount_flags. */ * If 'options' is NULL, this just copies 'mount_flags' to *ret_mount_flags. */
assert(ret_mount_flags);
assert(ret_remaining_options);
r = dlopen_libmount(); r = dlopen_libmount();
if (r < 0) if (r < 0)
return r; return r;
@ -922,6 +941,9 @@ int mount_option_mangle(
*ret_remaining_options = TAKE_PTR(ret); *ret_remaining_options = TAKE_PTR(ret);
return 0; return 0;
#else
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in");
#endif
} }
static int mount_in_namespace_legacy( static int mount_in_namespace_legacy(
@ -1640,6 +1662,7 @@ void sub_mount_array_free(SubMount *s, size_t n) {
free(s); free(s);
} }
#if HAVE_LIBMOUNT
static int sub_mount_compare(const SubMount *a, const SubMount *b) { static int sub_mount_compare(const SubMount *a, const SubMount *b) {
assert(a); assert(a);
assert(b); assert(b);
@ -1659,9 +1682,10 @@ static void sub_mount_drop(SubMount *s, size_t n) {
m = i; m = i;
} }
} }
#endif
int get_sub_mounts(const char *prefix, SubMount **ret_mounts, size_t *ret_n_mounts) { int get_sub_mounts(const char *prefix, SubMount **ret_mounts, size_t *ret_n_mounts) {
#if HAVE_LIBMOUNT
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
SubMount *mounts = NULL; SubMount *mounts = NULL;
@ -1738,6 +1762,9 @@ int get_sub_mounts(const char *prefix, SubMount **ret_mounts, size_t *ret_n_moun
*ret_mounts = TAKE_PTR(mounts); *ret_mounts = TAKE_PTR(mounts);
*ret_n_mounts = n; *ret_n_mounts = n;
return 0; return 0;
#else
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in");
#endif
} }
int bind_mount_submounts( int bind_mount_submounts(
@ -2015,6 +2042,7 @@ int path_get_mount_info_at(
char **ret_options, char **ret_options,
char **ret_source) { char **ret_source) {
#if HAVE_LIBMOUNT
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
int r, mnt_id; int r, mnt_id;
@ -2077,6 +2105,9 @@ int path_get_mount_info_at(
} }
return log_debug_errno(SYNTHETIC_ERRNO(ESTALE), "Cannot find mount ID %i from /proc/self/mountinfo.", mnt_id); return log_debug_errno(SYNTHETIC_ERRNO(ESTALE), "Cannot find mount ID %i from /proc/self/mountinfo.", mnt_id);
#else
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in");
#endif
} }
int path_is_network_fs_harder_at(int dir_fd, const char *path) { int path_is_network_fs_harder_at(int dir_fd, const char *path) {

View File

@ -1753,6 +1753,33 @@ int openssl_load_private_key(
return 0; return 0;
} }
int openssl_extract_public_key(EVP_PKEY *private_key, EVP_PKEY **ret) {
int r;
assert(private_key);
assert(ret);
_cleanup_(memstream_done) MemStream m = {};
FILE *tf = memstream_init(&m);
if (!tf)
return log_oom();
if (i2d_PUBKEY_fp(tf, private_key) != 1)
return -EIO;
_cleanup_(erase_and_freep) char *buf = NULL;
size_t len;
r = memstream_finalize(&m, &buf, &len);
if (r < 0)
return r;
const unsigned char *t = (unsigned char*) buf;
if (!d2i_PUBKEY(ret, &t, len))
return -EIO;
return 0;
}
#endif #endif
int parse_openssl_certificate_source_argument( int parse_openssl_certificate_source_argument(

View File

@ -195,6 +195,8 @@ int openssl_load_private_key(
EVP_PKEY **ret_private_key, EVP_PKEY **ret_private_key,
OpenSSLAskPasswordUI **ret_user_interface); OpenSSLAskPasswordUI **ret_user_interface);
int openssl_extract_public_key(EVP_PKEY *private_key, EVP_PKEY **ret);
struct OpenSSLAskPasswordUI { struct OpenSSLAskPasswordUI {
AskPasswordRequest request; AskPasswordRequest request;
#ifndef OPENSSL_NO_UI_CONSOLE #ifndef OPENSSL_NO_UI_CONSOLE

View File

@ -13,6 +13,7 @@
#include "dirent-util.h" #include "dirent-util.h"
#include "dlfcn-util.h" #include "dlfcn-util.h"
#include "efi-api.h" #include "efi-api.h"
#include "errno-util.h"
#include "extract-word.h" #include "extract-word.h"
#include "fd-util.h" #include "fd-util.h"
#include "fileio.h" #include "fileio.h"
@ -742,9 +743,12 @@ int tpm2_context_new(const char *device, Tpm2Context **ret_context) {
if (!filename_is_valid(fn)) if (!filename_is_valid(fn))
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 driver name '%s' not valid, refusing.", driver); return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 driver name '%s' not valid, refusing.", driver);
context->tcti_dl = dlopen(fn, RTLD_NOW|RTLD_NODELETE); const char *dle = NULL;
if (!context->tcti_dl) r = dlopen_safe(fn, &context->tcti_dl, &dle);
return log_debug_errno(SYNTHETIC_ERRNO(ENOPKG), "Failed to load %s: %s", fn, dlerror()); if (r < 0) {
log_debug_errno(r, "Failed to load %s: %s", fn, dle ?: STRERROR(r));
return -ENOPKG; /* Turn into recognizable error */
}
log_debug("Loaded '%s' via dlopen()", fn); log_debug("Loaded '%s' via dlopen()", fn);

View File

@ -1977,21 +1977,22 @@ int membershipdb_by_group_strv(const char *name, UserDBFlags flags, char ***ret)
} }
int userdb_block_nss_systemd(int b) { int userdb_block_nss_systemd(int b) {
_cleanup_(dlclosep) void *dl = NULL; int r;
int (*call)(bool b);
/* Note that we might be called from libnss_systemd.so.2 itself, but that should be fine, really. */ /* Note that we might be called from libnss_systemd.so.2 itself, but that should be fine, really. */
dl = dlopen(LIBDIR "/libnss_systemd.so.2", RTLD_NOW|RTLD_NODELETE); _cleanup_(dlclosep) void *dl = NULL;
if (!dl) { const char *dle;
r = dlopen_safe(LIBDIR "/libnss_systemd.so.2", &dl, &dle);
if (r < 0) {
/* If the file isn't installed, don't complain loudly */ /* If the file isn't installed, don't complain loudly */
log_debug("Failed to dlopen(libnss_systemd.so.2), ignoring: %s", dlerror()); log_debug_errno(r, "Failed to dlopen(libnss_systemd.so.2), ignoring: %s", dle ?: STRERROR(r));
return 0; return 0;
} }
log_debug("Loaded '%s' via dlopen()", LIBDIR "/libnss_systemd.so.2"); log_debug("Loaded '%s' via dlopen()", LIBDIR "/libnss_systemd.so.2");
call = dlsym(dl, "_nss_systemd_block"); int (*call)(bool b) = dlsym(dl, "_nss_systemd_block");
if (!call) if (!call)
/* If the file is installed but lacks the symbol we expect, things are weird, let's complain */ /* If the file is installed but lacks the symbol we expect, things are weird, let's complain */
return log_debug_errno(SYNTHETIC_ERRNO(ELIBBAD), return log_debug_errno(SYNTHETIC_ERRNO(ELIBBAD),

View File

@ -1,5 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
if conf.get('HAVE_LIBMOUNT') != 1
subdir_done()
endif
systemd_shutdown_sources = files( systemd_shutdown_sources = files(
'detach-dm.c', 'detach-dm.c',
'detach-loopback.c', 'detach-loopback.c',

View File

@ -6,6 +6,11 @@ executables += [
'public' : true, 'public' : true,
'conditions' : ['ENABLE_SYSEXT'], 'conditions' : ['ENABLE_SYSEXT'],
'sources' : files('sysext.c'), 'sources' : files('sysext.c'),
'dependencies' : [
libblkid_cflags,
libcryptsetup_cflags,
libmount_cflags,
],
}, },
] ]

View File

@ -11,6 +11,7 @@
#include "sd-varlink.h" #include "sd-varlink.h"
#include "argv-util.h" #include "argv-util.h"
#include "blkid-util.h"
#include "blockdev-util.h" #include "blockdev-util.h"
#include "build.h" #include "build.h"
#include "bus-unit-util.h" #include "bus-unit-util.h"
@ -18,6 +19,7 @@
#include "capability-util.h" #include "capability-util.h"
#include "chase.h" #include "chase.h"
#include "conf-parser.h" #include "conf-parser.h"
#include "cryptsetup-util.h"
#include "devnum-util.h" #include "devnum-util.h"
#include "discover-image.h" #include "discover-image.h"
#include "dissect-image.h" #include "dissect-image.h"
@ -33,6 +35,7 @@
#include "image-policy.h" #include "image-policy.h"
#include "initrd-util.h" #include "initrd-util.h"
#include "label-util.h" /* IWYU pragma: keep */ #include "label-util.h" /* IWYU pragma: keep */
#include "libmount-util.h"
#include "log.h" #include "log.h"
#include "loop-util.h" #include "loop-util.h"
#include "main-func.h" #include "main-func.h"
@ -523,6 +526,8 @@ static int unmerge(
bool need_to_reload; bool need_to_reload;
int r; int r;
(void) dlopen_libmount();
r = need_reload(image_class, hierarchies, no_reload); r = need_reload(image_class, hierarchies, no_reload);
if (r < 0) if (r < 0)
return r; return r;
@ -2100,6 +2105,10 @@ static int merge(ImageClass image_class,
pid_t pid; pid_t pid;
int r; int r;
(void) dlopen_cryptsetup();
(void) dlopen_libblkid();
(void) dlopen_libmount();
r = safe_fork("(sd-merge)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_NEW_MOUNTNS, &pid); r = safe_fork("(sd-merge)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_NEW_MOUNTNS, &pid);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to fork off child: %m"); return log_error_errno(r, "Failed to fork off child: %m");

View File

@ -349,6 +349,7 @@ executables += [
}, },
test_template + { test_template + {
'sources' : files('test-libmount.c'), 'sources' : files('test-libmount.c'),
'conditions' : ['HAVE_LIBMOUNT'],
'dependencies' : [ 'dependencies' : [
libmount_cflags, libmount_cflags,
threads, threads,
@ -368,6 +369,7 @@ executables += [
}, },
test_template + { test_template + {
'sources' : files('test-mount-util.c'), 'sources' : files('test-mount-util.c'),
'conditions' : ['HAVE_LIBMOUNT'],
'dependencies' : libmount_cflags, 'dependencies' : libmount_cflags,
}, },
test_template + { test_template + {
@ -574,6 +576,7 @@ executables += [
'sources' : files('test-namespace.c'), 'sources' : files('test-namespace.c'),
'dependencies' : [ 'dependencies' : [
threads, threads,
libmount_cflags,
], ],
}, },
core_test_template + { core_test_template + {

View File

@ -54,7 +54,7 @@ static int run(int argc, char **argv) {
ASSERT_DLOPEN(dlopen_libblkid, HAVE_BLKID); ASSERT_DLOPEN(dlopen_libblkid, HAVE_BLKID);
ASSERT_DLOPEN(dlopen_libfido2, HAVE_LIBFIDO2); ASSERT_DLOPEN(dlopen_libfido2, HAVE_LIBFIDO2);
ASSERT_DLOPEN(dlopen_libkmod, HAVE_KMOD); ASSERT_DLOPEN(dlopen_libkmod, HAVE_KMOD);
ASSERT_DLOPEN(dlopen_libmount, true); ASSERT_DLOPEN(dlopen_libmount, HAVE_LIBMOUNT);
ASSERT_DLOPEN(dlopen_libpam, HAVE_PAM); ASSERT_DLOPEN(dlopen_libpam, HAVE_PAM);
ASSERT_DLOPEN(dlopen_libseccomp, HAVE_SECCOMP); ASSERT_DLOPEN(dlopen_libseccomp, HAVE_SECCOMP);
ASSERT_DLOPEN(dlopen_libselinux, HAVE_SELINUX); ASSERT_DLOPEN(dlopen_libselinux, HAVE_SELINUX);

View File

@ -3,6 +3,7 @@
#include <dlfcn.h> #include <dlfcn.h>
#include <stdlib.h> #include <stdlib.h>
#include "dlfcn-util.h"
#include "shared-forward.h" #include "shared-forward.h"
int main(int argc, char **argv) { int main(int argc, char **argv) {
@ -10,7 +11,7 @@ int main(int argc, char **argv) {
int i; int i;
for (i = 0; i < argc - 1; i++) for (i = 0; i < argc - 1; i++)
assert_se(handles[i] = dlopen(argv[i + 1], RTLD_NOW|RTLD_NODELETE)); assert_se(dlopen_safe(argv[i + 1], handles + i, /* reterr_dlerror= */ NULL) >= 0);
for (i--; i >= 0; i--) for (i--; i >= 0; i--)
assert_se(dlclose(handles[i]) == 0); assert_se(dlclose(handles[i]) == 0);

View File

@ -20,6 +20,7 @@
#include "fd-util.h" #include "fd-util.h"
#include "fileio.h" #include "fileio.h"
#include "fs-util.h" #include "fs-util.h"
#include "libmount-util.h"
#include "manager.h" #include "manager.h"
#include "mkdir.h" #include "mkdir.h"
#include "mount-util.h" #include "mount-util.h"
@ -1604,6 +1605,8 @@ TEST(run_tests_unprivileged) {
} }
static int intro(void) { static int intro(void) {
int r;
#if HAS_FEATURE_ADDRESS_SANITIZER #if HAS_FEATURE_ADDRESS_SANITIZER
if (strstr_ptr(ci_environment(), "travis") || strstr_ptr(ci_environment(), "github-actions")) if (strstr_ptr(ci_environment(), "travis") || strstr_ptr(ci_environment(), "github-actions"))
return log_tests_skipped("Running on Travis CI/GH Actions under ASan, see https://github.com/systemd/systemd/issues/10696"); return log_tests_skipped("Running on Travis CI/GH Actions under ASan, see https://github.com/systemd/systemd/issues/10696");
@ -1612,7 +1615,7 @@ static int intro(void) {
if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0)
return log_tests_skipped("not privileged"); return log_tests_skipped("not privileged");
if (running_in_chroot() > 0) if (running_in_chroot() != 0)
return log_tests_skipped("running in chroot"); return log_tests_skipped("running in chroot");
if (enter_cgroup_subroot(NULL) == -ENOMEDIUM) if (enter_cgroup_subroot(NULL) == -ENOMEDIUM)
@ -1621,6 +1624,10 @@ static int intro(void) {
if (path_is_read_only_fs("/sys") > 0) if (path_is_read_only_fs("/sys") > 0)
return log_tests_skipped("/sys is mounted read-only"); return log_tests_skipped("/sys is mounted read-only");
r = dlopen_libmount();
if (r < 0)
return log_tests_skipped("libmount not available.");
/* Create dummy network interface for testing PrivateNetwork=yes */ /* Create dummy network interface for testing PrivateNetwork=yes */
have_net_dummy = system("ip link add dummy-test-exec type dummy") == 0; have_net_dummy = system("ip link add dummy-test-exec type dummy") == 0;

View File

@ -240,7 +240,7 @@ static int run(int argc, char *argv[]) {
if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0)
return log_tests_skipped("not running privileged"); return log_tests_skipped("not running privileged");
if (detect_container() > 0 || running_in_chroot() > 0) if (detect_container() != 0 || running_in_chroot() != 0)
return log_tests_skipped("Test not supported in a container/chroot, requires udev/uevent notifications"); return log_tests_skipped("Test not supported in a container/chroot, requires udev/uevent notifications");
assert_se(loop_device_make(fd, O_RDWR, 0, UINT64_MAX, 0, LO_FLAGS_PARTSCAN, LOCK_EX, &loop) >= 0); assert_se(loop_device_make(fd, O_RDWR, 0, UINT64_MAX, 0, LO_FLAGS_PARTSCAN, LOCK_EX, &loop) >= 0);

View File

@ -38,7 +38,7 @@
#define CHECK_PRIV \ #define CHECK_PRIV \
if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) \ if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) \
return (void) log_tests_skipped("Not privileged"); \ return (void) log_tests_skipped("Not privileged"); \
if (running_in_chroot() > 0) \ if (running_in_chroot() != 0) \
return (void) log_tests_skipped("running in chroot"); return (void) log_tests_skipped("running in chroot");
TEST(mount_option_mangle) { TEST(mount_option_mangle) {

View File

@ -457,7 +457,7 @@ static int intro(void) {
/* let's move into our own mount namespace with all propagation from the host turned off, so /* let's move into our own mount namespace with all propagation from the host turned off, so
* that /proc/self/mountinfo is static and constant for the whole time our test runs. */ * that /proc/self/mountinfo is static and constant for the whole time our test runs. */
if (running_in_chroot() > 0) { if (running_in_chroot() != 0) {
/* We cannot remount file system with MS_PRIVATE when running in chroot. */ /* We cannot remount file system with MS_PRIVATE when running in chroot. */
log_notice("Running in chroot, proceeding in originating mount namespace."); log_notice("Running in chroot, proceeding in originating mount namespace.");
return EXIT_SUCCESS; return EXIT_SUCCESS;

View File

@ -14,6 +14,7 @@
#include "alloc-util.h" #include "alloc-util.h"
#include "fd-util.h" #include "fd-util.h"
#include "fileio.h" #include "fileio.h"
#include "libmount-util.h"
#include "namespace-util.h" #include "namespace-util.h"
#include "namespace.h" #include "namespace.h"
#include "pidref.h" #include "pidref.h"
@ -203,6 +204,7 @@ TEST(protect_kernel_logs) {
.root_directory_fd = -EBADF, .root_directory_fd = -EBADF,
}; };
pid_t pid; pid_t pid;
int r;
if (geteuid() > 0) { if (geteuid() > 0) {
(void) log_tests_skipped("not root"); (void) log_tests_skipped("not root");
@ -215,6 +217,13 @@ TEST(protect_kernel_logs) {
return; return;
} }
r = dlopen_libmount();
if (ERRNO_IS_NEG_NOT_SUPPORTED(r)) {
(void) log_tests_skipped("libmount support not compiled in");
return;
}
ASSERT_OK(r);
pid = fork(); pid = fork();
ASSERT_OK_ERRNO(pid); ASSERT_OK_ERRNO(pid);

View File

@ -47,9 +47,9 @@ TEST(rereadpt) {
if (detect_container() > 0) if (detect_container() > 0)
return (void) log_tests_skipped("test not available in container"); return (void) log_tests_skipped("test not available in container");
if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) if (have_effective_cap(CAP_SYS_ADMIN) <= 0)
return (void) log_tests_skipped("test requires privileges"); return (void) log_tests_skipped("test requires privileges");
if (running_in_chroot() > 0) if (running_in_chroot() != 0)
return (void) log_tests_skipped("test not available in chroot()"); return (void) log_tests_skipped("test not available in chroot()");
_cleanup_free_ char *sfdisk_path = NULL; _cleanup_free_ char *sfdisk_path = NULL;
@ -75,7 +75,7 @@ TEST(rereadpt) {
if (ERRNO_IS_NEG_PRIVILEGE(r) || ERRNO_IS_NOT_SUPPORTED(r)) if (ERRNO_IS_NEG_PRIVILEGE(r) || ERRNO_IS_NOT_SUPPORTED(r))
return (void) log_tests_skipped("loopback block devices not available"); return (void) log_tests_skipped("loopback block devices not available");
if (r < 0) if (r < 0)
return (void) log_error_errno(r, "Failed to create loop device: %m"); return (void) log_tests_skipped_errno(r, "Failed to create loop device");
_cleanup_free_ char *p = NULL; _cleanup_free_ char *p = NULL;
ASSERT_OK(partition_node_of(loop->node, 1, &p)); ASSERT_OK(partition_node_of(loop->node, 1, &p));
@ -97,11 +97,12 @@ TEST(rereadpt) {
ASSERT_OK_ZERO_ERRNO(access(p, F_OK)); ASSERT_OK_ZERO_ERRNO(access(p, F_OK));
_cleanup_close_ int pfd = open(p, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); _cleanup_close_ int pfd = -EBADF;
ASSERT_OK_ERRNO(pfd); ASSERT_OK_ERRNO(pfd = open(p, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY));
uint64_t size; uint64_t size;
ASSERT_OK(blockdev_get_device_size(pfd, &size)); ASSERT_OK(blockdev_get_device_size(pfd, &size));
ASSERT_EQ(size, 20U*1024U*1024U); ASSERT_EQ(size, 20U*1024U*1024U);
pfd = safe_close(pfd);
/* No change */ /* No change */
ASSERT_OK(reread_partition_table_fd(loop->fd, /* flags= */ 0)); ASSERT_OK(reread_partition_table_fd(loop->fd, /* flags= */ 0));
@ -122,11 +123,14 @@ TEST(rereadpt) {
ASSERT_OK(reread_partition_table_fd(loop->fd, /* flags= */ 0)); ASSERT_OK(reread_partition_table_fd(loop->fd, /* flags= */ 0));
ASSERT_OK_ZERO_ERRNO(access(p, F_OK)); ASSERT_OK_ZERO_ERRNO(access(p, F_OK));
ASSERT_OK_ERRNO(pfd = open(p, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY));
ASSERT_OK(blockdev_get_device_size(pfd, &size)); ASSERT_OK(blockdev_get_device_size(pfd, &size));
ASSERT_EQ(size, 30U*1024U*1024U); ASSERT_EQ(size, 30U*1024U*1024U);
pfd = safe_close(pfd);
/* No change */ /* No change */
ASSERT_OK(reread_partition_table_fd(loop->fd, /* flags= */ 0)); ASSERT_OK(reread_partition_table_fd(loop->fd, /* flags= */ 0));
ASSERT_OK_ERRNO(pfd = open(p, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY));
/* Move */ /* Move */
log_notice("MOVING BY 50M"); log_notice("MOVING BY 50M");
@ -137,19 +141,19 @@ TEST(rereadpt) {
ASSERT_OK_ZERO_ERRNO(access(p, F_OK)); ASSERT_OK_ZERO_ERRNO(access(p, F_OK));
ASSERT_ERROR(reread_partition_table_fd(loop->fd, /* flags= */ 0), EBUSY); ASSERT_ERROR(reread_partition_table_fd(loop->fd, /* flags= */ 0), EBUSY);
pfd = safe_close(pfd);
ASSERT_OK_ZERO_ERRNO(access(p, F_OK)); ASSERT_OK_ZERO_ERRNO(access(p, F_OK));
safe_close(pfd);
ASSERT_OK(reread_partition_table_fd(loop->fd, /* flags= */ 0)); ASSERT_OK(reread_partition_table_fd(loop->fd, /* flags= */ 0));
pfd = open(p, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); pfd = ASSERT_OK_ERRNO(open(p, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY));
ASSERT_OK_ERRNO(pfd);
ASSERT_OK(blockdev_get_device_size(pfd, &size)); ASSERT_OK(blockdev_get_device_size(pfd, &size));
ASSERT_EQ(size, 15U*1024U*1024U); ASSERT_EQ(size, 15U*1024U*1024U);
pfd = safe_close(pfd);
/* No change */ /* No change */
ASSERT_OK(reread_partition_table_fd(loop->fd, /* flags= */ 0)); ASSERT_OK(reread_partition_table_fd(loop->fd, /* flags= */ 0));
pfd = ASSERT_OK_ERRNO(open(p, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY));
/* Remove */ /* Remove */
log_notice("REMOVING"); log_notice("REMOVING");
@ -159,9 +163,9 @@ TEST(rereadpt) {
ASSERT_OK_ZERO_ERRNO(access(p, F_OK)); ASSERT_OK_ZERO_ERRNO(access(p, F_OK));
ASSERT_ERROR(reread_partition_table_fd(loop->fd, /* flags= */ 0), EBUSY); ASSERT_ERROR(reread_partition_table_fd(loop->fd, /* flags= */ 0), EBUSY);
pfd = safe_close(pfd);
ASSERT_OK_ZERO_ERRNO(access(p, F_OK)); ASSERT_OK_ZERO_ERRNO(access(p, F_OK));
pfd = safe_close(pfd);
ASSERT_OK(reread_partition_table_fd(loop->fd, /* flags= */ 0)); ASSERT_OK(reread_partition_table_fd(loop->fd, /* flags= */ 0));
ASSERT_ERROR_ERRNO(access(p, F_OK), ENOENT); ASSERT_ERROR_ERRNO(access(p, F_OK), ENOENT);
} }

View File

@ -116,7 +116,8 @@ endif
udev_dependencies = [ udev_dependencies = [
libacl_cflags, libacl_cflags,
libblkid_cflags, libblkid_cflags,
libkmod, libkmod_cflags,
libmount_cflags,
threads, threads,
] ]

View File

@ -8,10 +8,14 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include "acl-util.h"
#include "blkid-util.h"
#include "errno-util.h" #include "errno-util.h"
#include "fd-util.h" #include "fd-util.h"
#include "label-util.h" #include "label-util.h"
#include "libmount-util.h"
#include "log.h" #include "log.h"
#include "module-util.h"
#include "process-util.h" #include "process-util.h"
#include "rlimit-util.h" #include "rlimit-util.h"
#include "terminal-util.h" #include "terminal-util.h"
@ -52,6 +56,12 @@ int run_udevd(int argc, char *argv[]) {
if (r < 0 && r != -EEXIST) if (r < 0 && r != -EEXIST)
return log_error_errno(r, "Failed to create /run/udev: %m"); return log_error_errno(r, "Failed to create /run/udev: %m");
/* Load some shared libraries before we fork any workers */
(void) dlopen_libacl();
(void) dlopen_libblkid();
(void) dlopen_libkmod();
(void) dlopen_libmount();
if (arg_daemonize) { if (arg_daemonize) {
pid_t pid; pid_t pid;

View File

@ -108,7 +108,7 @@ endif
############################################################ ############################################################
test_compare_versions_sh = files('test-compare-versions.sh') test_compare_versions_sh = files('test-compare-versions.sh')
if want_tests != 'false' if want_tests != 'false' and executables_by_name.has_key('systemd-analyze')
exe = executables_by_name.get('systemd-analyze') exe = executables_by_name.get('systemd-analyze')
test('test-compare-versions', test('test-compare-versions',
test_compare_versions_sh, test_compare_versions_sh,
@ -151,7 +151,7 @@ endif
############################################################ ############################################################
test_fstab_generator_sh = files('test-fstab-generator.sh') test_fstab_generator_sh = files('test-fstab-generator.sh')
if want_tests != 'false' if want_tests != 'false' and executables_by_name.has_key('systemd-fstab-generator')
exe = executables_by_name.get('systemd-fstab-generator') exe = executables_by_name.get('systemd-fstab-generator')
test('test-fstab-generator', test('test-fstab-generator',
test_fstab_generator_sh, test_fstab_generator_sh,

View File

@ -1533,130 +1533,4 @@ testcase_cap_net_bind_service() {
rm -fr "$root" rm -fr "$root"
} }
testcase_link_journal_directory() {
# Test that journal symlinks point to the persistent path
# for --directory.
local root machine_id journal_path symlink_target
root="$(mktemp -d /var/lib/machines/TEST-13-NSPAWN.journal-persist.XXX)"
create_dummy_container "$root"
machine_id="$(systemd-id128 new)"
echo "$machine_id" >"$root/etc/machine-id"
journal_path="/var/log/journal/$machine_id"
mkdir -p "$journal_path"
# Run container with journal linking
systemd-nspawn --register=no \
--directory="$root" \
--link-journal=try-guest \
bash -c "exit 0"
# Verify the symlink was created and is not broken
test -L "$journal_path"
test -e "$journal_path"
# Verify the symlink points to the persistent path (e.g., /var/lib/machines/...)
# NOT to a temporary /tmp/nspawn-root-* path
symlink_target="$(readlink -f "$journal_path")"
[[ "$symlink_target" == "$root"* ]]
[[ "$symlink_target" != /tmp/nspawn-root-* ]]
rm -f "$journal_path"
rm -fr "$root"
}
testcase_link_journal_image() {
# Test that journal symlinks point to the persistent path
# for --image.
local root machine_id journal_path symlink_target image mnt_dir
local machine_name="test-journal-image"
local persistent_dir="/var/lib/machines/$machine_name"
root="$(mktemp -d /var/lib/machines/TEST-13-NSPAWN.journal-image-root.XXX)"
image="$(mktemp /var/lib/machines/TEST-13-NSPAWN.journal-image.XXX.img)"
mnt_dir="$(mktemp -d)"
mkdir -p "$persistent_dir"
create_dummy_container "$root"
dd if=/dev/zero of="$image" bs=1M count=256 status=none
mkfs.ext4 -q "$image"
mount -o loop "$image" "$mnt_dir"
cp -r "$root"/* "$mnt_dir/"
machine_id="$(systemd-id128 new)"
echo "$machine_id" >"$mnt_dir/etc/machine-id"
umount "$mnt_dir"
journal_path="/var/log/journal/$machine_id"
mkdir -p "$journal_path"
# Run container with journal linking
systemd-nspawn --register=no \
--image="$image" \
--machine="$machine_name" \
--link-journal=try-guest \
bash -c "exit 0"
# Verify the symlink was created and points to the persistent directory.
# Note: We don't check that the target exists, as journald hasn't run in this test
# to create the directory structure - that's journald's responsibility, not nspawn's.
test -L "$journal_path"
symlink_target="$(readlink "$journal_path")"
[[ "$symlink_target" == "$persistent_dir"* ]]
rm -f "$journal_path"
rm -f "$image"
rm -fr "$root"
rm -fr "$mnt_dir"
rm -fr "$persistent_dir"
}
testcase_link_journal_ephemeral() {
# Test that journal symlinks are NOT created for --ephemeral.
local root machine_id journal_path
root="$(mktemp -d /var/lib/machines/TEST-13-NSPAWN.journal-ephemeral.XXX)"
create_dummy_container "$root"
machine_id="$(systemd-id128 new)"
echo "$machine_id" >"$root/etc/machine-id"
journal_path="/var/log/journal/$machine_id"
# Run ephemeral container with journal linking
systemd-nspawn --register=no \
--directory="$root" \
--ephemeral \
--link-journal=try-guest \
bash -c "exit 0"
# Verify the symlink was NOT created, as per existing logic
test ! -e "$journal_path"
rm -fr "$root"
}
testcase_link_journal_negative() {
# Test that no symlink is created when --link-journal is not used.
local root machine_id journal_path
root="$(mktemp -d /var/lib/machines/TEST-13-NSPAWN.journal-no-link.XXX)"
create_dummy_container "$root"
machine_id="$(systemd-id128 new)"
echo "$machine_id" >"$root/etc/machine-id"
journal_path="/var/log/journal/$machine_id"
# Run container WITHOUT journal linking
systemd-nspawn --register=no \
--directory="$root" \
bash -c "exit 0"
# Verify the symlink was NOT created
test ! -e "$journal_path"
rm -fr "$root"
}
run_testcases run_testcases

View File

@ -331,8 +331,8 @@ def main():
print(item, file=sys.stderr) print(item, file=sys.stderr)
sys.exit(77 if arguments.test else 1) sys.exit(77 if arguments.test else 1)
if not os.path.exists(f'{arguments.build_dir}/systemd'): if not os.path.exists(f'{arguments.build_dir}'):
sys.exit(f"{arguments.build_dir}/systemd doesn't exist. Use --build-dir=.") sys.exit(f"{arguments.build_dir} doesn't exist.")
missing_version = [] missing_version = []
stats = {page.split('/')[-1] : process(page, missing_version) for page in arguments.pages} stats = {page.split('/')[-1] : process(page, missing_version) for page in arguments.pages}