diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-09-16 18:18:34 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-09-16 18:18:34 +0000 |
commit | 67497cedb2f732b3445ecdc0d09b881f9c69f852 (patch) | |
tree | b7197679acca419c7ddc0300873e19141d5fae3e | |
parent | Adding debian version 256.1-2. (diff) | |
download | systemd-67497cedb2f732b3445ecdc0d09b881f9c69f852.tar.xz systemd-67497cedb2f732b3445ecdc0d09b881f9c69f852.zip |
Merging upstream version 256.2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
117 files changed, 1775 insertions, 1315 deletions
diff --git a/.github/labeler.yml b/.github/labeler.yml index 24ff2f0..5782c66 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -15,7 +15,7 @@ btrfs: - any-glob-to-any-file: '**/*btrfs*' build-system: - changed-files: - - any-glob-to-any-file: ['meson_options.txt', '**/meson.build', 'Makefile', 'configure'] + - any-glob-to-any-file: ['meson_options.txt', '**/meson.build'] busctl: - changed-files: - any-glob-to-any-file: '**/*busctl*' @@ -75,10 +75,10 @@ meson: - any-glob-to-any-file: ['meson_options.txt', '**/meson.build'] mkosi: - changed-files: - - any-glob-to-any-file: ['.mkosi/*', 'mkosi.build'] + - any-glob-to-any-file: '**/*mkosi*' mountfsd: - changed-files: - - any-glob-to-any-file: ['src/mountfsd/*'] + - any-glob-to-any-file: 'src/mountfsd/*' network: - changed-files: - any-glob-to-any-file: ['src/libsystemd-network/**/*', 'src/network/**/*'] diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 241b581..57e8c89 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -35,7 +35,7 @@ jobs: - name: Label PR based on policy in labeler.yml uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 - if: startsWith(github.event_name, 'pull_request') && github.event.action != 'closed' + if: startsWith(github.event_name, 'pull_request') && github.base_ref == 'main' && github.event.action != 'closed' with: repo-token: "${{ secrets.GITHUB_TOKEN }}" configuration-path: .github/labeler.yml diff --git a/.github/workflows/mkosi.yml b/.github/workflows/mkosi.yml index 3a8dabd..1b2f77c 100644 --- a/.github/workflows/mkosi.yml +++ b/.github/workflows/mkosi.yml @@ -92,7 +92,7 @@ jobs: steps: - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - - uses: systemd/mkosi@6972f9efba5c8472d990be3783b7e7dbf76e109e + - uses: systemd/mkosi@70aa901697f12182ccaa24e2325867d275479b55 # Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space # immediately, we remove the files in the background. However, we first move them to a different location diff --git a/.semaphore/semaphore-runner.sh b/.semaphore/semaphore-runner.sh index 755de22..bc0cb6a 100755 --- a/.semaphore/semaphore-runner.sh +++ b/.semaphore/semaphore-runner.sh @@ -8,7 +8,7 @@ set -o pipefail DISTRO="${DISTRO:-debian}" RELEASE="${RELEASE:-bookworm}" SALSA_URL="${SALSA_URL:-https://salsa.debian.org/systemd-team/systemd.git}" -BRANCH="${BRANCH:-debian/master}" +BRANCH="${BRANCH:-ci/v256-stable}" ARCH="${ARCH:-amd64}" CONTAINER="${RELEASE}-${ARCH}" CACHE_DIR="${SEMAPHORE_CACHE_DIR:-/tmp}" diff --git a/LICENSES/README.md b/LICENSES/README.md index ea21baf..76fd437 100644 --- a/LICENSES/README.md +++ b/LICENSES/README.md @@ -13,7 +13,14 @@ The 'LICENSES/' directory contains all the licenses used by the sources included the systemd project source tree. Unless otherwise noted, the systemd project sources are licensed under the terms -and conditions of the **GNU Lesser General Public License v2.1 or later**. +and conditions of +**LGPL-2.1-or-later** (**GNU Lesser General Public License v2.1 or later**). + +Unless otherwise noted, compiled programs and all shared or static libraries +include sources under **LGPL-2.1-or-later** along with more permissive +licenses, and are effectively licensed **LGPL-2.1-or-later**. +systemd-udevd and other udev helper programs also include sources under +**GPL-2.0-or-later**, and are effectively licensed **GPL-2.0-or-later**. New sources that cannot be distributed under LGPL-2.1-or-later will no longer be accepted for inclusion in the systemd project to maintain license uniformity. @@ -22,8 +29,9 @@ be accepted for inclusion in the systemd project to maintain license uniformity. The following exceptions apply: - * some udev sources under src/udev/ are licensed under **GPL-2.0-or-later**, so the - udev binaries as a whole are also distributed under **GPL-2.0-or-later**. + * some sources under src/udev/ are licensed under **GPL-2.0-or-later**, + so all udev programs (`systemd-udevd`, `udevadm`, and the udev builtins + and test programs) are also distributed under **GPL-2.0-or-later**. * the header files contained in src/basic/linux/ and src/shared/linux/ are copied verbatim from the Linux kernel source tree and are licensed under **GPL-2.0 WITH Linux-syscall-note** and are used within the scope of the Linux-syscall-note @@ -130,9 +130,10 @@ REQUIREMENTS: Required for signed Verity images support: CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG - Required to verify signed Verity images using keys enrolled in the MoK - (Machine-Owner Key) keyring: + Required to verify signed Verity images using keys enrolled in the MOK + (Machine-Owner Key) and DB UEFI certificate stores: CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING + CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_PLATFORM_KEYRING CONFIG_IMA_ARCH_POLICY CONFIG_INTEGRITY_MACHINE_KEYRING @@ -168,6 +169,7 @@ REQUIREMENTS: Required for systemd-oomd: CONFIG_PSI + CONFIG_MEMCG Note that kernel auditing is broken when used with systemd's container code. When using systemd in conjunction with containers, please make diff --git a/docs/CODING_STYLE.md b/docs/CODING_STYLE.md index 309436a..82ed0a5 100644 --- a/docs/CODING_STYLE.md +++ b/docs/CODING_STYLE.md @@ -54,6 +54,18 @@ SPDX-License-Identifier: LGPL-2.1-or-later } ``` +- Function return types should be seen/written as whole, i.e. write this: + + ```c + const char* foo(const char *input); + ``` + + instead of this: + + ```c + const char *foo(const char *input); + ``` + - Single-line `if` blocks should not be enclosed in `{}`. Write this: ```c @@ -182,7 +194,7 @@ SPDX-License-Identifier: LGPL-2.1-or-later ```c static int foobar_frobnicate( - Foobar* object, /* the associated mutable object */ + Foobar *object, /* the associated mutable object */ const char *input, /* immutable input parameter */ char **ret_frobnicated, /* return parameter on success */ unsigned *reterr_line, /* return parameter on failure */ diff --git a/docs/ENVIRONMENT.md b/docs/ENVIRONMENT.md index fd8aa0c..b661f18 100644 --- a/docs/ENVIRONMENT.md +++ b/docs/ENVIRONMENT.md @@ -713,3 +713,7 @@ Tools using the Varlink protocol (such as `varlinkctl`) or sd-bus (such as and `run0` invocations is turned off. Note that this environment variable has no effect if the background color is explicitly selected via the relevant `--background=` switch of the tool. + +* `$SYSTEMD_ADJUST_TERMINAL_TITLE` – Takes a boolean. When false the terminal + window title will not be updated for interactive invocation of the mentioned + tools. diff --git a/docs/HACKING.md b/docs/HACKING.md index 51499d7..5b1e355 100644 --- a/docs/HACKING.md +++ b/docs/HACKING.md @@ -45,27 +45,10 @@ or: $ mkosi qemu ``` -Every time you rerun the `mkosi` command a fresh image is built, -incorporating all current changes you made to the project tree. - -By default a directory image is built. -This requires `virtiofsd` to be installed on the host. -To build a disk image instead which does not require `virtiofsd`, add the following to `mkosi.local.conf`: - -```conf -[Output] -Format=disk -``` - -To boot in UEFI mode instead of using QEMU's direct kernel boot, add the following to `mkosi.local.conf`: - -```conf -[Host] -QemuFirmware=uefi -``` - -To avoid having to build a new image all the time when iterating on a patch, -add the following to `mkosi.local.conf`: +Every time you rerun the `mkosi` command a fresh image is built, incorporating +all current changes you made to the project tree. To avoid having to build a new +image all the time when iterating on a patch, add the following to +`mkosi.local.conf`: ```conf [Host] @@ -74,31 +57,21 @@ RuntimeBuildSources=yes After enabling this setting, the source and build directories will be mounted to `/work/src` and `/work/build` respectively when booting the image as a container -or virtual machine. To build the latest changes and re-install, run -`meson install -C /work/build --only-changed` in the container or virtual machine -and optionally restart the daemon(s) you're working on using -`systemctl restart <units>` or `systemctl daemon-reexec` if you're working on pid1 -or `systemctl soft-reboot` to restart everything. - -Aside from the image, the `mkosi.output` directory will also be populated with a -set of distribution packages. Assuming you're running the same distribution and -release as the mkosi image, you can install these rpms on your host or test -system as well for any testing or debugging that cannot easily be performed in a -VM or container. - -By default, no debuginfo packages are produced. To produce debuginfo packages, -run mkosi with the `WITH_DEBUG` environment variable set to `1`: +or virtual machine. To build the latest changes and re-install after booting the +image, run `mkosi -t none` in another terminal on the host and run one of the +following commands in the container or virtual machine depending on the +distribution: ```sh -$ mkosi -E WITH_DEBUG=1 -f +dnf upgrade --disablerepo="*" /work/build/*.rpm # CentOS/Fedora +apt install --reinstall /work/build/*.deb # Debian/Ubuntu +pacman -U /work/build/*.pkg.tar # Arch Linux +zypper install --allow-unsigned-rpm /work/build/*.rpm # OpenSUSE ``` -or configure it in `mkosi.local.conf`: - -```conf -[Content] -Environment=WITH_DEBUG=1 -``` +and optionally restart the daemon(s) you're working on using +`systemctl restart <units>` or `systemctl daemon-reexec` if you're working on +pid1 or `systemctl soft-reboot` to restart everything. Putting this all together, here's a series of commands for preparing a patch for systemd: @@ -110,6 +83,7 @@ $ cd systemd $ git checkout -b <BRANCH> # where BRANCH is the name of the branch $ vim src/core/main.c # or wherever you'd like to make your changes $ mkosi -f qemu # (re-)build and boot up the test image in qemu +$ mkosi -t none # Build new packages without rebuilding the image $ git add -p # interactively put together your patch $ git commit # commit it $ git push -u <REMOTE> # where REMOTE is your "fork" on GitHub @@ -142,6 +116,50 @@ $ meson test -C build Happy hacking! +## Building distribution packages with mkosi + +To build distribution packages for a specific distribution and release without +building an actual image, the following command can be used: + +```sh +mkosi -d <distribution> -r <release> -t none -f +``` + +Afterwards the distribution packages will be located in `build/mkosi.output`. To +also build debuginfo packages, the following command can be used: + +```sh +mkosi -d <distribution> -r <release> -E WITH_DEBUG=1 -t none -f +``` + +To upgrade the systemd packages on the host system to the newer versions built +by mkosi, run the following: + +```sh +dnf upgrade build/mkosi.output/*.rpm # Fedora/CentOS +# TODO: Other distributions +``` + +To downgrade back to the old version shipped by the distribution, run the +following: + +```sh +dnf downgrade "systemd*" # Fedora/CentOS +# TODO: Other distributions +``` + +Additionally, for each pull request, the built distribution packages are +attached as CI artifacts to the pull request CI jobs, which means that users can +download and install them to test out if a pull request fixes the issue that +they reported. To download the packages from a pull request, click on the +`Checks` tab. Then click on the `mkosi` workflow in the list of workflows on the +left of the `Checks` page. Finally, scroll down to find the list of CI +artifacts. In this list of artifacts you can find artifacts containing +distribution packages. To install these, download the artifact which is a zip +archive, extract the zip archive to access the individual packages, and install +them with your package manager in the same way as described above for packages +that were built locally. + ## Templating engines in .in files Some source files are generated during build. We use two templating engines: diff --git a/docs/MEMORY_PRESSURE.md b/docs/MEMORY_PRESSURE.md index da1c9b2..532f894 100644 --- a/docs/MEMORY_PRESSURE.md +++ b/docs/MEMORY_PRESSURE.md @@ -227,7 +227,7 @@ handling, it's typically sufficient to add a line such as: Other programming environments might have native APIs to watch memory pressure/low memory events. Most notable is probably GLib's -[GMemoryMonitor](https://developer-old.gnome.org/gio/stable/GMemoryMonitor.html). It +[GMemoryMonitor](https://docs.gtk.org/gio/iface.MemoryMonitor.html). It currently uses the per-system Linux PSI interface as the backend, but operates differently than the above: memory pressure events are picked up by a system service, which then propagates this through D-Bus to the applications. This is diff --git a/docs/RELEASE.md b/docs/RELEASE.md index f299c62..0d8c0b9 100644 --- a/docs/RELEASE.md +++ b/docs/RELEASE.md @@ -23,8 +23,7 @@ SPDX-License-Identifier: LGPL-2.1-or-later 14. "Draft" a new release on github (https://github.com/systemd/systemd/releases/new), mark "This is a pre-release" if appropriate. 15. Check that announcement to systemd-devel, with a copy&paste from NEWS, was sent. This should happen automatically. 16. Update IRC topic (`/msg chanserv TOPIC #systemd Version NNN released | Online resources https://systemd.io/`) -17. [FINAL] Push commits to stable, create an empty -stable branch: `git push systemd-stable --atomic origin/main:main origin/main:refs/heads/${version}-stable`. +17. [FINAL] Create an empty -stable branch: `git push systemd origin/main:refs/heads/v${version}-stable`. 18. [FINAL] Build and upload the documentation (on the -stable branch): `ninja -C build doc-sync` -19. [FINAL] Change the default branch to latest release (https://github.com/systemd/systemd-stable/settings/branches). -20. [FINAL] Change the Github Pages branch in the stable repository to the newly created branch (https://github.com/systemd/systemd-stable/settings/pages) and set the 'Custom domain' to 'systemd.io' +20. [FINAL] Change the Github Pages branch to the newly created branch (https://github.com/systemd/systemd/settings/pages) and set the 'Custom domain' to 'systemd.io' 21. [FINAL] Update version number in `meson.version` to the devel version of the next release (e.g. from `v256` to `v257~devel`) diff --git a/man/capsule@.service.xml b/man/capsule@.service.xml index aa5b1bb..f9c5455 100644 --- a/man/capsule@.service.xml +++ b/man/capsule@.service.xml @@ -41,7 +41,7 @@ <listitem><para>The capsule service manager utilizes <varname>DynamicUser=</varname> (see <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>) to allocate a new UID dynamically on invocation. The user name is automatically generated from the capsule - name, by prefixng <literal>p_</literal>. The UID is released when the service is terminated. The user + name, by prefixing <literal>c-</literal>. The UID is released when the service is terminated. The user service manager on the other hand operates under a statically allocated user ID that must be pre-existing, before the user service manager is invoked.</para></listitem> diff --git a/man/file-hierarchy.xml b/man/file-hierarchy.xml index 02841a7..04dfbe4 100644 --- a/man/file-hierarchy.xml +++ b/man/file-hierarchy.xml @@ -48,93 +48,63 @@ <variablelist> <varlistentry> <term><filename>/</filename></term> - <listitem><para>The file system root. Usually writable, but - this is not required. Possibly a temporary file system - (<literal>tmpfs</literal>). Not shared with other hosts - (unless read-only). </para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + <listitem><para>The file system root. Usually writable, but this is not required. Possibly a + temporary file system (<literal>tmpfs</literal>). Not shared with other hosts (unless + read-only).</para></listitem> </varlistentry> <varlistentry> <term><filename>/boot/</filename></term> - <listitem><para>The boot partition used for bringing up the - system. On EFI systems, this is possibly the EFI System - Partition (ESP), also see + <listitem><para>The boot partition used for bringing up the system. On EFI systems, this is possibly + the EFI System Partition (ESP), also see <citerefentry><refentrytitle>systemd-gpt-auto-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>. - This directory is usually strictly local to the host, and - should be considered read-only, except when a new kernel or - boot loader is installed. This directory only exists on - systems that run on physical or emulated hardware that - requires boot loaders.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + This directory is usually strictly local to the host, and should be considered read-only, except when + a new kernel or boot loader is installed. This directory only exists on systems that run on physical + or emulated hardware that requires boot loaders.</para></listitem> </varlistentry> <varlistentry> <term><filename>/efi/</filename></term> - <listitem><para>If the boot partition <filename>/boot/</filename> is maintained separately from the EFI System - Partition (ESP), the latter is mounted here. Tools that need to operate on the EFI system partition should look - for it at this mount point first, and fall back to <filename>/boot/</filename> — if the former doesn't qualify - (for example if it is not a mount point or does not have the correct file system type - <constant>MSDOS_SUPER_MAGIC</constant>).</para> - - <xi:include href="version-info.xml" xpointer="v239"/></listitem> + <listitem><para>If the boot partition <filename>/boot/</filename> is maintained separately from the + EFI System Partition (ESP), the latter is mounted here. Tools that need to operate on the EFI system + partition should look for it at this mount point first, and fall back to <filename>/boot/</filename> + — if the former doesn't qualify (for example if it is not a mount point or does not have the correct + file system type <constant>MSDOS_SUPER_MAGIC</constant>).</para></listitem> </varlistentry> <varlistentry> <term><filename>/etc/</filename></term> - <listitem><para>System-specific configuration. This directory - may or may not be read-only. Frequently, this directory is - pre-populated with vendor-supplied configuration files, but - applications should not make assumptions about this directory - being fully populated or populated at all, and should fall - back to defaults if configuration is - missing.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + <listitem><para>System-specific configuration. This directory may or may not be + read-only. Frequently, this directory is pre-populated with vendor-supplied configuration files, but + applications should not make assumptions about this directory being fully populated or populated at + all, and should fall back to defaults if configuration is missing.</para></listitem> </varlistentry> <varlistentry> <term><filename>/home/</filename></term> - <listitem><para>The location for normal user's home - directories. Possibly shared with other systems, and never - read-only. This directory should only be used for normal - users, never for system users. This directory and possibly the - directories contained within it might only become available or - writable in late boot or even only after user authentication. - This directory might be placed on limited-functionality - network file systems, hence applications should not assume the - full set of file API is available on this directory. - Applications should generally not reference this directory - directly, but via the per-user <varname>$HOME</varname> - environment variable, or via the home directory field of the - user database.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + <listitem><para>The location for normal user's home directories. Possibly shared with other systems, + and never read-only. This directory should only be used for normal users, never for system + users. This directory and possibly the directories contained within it might only become available or + writable in late boot or even only after user authentication. This directory might be placed on + limited-functionality network file systems, hence applications should not assume the full set of file + API is available on this directory. Applications should generally not reference this directory + directly, but via the per-user <varname>$HOME</varname> environment variable, or via the home + directory field of the user database.</para></listitem> </varlistentry> <varlistentry> <term><filename>/root/</filename></term> - <listitem><para>The home directory of the root user. The root - user's home directory is located outside of - <filename>/home/</filename> in order to make sure the root user - may log in even without <filename>/home/</filename> being - available and mounted.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + <listitem><para>The home directory of the root user. The root user's home directory is located + outside of <filename>/home/</filename> in order to make sure the root user may log in even without + <filename>/home/</filename> being available and mounted.</para></listitem> </varlistentry> <varlistentry> <term><filename>/srv/</filename></term> - <listitem><para>The place to store general server payload, - managed by the administrator. No restrictions are made how - this directory is organized internally. Generally writable, - and possibly shared among systems. This directory might become - available or writable only very late during - boot.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + <listitem><para>The place to store general server payload, managed by the administrator. No + restrictions are made how this directory is organized internally. Generally writable, and possibly + shared among systems. This directory might become available or writable only very late during + boot.</para></listitem> </varlistentry> <varlistentry> @@ -156,10 +126,7 @@ <citerefentry project='man-pages'><refentrytitle>mkdtemp</refentrytitle><manvolnum>3</manvolnum></citerefentry>, and similar calls. For more details, see <ulink url="https://systemd.io/TEMPORARY_DIRECTORIES">Using - /tmp/ and /var/tmp/ Safely</ulink>.</para> - - <xi:include href="version-info.xml" xpointer="v215"/> - </listitem> + /tmp/ and /var/tmp/ Safely</ulink>.</para></listitem> </varlistentry> </variablelist> @@ -173,34 +140,24 @@ <term><filename>/run/</filename></term> <listitem><para>A <literal>tmpfs</literal> file system for system packages to place runtime data, socket files, and similar. This directory is flushed on boot, and generally writable for privileged - programs only. Always writable.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + programs only. Always writable.</para></listitem> </varlistentry> <varlistentry> <term><filename>/run/log/</filename></term> - <listitem><para>Runtime system logs. System components may - place private logs in this directory. Always writable, even - when <filename>/var/log/</filename> might not be accessible - yet.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + <listitem><para>Runtime system logs. System components may place private logs in this + directory. Always writable, even when <filename>/var/log/</filename> might not be accessible + yet.</para></listitem> </varlistentry> <varlistentry> <term><filename>/run/user/</filename></term> - <listitem><para>Contains per-user runtime directories, each - usually individually mounted <literal>tmpfs</literal> - instances. Always writable, flushed at each reboot and when - the user logs out. User code should not reference this - directory directly, but via the - <varname>$XDG_RUNTIME_DIR</varname> environment variable, as - documented in the <ulink - url="https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html">XDG - Base Directory Specification</ulink>.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + <listitem><para>Contains per-user runtime directories, each usually individually mounted + <literal>tmpfs</literal> instances. Always writable, flushed at each reboot and when the user logs + out. User code should not reference this directory directly, but via the + <varname>$XDG_RUNTIME_DIR</varname> environment variable, as documented in the <ulink + url="https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html">XDG Base Directory + Specification</ulink>.</para></listitem> </varlistentry> </variablelist> </refsect1> @@ -212,99 +169,68 @@ <varlistentry> <term><filename>/usr/</filename></term> - <listitem><para>Vendor-supplied operating system resources. - Usually read-only, but this is not required. Possibly shared - between multiple hosts. This directory should not be modified - by the administrator, except when installing or removing - vendor-supplied packages.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + <listitem><para>Vendor-supplied operating system resources. Usually read-only, but this is not + required. Possibly shared between multiple hosts. This directory should not be modified by the + administrator, except when installing or removing vendor-supplied packages.</para></listitem> </varlistentry> <varlistentry> <term><filename>/usr/bin/</filename></term> - <listitem><para>Binaries and executables for user commands - that shall appear in the <varname>$PATH</varname> search path. - It is recommended not to place binaries in this directory that - are not useful for invocation from a shell (such as daemon - binaries); these should be placed in a subdirectory of - <filename>/usr/lib/</filename> instead.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + <listitem><para>Binaries and executables for user commands that shall appear in the + <varname>$PATH</varname> search path. It is recommended not to place binaries in this directory that + are not useful for invocation from a shell (such as daemon binaries); these should be placed in a + subdirectory of <filename>/usr/lib/</filename> instead.</para></listitem> </varlistentry> <varlistentry> <term><filename>/usr/include/</filename></term> - <listitem><para>C and C++ API header files of system - libraries.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + <listitem><para>C and C++ API header files of system libraries.</para></listitem> </varlistentry> <varlistentry> <term><filename>/usr/lib/</filename></term> - <listitem><para>Static, private vendor data that is compatible - with all architectures (though not necessarily - architecture-independent). Note that this includes internal - executables or other binaries that are not regularly invoked - from a shell. Such binaries may be for any architecture - supported by the system. Do not place public libraries in this - directory, use <varname>$libdir</varname> (see below), - instead.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + <listitem><para>Static, private vendor data that is compatible with all architectures (though not + necessarily architecture-independent). Note that this includes internal executables or other binaries + that are not regularly invoked from a shell. Such binaries may be for any architecture supported by + the system. Do not place public libraries in this directory, use <varname>$libdir</varname> (see + below), instead.</para></listitem> </varlistentry> <varlistentry> <term><filename>/usr/lib/<replaceable>arch-id</replaceable>/</filename></term> - <listitem><para>Location for placing dynamic libraries into, also - called <varname>$libdir</varname>. The architecture identifier - to use is defined on <ulink - url="https://wiki.debian.org/Multiarch/Tuples">Multiarch - Architecture Specifiers (Tuples)</ulink> list. Legacy - locations of <varname>$libdir</varname> are - <filename>/usr/lib/</filename>, - <filename>/usr/lib64/</filename>. This directory should not be - used for package-specific data, unless this data is - architecture-dependent, too. To query - <varname>$libdir</varname> for the primary architecture of the - system, invoke: - <programlisting># systemd-path system-library-arch</programlisting></para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> - + <listitem><para>Location for placing dynamic libraries into, also called + <varname>$libdir</varname>. The architecture identifier to use is defined on <ulink + url="https://wiki.debian.org/Multiarch/Tuples">Multiarch Architecture Specifiers (Tuples)</ulink> + list. Legacy locations of <varname>$libdir</varname> are <filename>/usr/lib/</filename>, + <filename>/usr/lib64/</filename>. This directory should not be used for package-specific data, unless + this data is architecture-dependent, too. To query <varname>$libdir</varname> for the primary + architecture of the system, invoke: <programlisting># systemd-path + system-library-arch</programlisting></para></listitem> </varlistentry> <varlistentry> <term><filename>/usr/share/</filename></term> - <listitem><para>Resources shared between multiple packages, - such as documentation, man pages, time zone information, fonts - and other resources. Usually, the precise location and format - of files stored below this directory is subject to - specifications that ensure interoperability.</para> + <listitem><para>Resources shared between multiple packages, such as documentation, man pages, time + zone information, fonts and other resources. Usually, the precise location and format of files stored + below this directory is subject to specifications that ensure interoperability.</para> - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + <para>Note that resources placed in this directory typically are under shared ownership, + i.e. multiple different packages have provide and consume these resources, on equal footing, without + any obvious primary owner. This makes makes things systematically different from + <filename>/usr/lib/</filename>, where ownership is generally not shared.</para></listitem> </varlistentry> <varlistentry> <term><filename>/usr/share/doc/</filename></term> - <listitem><para>Documentation for the operating system or - system packages.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + <listitem><para>Documentation for the operating system or system packages.</para></listitem> </varlistentry> <varlistentry> <term><filename>/usr/share/factory/etc/</filename></term> - <listitem><para>Repository for vendor-supplied default - configuration files. This directory should be populated with - pristine vendor versions of all configuration files that may - be placed in <filename>/etc/</filename>. This is useful to - compare the local configuration of a system with vendor - defaults and to populate the local configuration with - defaults.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + <listitem><para>Repository for vendor-supplied default configuration files. This directory should be + populated with pristine vendor versions of all configuration files that may be placed in + <filename>/etc/</filename>. This is useful to compare the local configuration of a system with vendor + defaults and to populate the local configuration with defaults.</para></listitem> </varlistentry> <varlistentry> @@ -313,10 +239,7 @@ <listitem><para>Similar to <filename>/usr/share/factory/etc/</filename>, but for vendor versions of files in the variable, persistent data directory - <filename>/var/</filename>.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> - + <filename>/var/</filename>.</para></listitem> </varlistentry> </variablelist> </refsect1> @@ -333,49 +256,34 @@ system might start up without this directory being populated. Persistency is recommended, but optional, to support ephemeral systems. This directory might become available or writable only very late during boot. Components that are required to operate during early boot hence shall not - unconditionally rely on this directory.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + unconditionally rely on this directory.</para></listitem> </varlistentry> <varlistentry> <term><filename>/var/cache/</filename></term> - <listitem><para>Persistent system cache data. System - components may place non-essential data in this directory. - Flushing this directory should have no effect on operation of - programs, except for increased runtimes necessary to rebuild - these caches.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + <listitem><para>Persistent system cache data. System components may place non-essential data in this + directory. Flushing this directory should have no effect on operation of programs, except for + increased runtimes necessary to rebuild these caches.</para></listitem> </varlistentry> <varlistentry> <term><filename>/var/lib/</filename></term> - <listitem><para>Persistent system data. System components may - place private data in this directory.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + <listitem><para>Persistent system data. System components may place private data in this + directory.</para></listitem> </varlistentry> <varlistentry> <term><filename>/var/log/</filename></term> - <listitem><para>Persistent system logs. System components may - place private logs in this directory, though it is recommended - to do most logging via the - <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry> - and + <listitem><para>Persistent system logs. System components may place private logs in this directory, + though it is recommended to do most logging via the <citerefentry + project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry> and <citerefentry><refentrytitle>sd_journal_print</refentrytitle><manvolnum>3</manvolnum></citerefentry> - calls.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + calls.</para></listitem> </varlistentry> <varlistentry> <term><filename>/var/spool/</filename></term> - <listitem><para>Persistent system spool data, such as printer - or mail queues.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + <listitem><para>Persistent system spool data, such as printer or mail queues.</para></listitem> </varlistentry> <varlistentry> @@ -396,10 +304,8 @@ <citerefentry project='man-pages'><refentrytitle>mkdtemp</refentrytitle><manvolnum>3</manvolnum></citerefentry>, and similar calls should be used. For further details about this directory, see <ulink - url="https://systemd.io/TEMPORARY_DIRECTORIES">Using /tmp/ and /var/tmp/ Safely</ulink>.</para> - - <xi:include href="version-info.xml" xpointer="v215"/> - </listitem> + url="https://systemd.io/TEMPORARY_DIRECTORIES">Using /tmp/ and /var/tmp/ + Safely</ulink>.</para></listitem> </varlistentry> </variablelist> @@ -411,97 +317,67 @@ <variablelist> <varlistentry> <term><filename>/dev/</filename></term> - <listitem><para>The root directory for device nodes. Usually, - this directory is mounted as a <literal>devtmpfs</literal> - instance, but might be of a different type in - sandboxed/containerized setups. This directory is managed - jointly by the kernel and + <listitem><para>The root directory for device nodes. Usually, this directory is mounted as a + <literal>devtmpfs</literal> instance, but might be of a different type in sandboxed/containerized + setups. This directory is managed jointly by the kernel and <citerefentry><refentrytitle>systemd-udevd</refentrytitle><manvolnum>8</manvolnum></citerefentry>, - and should not be written to by other components. A number of - special purpose virtual file systems might be mounted below - this directory.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + and should not be written to by other components. A number of special purpose virtual file systems + might be mounted below this directory.</para></listitem> </varlistentry> <varlistentry> <term><filename>/dev/shm/</filename></term> - <listitem><para>Place for POSIX shared memory segments, as - created via - <citerefentry project='die-net'><refentrytitle>shm_open</refentrytitle><manvolnum>3</manvolnum></citerefentry>. - This directory is flushed on boot, and is a - <literal>tmpfs</literal> file system. Since all users have - write access to this directory, special care should be taken - to avoid name clashes and vulnerabilities. For normal users, - shared memory segments in this directory are usually deleted - when the user logs out. Usually, it is a better idea to use - memory mapped files in <filename>/run/</filename> (for system - programs) or <varname>$XDG_RUNTIME_DIR</varname> (for user - programs) instead of POSIX shared memory segments, since these - directories are not world-writable and hence not vulnerable to - security-sensitive name clashes.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + <listitem><para>Place for POSIX shared memory segments, as created via <citerefentry + project='die-net'><refentrytitle>shm_open</refentrytitle><manvolnum>3</manvolnum></citerefentry>. + This directory is flushed on boot, and is a <literal>tmpfs</literal> file system. Since all users + have write access to this directory, special care should be taken to avoid name clashes and + vulnerabilities. For normal users, shared memory segments in this directory are usually deleted when + the user logs out. Usually, it is a better idea to use memory mapped files in + <filename>/run/</filename> (for system programs) or <varname>$XDG_RUNTIME_DIR</varname> (for user + programs) instead of POSIX shared memory segments, since these directories are not world-writable and + hence not vulnerable to security-sensitive name clashes.</para></listitem> </varlistentry> <varlistentry> <term><filename>/proc/</filename></term> - <listitem><para>A virtual kernel file system exposing the - process list and other functionality. This file system is - mostly an API to interface with the kernel and not a place - where normal files may be stored. For details, see - <citerefentry project='man-pages'><refentrytitle>proc</refentrytitle><manvolnum>5</manvolnum></citerefentry>. - A number of special purpose virtual file systems might be - mounted below this directory.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + <listitem><para>A virtual kernel file system exposing the process list and other functionality. This + file system is mostly an API to interface with the kernel and not a place where normal files may be + stored. For details, see <citerefentry + project='man-pages'><refentrytitle>proc</refentrytitle><manvolnum>5</manvolnum></citerefentry>. A + number of special purpose virtual file systems might be mounted below this + directory.</para></listitem> </varlistentry> <varlistentry> <term><filename>/proc/sys/</filename></term> - <listitem><para>A hierarchy below <filename>/proc/</filename> - that exposes a number of kernel tunables. The primary way to - configure the settings in this API file tree is via + <listitem><para>A hierarchy below <filename>/proc/</filename> that exposes a number of kernel + tunables. The primary way to configure the settings in this API file tree is via <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry> - files. In sandboxed/containerized setups, this directory is - generally mounted read-only.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + files. In sandboxed/containerized setups, this directory is generally mounted + read-only.</para></listitem> </varlistentry> <varlistentry> <term><filename>/sys/</filename></term> - <listitem><para>A virtual kernel file system exposing - discovered devices and other functionality. This file system - is mostly an API to interface with the kernel and not a place - where normal files may be stored. In sandboxed/containerized - setups, this directory is generally mounted read-only. A number - of special purpose virtual file systems might be mounted below - this directory.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + <listitem><para>A virtual kernel file system exposing discovered devices and other + functionality. This file system is mostly an API to interface with the kernel and not a place where + normal files may be stored. In sandboxed/containerized setups, this directory is generally mounted + read-only. A number of special purpose virtual file systems might be mounted below this + directory.</para></listitem> </varlistentry> <varlistentry> <term><filename>/sys/fs/cgroup/</filename></term> - <listitem><para>A virtual kernel file system exposing process - control groups (cgroups). This file system is an API to interface - with the kernel and not a place where normal files may be stored. On - current systems running in the default "unified" mode, - this directory serves as the mount point for the - <literal>cgroup2</literal> filesystem, which provides a unified - cgroup hierarchy for all resource controllers. On systems with - non-default configurations, this directory may instead be a tmpfs - filesystem containing mount points for various - <literal>cgroup</literal> (v1) resource controllers; in such - configurations, if <literal>cgroup2</literal> is mounted it will be - mounted on <filename>/sys/fs/cgroup/unified/</filename>, but - cgroup2 will not have resource controllers attached. In - sandboxed/containerized setups, this directory may either not exist or - may include a subset of functionality. - </para> - - <xi:include href="version-info.xml" xpointer="v251"/></listitem> + <listitem><para>A virtual kernel file system exposing process control groups (cgroups). This file + system is an API to interface with the kernel and not a place where normal files may be stored. On + current systems running in the default "unified" mode, this directory serves as the mount point for + the <literal>cgroup2</literal> filesystem, which provides a unified cgroup hierarchy for all resource + controllers. On systems with non-default configurations, this directory may instead be a tmpfs + filesystem containing mount points for various <literal>cgroup</literal> (v1) resource controllers; + in such configurations, if <literal>cgroup2</literal> is mounted it will be mounted on + <filename>/sys/fs/cgroup/unified/</filename>, but cgroup2 will not have resource controllers + attached. In sandboxed/containerized setups, this directory may either not exist or may include a + subset of functionality.</para></listitem> </varlistentry> </variablelist> </refsect1> @@ -515,47 +391,31 @@ <term><filename>/sbin/</filename></term> <term><filename>/usr/sbin/</filename></term> - <listitem><para>These compatibility symlinks point to - <filename>/usr/bin/</filename>, ensuring that scripts and - binaries referencing these legacy paths correctly find their - binaries.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + <listitem><para>These compatibility symlinks point to <filename>/usr/bin/</filename>, ensuring that + scripts and binaries referencing these legacy paths correctly find their binaries.</para></listitem> </varlistentry> <varlistentry> <term><filename>/lib/</filename></term> - <listitem><para>This compatibility symlink points to - <filename>/usr/lib/</filename>, ensuring that programs - referencing this legacy path correctly find their - resources.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + <listitem><para>This compatibility symlink points to <filename>/usr/lib/</filename>, ensuring that + programs referencing this legacy path correctly find their resources.</para></listitem> </varlistentry> <varlistentry> <term><filename>/lib64/</filename></term> - <listitem><para>On some architecture ABIs, this compatibility - symlink points to <varname>$libdir</varname>, ensuring that - binaries referencing this legacy path correctly find their - dynamic loader. This symlink only exists on architectures - whose ABI places the dynamic loader in this - path.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + <listitem><para>On some architecture ABIs, this compatibility symlink points to + <varname>$libdir</varname>, ensuring that binaries referencing this legacy path correctly find their + dynamic loader. This symlink only exists on architectures whose ABI places the dynamic loader in this + path.</para></listitem> </varlistentry> <varlistentry> <term><filename>/var/run/</filename></term> - <listitem><para>This compatibility symlink points to - <filename>/run/</filename>, ensuring that programs referencing - this legacy path correctly find their runtime - data.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + <listitem><para>This compatibility symlink points to <filename>/run/</filename>, ensuring that + programs referencing this legacy path correctly find their runtime data.</para></listitem> </varlistentry> </variablelist> @@ -581,9 +441,7 @@ directory. Flushing this directory should have no effect on operation of programs, except for increased runtimes necessary to rebuild these caches. If an application finds <varname>$XDG_CACHE_HOME</varname> set, it should use the directory specified in it instead of this - directory.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + directory.</para></listitem> </varlistentry> <varlistentry> @@ -592,9 +450,7 @@ <listitem><para>Application configuration. When a new user is created, this directory will be empty or not exist at all. Applications should fall back to defaults should their configuration in this directory be missing. If an application finds <varname>$XDG_CONFIG_HOME</varname> set, it should use - the directory specified in it instead of this directory.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + the directory specified in it instead of this directory.</para></listitem> </varlistentry> <varlistentry> @@ -605,18 +461,14 @@ shell; these should be placed in a subdirectory of <filename>~/.local/lib/</filename> instead. Care should be taken when placing architecture-dependent binaries in this place, which might be problematic if the home directory is shared between multiple hosts with different - architectures.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + architectures.</para></listitem> </varlistentry> <varlistentry> <term><filename>~/.local/lib/</filename></term> <listitem><para>Static, private vendor data that is compatible with all - architectures.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + architectures.</para></listitem> </varlistentry> <varlistentry> @@ -624,9 +476,7 @@ <listitem><para>Location for placing public dynamic libraries. The architecture identifier to use is defined on <ulink url="https://wiki.debian.org/Multiarch/Tuples">Multiarch Architecture Specifiers - (Tuples)</ulink> list.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + (Tuples)</ulink> list.</para></listitem> </varlistentry> <varlistentry> @@ -635,9 +485,7 @@ <listitem><para>Resources shared between multiple packages, such as fonts or artwork. Usually, the precise location and format of files stored below this directory is subject to specifications that ensure interoperability. If an application finds <varname>$XDG_DATA_HOME</varname> set, it should use - the directory specified in it instead of this directory.</para> - - <xi:include href="version-info.xml" xpointer="v215"/></listitem> + the directory specified in it instead of this directory.</para></listitem> </varlistentry> <varlistentry> @@ -646,9 +494,7 @@ <listitem><para>Application state. When a new user is created, this directory will be empty or not exist at all. Applications should fall back to defaults should their state in this directory be missing. If an application finds <varname>$XDG_STATE_HOME</varname> set, it should use the directory - specified in it instead of this directory.</para> - - <xi:include href="version-info.xml" xpointer="v254"/></listitem> + specified in it instead of this directory.</para></listitem> </varlistentry> </variablelist> @@ -777,9 +623,9 @@ </tgroup> </table> - <para>Additional static vendor files may be installed in the - <filename>/usr/share/</filename> hierarchy to the locations - defined by the various relevant specifications.</para> + <para>Additional static vendor files with shared ownership may be installed in the + <filename>/usr/share/</filename> hierarchy to the locations defined by the various relevant + specifications.</para> <para>The following directories shall be used by the package for local configuration and files created during runtime:</para> @@ -869,9 +715,9 @@ </tgroup> </table> - <para>Additional static vendor files may be installed in the <filename>~/.local/share/</filename> - hierarchy, mirroring the subdirectories specified in the section "Vendor-supplied operating system - resources" above.</para> + <para>Additional static vendor files with shared ownership may be installed in the + <filename>~/.local/share/</filename> hierarchy, mirroring the subdirectories specified in the section + "Vendor-supplied operating system resources" above.</para> <para>The following directories shall be used by the package for per-user local configuration and files created during runtime:</para> @@ -890,7 +736,7 @@ <tbody> <row> <entry><filename>~/.config/<replaceable>package</replaceable>/</filename></entry> - <entry>User-specific configuration and state for the package. It is required to default to safe fallbacks if this configuration is missing.</entry> + <entry>User-specific configuration for the package. It is required to default to safe fallbacks if this configuration is missing.</entry> </row> <row> <entry><filename><varname>$XDG_RUNTIME_DIR</varname>/<replaceable>package</replaceable>/</filename></entry> @@ -900,6 +746,10 @@ <entry><filename>~/.cache/<replaceable>package</replaceable>/</filename></entry> <entry>Persistent cache data of the package. If this directory is flushed, the application should work correctly on next invocation, though possibly slowed down due to the need to rebuild any local cache files. The application must be capable of recreating this directory should it be missing and necessary.</entry> </row> + <row> + <entry><filename>~/.local/state/<replaceable>package</replaceable>/</filename></entry> + <entry>Persistent state data of the package.</entry> + </row> </tbody> </tgroup> </table> diff --git a/man/kernel-install.xml b/man/kernel-install.xml index 54c254e..f3468bb 100644 --- a/man/kernel-install.xml +++ b/man/kernel-install.xml @@ -18,7 +18,7 @@ <refnamediv> <refname>kernel-install</refname> - <refpurpose>Add and remove kernel and initrd images to and from /boot</refpurpose> + <refpurpose>Add and remove kernel and initrd images to and from the boot partition</refpurpose> </refnamediv> <refsynopsisdiv> @@ -64,9 +64,9 @@ <citerefentry><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry> for an explanation.</para> </footnote> - to and from the boot loader partition, referred to as <varname>$BOOT</varname> here. It will usually be - one of <filename>/boot/</filename>, <filename>/efi/</filename>, or <filename>/boot/efi/</filename>, see - below.</para> + to and from the boot partition, referred to as <varname>$BOOT</varname> here. It will usually be one of + <filename>/boot/</filename>, <filename>/efi/</filename>, or <filename>/boot/efi/</filename>, see below. + </para> <para><command>kernel-install</command> will run the executable files ("plugins") located in the directory <filename>/usr/lib/kernel/install.d/</filename> and the local administration directory diff --git a/man/machine-id.xml b/man/machine-id.xml index 4ee100b..b142d2f 100644 --- a/man/machine-id.xml +++ b/man/machine-id.xml @@ -124,7 +124,7 @@ are as follows:</para> <orderedlist> - <listitem><para>The kernel command argument <varname>systemd.condition-first-boot=</varname> may be + <listitem><para>The kernel command argument <varname>systemd.condition_first_boot=</varname> may be used to override the autodetection logic, see <citerefentry><refentrytitle>kernel-command-line</refentrytitle><manvolnum>7</manvolnum></citerefentry>. </para></listitem> diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml index 2a494b9..e744a4c 100644 --- a/man/systemd-tmpfiles.xml +++ b/man/systemd-tmpfiles.xml @@ -169,7 +169,7 @@ <para>It is recommended to first run this command in combination with <option>--dry-run</option> (see below) to verify which files and directories will be deleted.</para> - <para><emphasis>Warning!</emphasis> This is is usually not the command you want! In most cases + <para><emphasis>Warning!</emphasis> This is usually not the command you want! In most cases <option>--remove</option> is what you are looking for.</para> <xi:include href="version-info.xml" xpointer="v256"/></listitem> diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 56eb6af..21527f7 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -2021,8 +2021,9 @@ BindReadOnlyPaths=/var/lib/systemd</programlisting> <filename>/proc/sys/</filename>, <filename>/sys/</filename>, <filename>/proc/sysrq-trigger</filename>, <filename>/proc/latency_stats</filename>, <filename>/proc/acpi</filename>, <filename>/proc/timer_stats</filename>, <filename>/proc/fs</filename> and <filename>/proc/irq</filename> will - be made read-only to all processes of the unit. Usually, tunable kernel variables should be initialized only at - boot-time, for example with the + be made read-only and <filename>/proc/kallsyms</filename> as well as <filename>/proc/kcore</filename> will be + inaccessible to all processes of the unit. + Usually, tunable kernel variables should be initialized only at boot-time, for example with the <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry> mechanism. Few services need to write to these at runtime; it is hence recommended to turn this on for most services. For this setting the same restrictions regarding mount propagation and privileges apply as for diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml index c897068..e0baf38 100644 --- a/man/tmpfiles.d.xml +++ b/man/tmpfiles.d.xml @@ -306,7 +306,7 @@ L /tmp/foobar - - - - /dev/null</programlisting> argument is omitted, symlinks to files with the same name residing in the directory <filename>/usr/share/factory/</filename> are created. Note - that permissions and ownership on symlinks are ignored. + that permissions on symlinks are ignored. </para></listitem> </varlistentry> @@ -588,8 +588,8 @@ w- /proc/sys/vm/swappiness - - - - 10</programlisting></para> <citerefentry><refentrytitle>systemd-tmpfiles</refentrytitle><manvolnum>8</manvolnum></citerefentry> is used. For <varname>z</varname> and <varname>Z</varname> lines, when omitted or when set to <literal>-</literal>, the file ownership will not be modified. These parameters are ignored for - <varname>x</varname>, <varname>r</varname>, <varname>R</varname>, <varname>L</varname>, - <varname>t</varname>, and <varname>a</varname> lines.</para> + <varname>x</varname>, <varname>r</varname>, <varname>R</varname>, <varname>t</varname>, + and <varname>a</varname> lines.</para> <para>This field should generally only reference system users/groups, i.e. users/groups that are guaranteed to be resolvable during early boot. If this field references users/groups that only become diff --git a/meson.build b/meson.build index e421519..b1a110c 100644 --- a/meson.build +++ b/meson.build @@ -13,12 +13,19 @@ project('systemd', 'c', meson_version : '>= 0.60.0', ) +project_major_version = meson.project_version().split('.')[0].split('~')[0] +if meson.project_version().contains('.') + project_minor_version = meson.project_version().split('.')[-1].split('~')[0] +else + project_minor_version = '0' +endif + libsystemd_version = '0.39.0' libudev_version = '1.7.9' conf = configuration_data() conf.set_quoted('PROJECT_URL', 'https://systemd.io/') -conf.set('PROJECT_VERSION', meson.project_version().split('~')[0], +conf.set('PROJECT_VERSION', project_major_version, description : 'Numerical project version (used where a simple number is expected)') conf.set_quoted('PROJECT_VERSION_FULL', meson.project_version(), description : 'Full project version') @@ -547,6 +554,7 @@ decl_headers = ''' #include <uchar.h> #include <sys/mount.h> #include <sys/stat.h> +#include <sched.h> ''' foreach decl : ['char16_t', @@ -554,6 +562,7 @@ foreach decl : ['char16_t', 'struct mount_attr', 'struct statx', 'struct dirent64', + 'struct sched_attr', ] # We get -1 if the size cannot be determined @@ -601,6 +610,7 @@ foreach ident : [ #include <unistd.h>'''], # no known header declares pivot_root ['ioprio_get', '''#include <sched.h>'''], # no known header declares ioprio_get ['ioprio_set', '''#include <sched.h>'''], # no known header declares ioprio_set + ['sched_setattr', '''#include <sched.h>'''], # no known header declares sched_setattr ['name_to_handle_at', '''#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>'''], @@ -1740,6 +1750,7 @@ if conf.get('BPF_FRAMEWORK') == 1 '-ffile-prefix-map=', '-fdebug-prefix-map=', '-fmacro-prefix-map=', + '--sysroot=', ] foreach opt : c_args @@ -1759,15 +1770,15 @@ if conf.get('BPF_FRAMEWORK') == 1 # C.f. https://mesonbuild.com/Reference-tables.html#cpu-families # and src/basic/missing_syscall_def.h. cpu_arch_defines = { - 'ppc' : ['-D__powerpc__'], - 'ppc64' : ['-D__powerpc64__', '-D_CALL_ELF=2'], - 'riscv32' : ['-D__riscv', '-D__riscv_xlen=32'], - 'riscv64' : ['-D__riscv', '-D__riscv_xlen=64'], - 'x86' : ['-D__i386__'], - 's390x' : ['-D__s390__', '-D__s390x__'], + 'ppc' : ['-D__powerpc__', '-D__TARGET_ARCH_powerpc'], + 'ppc64' : ['-D__powerpc64__', '-D__TARGET_ARCH_powerpc', '-D_CALL_ELF=2'], + 'riscv32' : ['-D__riscv', '-D__riscv_xlen=32', '-D__TARGET_ARCH_riscv'], + 'riscv64' : ['-D__riscv', '-D__riscv_xlen=64', '-D__TARGET_ARCH_riscv'], + 'x86' : ['-D__i386__', '-D__TARGET_ARCH_x86'], + 's390x' : ['-D__s390__', '-D__s390x__', '-D__TARGET_ARCH_s390'], # For arm, assume hardware fp is available. - 'arm' : ['-D__arm__', '-D__ARM_PCS_VFP'], + 'arm' : ['-D__arm__', '-D__ARM_PCS_VFP', '-D__TARGET_ARCH_arm'], } bpf_arch_flags = cpu_arch_defines.get(host_machine.cpu_family(), @@ -1993,7 +2004,7 @@ version_h = vcs_tag( shared_lib_tag = get_option('shared-lib-tag') if shared_lib_tag == '' - shared_lib_tag = meson.project_version().split('~')[0] + shared_lib_tag = project_major_version endif ##################################################################### @@ -2754,17 +2765,11 @@ foreach exec : public_programs args : exec.full_path(), depends: exec) - version = meson.project_version() - if name == 'udevadm' - # For compatibility reasons we can't use the full version in udevadm. - version = version.split('~')[0] - endif - test('check-version-' + name, check_version, suite : 'dist', args : [exec.full_path(), - version], + project_major_version], depends: exec) endif endforeach diff --git a/meson.version b/meson.version index 9183bf0..47da505 100644 --- a/meson.version +++ b/meson.version @@ -1 +1 @@ -256 +256.2 diff --git a/meson_options.txt b/meson_options.txt index d52ca4e..667340c 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -12,13 +12,13 @@ option('mode', type : 'combo', choices : ['developer', 'release'], description : 'autoenable features suitable for systemd development/release builds') option('split-usr', type : 'combo', choices : ['auto', 'true', 'false'], deprecated: true, - description : '''This option is deprecated and will be removed in a future release''') + description : 'This option is deprecated and will be removed in a future release') option('split-bin', type : 'combo', choices : ['auto', 'true', 'false'], - description : '''sbin is not a symlink to bin''') + description : 'sbin is not a symlink to bin') option('rootlibdir', type : 'string', deprecated: true, - description : '''This option is deprecated and will be removed in a future release''') + description : 'This option is deprecated and will be removed in a future release') option('rootprefix', type : 'string', deprecated: true, - description : '''This option is deprecated and will be removed in a future release''') + description : 'This option is deprecated and will be removed in a future release') option('link-udev-shared', type : 'boolean', description : 'link systemd-udevd and its helpers to libsystemd-shared.so') option('link-systemctl-shared', type: 'boolean', @@ -38,7 +38,7 @@ option('first-boot-full-preset', type: 'boolean', value: false, option('static-libsystemd', type : 'combo', choices : ['false', 'true', 'pic', 'no-pic'], - description : '''install a static library for libsystemd''') + description : 'install a static library for libsystemd') option('static-libudev', type : 'combo', choices : ['false', 'true', 'pic', 'no-pic'], description : 'install a static library for libudev') @@ -234,7 +234,7 @@ option('fallback-hostname', type : 'string', value : 'localhost', description : 'the hostname used if none configured') option('default-hierarchy', type : 'combo', choices : ['legacy', 'hybrid', 'unified'], deprecated : true, - description : '''This option is deprecated and will be removed in a future release''') + description : 'This option is deprecated and will be removed in a future release') option('extra-net-naming-schemes', type : 'string', description : 'comma-separated list of extra net.naming_scheme= definitions') option('default-net-naming-scheme', type : 'string', value : 'latest', diff --git a/mkosi.conf.d/10-centos.conf b/mkosi.conf.d/10-centos.conf index ae2706c..ee8d0e5 100644 --- a/mkosi.conf.d/10-centos.conf +++ b/mkosi.conf.d/10-centos.conf @@ -8,3 +8,4 @@ Distribution=centos Repositories=epel epel-next hyperscale-packages-main + hyperscale-packages-experimental diff --git a/mkosi.images/exitrd/mkosi.conf.d/10-debian.conf b/mkosi.images/exitrd/mkosi.conf.d/10-debian.conf new file mode 100644 index 0000000..68b0aa5 --- /dev/null +++ b/mkosi.images/exitrd/mkosi.conf.d/10-debian.conf @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +[Match] +Distribution=debian + +[Content] +Packages= + systemd-standalone-shutdown diff --git a/mkosi.images/exitrd/mkosi.conf.d/10-debian-ubuntu.conf b/mkosi.images/exitrd/mkosi.conf.d/10-ubuntu.conf index babde60..ddd68dc 100644 --- a/mkosi.images/exitrd/mkosi.conf.d/10-debian-ubuntu.conf +++ b/mkosi.images/exitrd/mkosi.conf.d/10-ubuntu.conf @@ -1,8 +1,7 @@ # SPDX-License-Identifier: LGPL-2.1-or-later [Match] -Distribution=|debian -Distribution=|ubuntu +Distribution=ubuntu [Content] Packages= diff --git a/mkosi.images/system/mkosi.conf b/mkosi.images/system/mkosi.conf index 562650a..f8a91df 100644 --- a/mkosi.images/system/mkosi.conf +++ b/mkosi.images/system/mkosi.conf @@ -4,7 +4,6 @@ InitrdInclude=initrd/ [Output] -@Format=directory RepartDirectories=mkosi.repart [Content] @@ -17,6 +16,7 @@ ExtraTrees= PostInstallationScripts=mkosi.sanitizers.chroot InitrdPackages= + btrfs-progs findutils grep sed @@ -26,6 +26,7 @@ Packages= attr bash-completion bpftrace + btrfs-progs clang coreutils curl @@ -55,6 +56,7 @@ Packages= opensc openssl p11-kit + pciutils python3 qrencode radvd diff --git a/mkosi.images/system/mkosi.conf.d/10-arch/mkosi.build.chroot b/mkosi.images/system/mkosi.conf.d/10-arch/mkosi.build.chroot index 1f6e0c3..2c99a67 100755 --- a/mkosi.images/system/mkosi.conf.d/10-arch/mkosi.build.chroot +++ b/mkosi.images/system/mkosi.conf.d/10-arch/mkosi.build.chroot @@ -16,7 +16,7 @@ fi # We can't configure the source or build directory so we use symlinks instead to make sure they are in the # expected locations. -ln --symbolic "$SRCDIR" "pkg/$ID/systemd-stable" +ln --symbolic "$SRCDIR" "pkg/$ID/systemd" ln --symbolic "$BUILDDIR" "pkg/$ID/build" # Because we run with --noextract we are responsible for making sure the source files appear in src/. ln --symbolic . "pkg/$ID/src" @@ -90,4 +90,10 @@ env --chdir="pkg/$ID" \ PKGEXT=".pkg.tar" \ MESON_EXTRA_CONFIGURE_OPTIONS="$MKOSI_MESON_OPTIONS $MESON_OPTIONS" +( + shopt -s nullglob + rm -f "$BUILDDIR"/*.pkg.tar +) + cp "$OUTPUTDIR"/*.pkg.tar "$PACKAGEDIR" +cp "$OUTPUTDIR"/*.pkg.tar "$BUILDDIR" diff --git a/mkosi.images/system/mkosi.conf.d/10-arch/mkosi.conf b/mkosi.images/system/mkosi.conf.d/10-arch/mkosi.conf index 036b0a3..96ae8c8 100644 --- a/mkosi.images/system/mkosi.conf.d/10-arch/mkosi.conf +++ b/mkosi.images/system/mkosi.conf.d/10-arch/mkosi.conf @@ -7,7 +7,7 @@ Distribution=arch Environment= GIT_URL=https://gitlab.archlinux.org/archlinux/packaging/packages/systemd.git GIT_BRANCH=main - GIT_COMMIT=dc6c099e0785753c1c88b4adcbcbfc209a8d12e3 + GIT_COMMIT=d74b24c7c6077740c35a876445febe6d26bf013c VolatilePackages= systemd @@ -20,7 +20,6 @@ VolatilePackages= Packages= bind bpf - btrfs-progs compiler-rt compsize cryptsetup @@ -43,6 +42,7 @@ Packages= openssh openssl pacman + perf pkgconf polkit procps-ng @@ -61,7 +61,6 @@ Packages= vim InitrdPackages= - btrfs-progs compiler-rt tpm2-tools diff --git a/mkosi.images/system/mkosi.conf.d/10-centos-fedora/mkosi.build.chroot b/mkosi.images/system/mkosi.conf.d/10-centos-fedora/mkosi.build.chroot index 2c05787..21f1062 100755 --- a/mkosi.images/system/mkosi.conf.d/10-centos-fedora/mkosi.build.chroot +++ b/mkosi.images/system/mkosi.conf.d/10-centos-fedora/mkosi.build.chroot @@ -113,4 +113,10 @@ CXX_LD="$( ((LLVM)) && echo lld)" \ --noclean \ "pkg/$ID/systemd.spec" +( + shopt -s nullglob + rm -f "$BUILDDIR"/*.rpm +) + cp "$OUTPUTDIR"/*.rpm "$PACKAGEDIR" +cp "$OUTPUTDIR"/*.rpm "$BUILDDIR" diff --git a/mkosi.images/system/mkosi.conf.d/10-centos-fedora/mkosi.conf b/mkosi.images/system/mkosi.conf.d/10-centos-fedora/mkosi.conf index 6fbd507..f200409 100644 --- a/mkosi.images/system/mkosi.conf.d/10-centos-fedora/mkosi.conf +++ b/mkosi.images/system/mkosi.conf.d/10-centos-fedora/mkosi.conf @@ -50,6 +50,7 @@ Packages= openssh-server pam passwd + perf policycoreutils polkit procps-ng diff --git a/mkosi.images/system/mkosi.conf.d/10-debian-ubuntu/mkosi.build.chroot b/mkosi.images/system/mkosi.conf.d/10-debian-ubuntu/mkosi.build.chroot index 7e4eab9..f1eed03 100755 --- a/mkosi.images/system/mkosi.conf.d/10-debian-ubuntu/mkosi.build.chroot +++ b/mkosi.images/system/mkosi.conf.d/10-debian-ubuntu/mkosi.build.chroot @@ -137,6 +137,11 @@ fi ( shopt -s nullglob + rm -f "$BUILDDIR"/*.deb "$BUILDDIR"/*.ddeb + cp ../*.deb ../*.ddeb "$PACKAGEDIR" cp ../*.deb ../*.ddeb "$OUTPUTDIR" + cp ../*.deb ../*.ddeb "$BUILDDIR" + # These conflict with the packages that we actually want to install, so remove them + rm -f "$BUILDDIR"/systemd-standalone-*.deb "$BUILDDIR"/systemd-standalone-*.ddeb ) diff --git a/mkosi.images/system/mkosi.conf.d/10-debian-ubuntu/mkosi.conf b/mkosi.images/system/mkosi.conf.d/10-debian-ubuntu/mkosi.conf index ecac780..c6b8154 100644 --- a/mkosi.images/system/mkosi.conf.d/10-debian-ubuntu/mkosi.conf +++ b/mkosi.images/system/mkosi.conf.d/10-debian-ubuntu/mkosi.conf @@ -8,8 +8,8 @@ Distribution=|ubuntu Environment= GIT_URL=https://salsa.debian.org/systemd-team/systemd.git GIT_SUBDIR=debian - GIT_BRANCH=debian/master - GIT_COMMIT=596a70511736d78c1d8a5a27dca3989806cfa733 + GIT_BRANCH=ci/v256-stable + GIT_COMMIT=5f07b24c429e854db1afad5f14729804a46a59af VolatilePackages= libnss-myhostname @@ -22,10 +22,12 @@ VolatilePackages= systemd systemd-container systemd-coredump + systemd-cryptsetup systemd-dev systemd-homed systemd-journal-remote systemd-oomd + systemd-repart systemd-resolved systemd-sysv systemd-tests @@ -41,7 +43,6 @@ Packages= ^libubsan[0-9]+$ apt bind9-dnsutils - btrfs-progs cryptsetup-bin dbus-broker dbus-user-session @@ -81,10 +82,11 @@ Packages= xxd InitrdPackages= - btrfs-progs libclang-rt-dev tpm2-tools InitrdVolatilePackages= systemd + systemd-cryptsetup + systemd-repart udev diff --git a/mkosi.images/system/mkosi.conf.d/10-debian-ubuntu/mkosi.conf.d/10-debug.conf b/mkosi.images/system/mkosi.conf.d/10-debian-ubuntu/mkosi.conf.d/10-debug.conf index b53b3dc..2bb6164 100644 --- a/mkosi.images/system/mkosi.conf.d/10-debian-ubuntu/mkosi.conf.d/10-debug.conf +++ b/mkosi.images/system/mkosi.conf.d/10-debian-ubuntu/mkosi.conf.d/10-debug.conf @@ -16,10 +16,12 @@ VolatilePackages= systemd-boot-dbgsym systemd-container-dbgsym systemd-coredump-dbgsym + systemd-cryptsetup-dbgsym systemd-dbgsym systemd-homed-dbgsym systemd-journal-remote-dbgsym systemd-oomd-dbgsym + systemd-repart-dbgsym systemd-resolved-dbgsym systemd-tests-dbgsym systemd-timesyncd-dbgsym diff --git a/mkosi.images/system/mkosi.conf.d/10-debian/mkosi.conf b/mkosi.images/system/mkosi.conf.d/10-debian/mkosi.conf index c6b6155..50dfa11 100644 --- a/mkosi.images/system/mkosi.conf.d/10-debian/mkosi.conf +++ b/mkosi.images/system/mkosi.conf.d/10-debian/mkosi.conf @@ -2,3 +2,7 @@ [Match] Distribution=debian + +[Content] +Packages= + linux-perf diff --git a/mkosi.images/system/mkosi.conf.d/10-fedora/mkosi.conf b/mkosi.images/system/mkosi.conf.d/10-fedora/mkosi.conf index 689fe7d..c4617d2 100644 --- a/mkosi.images/system/mkosi.conf.d/10-fedora/mkosi.conf +++ b/mkosi.images/system/mkosi.conf.d/10-fedora/mkosi.conf @@ -7,10 +7,9 @@ Distribution=fedora Environment= GIT_URL=https://src.fedoraproject.org/rpms/systemd.git GIT_BRANCH=rawhide - GIT_COMMIT=1f94b56cee818068f57debfd78f035edd29f0e61 + GIT_COMMIT=f9fe17dbdee7242ccd4fd2858128c8952890bdb8 Packages= - btrfs-progs compsize dnf5 f2fs-tools @@ -18,6 +17,3 @@ Packages= # Required for systemd-networkd-tests.py (netdevsim and sch_xxx modules) kernel-modules-extra kernel-modules-internal - -InitrdPackages= - btrfs-progs diff --git a/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.build.chroot b/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.build.chroot index 3d6cc58..67481d0 100755 --- a/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.build.chroot +++ b/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.build.chroot @@ -67,6 +67,9 @@ if ((WIPE)); then MKOSI_MESON_OPTIONS="$MKOSI_MESON_OPTIONS --wipe" fi +# TODO: Drop when the spec is fixed (either the patch is adapted or not applied when building for upstream). +sed --in-place '/0009-pid1-handle-console-specificities-weirdness-for-s390.patch/d' "pkg/$ID/systemd.spec" + build() { IFS= # shellcheck disable=SC2046 @@ -129,4 +132,10 @@ if ! build; then build --noprep --nocheck fi +( + shopt -s nullglob + rm -f "$BUILDDIR"/*.rpm +) + cp "$OUTPUTDIR"/*.rpm "$PACKAGEDIR" +cp "$OUTPUTDIR"/*.rpm "$BUILDDIR" diff --git a/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.conf b/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.conf index 38ae052..e488b2d 100644 --- a/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.conf +++ b/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.conf @@ -9,8 +9,8 @@ InitrdInclude=initrd/ [Content] Environment= GIT_URL=https://src.opensuse.org/rpm/systemd - GIT_BRANCH=factory - GIT_COMMIT=973534fe1a0a5746ead5bbb6dff8b9ccb9e010982997ed56eba8e44a41c5895d + GIT_BRANCH=devel + GIT_COMMIT=23bfa9d83b6e24a5395a704b816a351f3dc5b5316e580cacedd1b5d9e068c117 VolatilePackages= systemd @@ -32,7 +32,6 @@ VolatilePackages= Packages= bind-utils bpftool - btrfs-progs cryptsetup device-mapper dhcp-server @@ -62,6 +61,7 @@ Packages= openssh-server pam patterns-base-minimal_base + perf procps4 psmisc python3-pefile @@ -86,9 +86,9 @@ Packages= veritysetup vim xz + zypper InitrdPackages= - btrfs-progs clang kmod libkmod2 diff --git a/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.conf.d/10-debug.conf b/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.conf.d/10-debug.conf index 2262eae..6c57d04 100644 --- a/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.conf.d/10-debug.conf +++ b/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.conf.d/10-debug.conf @@ -9,7 +9,6 @@ VolatilePackages= libudev1-debuginfo systemd-boot-debuginfo systemd-container-debuginfo - systemd-coredump-debuginfo systemd-debuginfo systemd-debugsource systemd-experimental-debuginfo diff --git a/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.prepare b/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.prepare index 282a360..c57aa87 100755 --- a/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.prepare +++ b/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.prepare @@ -15,6 +15,9 @@ if [ ! -f "pkg/$ID/systemd.spec" ]; then exit 1 fi +# TODO: Drop when the spec is fixed (either the patch is adapted or not applied when building for upstream). +sed --in-place '/0009-pid1-handle-console-specificities-weirdness-for-s390.patch/d' "pkg/$ID/systemd.spec" + for DEPS in --requires --buildrequires; do mkosi-chroot \ rpmspec \ diff --git a/mkosi.images/system/mkosi.repart/10-root.conf b/mkosi.images/system/mkosi.repart/10-root.conf index 715b925..3c25dbf 100644 --- a/mkosi.images/system/mkosi.repart/10-root.conf +++ b/mkosi.images/system/mkosi.repart/10-root.conf @@ -2,7 +2,7 @@ [Partition] Type=root -Format=ext4 +Format=btrfs CopyFiles=/ SizeMinBytes=8G SizeMaxBytes=8G diff --git a/mkosi.images/system/mkosi.sync b/mkosi.images/system/mkosi.sync index d21ecd1..d56ddf5 100755 --- a/mkosi.images/system/mkosi.sync +++ b/mkosi.images/system/mkosi.sync @@ -9,20 +9,32 @@ fi PKG_SUBDIR="$(realpath --canonicalize-missing "pkg/$DISTRIBUTION" --relative-to "$PWD")" -if [[ -d "$PKG_SUBDIR/.git" ]] && [[ "$(git -C "$PKG_SUBDIR" rev-parse HEAD)" == "$GIT_COMMIT" ]]; then - exit 0 -fi +if [[ -d "$PKG_SUBDIR/.git" ]]; then + if [[ "$(git -C "$PKG_SUBDIR" rev-parse HEAD)" == "$GIT_COMMIT" ]]; then + exit 0 + fi -# The repository on Salsa has the full upstream sources, so it's a waste of space to -# redownload and duplicate everything, so do a sparse checkout as we only need the -# packaging directory anyway -if [[ -n "${GIT_SUBDIR:-}" ]]; then - sparse=(--no-checkout --filter=tree:0) -else - sparse=() + # If work is being done on the packaging rules in a separate branch, don't touch the checkout. + if ! git -C "$PKG_SUBDIR" merge-base --is-ancestor HEAD "origin/$GIT_BRANCH"; then + EXIT_STATUS=$? + if [[ $EXIT_STATUS -eq 1 ]]; then + exit 0 + else + exit $EXIT_STATUS + fi + fi fi if [[ ! -e "$PKG_SUBDIR" ]] || [[ -z "$(ls --almost-all "$PKG_SUBDIR")" ]]; then + # The repository on Salsa has the full upstream sources, so it's a waste of + # space to redownload and duplicate everything, so do a sparse checkout as + # we only need the packaging directory anyway. + if [[ -n "${GIT_SUBDIR:-}" ]]; then + sparse=(--no-checkout --filter=tree:0) + else + sparse=() + fi + git clone "$GIT_URL" --branch "$GIT_BRANCH" "${sparse[@]}" "$PKG_SUBDIR" if [[ -n "${GIT_SUBDIR:-}" ]]; then # --no-cone is needed to check out only one top-level directory diff --git a/shell-completion/zsh/_run0 b/shell-completion/zsh/_run0 new file mode 100644 index 0000000..b354462 --- /dev/null +++ b/shell-completion/zsh/_run0 @@ -0,0 +1,57 @@ +#compdef run0 + +(( $+functions[_run0_unit_properties] )) || +_run0_unit_properties() { + local -a props=( + BlockIOAccounting BlockIODeviceWeight BlockIOReadBandwidth + BlockIOWeight BlockIOWriteBandwidth CPUAccounting + CPUShares DeviceAllow DevicePolicy + Environment EnvironmentFile ExitType + FinalKillSignal Group InaccessiblePaths + KillMode KillSignal LimitAS + LimitCORE LimitCPU LimitDATA + LimitFSIZE LimitLOCKS LimitMEMLOCK + LimitMSGQUEUE LimitNICE LimitNOFILE + LimitNPROC LimitRSS LimitRTPRIO + LimitRTTIME LimitSIGPENDING LimitSTACK + MemoryAccounting MemoryLimit Nice + NoNewPrivileges OOMScoreAdjust PassEnvironment + PrivateDevices PrivateNetwork PrivateTmp + ProtectHome ProtectSystem ReadOnlyPaths + ReadWritePaths RestartKillSignal RootDirectory + RuntimeDirectory SendSIGHUP SendSIGKILL + SyslogFacility SyslogIdentifier SyslogLevel + SyslogLevelPrefix TTYPath TimerSlackNSec + User WorkingDirectory + ) + _values -S= 'properties' ${^props}'::()' +} + +(( $+functions[_run0_slices] )) || +_run0_slices() { + local -a slices=( + ${(@f)"$(_call_program slice-units systemctl --no-pager --legend=no --plain list-units --all -t slice 2>/dev/null)"} + ) + slices=( ${slices%% *} ) + _describe -t slice-units 'slice unit' slices +} + +local -a args=( + '--no-ask-password[Do not query the user for authentication]' + '--unit=[Use this unit name instead of an automatically generated one]' + {--property=,-p+}'[Sets a property on the service unit created]:property:_run0_unit_properties' + '--description=[Provide a description for the service unit]' + '--slice=[Make the new .service unit part of the specified slice]:slice unit:_run0_slices' + '--slice-inherit[Make the new service unit part of the current slice]' + {--user=,-u+}'[Switch to the specified user]:user:_users' + {--group=,-g+}'[Switch to the specified group]:group:_groups' + '--nice=[Run with specified nice level]:nice value' + {--chdir=,-D+}'[Run within the specified working directory]:directory:_files -/' + '--setenv=[Set the specified environment variable in the session]:environment variable:_parameters -g "*export*" -S = -q' + '--background=[Change the terminal background color to the specified ANSI color]:ansi color' + '--machine=[Execute the operation on a local container]:machine:_sd_machines' + {-h,--help}'[Show the help text and exit]' + '--version[Print a short version string and exit]' +) + +_arguments -S $args '*:: :{_normal -p $service}' diff --git a/shell-completion/zsh/meson.build b/shell-completion/zsh/meson.build index ebe79f3..acbf34e 100644 --- a/shell-completion/zsh/meson.build +++ b/shell-completion/zsh/meson.build @@ -21,6 +21,7 @@ items = [['_busctl', ''], ['_systemd', ''], ['_systemd-path', ''], ['_systemd-run', ''], + ['_run0', ''], ['_udevadm', ''], ['_kernel-install', 'ENABLE_KERNEL_INSTALL'], ['_sd_hosts_or_user_at_host', ''], diff --git a/src/analyze/analyze-security.c b/src/analyze/analyze-security.c index 75508f4..3d7b647 100644 --- a/src/analyze/analyze-security.c +++ b/src/analyze/analyze-security.c @@ -1244,8 +1244,8 @@ static const struct security_assessor security_assessor_table[] = { { .id = "CapabilityBoundingSet=~CAP_BPF", .json_field = "CapabilityBoundingSet_CAP_BPF", - .description_good = "Service may load BPF programs", - .description_bad = "Service may not load BPF programs", + .description_good = "Service may not load BPF programs", + .description_bad = "Service may load BPF programs", .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#CapabilityBoundingSet=", .weight = 25, .range = 1, diff --git a/src/basic/build.c b/src/basic/build.c index 3ab25f7..488ed20 100644 --- a/src/basic/build.c +++ b/src/basic/build.c @@ -287,8 +287,8 @@ int version(void) { if (colors_enabled()) b = systemd_features_with_color(); - printf("%ssystemd " PROJECT_VERSION_FULL "%s (" GIT_VERSION ")\n%s\n", - ansi_highlight(), ansi_normal(), + printf("%ssystemd %i%s (" GIT_VERSION ")\n%s\n", + ansi_highlight(), PROJECT_VERSION, ansi_normal(), b ?: systemd_features); return 0; } diff --git a/src/basic/missing_sched.h b/src/basic/missing_sched.h index b8109d3..bd83b41 100644 --- a/src/basic/missing_sched.h +++ b/src/basic/missing_sched.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once +#include <linux/types.h> #include <sched.h> #include "macro.h" @@ -35,3 +36,20 @@ assert_cc(PF_KTHREAD == 0x00200000); #else assert_cc(TASK_COMM_LEN == 16); #endif + +#if !HAVE_STRUCT_SCHED_ATTR +struct sched_attr { + __u32 size; /* Size of this structure */ + __u32 sched_policy; /* Policy (SCHED_*) */ + __u64 sched_flags; /* Flags */ + __s32 sched_nice; /* Nice value (SCHED_OTHER, + SCHED_BATCH) */ + __u32 sched_priority; /* Static priority (SCHED_FIFO, + SCHED_RR) */ + /* Remaining fields are for SCHED_DEADLINE + and potentially soon for SCHED_OTHER/SCHED_BATCH */ + __u64 sched_runtime; + __u64 sched_deadline; + __u64 sched_period; +}; +#endif diff --git a/src/basic/missing_syscall.h b/src/basic/missing_syscall.h index 8628077..e2cd8b4 100644 --- a/src/basic/missing_syscall.h +++ b/src/basic/missing_syscall.h @@ -22,6 +22,7 @@ #include "macro.h" #include "missing_keyctl.h" +#include "missing_sched.h" #include "missing_stat.h" #include "missing_syscall_def.h" @@ -667,6 +668,22 @@ static inline ssize_t missing_getdents64(int fd, void *buffer, size_t length) { /* ======================================================================= */ +#if !HAVE_SCHED_SETATTR + +static inline ssize_t missing_sched_setattr(pid_t pid, struct sched_attr *attr, unsigned int flags) { +# if defined __NR_sched_setattr + return syscall(__NR_sched_setattr, pid, attr, flags); +# else + errno = ENOSYS; + return -1; +# endif +} + +# define sched_setattr missing_sched_setattr +#endif + +/* ======================================================================= */ + /* glibc does not provide clone() on ia64, only clone2(). Not only that, but it also doesn't provide a * prototype, only the symbol in the shared library (it provides a prototype for clone(), but not the * symbol in the shared library). */ diff --git a/src/basic/mountpoint-util.c b/src/basic/mountpoint-util.c index 66fa35b..135b296 100644 --- a/src/basic/mountpoint-util.c +++ b/src/basic/mountpoint-util.c @@ -231,8 +231,6 @@ int fd_is_mount_point(int fd, const char *filename, int flags) { /* If statx() is not available or forbidden, fall back to name_to_handle_at() below */ } else if (FLAGS_SET(sx.stx_attributes_mask, STATX_ATTR_MOUNT_ROOT)) /* yay! */ return FLAGS_SET(sx.stx_attributes, STATX_ATTR_MOUNT_ROOT); - else if (FLAGS_SET(sx.stx_mask, STATX_TYPE) && S_ISLNK(sx.stx_mode)) - return false; /* symlinks are never mount points */ r = name_to_handle_at_loop(fd, filename, &h, &mount_id, flags); if (r < 0) { @@ -311,8 +309,6 @@ fallback_fstat: flags |= AT_SYMLINK_NOFOLLOW; if (fstatat(fd, filename, &a, flags) < 0) return -errno; - if (S_ISLNK(a.st_mode)) /* Symlinks are never mount points */ - return false; if (isempty(filename)) r = fstatat(fd, "..", &b, 0); diff --git a/src/basic/os-util.c b/src/basic/os-util.c index 0d26d18..79f641b 100644 --- a/src/basic/os-util.c +++ b/src/basic/os-util.c @@ -259,13 +259,7 @@ int open_extension_release_at( } if (!relax_extension_release_check) { - _cleanup_free_ char *base_image_name = NULL, *base_extension = NULL; - - r = path_extract_image_name(image_name, &base_image_name); - if (r < 0) { - log_debug_errno(r, "Failed to extract image name from %s/%s, ignoring: %m", dir_path, de->d_name); - continue; - } + _cleanup_free_ char *base_extension = NULL; r = path_extract_image_name(extension, &base_extension); if (r < 0) { @@ -273,7 +267,7 @@ int open_extension_release_at( continue; } - if (!streq(base_image_name, base_extension) && + if (!streq(image_name, base_extension) && extension_release_strict_xattr_value(fd, dir_path, image_name) != 0) continue; } diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h index ecfe574..c70c938 100644 --- a/src/basic/terminal-util.h +++ b/src/basic/terminal-util.h @@ -42,26 +42,26 @@ #define ANSI_HIGHLIGHT_MAGENTA "\x1B[0;1;35m" #define ANSI_HIGHLIGHT_CYAN "\x1B[0;1;36m" #define ANSI_HIGHLIGHT_WHITE "\x1B[0;1;37m" -#define ANSI_HIGHLIGHT_YELLOW4 "\x1B[0;1;38;5;100m" -#define ANSI_HIGHLIGHT_KHAKI3 "\x1B[0;1;38;5;185m" -#define ANSI_HIGHLIGHT_GREY "\x1B[0;1;38;5;245m" +#define ANSI_HIGHLIGHT_YELLOW4 "\x1B[0;1;38:5:100m" +#define ANSI_HIGHLIGHT_KHAKI3 "\x1B[0;1;38:5:185m" +#define ANSI_HIGHLIGHT_GREY "\x1B[0;1;38:5:245m" #define ANSI_HIGHLIGHT_YELLOW ANSI_HIGHLIGHT_KHAKI3 /* Replacement yellow that is more legible */ /* Underlined */ -#define ANSI_GREY_UNDERLINE "\x1B[0;4;38;5;245m" +#define ANSI_GREY_UNDERLINE "\x1B[0;4;38:5:245m" #define ANSI_BRIGHT_BLACK_UNDERLINE "\x1B[0;4;90m" #define ANSI_HIGHLIGHT_RED_UNDERLINE "\x1B[0;1;4;31m" #define ANSI_HIGHLIGHT_GREEN_UNDERLINE "\x1B[0;1;4;32m" -#define ANSI_HIGHLIGHT_YELLOW_UNDERLINE "\x1B[0;1;4;38;5;185m" +#define ANSI_HIGHLIGHT_YELLOW_UNDERLINE "\x1B[0;1;4;38:5:185m" #define ANSI_HIGHLIGHT_BLUE_UNDERLINE "\x1B[0;1;4;34m" #define ANSI_HIGHLIGHT_MAGENTA_UNDERLINE "\x1B[0;1;4;35m" -#define ANSI_HIGHLIGHT_GREY_UNDERLINE "\x1B[0;1;4;38;5;245m" +#define ANSI_HIGHLIGHT_GREY_UNDERLINE "\x1B[0;1;4;38:5:245m" /* Other ANSI codes */ #define ANSI_UNDERLINE "\x1B[0;4m" #define ANSI_ADD_UNDERLINE "\x1B[4m" -#define ANSI_ADD_UNDERLINE_GREY ANSI_ADD_UNDERLINE "\x1B[58;5;245m" +#define ANSI_ADD_UNDERLINE_GREY ANSI_ADD_UNDERLINE "\x1B[58:5:245m" #define ANSI_HIGHLIGHT "\x1B[0;1;39m" #define ANSI_HIGHLIGHT_UNDERLINE "\x1B[0;1;4m" diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index 79de121..8287c21 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -879,6 +879,7 @@ static bool menu_run( switch (key) { case KEYPRESS(0, SCAN_UP, 0): + case KEYPRESS(0, SCAN_VOLUME_UP, 0): /* Handle phones/tablets that only have a volume up/down rocker + power key (and otherwise just touchscreen input) */ case KEYPRESS(0, 0, 'k'): case KEYPRESS(0, 0, 'K'): if (idx_highlight > 0) @@ -886,6 +887,7 @@ static bool menu_run( break; case KEYPRESS(0, SCAN_DOWN, 0): + case KEYPRESS(0, SCAN_VOLUME_DOWN, 0): case KEYPRESS(0, 0, 'j'): case KEYPRESS(0, 0, 'J'): if (idx_highlight < config->n_entries-1) @@ -923,9 +925,10 @@ static bool menu_run( case KEYPRESS(0, 0, '\n'): case KEYPRESS(0, 0, '\r'): - case KEYPRESS(0, SCAN_F3, 0): /* EZpad Mini 4s firmware sends malformed events */ - case KEYPRESS(0, SCAN_F3, '\r'): /* Teclast X98+ II firmware sends malformed events */ + case KEYPRESS(0, SCAN_F3, 0): /* EZpad Mini 4s firmware sends malformed events */ + case KEYPRESS(0, SCAN_F3, '\r'): /* Teclast X98+ II firmware sends malformed events */ case KEYPRESS(0, SCAN_RIGHT, 0): + case KEYPRESS(0, SCAN_SUSPEND, 0): /* Handle phones/tablets with only a power key + volume up/down rocker (and otherwise just touchscreen input) */ action = ACTION_RUN; break; diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index 7a60b0e..a1bdd58 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -63,13 +63,14 @@ foreach ctype : ['color-normal', 'color-entry', 'color-highlight', 'color-edit'] 'EFI_' + c[1].strip().underscorify().to_upper())) endforeach +efi_conf.set_quoted('PROJECT_VERSION', project_major_version) +efi_conf.set_quoted('VERSION_TAG', version_tag) +efi_conf.set('PROJECT_URL', conf.get('PROJECT_URL')) + if meson.is_cross_build() and get_option('sbat-distro') == 'auto' warning('Auto detection of SBAT information not supported when cross-building, disabling SBAT.') elif get_option('sbat-distro') != '' efi_conf.set_quoted('SBAT_PROJECT', meson.project_name()) - efi_conf.set_quoted('PROJECT_VERSION', meson.project_version().split('~')[0]) - efi_conf.set_quoted('VERSION_TAG', version_tag) - efi_conf.set('PROJECT_URL', conf.get('PROJECT_URL')) if get_option('sbat-distro-generation') < 1 error('SBAT Distro Generation must be a positive integer') endif @@ -388,8 +389,8 @@ foreach efi_elf_binary : efi_elf_binaries install_tag : 'systemd-boot', command : [ elf2efi_py, - '--version-major=' + meson.project_version().split('~')[0], - '--version-minor=0', + '--version-major=' + project_major_version, + '--version-minor=' + project_minor_version, '--efi-major=1', '--efi-minor=1', '--subsystem=10', diff --git a/src/boot/efi/util.c b/src/boot/efi/util.c index b5c8c63..eb29eb2 100644 --- a/src/boot/efi/util.c +++ b/src/boot/efi/util.c @@ -330,7 +330,14 @@ EFI_STATUS chunked_read(EFI_FILE *file, size_t *size, void *buf) { return EFI_SUCCESS; } -EFI_STATUS file_read(EFI_FILE *dir, const char16_t *name, size_t off, size_t size, char **ret, size_t *ret_size) { +EFI_STATUS file_read( + EFI_FILE *dir, + const char16_t *name, + uint64_t off, + size_t size, + char **ret, + size_t *ret_size) { + _cleanup_(file_closep) EFI_FILE *handle = NULL; _cleanup_free_ char *buf = NULL; EFI_STATUS err; @@ -350,6 +357,9 @@ EFI_STATUS file_read(EFI_FILE *dir, const char16_t *name, size_t off, size_t siz if (err != EFI_SUCCESS) return err; + if (info->FileSize > SIZE_MAX) + return EFI_BAD_BUFFER_SIZE; + size = info->FileSize; } diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h index ceac07c..dc624f4 100644 --- a/src/boot/efi/util.h +++ b/src/boot/efi/util.h @@ -102,7 +102,7 @@ char16_t *xstr8_to_path(const char *stra); char16_t *mangle_stub_cmdline(char16_t *cmdline); EFI_STATUS chunked_read(EFI_FILE *file, size_t *size, void *buf); -EFI_STATUS file_read(EFI_FILE *dir, const char16_t *name, size_t off, size_t size, char **content, size_t *content_size); +EFI_STATUS file_read(EFI_FILE *dir, const char16_t *name, uint64_t off, size_t size, char **content, size_t *content_size); static inline void file_closep(EFI_FILE **handle) { if (!*handle) diff --git a/src/boot/efi/vmm.c b/src/boot/efi/vmm.c index 60e216d..bfc7acc 100644 --- a/src/boot/efi/vmm.c +++ b/src/boot/efi/vmm.c @@ -241,13 +241,21 @@ static const SmbiosHeader *get_smbios_table(uint8_t type, uint64_t *ret_size_lef size -= header->length; p += header->length; - /* Skip over string table. */ + /* Special case: if there are no strings appended, we'll see two NUL bytes, skip over them */ + if (size >= 2 && p[0] == 0 && p[1] == 0) { + size -= 2; + p += 2; + continue; + } + + /* Skip over a populated string table. */ + bool first = true; for (;;) { const uint8_t *e = memchr(p, 0, size); if (!e) return NULL; - if (e == p) {/* Double NUL byte means we've reached the end of the string table. */ + if (!first && e == p) {/* Double NUL byte means we've reached the end of the string table. */ p++; size--; break; @@ -255,6 +263,7 @@ static const SmbiosHeader *get_smbios_table(uint8_t type, uint64_t *ret_size_lef size -= e + 1 - p; p = e + 1; + first = false; } } diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 21c260b..b0d9402 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -2743,10 +2743,6 @@ int bus_exec_context_set_transient_property( if (!path_is_normalized(simplified)) return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "WorkingDirectory= expects a normalized path or '~'"); - - if (path_below_api_vfs(simplified)) - return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, - "WorkingDirectory= may not be below /proc/, /sys/ or /dev/"); } } diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 2515f54..7da35a8 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -1708,6 +1708,10 @@ static int method_soft_reboot(sd_bus_message *message, void *userdata, sd_bus_er assert(message); + if (!MANAGER_IS_SYSTEM(m)) + return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED, + "Soft reboot is only supported by system manager."); + r = verify_run_space_permissive("soft reboot may fail", error); if (r < 0) return r; diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c index ee8db04..09f98d3 100644 --- a/src/core/exec-invoke.c +++ b/src/core/exec-invoke.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include <linux/sched.h> #include <sys/eventfd.h> #include <sys/ioctl.h> #include <sys/mount.h> @@ -44,6 +45,7 @@ #include "journal-send.h" #include "missing_ioprio.h" #include "missing_prctl.h" +#include "missing_sched.h" #include "missing_securebits.h" #include "missing_syscall.h" #include "mkdir-label.h" @@ -1439,6 +1441,13 @@ static int apply_syscall_filter(const ExecContext *c, const ExecParameters *p, b return r; } + /* Sending over exec_fd or handoff_timestamp_fd requires write() syscall. */ + if (p->exec_fd >= 0 || p->handoff_timestamp_fd >= 0) { + r = seccomp_filter_set_add_by_name(c->syscall_filter, c->syscall_allow_list, "write"); + if (r < 0) + return r; + } + return seccomp_load_syscall_filter_set_raw(default_action, c->syscall_filter, action, false); } @@ -3775,7 +3784,7 @@ static int get_open_file_fd(const ExecContext *c, const ExecParameters *p, const else if (FLAGS_SET(of->flags, OPENFILE_TRUNCATE)) flags |= O_TRUNC; - fd = fd_reopen(ofd, flags | O_CLOEXEC); + fd = fd_reopen(ofd, flags|O_NOCTTY|O_CLOEXEC); if (fd < 0) return log_exec_error_errno(c, p, fd, "Failed to reopen file '%s': %m", of->path); @@ -4011,7 +4020,7 @@ static int send_handoff_timestamp( dual_timestamp dt; dual_timestamp_now(&dt); - if (send(p->handoff_timestamp_fd, (const usec_t[2]) { dt.realtime, dt.monotonic }, sizeof(usec_t) * 2, 0) < 0) { + if (write(p->handoff_timestamp_fd, (const usec_t[2]) { dt.realtime, dt.monotonic }, sizeof(usec_t) * 2) < 0) { if (reterr_exit_status) *reterr_exit_status = EXIT_EXEC; return log_exec_error_errno(c, p, errno, "Failed to send handoff timestamp: %m"); @@ -4402,15 +4411,14 @@ int exec_invoke( } if (context->cpu_sched_set) { - struct sched_param param = { + struct sched_attr attr = { + .size = sizeof(attr), + .sched_policy = context->cpu_sched_policy, .sched_priority = context->cpu_sched_priority, + .sched_flags = context->cpu_sched_reset_on_fork ? SCHED_FLAG_RESET_ON_FORK : 0, }; - r = sched_setscheduler(0, - context->cpu_sched_policy | - (context->cpu_sched_reset_on_fork ? - SCHED_RESET_ON_FORK : 0), - ¶m); + r = sched_setattr(/* pid= */ 0, &attr, /* flags= */ 0); if (r < 0) { *exit_status = EXIT_SETSCHEDULER; return log_exec_error_errno(context, params, errno, "Failed to set up CPU scheduling: %m"); diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 5ae6888..a1a116a 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -2634,7 +2634,8 @@ int config_parse_working_directory( return missing_ok ? 0 : -ENOEXEC; } - r = path_simplify_and_warn(k, PATH_CHECK_ABSOLUTE|PATH_CHECK_NON_API_VFS|(missing_ok ? 0 : PATH_CHECK_FATAL), unit, filename, line, lvalue); + r = path_simplify_and_warn(k, PATH_CHECK_ABSOLUTE|(missing_ok ? 0 : PATH_CHECK_FATAL), + unit, filename, line, lvalue); if (r < 0) return missing_ok ? 0 : -ENOEXEC; @@ -5396,7 +5397,7 @@ int config_parse_mount_images( continue; } - r = path_simplify_and_warn(sresolved, PATH_CHECK_ABSOLUTE|PATH_CHECK_NON_API_VFS, unit, filename, line, lvalue); + r = path_simplify_and_warn(sresolved, PATH_CHECK_ABSOLUTE|PATH_CHECK_NON_API_VFS_DEV_OK, unit, filename, line, lvalue); if (r < 0) continue; @@ -5412,7 +5413,7 @@ int config_parse_mount_images( continue; } - r = path_simplify_and_warn(dresolved, PATH_CHECK_ABSOLUTE|PATH_CHECK_NON_API_VFS, unit, filename, line, lvalue); + r = path_simplify_and_warn(dresolved, PATH_CHECK_ABSOLUTE|PATH_CHECK_NON_API_VFS_DEV_OK, unit, filename, line, lvalue); if (r < 0) continue; diff --git a/src/core/manager.c b/src/core/manager.c index 90e72b0..5997ef0 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -3086,41 +3086,43 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t default: { - /* Starting SIGRTMIN+0 */ - static const struct { - const char *target; - JobMode mode; - } target_table[] = { - [0] = { SPECIAL_DEFAULT_TARGET, JOB_ISOLATE }, - [1] = { SPECIAL_RESCUE_TARGET, JOB_ISOLATE }, - [2] = { SPECIAL_EMERGENCY_TARGET, JOB_ISOLATE }, - [3] = { SPECIAL_HALT_TARGET, JOB_REPLACE_IRREVERSIBLY }, - [4] = { SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY }, - [5] = { SPECIAL_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY }, - [6] = { SPECIAL_KEXEC_TARGET, JOB_REPLACE_IRREVERSIBLY }, - [7] = { SPECIAL_SOFT_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY }, - }; - - /* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */ - static const ManagerObjective objective_table[] = { - [0] = MANAGER_HALT, - [1] = MANAGER_POWEROFF, - [2] = MANAGER_REBOOT, - [3] = MANAGER_KEXEC, - [4] = MANAGER_SOFT_REBOOT, - }; - - if ((int) sfsi.ssi_signo >= SIGRTMIN+0 && - (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) { - int idx = (int) sfsi.ssi_signo - SIGRTMIN; - manager_start_special(m, target_table[idx].target, target_table[idx].mode); - break; - } + if (MANAGER_IS_SYSTEM(m)) { + /* Starting SIGRTMIN+0 */ + static const struct { + const char *target; + JobMode mode; + } target_table[] = { + [0] = { SPECIAL_DEFAULT_TARGET, JOB_ISOLATE }, + [1] = { SPECIAL_RESCUE_TARGET, JOB_ISOLATE }, + [2] = { SPECIAL_EMERGENCY_TARGET, JOB_ISOLATE }, + [3] = { SPECIAL_HALT_TARGET, JOB_REPLACE_IRREVERSIBLY }, + [4] = { SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY }, + [5] = { SPECIAL_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY }, + [6] = { SPECIAL_KEXEC_TARGET, JOB_REPLACE_IRREVERSIBLY }, + [7] = { SPECIAL_SOFT_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY }, + }; + + /* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */ + static const ManagerObjective objective_table[] = { + [0] = MANAGER_HALT, + [1] = MANAGER_POWEROFF, + [2] = MANAGER_REBOOT, + [3] = MANAGER_KEXEC, + [4] = MANAGER_SOFT_REBOOT, + }; + + if ((int) sfsi.ssi_signo >= SIGRTMIN+0 && + (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) { + int idx = (int) sfsi.ssi_signo - SIGRTMIN; + manager_start_special(m, target_table[idx].target, target_table[idx].mode); + break; + } - if ((int) sfsi.ssi_signo >= SIGRTMIN+13 && - (int) sfsi.ssi_signo < SIGRTMIN+13+(int) ELEMENTSOF(objective_table)) { - m->objective = objective_table[sfsi.ssi_signo - SIGRTMIN - 13]; - break; + if ((int) sfsi.ssi_signo >= SIGRTMIN+13 && + (int) sfsi.ssi_signo < SIGRTMIN+13+(int) ELEMENTSOF(objective_table)) { + m->objective = objective_table[sfsi.ssi_signo - SIGRTMIN - 13]; + break; + } } switch (sfsi.ssi_signo - SIGRTMIN) { diff --git a/src/core/namespace.c b/src/core/namespace.c index 6c0dc94..a9b98bc 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -1695,11 +1695,11 @@ static int apply_one_mount( (void) mkdir_parents(mount_entry_path(m), 0755); q = make_mount_point_inode_from_path(what, mount_entry_path(m), 0755); - if (q < 0) { - if (q != -EEXIST) // FIXME: this shouldn't be logged at LOG_WARNING, but be bubbled up, and logged there to avoid duplicate logging - log_warning_errno(q, "Failed to create destination mount point node '%s', ignoring: %m", - mount_entry_path(m)); - } else + if (q < 0 && q != -EEXIST) + // FIXME: this shouldn't be logged at LOG_WARNING, but be bubbled up, and logged there to avoid duplicate logging + log_warning_errno(q, "Failed to create destination mount point node '%s', ignoring: %m", + mount_entry_path(m)); + else try_again = true; } diff --git a/src/core/unit.c b/src/core/unit.c index 2d40618..852926b 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -41,6 +41,7 @@ #include "logarithm.h" #include "macro.h" #include "mkdir-label.h" +#include "mountpoint-util.h" #include "path-util.h" #include "process-util.h" #include "rm-rf.h" @@ -1405,11 +1406,13 @@ int unit_load_fragment_and_dropin(Unit *u, bool fragment_required) { u->load_state = UNIT_LOADED; } + u = unit_follow_merge(u); + /* Load drop-in directory data. If u is an alias, we might be reloading the * target unit needlessly. But we cannot be sure which drops-ins have already * been loaded and which not, at least without doing complicated book-keeping, * so let's always reread all drop-ins. */ - r = unit_load_dropin(unit_follow_merge(u)); + r = unit_load_dropin(u); if (r < 0) return r; @@ -4234,6 +4237,10 @@ static int unit_verify_contexts(const Unit *u, const ExecContext *ec) { if (ec->dynamic_user && ec->working_directory_home) return log_unit_error_errno(u, SYNTHETIC_ERRNO(ENOEXEC), "WorkingDirectory=~ is not allowed under DynamicUser=yes. Refusing."); + if (ec->working_directory && path_below_api_vfs(ec->working_directory) && + exec_needs_mount_namespace(ec, /* params = */ NULL, /* runtime = */ NULL)) + return log_unit_error_errno(u, SYNTHETIC_ERRNO(ENOEXEC), "WorkingDirectory= may not be below /proc/, /sys/ or /dev/ when using mount namespacing. Refusing."); + return 0; } diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c index a8ee8e0..f5c4cf5 100644 --- a/src/coredump/coredump.c +++ b/src/coredump/coredump.c @@ -503,17 +503,21 @@ static int save_external_coredump( bus_error_message(&error, r)); } + /* First, ensure we are not going to go over the cgroup limit */ max_size = MIN(cgroup_limit, max_size); - max_size = LESS_BY(max_size, 1024U) / 2; /* Account for 1KB metadata overhead for compressing */ - max_size = MAX(PROCESS_SIZE_MIN, max_size); /* Impose a lower minimum */ - - /* tmpfs might get full quickly, so check the available space too. - * But don't worry about errors here, failing to access the storage - * location will be better logged when writing to it. */ + /* tmpfs might get full quickly, so check the available space too. But don't worry about + * errors here, failing to access the storage location will be better logged when writing to + * it. */ if (fstatvfs(fd, &sv) >= 0) max_size = MIN((uint64_t)sv.f_frsize * (uint64_t)sv.f_bfree, max_size); - - log_debug("Limiting core file size to %" PRIu64 " bytes due to cgroup memory limits.", max_size); + /* Impose a lower minimum, otherwise we will miss the basic headers. */ + max_size = MAX(PROCESS_SIZE_MIN, max_size); + /* Ensure we can always switch to compressing on the fly in case we are running out of space + * by keeping half of the space/memory available, plus 1KB metadata overhead from the + * compression algorithm. */ + max_size = LESS_BY(max_size, 1024U) / 2; + + log_debug("Limiting core file size to %" PRIu64 " bytes due to cgroup and/or filesystem limits.", max_size); } r = copy_bytes(input_fd, fd, max_size, 0); diff --git a/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c b/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c index 8b4754a..f064e1d 100644 --- a/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c +++ b/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c @@ -223,7 +223,7 @@ _public_ void cryptsetup_token_dump( crypt_log(cd, "\ttpm2-pubkey:" CRYPT_DUMP_LINE_SEP "%s\n", pubkey_str); crypt_log(cd, "\ttpm2-pubkey-pcrs: %s\n", strna(pubkey_pcrs_str)); crypt_log(cd, "\ttpm2-primary-alg: %s\n", strna(tpm2_asym_alg_to_string(primary_alg))); - crypt_log(cd, "\ttpm2-blob: %s\n", blob_str); + crypt_log(cd, "\ttpm2-blob: %s\n", blob_str); crypt_log(cd, "\ttpm2-policy-hash:" CRYPT_DUMP_LINE_SEP "%s\n", policy_hash_str); crypt_log(cd, "\ttpm2-pin: %s\n", true_false(flags & TPM2_FLAGS_USE_PIN)); crypt_log(cd, "\ttpm2-pcrlock: %s\n", true_false(flags & TPM2_FLAGS_USE_PCRLOCK)); diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index fe1216f..a4030d0 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -1619,11 +1619,13 @@ static int vl_method_describe(Varlink *link, JsonVariant *parameters, VarlinkMet if (r != 0) return r; - r = varlink_verify_polkit_async( + r = varlink_verify_polkit_async_full( link, c->bus, "org.freedesktop.hostname1.get-hardware-serial", /* details= */ NULL, + UID_INVALID, + POLKIT_DONT_REPLY, &c->polkit_registry); if (r == 0) return 0; /* No authorization for now, but the async polkit stuff will call us again when it has it */ diff --git a/src/kernel-install/60-ukify.install.in b/src/kernel-install/60-ukify.install.in index 54a5daf..076390d 100755 --- a/src/kernel-install/60-ukify.install.in +++ b/src/kernel-install/60-ukify.install.in @@ -27,7 +27,7 @@ from shutil import which from pathlib import Path from typing import Optional -__version__ = '{{PROJECT_VERSION_FULL}} ({{VERSION_TAG}})' +__version__ = '{{PROJECT_VERSION}} ({{VERSION_TAG}})' try: VERBOSE = int(os.environ['KERNEL_INSTALL_VERBOSE']) > 0 diff --git a/src/kernel-install/kernel-install.c b/src/kernel-install/kernel-install.c index 5d559a9..2762927 100644 --- a/src/kernel-install/kernel-install.c +++ b/src/kernel-install/kernel-install.c @@ -1467,7 +1467,7 @@ static int help(void) { return log_oom(); printf("%1$s [OPTIONS...] COMMAND ...\n\n" - "%5$sAdd and remove kernel and initrd images to and from /boot/%6$s\n" + "%5$sAdd and remove kernel and initrd images to and from the boot partition.%6$s\n" "\n%3$sUsage:%4$s\n" " kernel-install [OPTIONS...] add [[[KERNEL-VERSION] KERNEL-IMAGE] [INITRD ...]]\n" " kernel-install [OPTIONS...] add-all\n" diff --git a/src/login/user-runtime-dir.c b/src/login/user-runtime-dir.c index 575f8eb..b242f83 100644 --- a/src/login/user-runtime-dir.c +++ b/src/login/user-runtime-dir.c @@ -25,27 +25,38 @@ #include "strv.h" #include "user-util.h" -static int acquire_runtime_dir_properties(uint64_t *size, uint64_t *inodes) { +static int acquire_runtime_dir_properties(uint64_t *ret_size, uint64_t *ret_inodes) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + uint64_t size, inodes; int r; + assert(ret_size); + assert(ret_inodes); + r = sd_bus_default_system(&bus); if (r < 0) return log_error_errno(r, "Failed to connect to system bus: %m"); - r = bus_get_property_trivial(bus, bus_login_mgr, "RuntimeDirectorySize", &error, 't', size); + r = bus_get_property_trivial(bus, bus_login_mgr, "RuntimeDirectorySize", &error, 't', &size); if (r < 0) { log_warning_errno(r, "Failed to acquire runtime directory size, ignoring: %s", bus_error_message(&error, r)); - *size = physical_memory_scale(10U, 100U); /* 10% */ + sd_bus_error_free(&error); + + size = physical_memory_scale(10U, 100U); /* 10% */ } - r = bus_get_property_trivial(bus, bus_login_mgr, "RuntimeDirectoryInodesMax", &error, 't', inodes); + r = bus_get_property_trivial(bus, bus_login_mgr, "RuntimeDirectoryInodesMax", &error, 't', &inodes); if (r < 0) { log_warning_errno(r, "Failed to acquire number of inodes for runtime directory, ignoring: %s", bus_error_message(&error, r)); - *inodes = DIV_ROUND_UP(*size, 4096); + sd_bus_error_free(&error); + + inodes = DIV_ROUND_UP(size, 4096); } + *ret_size = size; + *ret_inodes = inodes; + return 0; } @@ -70,7 +81,7 @@ static int user_mkdir_runtime_path( if (path_is_mount_point(runtime_path) > 0) log_debug("%s is already a mount point", runtime_path); else { - char options[sizeof("mode=0700,uid=,gid=,size=,nr_inodes=,smackfsroot=*") + char options[STRLEN("mode=0700,uid=,gid=,size=,nr_inodes=,smackfsroot=*") + DECIMAL_STR_MAX(uid_t) + DECIMAL_STR_MAX(gid_t) + DECIMAL_STR_MAX(uint64_t) @@ -140,7 +151,7 @@ static int user_remove_runtime_path(const char *runtime_path) { } static int do_mount(const char *user) { - char runtime_path[sizeof("/run/user") + DECIMAL_STR_MAX(uid_t)]; + char runtime_path[STRLEN("/run/user/") + DECIMAL_STR_MAX(uid_t)]; uint64_t runtime_dir_size, runtime_dir_inodes; uid_t uid; gid_t gid; @@ -165,7 +176,7 @@ static int do_mount(const char *user) { } static int do_umount(const char *user) { - char runtime_path[sizeof("/run/user") + DECIMAL_STR_MAX(uid_t)]; + char runtime_path[STRLEN("/run/user/") + DECIMAL_STR_MAX(uid_t)]; uid_t uid; int r; diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index 7cafe1f..50d284b 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -222,20 +222,33 @@ static int ndisc_request_route(Route *route, Link *link) { /* Note, here do not call route_remove_and_cancel() with 'route' directly, otherwise * existing route(s) may be removed needlessly. */ - if (route_get(link->manager, route, &existing) >= 0) { - /* Found an existing route that may conflict with this route. */ + /* First, check if a conflicting route is already requested. If there is an existing route, + * and also an existing pending request, then the source may be updated by the request. So, + * we first need to check the source of the requested route. */ + if (route_get_request(link->manager, route, &req) >= 0) { + existing = ASSERT_PTR(req->userdata); if (!route_can_update(existing, route)) { - log_link_debug(link, "Found an existing route that conflicts with new route based on a received RA, removing."); + if (existing->source == NETWORK_CONFIG_SOURCE_STATIC) { + log_link_debug(link, "Found a pending route request that conflicts with new request based on a received RA, ignoring request."); + return 0; + } + + log_link_debug(link, "Found a pending route request that conflicts with new request based on a received RA, cancelling."); r = route_remove_and_cancel(existing, link->manager); if (r < 0) return r; } } - if (route_get_request(link->manager, route, &req) >= 0) { - existing = ASSERT_PTR(req->userdata); + /* Then, check if a conflicting route exists. */ + if (route_get(link->manager, route, &existing) >= 0) { if (!route_can_update(existing, route)) { - log_link_debug(link, "Found a pending route request that conflicts with new request based on a received RA, cancelling."); + if (existing->source == NETWORK_CONFIG_SOURCE_STATIC) { + log_link_debug(link, "Found an existing route that conflicts with new route based on a received RA, ignoring request."); + return 0; + } + + log_link_debug(link, "Found an existing route that conflicts with new route based on a received RA, removing."); r = route_remove_and_cancel(existing, link->manager); if (r < 0) return r; @@ -291,18 +304,44 @@ static int ndisc_remove_route(Route *route, Link *link) { if (r < 0) return r; - if (route->pref_set) { - ndisc_set_route_priority(link, route); - return route_remove_and_cancel(route, link->manager); - } - - uint8_t pref; + uint8_t pref, pref_original = route->pref; FOREACH_ARGUMENT(pref, SD_NDISC_PREFERENCE_LOW, SD_NDISC_PREFERENCE_MEDIUM, SD_NDISC_PREFERENCE_HIGH) { + Route *existing; + Request *req; + + /* If the preference is specified by the user config (that is, for semi-static routes), + * rather than RA, then only search conflicting routes that have the same preference. */ + if (route->pref_set && pref != pref_original) + continue; + route->pref = pref; ndisc_set_route_priority(link, route); - r = route_remove_and_cancel(route, link->manager); - if (r < 0) - return r; + + /* Unfortunately, we cannot directly pass 'route' to route_remove_and_cancel() here, as the + * same or similar route may be configured or requested statically. */ + + /* First, check if the route is already requested. If there is an existing route, and also an + * existing pending request, then the source may be updated by the request. So, we first need + * to check the source of the requested route. */ + if (route_get_request(link->manager, route, &req) >= 0) { + existing = ASSERT_PTR(req->userdata); + if (existing->source == NETWORK_CONFIG_SOURCE_STATIC) + continue; + + r = route_remove_and_cancel(existing, link->manager); + if (r < 0) + return r; + } + + /* Then, check if the route exists. */ + if (route_get(link->manager, route, &existing) >= 0) { + if (existing->source == NETWORK_CONFIG_SOURCE_STATIC) + continue; + + r = route_remove_and_cancel(existing, link->manager); + if (r < 0) + return r; + } } return 0; diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 5842d3b..f8c34b5 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -5567,7 +5567,8 @@ static int run_container( } else if (!isempty(arg_background)) (void) pty_forward_set_background_color(forward, arg_background); - set_window_title(forward); + if (shall_set_terminal_title()) + set_window_title(forward); break; default: diff --git a/src/partition/repart.c b/src/partition/repart.c index 8f64520..f87a87e 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -2562,7 +2562,7 @@ static int context_load_partition_table(Context *context) { if (IN_SET(arg_empty, EMPTY_REQUIRE, EMPTY_FORCE, EMPTY_CREATE) && S_ISREG(st.st_mode)) /* Don't probe sector size from partition table if we are supposed to start from an empty disk */ - fs_secsz = ssz = 512; + ssz = 512; else { /* Auto-detect sector size if not specified. */ r = probe_sector_size_prefer_ioctl(context->backing_fd, &ssz); @@ -2572,8 +2572,10 @@ static int context_load_partition_table(Context *context) { /* If we found the sector size and we're operating on a block device, use it as the file * system sector size as well, as we know its the sector size of the actual block device and * not just the offset at which we found the GPT header. */ - if (r > 0 && S_ISBLK(st.st_mode)) + if (r > 0 && S_ISBLK(st.st_mode)) { + log_debug("Probed sector size of %s is %" PRIu32 " bytes.", context->node, ssz); fs_secsz = ssz; + } } r = fdisk_save_user_sector_size(c, /* phy= */ 0, ssz); @@ -2637,7 +2639,7 @@ static int context_load_partition_table(Context *context) { * larger */ grainsz = secsz < 4096 ? 4096 : secsz; - log_debug("Sector size of device is %lu bytes. Using grain size of %" PRIu64 ".", secsz, grainsz); + log_debug("Sector size of device is %lu bytes. Using filesystem sector size of %" PRIu64 " and grain size of %" PRIu64 ".", secsz, fs_secsz, grainsz); switch (arg_empty) { @@ -6902,26 +6904,38 @@ static int help(void) { if (r < 0) return log_oom(); - printf("%s [OPTIONS...] [DEVICE]\n" - "\n%sGrow and add partitions to partition table.%s\n\n" + printf("%1$s [OPTIONS...] [DEVICE]\n" + "\n%5$sGrow and add partitions to a partition table, and generate disk images (DDIs).%6$s\n\n" " -h --help Show this help\n" " --version Show package version\n" " --no-pager Do not pipe output into a pager\n" " --no-legend Do not show the headers and footers\n" + "\n%3$sOperation:%4$s\n" " --dry-run=BOOL Whether to run dry-run operation\n" " --empty=MODE One of refuse, allow, require, force, create; controls\n" " how to handle empty disks lacking partition tables\n" + " --offline=BOOL Whether to build the image offline\n" " --discard=BOOL Whether to discard backing blocks for new partitions\n" + " --sector-size=SIZE Set the logical sector size for the image\n" + " --architecture=ARCH Set the generic architecture for the image\n" + " --size=BYTES Grow loopback file to specified size\n" + " --seed=UUID 128-bit seed UUID to derive all UUIDs from\n" + " --split=BOOL Whether to generate split artifacts\n" + "\n%3$sOutput:%4$s\n" " --pretty=BOOL Whether to show pretty summary before doing changes\n" + " --json=pretty|short|off\n" + " Generate JSON output\n" + "\n%3$sFactory Reset:%4$s\n" " --factory-reset=BOOL Whether to remove data partitions before recreating\n" " them\n" " --can-factory-reset Test whether factory reset is defined\n" + "\n%3$sConfiguration & Image Control:%4$s\n" " --root=PATH Operate relative to root path\n" " --image=PATH Operate relative to image file\n" " --image-policy=POLICY\n" " Specify disk image dissection policy\n" " --definitions=DIR Find partition definitions in specified directory\n" - " --key-file=PATH Key to use when encrypting partitions\n" + "\n%3$sVerity:%4$s\n" " --private-key=PATH|URI\n" " Private key to use when generating verity roothash\n" " signatures, or an engine or provider specific\n" @@ -6932,6 +6946,8 @@ static int help(void) { " verity roothash signatures\n" " --certificate=PATH PEM certificate to use when generating verity\n" " roothash signatures\n" + "\n%3$sEncryption:%4$s\n" + " --key-file=PATH Key to use when encrypting partitions\n" " --tpm2-device=PATH Path to TPM2 device node to use\n" " --tpm2-device-key=PATH\n" " Enroll a TPM2 device using its public key\n" @@ -6945,11 +6961,7 @@ static int help(void) { " Enroll signed TPM2 PCR policy for specified TPM2 PCRs\n" " --tpm2-pcrlock=PATH\n" " Specify pcrlock policy to lock against\n" - " --seed=UUID 128-bit seed UUID to derive all UUIDs from\n" - " --size=BYTES Grow loopback file to specified size\n" - " --json=pretty|short|off\n" - " Generate JSON output\n" - " --split=BOOL Whether to generate split artifacts\n" + "\n%3$sPartition Control:%4$s\n" " --include-partitions=PARTITION1,PARTITION2,PARTITION3,…\n" " Ignore partitions not of the specified types\n" " --exclude-partitions=PARTITION1,PARTITION2,PARTITION3,…\n" @@ -6957,23 +6969,25 @@ static int help(void) { " --defer-partitions=PARTITION1,PARTITION2,PARTITION3,…\n" " Take partitions of the specified types into account\n" " but don't populate them yet\n" - " --sector-size=SIZE Set the logical sector size for the image\n" - " --architecture=ARCH Set the generic architecture for the image\n" - " --offline=BOOL Whether to build the image offline\n" + "\n%3$sCopying:%4$s\n" " -s --copy-source=PATH Specify the primary source tree to copy files from\n" " --copy-from=IMAGE Copy partitions from the given image(s)\n" + "\n%3$sDDI Profile:%4$s\n" " -S --make-ddi=sysext Make a system extension DDI\n" " -C --make-ddi=confext Make a configuration extension DDI\n" " -P --make-ddi=portable Make a portable service DDI\n" + "\n%3$sAuxiliary Resource Generation:%4$s\n" " --generate-fstab=PATH\n" " Write fstab configuration to the given path\n" " --generate-crypttab=PATH\n" " Write crypttab configuration to the given path\n" - "\nSee the %s for details.\n", + "\nSee the %2$s for details.\n", program_invocation_short_name, - ansi_highlight(), + link, + ansi_underline(), ansi_normal(), - link); + ansi_highlight(), + ansi_normal()); return 0; } diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index e626740..e446461 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -1804,9 +1804,9 @@ int dns_packet_read_rr( if (r < 0) return r; - /* RFC 2181, Section 8, suggests to - * treat a TTL with the MSB set as a zero TTL. */ - if (rr->ttl & UINT32_C(0x80000000)) + /* RFC 2181, Section 8, suggests to treat a TTL with the MSB set as a zero TTL. We avoid doing this + * for OPT records so that all 8 bits of the extended RCODE may be used .*/ + if (key->type != DNS_TYPE_OPT && rr->ttl & UINT32_C(0x80000000)) rr->ttl = 0; r = dns_packet_read_uint16(p, &rdlength, NULL); diff --git a/src/resolve/resolved-dns-packet.h b/src/resolve/resolved-dns-packet.h index 393b7b2..1b649af 100644 --- a/src/resolve/resolved-dns-packet.h +++ b/src/resolve/resolved-dns-packet.h @@ -117,7 +117,7 @@ static inline uint16_t DNS_PACKET_RCODE(DnsPacket *p) { uint16_t rcode; if (p->opt) - rcode = (uint16_t) (p->opt->ttl >> 24); + rcode = (uint16_t) ((p->opt->ttl >> 20) & 0xFF0); else rcode = 0; diff --git a/src/run/run.c b/src/run/run.c index 5779403..ba7bb21 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -1848,7 +1848,8 @@ static int start_transient_service(sd_bus *bus) { if (!isempty(arg_background)) (void) pty_forward_set_background_color(c.forward, arg_background); - set_window_title(c.forward); + if (shall_set_terminal_title()) + set_window_title(c.forward); } path = unit_dbus_path_from_name(service); diff --git a/src/shared/bus-polkit.c b/src/shared/bus-polkit.c index 0382d0b..58cffb6 100644 --- a/src/shared/bus-polkit.c +++ b/src/shared/bus-polkit.c @@ -786,11 +786,13 @@ int varlink_verify_polkit_async_full( if (r != 0) log_debug("Found matching previous polkit authentication for '%s'.", action); if (r < 0) { - /* Reply with a nice error */ - if (sd_bus_error_has_name(&error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED)) - (void) varlink_error(link, VARLINK_ERROR_INTERACTIVE_AUTHENTICATION_REQUIRED, NULL); - else if (ERRNO_IS_NEG_PRIVILEGE(r)) - (void) varlink_error(link, VARLINK_ERROR_PERMISSION_DENIED, NULL); + if (!FLAGS_SET(flags, POLKIT_DONT_REPLY)) { + /* Reply with a nice error */ + if (sd_bus_error_has_name(&error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED)) + (void) varlink_error(link, VARLINK_ERROR_INTERACTIVE_AUTHENTICATION_REQUIRED, NULL); + else if (ERRNO_IS_NEG_PRIVILEGE(r)) + (void) varlink_error(link, VARLINK_ERROR_PERMISSION_DENIED, NULL); + } return r; } diff --git a/src/shared/bus-polkit.h b/src/shared/bus-polkit.h index f3741b2..e0999bc 100644 --- a/src/shared/bus-polkit.h +++ b/src/shared/bus-polkit.h @@ -11,6 +11,7 @@ typedef enum PolkitFLags { POLKIT_ALLOW_INTERACTIVE = 1 << 0, /* Allow interactive auth (typically not required, because can be derived from bus message/link automatically) */ POLKIT_ALWAYS_QUERY = 1 << 1, /* Query polkit even if client is privileged */ POLKIT_DEFAULT_ALLOW = 1 << 2, /* If polkit is not around, assume "allow" rather than the usual "deny" */ + POLKIT_DONT_REPLY = 1 << 3, /* Varlink: don't immediately propagate polkit error to the Varlink client */ } PolkitFlags; int bus_test_polkit(sd_bus_message *call, const char *action, const char **details, uid_t good_user, bool *_challenge, sd_bus_error *e); diff --git a/src/shared/condition.c b/src/shared/condition.c index b53b2ef..1f72ba8 100644 --- a/src/shared/condition.c +++ b/src/shared/condition.c @@ -1009,6 +1009,7 @@ static int condition_test_psi(Condition *c, char **env) { loadavg_t *current, limit; ResourcePressure pressure; int r; + PressureType preferred_pressure_type = PRESSURE_TYPE_FULL; assert(c); assert(c->parameter); @@ -1029,6 +1030,10 @@ static int condition_test_psi(Condition *c, char **env) { return log_debug_errno(r < 0 ? r : SYNTHETIC_ERRNO(EINVAL), "Failed to parse condition parameter %s: %m", c->parameter); /* If only one parameter is passed, then we look at the global system pressure rather than a specific cgroup. */ if (r == 1) { + /* cpu.pressure 'full' is reported but undefined at system level */ + if(c->type == CONDITION_CPU_PRESSURE) + preferred_pressure_type = PRESSURE_TYPE_SOME; + pressure_path = path_join("/proc/pressure", pressure_type); if (!pressure_path) return log_oom_debug(); @@ -1133,8 +1138,9 @@ static int condition_test_psi(Condition *c, char **env) { if (r < 0) return log_debug_errno(r, "Failed to parse loadavg: %s", c->parameter); - r = read_resource_pressure(pressure_path, PRESSURE_TYPE_FULL, &pressure); - if (r == -ENODATA) /* cpu.pressure 'full' was added recently, fall back to 'some'. */ + r = read_resource_pressure(pressure_path, preferred_pressure_type, &pressure); + /* cpu.pressure 'full' was recently added at cgroup level, fall back to 'some' */ + if (r == -ENODATA && preferred_pressure_type == PRESSURE_TYPE_FULL) r = read_resource_pressure(pressure_path, PRESSURE_TYPE_SOME, &pressure); if (r == -ENOENT) { /* We already checked that /proc/pressure exists, so this means we were given a cgroup diff --git a/src/shared/mkfs-util.c b/src/shared/mkfs-util.c index 4d44012..14bf82b 100644 --- a/src/shared/mkfs-util.c +++ b/src/shared/mkfs-util.c @@ -461,6 +461,15 @@ int make_filesystem( if (quiet) stdio_fds[1] = -EBADF; + if (sector_size > 0) { + if (strv_extend(&argv, "--sectorsize") < 0) + return log_oom(); + + /* mkfs.btrfs expects a sector size of at least 4k bytes. */ + if (strv_extendf(&argv, "%"PRIu64, MAX(sector_size, 4 * U64_KB)) < 0) + return log_oom(); + } + } else if (streq(fstype, "f2fs")) { argv = strv_new(mkfs, "-g", /* "default options" */ diff --git a/src/shared/parse-helpers.c b/src/shared/parse-helpers.c index ca6842d..63f592d 100644 --- a/src/shared/parse-helpers.c +++ b/src/shared/parse-helpers.c @@ -10,6 +10,22 @@ #include "path-util.h" #include "utf8.h" +static bool validate_api_vfs(const char *path, PathSimplifyWarnFlags flags) { + + assert(path); + + if ((flags & (PATH_CHECK_NON_API_VFS|PATH_CHECK_NON_API_VFS_DEV_OK)) == 0) + return true; + + if (!path_below_api_vfs(path)) + return true; + + if (FLAGS_SET(flags, PATH_CHECK_NON_API_VFS_DEV_OK) && path_startswith(path, "/dev")) + return true; + + return false; +} + int path_simplify_and_warn( char *path, PathSimplifyWarnFlags flags, @@ -23,6 +39,7 @@ int path_simplify_and_warn( assert(path); assert(!FLAGS_SET(flags, PATH_CHECK_ABSOLUTE | PATH_CHECK_RELATIVE)); + assert(!FLAGS_SET(flags, PATH_CHECK_NON_API_VFS | PATH_CHECK_NON_API_VFS_DEV_OK)); assert(lvalue); if (!utf8_is_valid(path)) @@ -56,7 +73,7 @@ int path_simplify_and_warn( "%s= path is not normalized%s: %s", lvalue, fatal ? "" : ", ignoring", path); - if (FLAGS_SET(flags, PATH_CHECK_NON_API_VFS) && path_below_api_vfs(path)) + if (!validate_api_vfs(path, flags)) return log_syntax(unit, level, filename, line, SYNTHETIC_ERRNO(EINVAL), "%s= path is below API VFS%s: %s", lvalue, fatal ? ", refusing" : ", ignoring", diff --git a/src/shared/parse-helpers.h b/src/shared/parse-helpers.h index 6d1034b..29ab60f 100644 --- a/src/shared/parse-helpers.h +++ b/src/shared/parse-helpers.h @@ -4,11 +4,12 @@ #include <stdint.h> typedef enum PathSimplifyWarnFlags { - PATH_CHECK_FATAL = 1 << 0, /* If not set, then error message is appended with 'ignoring'. */ - PATH_CHECK_ABSOLUTE = 1 << 1, - PATH_CHECK_RELATIVE = 1 << 2, - PATH_KEEP_TRAILING_SLASH = 1 << 3, - PATH_CHECK_NON_API_VFS = 1 << 4, + PATH_CHECK_FATAL = 1 << 0, /* If not set, then error message is appended with 'ignoring'. */ + PATH_CHECK_ABSOLUTE = 1 << 1, + PATH_CHECK_RELATIVE = 1 << 2, + PATH_KEEP_TRAILING_SLASH = 1 << 3, + PATH_CHECK_NON_API_VFS = 1 << 4, + PATH_CHECK_NON_API_VFS_DEV_OK = 1 << 5, } PathSimplifyWarnFlags; int path_simplify_and_warn( diff --git a/src/shared/pretty-print.c b/src/shared/pretty-print.c index c75f74a..4692a6a 100644 --- a/src/shared/pretty-print.c +++ b/src/shared/pretty-print.c @@ -17,6 +17,7 @@ #include "string-util.h" #include "strv.h" #include "terminal-util.h" +#include "utf8.h" void draw_cylon(char buffer[], size_t buflen, unsigned width, unsigned pos) { char *p = buffer; @@ -467,8 +468,8 @@ void draw_progress_bar(const char *prefix, double percentage) { if (!terminal_is_dumb()) { size_t cols = columns(); - size_t prefix_length = strlen_ptr(prefix); - size_t length = cols > prefix_length + 6 ? cols - prefix_length - 6 : 0; + size_t prefix_width = utf8_console_width(prefix); + size_t length = cols > prefix_width + 6 ? cols - prefix_width - 6 : 0; if (length > 5 && percentage >= 0.0 && percentage <= 100.0) { size_t p = (size_t) (length * percentage / 100.0); @@ -519,7 +520,7 @@ void clear_progress_bar(const char *prefix) { fputc('\r', stderr); if (terminal_is_dumb()) - fputs(strrepa(" ", strlen_ptr(prefix) + 4), /* 4: %3.0f%% */ + fputs(strrepa(" ", utf8_console_width(prefix) + 4), /* 4: %3.0f%% */ stderr); else fputs(ANSI_ERASE_TO_END_OF_LINE, stderr); diff --git a/src/shared/ptyfwd.c b/src/shared/ptyfwd.c index 998ce96..842aef9 100644 --- a/src/shared/ptyfwd.c +++ b/src/shared/ptyfwd.c @@ -17,6 +17,7 @@ #include "sd-event.h" #include "alloc-util.h" +#include "env-util.h" #include "errno-util.h" #include "extract-word.h" #include "fd-util.h" @@ -367,6 +368,21 @@ static int insert_background_fix(PTYForward *f, size_t offset) { return insert_string(f, offset, s); } +bool shall_set_terminal_title(void) { + static int cache = -1; + + if (cache >= 0) + return cache; + + cache = getenv_bool("SYSTEMD_ADJUST_TERMINAL_TITLE"); + if (cache == -ENXIO) + return (cache = true); + if (cache < 0) + log_debug_errno(cache, "Failed to parse $SYSTEMD_ADJUST_TERMINAL_TITLE, leaving terminal title setting enabled: %m"); + + return cache != 0; +} + static int insert_window_title_fix(PTYForward *f, size_t offset) { assert(f); diff --git a/src/shared/ptyfwd.h b/src/shared/ptyfwd.h index 248646d..b86027e 100644 --- a/src/shared/ptyfwd.h +++ b/src/shared/ptyfwd.h @@ -50,4 +50,6 @@ int pty_forward_set_titlef(PTYForward *f, const char *format, ...) _printf_(2,3) int pty_forward_set_title_prefix(PTYForward *f, const char *prefix); +bool shall_set_terminal_title(void); + DEFINE_TRIVIAL_CLEANUP_FUNC(PTYForward*, pty_forward_free); diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c index 2469e24..d31d6b4 100644 --- a/src/shared/seccomp-util.c +++ b/src/shared/seccomp-util.c @@ -2030,39 +2030,43 @@ int parse_syscall_archs(char **l, Set **ret_archs) { return 0; } -int seccomp_filter_set_add(Hashmap *filter, bool add, const SyscallFilterSet *set) { - int r; +int seccomp_filter_set_add_by_name(Hashmap *filter, bool add, const char *name) { + assert(filter); + assert(name); - assert(set); + if (name[0] == '@') { + const SyscallFilterSet *more; - NULSTR_FOREACH(i, set->value) { + more = syscall_filter_set_find(name); + if (!more) + return -ENXIO; - if (i[0] == '@') { - const SyscallFilterSet *more; + return seccomp_filter_set_add(filter, add, more); + } - more = syscall_filter_set_find(i); - if (!more) - return -ENXIO; + int id = seccomp_syscall_resolve_name(name); + if (id == __NR_SCMP_ERROR) { + log_debug("System call %s is not known, ignoring.", name); + return 0; + } - r = seccomp_filter_set_add(filter, add, more); - if (r < 0) - return r; - } else { - int id; + if (add) + return hashmap_put(filter, INT_TO_PTR(id + 1), INT_TO_PTR(-1)); - id = seccomp_syscall_resolve_name(i); - if (id == __NR_SCMP_ERROR) { - log_debug("System call %s is not known, ignoring.", i); - continue; - } + (void) hashmap_remove(filter, INT_TO_PTR(id + 1)); + return 0; +} - if (add) { - r = hashmap_put(filter, INT_TO_PTR(id + 1), INT_TO_PTR(-1)); - if (r < 0) - return r; - } else - (void) hashmap_remove(filter, INT_TO_PTR(id + 1)); - } +int seccomp_filter_set_add(Hashmap *filter, bool add, const SyscallFilterSet *set) { + int r; + + assert(filter); + assert(set); + + NULSTR_FOREACH(i, set->value) { + r = seccomp_filter_set_add_by_name(filter, add, i); + if (r < 0) + return r; } return 0; diff --git a/src/shared/seccomp-util.h b/src/shared/seccomp-util.h index 7583357..7be1117 100644 --- a/src/shared/seccomp-util.h +++ b/src/shared/seccomp-util.h @@ -70,6 +70,7 @@ extern const SyscallFilterSet syscall_filter_sets[]; const SyscallFilterSet *syscall_filter_set_find(const char *name); +int seccomp_filter_set_add_by_name(Hashmap *s, bool b, const char *name); int seccomp_filter_set_add(Hashmap *s, bool b, const SyscallFilterSet *set); int seccomp_add_syscall_filter_item( diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index 52f4a47..5fe3b0c 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -1051,7 +1051,7 @@ static int uid_is_ok( if (r >= 0) return 0; if (r != -ESRCH) - return r; + log_warning_errno(r, "Unexpected failure while looking up UID '" UID_FMT "' via NSS, assuming it doesn't exist: %m", uid); if (check_with_gid) { r = getgrgid_malloc((gid_t) uid, &g); @@ -1059,7 +1059,7 @@ static int uid_is_ok( if (!streq(g->gr_name, name)) return 0; } else if (r != -ESRCH) - return r; + log_warning_errno(r, "Unexpected failure while looking up GID '" GID_FMT "' via NSS, assuming it doesn't exist: %m", uid); } } @@ -1164,7 +1164,7 @@ static int add_user(Context *c, Item *i) { return 0; } if (r != -ESRCH) - return log_error_errno(r, "Failed to check if user %s already exists: %m", i->name); + log_warning_errno(r, "Unexpected failure while looking up user '%s' via NSS, assuming it doesn't exist: %m", i->name); } /* Try to use the suggested numeric UID */ @@ -1284,14 +1284,14 @@ static int gid_is_ok( if (r >= 0) return 0; if (r != -ESRCH) - return r; + log_warning_errno(r, "Unexpected failure while looking up GID '" GID_FMT "' via NSS, assuming it doesn't exist: %m", gid); if (check_with_uid) { r = getpwuid_malloc(gid, /* ret= */ NULL); if (r >= 0) return 0; if (r != -ESRCH) - return r; + log_warning_errno(r, "Unexpected failure while looking up GID '" GID_FMT "' via NSS, assuming it doesn't exist: %m", gid); } } @@ -1326,7 +1326,7 @@ static int get_gid_by_name( return 0; } if (r != -ESRCH) - return log_error_errno(r, "Failed to check if group %s already exists: %m", name); + log_warning_errno(r, "Unexpected failure while looking up group '%s' via NSS, assuming it doesn't exist: %m", name); } return -ENOENT; diff --git a/src/test/test-cgroup.c b/src/test/test-cgroup.c index 8bd4af9..040e9e9 100644 --- a/src/test/test-cgroup.c +++ b/src/test/test-cgroup.c @@ -159,6 +159,8 @@ TEST(id) { if (ERRNO_IS_NEG_PRIVILEGE(fd2)) log_notice("Skipping open-by-cgroup-id test because lacking privs."); + else if (ERRNO_IS_NEG_NOT_SUPPORTED(fd2)) + log_notice("Skipping open-by-cgroup-id test because syscall is missing or blocked."); else { assert_se(fd2 >= 0); diff --git a/src/test/test-execute.c b/src/test/test-execute.c index 4b8daa4..56f5e34 100644 --- a/src/test/test-execute.c +++ b/src/test/test-execute.c @@ -832,6 +832,8 @@ static void test_exec_systemcallfilter(Manager *m) { return; } + test(m, "exec-systemcallfilter-writing-handoff-timestamp.service", 0, CLD_EXITED); + test(m, "exec-systemcallfilter-not-failing.service", 0, CLD_EXITED); test(m, "exec-systemcallfilter-not-failing2.service", 0, CLD_EXITED); test(m, "exec-systemcallfilter-not-failing3.service", 0, CLD_EXITED); diff --git a/src/test/test-mountpoint-util.c b/src/test/test-mountpoint-util.c index 85c0859..07c0480 100644 --- a/src/test/test-mountpoint-util.c +++ b/src/test/test-mountpoint-util.c @@ -10,6 +10,7 @@ #include "fileio.h" #include "hashmap.h" #include "log.h" +#include "missing_syscall.h" #include "mountpoint-util.h" #include "path-util.h" #include "rm-rf.h" @@ -317,6 +318,35 @@ TEST(fd_is_mount_point) { r = fd_is_mount_point(fd, NULL, 0); assert_se(IN_SET(r, 0, -ENOTDIR)); /* on old kernels we can't determine if regular files are mount points if we have no directory fd */ assert_se(fd_is_mount_point(fd, "", 0) == -EINVAL); + + if (!mount_new_api_supported()) + return; + + /* Symlinks can be mount points with new mount API */ + _cleanup_close_ int mfd = -EBADF, rfd = -EBADF; + _cleanup_free_ char *t = NULL; + struct stat st; + + safe_close(fd); + ASSERT_OK_ERRNO(fd = open(tmpdir, O_DIRECTORY|O_PATH|O_CLOEXEC)); + + ASSERT_OK_ERRNO(symlinkat("/usr", fd, "symlink")); + + mfd = open_tree(fd, "symlink", AT_SYMLINK_NOFOLLOW|OPEN_TREE_CLONE|OPEN_TREE_CLOEXEC); + if (mfd < 0 && ERRNO_IS_PRIVILEGE(errno)) + return; + ASSERT_OK_ERRNO(mfd); + + ASSERT_OK_ERRNO(rfd = openat(fd, "regular", O_CLOEXEC|O_CREAT|O_EXCL, 0644)); + + ASSERT_OK_ERRNO(move_mount(mfd, "", rfd, "", MOVE_MOUNT_F_EMPTY_PATH|MOVE_MOUNT_T_EMPTY_PATH)); + + ASSERT_OK_ERRNO(fstatat(fd, "regular", &st, AT_SYMLINK_NOFOLLOW)); + ASSERT_OK(stat_verify_symlink(&st)); + ASSERT_OK(readlinkat_malloc(fd, "regular", &t)); + ASSERT_STREQ(t, "/usr"); + + ASSERT_OK(fd_is_mount_point(fd, "regular", 0)); } TEST(ms_nosymfollow_supported) { diff --git a/src/ukify/ukify.py b/src/ukify/ukify.py index f1db9ba..75e4286 100755 --- a/src/ukify/ukify.py +++ b/src/ukify/ukify.py @@ -51,7 +51,7 @@ from typing import (Any, import pefile # type: ignore -__version__ = '{{PROJECT_VERSION_FULL}} ({{VERSION_TAG}})' +__version__ = '{{PROJECT_VERSION}} ({{VERSION_TAG}})' EFI_ARCH_MAP = { # host_arch glob : [efi_arch, 32_bit_efi_arch if mixed mode is supported] diff --git a/src/vmspawn/vmspawn-util.h b/src/vmspawn/vmspawn-util.h index fed0996..ee02752 100644 --- a/src/vmspawn/vmspawn-util.h +++ b/src/vmspawn/vmspawn-util.h @@ -34,7 +34,7 @@ #if defined(__x86_64__) || defined(__i386__) # define QEMU_MACHINE_TYPE "q35" -#elif defined(__arm__) || defined(__aarch64__) +#elif defined(__arm__) || defined(__aarch64__) || defined(__riscv) || defined(__loongarch64) # define QEMU_MACHINE_TYPE "virt" #elif defined(__s390__) || defined(__s390x__) # define QEMU_MACHINE_TYPE "s390-ccw-virtio" diff --git a/src/vmspawn/vmspawn.c b/src/vmspawn/vmspawn.c index 326722d..8f15d04 100644 --- a/src/vmspawn/vmspawn.c +++ b/src/vmspawn/vmspawn.c @@ -2141,7 +2141,8 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) { } else if (!isempty(arg_background)) (void) pty_forward_set_background_color(forward, arg_background); - set_window_title(forward); + if (shall_set_terminal_title()) + set_window_title(forward); } r = sd_event_loop(event); diff --git a/test/TEST-06-SELINUX/meson.build b/test/TEST-06-SELINUX/meson.build index 9261a49..5036b64 100644 --- a/test/TEST-06-SELINUX/meson.build +++ b/test/TEST-06-SELINUX/meson.build @@ -3,7 +3,7 @@ integration_tests += [ integration_test_template + { 'name' : fs.name(meson.current_source_dir()), - 'cmdline' : integration_test_template['cmdline'] + ['selinux=1', 'lsm=selinux'], + 'cmdline' : integration_test_template['cmdline'] + ['systemd.wants=autorelabel.service', 'selinux=1', 'lsm=selinux'], # FIXME; Figure out why reboot sometimes hangs with 'linux' firmware. # Use 'auto' to automatically fallback on non-uefi architectures. 'firmware' : 'auto', diff --git a/test/TEST-09-REBOOT/meson.build b/test/TEST-09-REBOOT/meson.build index b755618..3e46a73 100644 --- a/test/TEST-09-REBOOT/meson.build +++ b/test/TEST-09-REBOOT/meson.build @@ -4,5 +4,8 @@ integration_tests += [ integration_test_template + { 'name' : fs.name(meson.current_source_dir()), 'storage' : 'persistent', + # FIXME: Figure out why reboot sometimes hangs with 'linux' firmware. + # Use 'auto' to automatically fallback on non-uefi architectures. + 'firmware' : 'auto', }, ] diff --git a/test/TEST-18-FAILUREACTION/meson.build b/test/TEST-18-FAILUREACTION/meson.build index 8dec5f3..ee96008 100644 --- a/test/TEST-18-FAILUREACTION/meson.build +++ b/test/TEST-18-FAILUREACTION/meson.build @@ -3,5 +3,8 @@ integration_tests += [ integration_test_template + { 'name' : fs.name(meson.current_source_dir()), + # FIXME: Figure out why reboot sometimes hangs with 'linux' firmware. + # Use 'auto' to automatically fallback on non-uefi architectures. + 'firmware' : 'auto', }, ] diff --git a/test/TEST-24-CRYPTSETUP/test.sh b/test/TEST-24-CRYPTSETUP/test.sh index a7e118c..a275cca 100755 --- a/test/TEST-24-CRYPTSETUP/test.sh +++ b/test/TEST-24-CRYPTSETUP/test.sh @@ -198,7 +198,7 @@ EOF # Forward journal messages to the console, so we have something to investigate even if we fail to mount # the encrypted /var - mkdir "$initdir/etc/systemd/journald.conf.d/" + mkdir -p "$initdir/etc/systemd/journald.conf.d/" echo -ne "[Journal]\nForwardToConsole=yes\n" >"$initdir/etc/systemd/journald.conf.d/99-forward.conf" # If $INITRD wasn't provided explicitly, generate a custom one with dm-crypt diff --git a/test/TEST-54-CREDS/meson.build b/test/TEST-54-CREDS/meson.build index 8edb043..f725035 100644 --- a/test/TEST-54-CREDS/meson.build +++ b/test/TEST-54-CREDS/meson.build @@ -27,5 +27,6 @@ integration_tests += [ '-smbios', 'type=11,value=io.systemd.credential.binary:fstab.extra=aW5qZWN0ZWQgL2luamVjdGVkIHRtcGZzIFgtbW91bnQubWtkaXIgMCAwCg==', '-smbios', 'type=11,value=io.systemd.credential:getty.ttys.container=idontexist', ], + 'firmware' : 'auto', }, ] diff --git a/test/TEST-64-UDEV-STORAGE/long_sysfs_path.configure b/test/TEST-64-UDEV-STORAGE/long_sysfs_path.configure index 6108bdb..6e8e312 100755 --- a/test/TEST-64-UDEV-STORAGE/long_sysfs_path.configure +++ b/test/TEST-64-UDEV-STORAGE/long_sysfs_path.configure @@ -23,10 +23,9 @@ config["QemuArgs"] += ["-device", "pci-bridge,id=pci_bridge0,chassis_nr=64"] for bridge in range(1, 26): config["QemuArgs"] += [ "-device", - f"pci-bridge,id=pci_bridge{bridge},bus=pci_bridge{bridge - 1}," - f"chassis_nr={64 + bridge}" + f"pci-bridge,id=pci_bridge{bridge},bus=pci_bridge{bridge - 1},chassis_nr={64 + bridge},addr=1", ] -config["QemuArgs"] += ["-device", f"virtio-blk-pci,drive=drive0,scsi=off,bus=pci_bridge25"] +config["QemuArgs"] += ["-device", f"virtio-blk-pci,drive=drive0,scsi=off,bus=pci_bridge25,addr=1"] json.dump(config, sys.stdout) diff --git a/test/TEST-64-UDEV-STORAGE/nvme_basic.configure b/test/TEST-64-UDEV-STORAGE/nvme_basic.configure index 37d0d35..28ddfa4 100755 --- a/test/TEST-64-UDEV-STORAGE/nvme_basic.configure +++ b/test/TEST-64-UDEV-STORAGE/nvme_basic.configure @@ -9,8 +9,8 @@ import sys config = json.load(sys.stdin) -qemu = f"qemu-system-{os.environ["QEMU_ARCHITECTURE"]}" -result = subprocess.run([qemu, '-device', 'help'], check=True, text=True, stdout=subprocess.PIPE) +qemu = f"qemu-system-{os.environ['QEMU_ARCHITECTURE']}" +result = subprocess.run([qemu, "-device", "help"], check=True, text=True, stdout=subprocess.PIPE) if 'name "nvme"' not in result.stdout: print("nvme device driver is not available, skipping test...", file=sys.stderr) exit(77) diff --git a/test/TEST-64-UDEV-STORAGE/nvme_subsystem.configure b/test/TEST-64-UDEV-STORAGE/nvme_subsystem.configure index eb601a6..3d79007 100755 --- a/test/TEST-64-UDEV-STORAGE/nvme_subsystem.configure +++ b/test/TEST-64-UDEV-STORAGE/nvme_subsystem.configure @@ -9,8 +9,8 @@ import sys config = json.load(sys.stdin) -qemu = f"qemu-system-{os.environ["QEMU_ARCHITECTURE"]}" -result = subprocess.run([qemu, '-device', 'help'], check=True, text=True, stdout=subprocess.PIPE) +qemu = f"qemu-system-{os.environ['QEMU_ARCHITECTURE']}" +result = subprocess.run([qemu, "-device", "help"], check=True, text=True, stdout=subprocess.PIPE) if 'name "nvme"' not in result.stdout: print("nvme device driver is not available, skipping test...", file=sys.stderr) exit(77) diff --git a/test/TEST-64-UDEV-STORAGE/virtio_scsi_identically_named_partitions.configure b/test/TEST-64-UDEV-STORAGE/virtio_scsi_identically_named_partitions.configure index e850247..edc5138 100755 --- a/test/TEST-64-UDEV-STORAGE/virtio_scsi_identically_named_partitions.configure +++ b/test/TEST-64-UDEV-STORAGE/virtio_scsi_identically_named_partitions.configure @@ -9,8 +9,8 @@ import sys config = json.load(sys.stdin) -qemu = f"qemu-system-{os.environ["QEMU_ARCHITECTURE"]}" -result = subprocess.run([qemu, '-device', 'help'], check=True, text=True, stdout=subprocess.PIPE) +qemu = f"qemu-system-{os.environ['QEMU_ARCHITECTURE']}" +result = subprocess.run([qemu, "-device", "help"], check=True, text=True, stdout=subprocess.PIPE) if 'name "virtio-scsi-pci"' not in result.stdout: print("virtio-scsi-pci device driver is not available, skipping test...", file=sys.stderr) exit(77) diff --git a/test/TEST-70-TPM2/meson.build b/test/TEST-70-TPM2/meson.build index d84c2b7..8836864 100644 --- a/test/TEST-70-TPM2/meson.build +++ b/test/TEST-70-TPM2/meson.build @@ -8,5 +8,6 @@ integration_tests += [ 'after' : '@0@ tpm2.target'.format(integration_test_template['configuration']['after']), }, 'vm' : true, + 'firmware' : 'auto', }, ] diff --git a/test/integration-test-wrapper.py b/test/integration-test-wrapper.py index b6a16aa..743a14c 100755 --- a/test/integration-test-wrapper.py +++ b/test/integration-test-wrapper.py @@ -61,6 +61,8 @@ def main(): print(f"TEST_NO_QEMU=1, skipping {args.name}", file=sys.stderr) exit(77) + keep_journal = os.getenv("TEST_SAVE_JOURNAL", "fail") + name = args.name + (f"-{i}" if (i := os.getenv("MESON_TEST_ITERATION")) else "") dropin = textwrap.dedent( @@ -101,6 +103,12 @@ def main(): journal_file = (args.meson_build_dir / (f"test/journal/{name}.journal")).absolute() journal_file.unlink(missing_ok=True) else: + dropin += textwrap.dedent( + """ + [Unit] + Wants=multi-user.target + """ + ) journal_file = None cmd = [ @@ -152,11 +160,10 @@ def main(): result = subprocess.run(cmd) - if result.returncode in (args.exit_code, 77): - # Do not keep journal files for tests that don't fail. - if journal_file: - journal_file.unlink(missing_ok=True) + if journal_file and (keep_journal == "0" or (result.returncode in (args.exit_code, 77) and keep_journal == "fail")): + journal_file.unlink(missing_ok=True) + if result.returncode in (args.exit_code, 77): exit(0 if result.returncode == args.exit_code else 77) if journal_file: diff --git a/test/test-execute/exec-systemcallfilter-writing-handoff-timestamp.service b/test/test-execute/exec-systemcallfilter-writing-handoff-timestamp.service new file mode 100644 index 0000000..3bf2a64 --- /dev/null +++ b/test/test-execute/exec-systemcallfilter-writing-handoff-timestamp.service @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +[Unit] +Description=Test for SystemCallFilter + +[Service] +ExecStart=true +Type=oneshot +# For issue #33299 +SystemCallFilter=~@network-io +SystemCallFilter=~write +SystemCallErrorNumber=ENOSYS diff --git a/test/test-functions b/test/test-functions index 8b497b2..03f188b 100644 --- a/test/test-functions +++ b/test/test-functions @@ -1947,6 +1947,7 @@ EOF install_config_files() { dinfo "Install config files" inst /etc/sysconfig/init || : + inst /etc/hosts inst /etc/passwd inst /etc/shadow inst_any /etc/login.defs /usr/etc/login.defs @@ -2959,6 +2960,8 @@ inst_recursive() { while read -r item; do if [[ -d "$item" ]]; then inst_dir "$item" + elif [[ -L "$item" ]]; then + inst_symlink "$item" elif [[ -f "$item" ]]; then inst_simple "$item" fi diff --git a/test/test-network/conf/25-ipv6-prefix-veth-static-route.network b/test/test-network/conf/25-ipv6-prefix-veth-static-route.network new file mode 100644 index 0000000..a2ea7bf --- /dev/null +++ b/test/test-network/conf/25-ipv6-prefix-veth-static-route.network @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +[Match] +Name=veth99 + +[Network] +IPv6AcceptRA=true + +[Route] +Gateway=fe80::1034:56ff:fe78:9abd +GatewayOnLink=no +Metric=256 + +[IPv6AcceptRA] +RouteMetric=256 diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 0355c7a..7c336ba 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -5824,6 +5824,30 @@ class NetworkdRATests(unittest.TestCase, Utilities): self.assertIn('pref high', output) self.assertNotIn('pref low', output) + def test_ndisc_vs_static_route(self): + copy_network_unit('25-veth.netdev', '25-ipv6-prefix.network', '25-ipv6-prefix-veth-static-route.network') + start_networkd() + self.wait_online('veth99:routable', 'veth-peer:degraded') + + output = check_output('ip -6 route show dev veth99 table all') + print(output) + + # If a conflicting static route is already configured, do not override the static route. + output = check_output('ip -6 route show dev veth99 default via fe80::1034:56ff:fe78:9abd') + print(output) + self.assertIn('default proto static metric 256 pref medium', output) + self.assertNotIn('proto ra', output) + + if not os.path.exists(test_ndisc_send): + self.skipTest(f"{test_ndisc_send} does not exist.") + + # Also check if the static route is protected from RA with zero lifetime + check_output(f'{test_ndisc_send} --interface veth-peer --type router-advertisement --lifetime 0') + time.sleep(2) + output = check_output('ip -6 route show dev veth99 default via fe80::1034:56ff:fe78:9abd') + print(output) + self.assertIn('default proto static metric 256 pref medium', output) + # radvd supports captive portal since v2.20. # https://github.com/radvd-project/radvd/commit/791179a7f730decbddb2290ef0e34aa85d71b1bc @unittest.skipUnless(radvd_check_config('captive-portal.conf'), "Installed radvd doesn't support captive portals") diff --git a/test/units/TEST-29-PORTABLE.sh b/test/units/TEST-29-PORTABLE.sh index 27c24a0..b4dcd5a 100755 --- a/test/units/TEST-29-PORTABLE.sh +++ b/test/units/TEST-29-PORTABLE.sh @@ -354,6 +354,17 @@ portablectl detach --now --runtime --enable /tmp/rootdir minimal-app0 portablectl "${ARGS[@]}" attach --copy=symlink --now --runtime /tmp/rootdir minimal-app0 portablectl detach --now --runtime --enable /tmp/rootdir minimal-app0 +# The wrong file should be ignored, given the right one has the xattr set +mkdir -p /tmp/wrongext/usr/lib/extension-release.d /tmp/wrongext/usr/lib/systemd/system/ +echo "[Service]" > /tmp/wrongext/usr/lib/systemd/system/app0.service +touch /tmp/wrongext/usr/lib/extension-release.d/extension-release.wrongext_somethingwrong.txt +cp /tmp/rootdir/usr/lib/os-release /tmp/wrongext/usr/lib/extension-release.d/extension-release.app0 +setfattr -n user.extension-release.strict -v "false" /tmp/wrongext/usr/lib/extension-release.d/extension-release.app0 +portablectl "${ARGS[@]}" attach --runtime --extension /tmp/wrongext /tmp/rootdir app0 +status="$(portablectl is-attached --extension wrongext rootdir)" +[[ "${status}" == "attached-runtime" ]] +portablectl detach --runtime --extension /tmp/wrongext /tmp/rootdir app0 + umount /tmp/rootdir umount /tmp/app0 umount /tmp/app1 diff --git a/test/units/TEST-45-TIMEDATE.sh b/test/units/TEST-45-TIMEDATE.sh index dff3ed0..420ebef 100755 --- a/test/units/TEST-45-TIMEDATE.sh +++ b/test/units/TEST-45-TIMEDATE.sh @@ -218,7 +218,7 @@ assert_ntp() { assert_timedated_signal() { local timestamp="${1:?}" local value="${2:?}" - local args=(-q -n 1 --since="$timestamp" -p info _SYSTEMD_UNIT="busctl-monitor.service") + local args=(-q -n 1 --since="$timestamp" -p info -t busctl) journalctl --sync @@ -298,7 +298,7 @@ assert_timesyncd_signal() { local timestamp="${1:?}" local property="${2:?}" local value="${3:?}" - local args=(-q --since="$timestamp" -p info _SYSTEMD_UNIT="busctl-monitor.service") + local args=(-q --since="$timestamp" -p info -t busctl) journalctl --sync diff --git a/test/units/TEST-58-REPART.sh b/test/units/TEST-58-REPART.sh index 8a014ac..743baad 100755 --- a/test/units/TEST-58-REPART.sh +++ b/test/units/TEST-58-REPART.sh @@ -423,7 +423,7 @@ EOF --json=pretty \ "$imgs/zzz") - diff -u <(echo "$output") - <<EOF + diff -u - <<EOF <(echo "$output") [ { "type" : "swap", @@ -484,7 +484,7 @@ EOF --json=pretty \ "$imgs/zzz") - diff -u <(echo "$output") - <<EOF + diff -u - <<EOF <(echo "$output") [ { "type" : "swap", @@ -1198,7 +1198,8 @@ EOF --json=pretty \ "$imgs/zzz") - diff -u <(echo "$output1" | grep -E "(offset|raw_size|raw_padding)") <(echo "$output2" | grep -E "(offset|raw_size|raw_padding)") + diff -u <(echo "$output1" | grep -E "(offset|raw_size|raw_padding)") \ + <(echo "$output2" | grep -E "(offset|raw_size|raw_padding)") } test_sector() { diff --git a/test/units/TEST-64-UDEV-STORAGE.sh b/test/units/TEST-64-UDEV-STORAGE.sh index 5ddddf5..431b530 100755 --- a/test/units/TEST-64-UDEV-STORAGE.sh +++ b/test/units/TEST-64-UDEV-STORAGE.sh @@ -231,8 +231,8 @@ testcase_nvme_subsystem() { /dev/disk/by-id/nvme-QEMU_NVMe_Ctrl_deadbeef_16 /dev/disk/by-id/nvme-QEMU_NVMe_Ctrl_deadbeef_17 # Shared namespaces - /dev/disk/by-path/pci-*-nvme-16 - /dev/disk/by-path/pci-*-nvme-17 + /dev/disk/by-path/*pci*-nvme-16 + /dev/disk/by-path/*pci*-nvme-17 ) udevadm wait --settle --timeout=30 "${expected_symlinks[@]}" diff --git a/test/units/TEST-69-SHUTDOWN.py b/test/units/TEST-69-SHUTDOWN.py index eb790f4..d044164 100755 --- a/test/units/TEST-69-SHUTDOWN.py +++ b/test/units/TEST-69-SHUTDOWN.py @@ -9,6 +9,13 @@ import pexpect def main(): + # TODO: drop once https://bugs.debian.org/1075733 is fixed + with open("/usr/lib/os-release") as f: + for line in f: + if line.startswith("ID="): + if "debian" in line: + sys.exit(77) + logger = logging.getLogger("test-shutdown") consoles = [] diff --git a/test/units/TEST-74-AUX-UTILS.ssh.sh b/test/units/TEST-74-AUX-UTILS.ssh.sh index 5d87d9f..79055a1 100755 --- a/test/units/TEST-74-AUX-UTILS.ssh.sh +++ b/test/units/TEST-74-AUX-UTILS.ssh.sh @@ -46,7 +46,10 @@ test -f /etc/ssh/ssh_host_rsa_key || ssh-keygen -t rsa -C '' -N '' -f /etc/ssh/s echo "PermitRootLogin yes" >> /etc/ssh/sshd_config echo "LogLevel DEBUG3" >> /etc/ssh/sshd_config -test -f /etc/ssh/ssh_config || echo 'Include /etc/ssh/ssh_config.d/*.conf' > /etc/ssh/ssh_config +test -f /etc/ssh/ssh_config || { + echo 'Include /etc/ssh/ssh_config.d/*.conf' + echo 'Include /usr/etc/ssh/ssh_config.d/*.conf' +} >/etc/ssh/ssh_config # ssh wants this dir around, but distros cannot agree on a common name for it, let's just create all that are aware of distros use mkdir -p /usr/share/empty.sshd /var/empty /var/empty/sshd /run/sshd diff --git a/test/units/TEST-74-AUX-UTILS.sysusers.sh b/test/units/TEST-74-AUX-UTILS.sysusers.sh new file mode 100755 index 0000000..dcd2993 --- /dev/null +++ b/test/units/TEST-74-AUX-UTILS.sysusers.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -eux +set -o pipefail + +# shellcheck source=test/units/util.sh +. "$(dirname "$0")"/util.sh + +at_exit() { + set +e + userdel -r foobarbaz + umount /run/systemd/userdb/ +} + +# Check that we indeed run under root to make the rest of the test work +[[ "$(id -u)" -eq 0 ]] + +trap at_exit EXIT + +# Ensure that a non-responsive NSS socket doesn't make sysusers fail +mount -t tmpfs tmpfs /run/systemd/userdb/ +touch /run/systemd/userdb/io.systemd.DynamicUser +echo 'u foobarbaz' | SYSTEMD_LOG_LEVEL=debug systemd-sysusers - +grep -q foobarbaz /etc/passwd diff --git a/test/units/TEST-75-RESOLVED.sh b/test/units/TEST-75-RESOLVED.sh index a4417ce..4f38720 100755 --- a/test/units/TEST-75-RESOLVED.sh +++ b/test/units/TEST-75-RESOLVED.sh @@ -11,6 +11,8 @@ set -eux set -o pipefail +# shellcheck source=test/units/test-control.sh +. "$(dirname "$0")"/test-control.sh # shellcheck source=test/units/util.sh . "$(dirname "$0")"/util.sh @@ -65,143 +67,25 @@ restart_resolved() { systemctl service-log-level systemd-resolved.service debug } -# Test for resolvectl, resolvconf -systemctl unmask systemd-resolved.service -systemctl enable --now systemd-resolved.service -systemctl service-log-level systemd-resolved.service debug -ip link add hoge type dummy -ip link add hoge.foo type dummy -resolvectl dns hoge 10.0.0.1 10.0.0.2 -resolvectl dns hoge.foo 10.0.0.3 10.0.0.4 -assert_in '10.0.0.1 10.0.0.2' "$(resolvectl dns hoge)" -assert_in '10.0.0.3 10.0.0.4' "$(resolvectl dns hoge.foo)" -resolvectl dns hoge 10.0.1.1 10.0.1.2 -resolvectl dns hoge.foo 10.0.1.3 10.0.1.4 -assert_in '10.0.1.1 10.0.1.2' "$(resolvectl dns hoge)" -assert_in '10.0.1.3 10.0.1.4' "$(resolvectl dns hoge.foo)" -if ! RESOLVCONF=$(command -v resolvconf 2>/dev/null); then - TMPDIR=$(mktemp -d -p /tmp resolvconf-tests.XXXXXX) - RESOLVCONF="$TMPDIR"/resolvconf - ln -s "$(command -v resolvectl 2>/dev/null)" "$RESOLVCONF" -fi -echo nameserver 10.0.2.1 10.0.2.2 | "$RESOLVCONF" -a hoge -echo nameserver 10.0.2.3 10.0.2.4 | "$RESOLVCONF" -a hoge.foo -assert_in '10.0.2.1 10.0.2.2' "$(resolvectl dns hoge)" -assert_in '10.0.2.3 10.0.2.4' "$(resolvectl dns hoge.foo)" -echo nameserver 10.0.3.1 10.0.3.2 | "$RESOLVCONF" -a hoge.inet.ipsec.192.168.35 -echo nameserver 10.0.3.3 10.0.3.4 | "$RESOLVCONF" -a hoge.foo.dhcp -assert_in '10.0.3.1 10.0.3.2' "$(resolvectl dns hoge)" -assert_in '10.0.3.3 10.0.3.4' "$(resolvectl dns hoge.foo)" - -# Tests for _localdnsstub and _localdnsproxy -assert_in '127.0.0.53' "$(resolvectl query _localdnsstub)" -assert_in '_localdnsstub' "$(resolvectl query 127.0.0.53)" -assert_in '127.0.0.54' "$(resolvectl query _localdnsproxy)" -assert_in '_localdnsproxy' "$(resolvectl query 127.0.0.54)" - -assert_in '127.0.0.53' "$(dig @127.0.0.53 _localdnsstub)" -assert_in '_localdnsstub' "$(dig @127.0.0.53 -x 127.0.0.53)" -assert_in '127.0.0.54' "$(dig @127.0.0.53 _localdnsproxy)" -assert_in '_localdnsproxy' "$(dig @127.0.0.53 -x 127.0.0.54)" +setup() { + : "SETUP BEGIN" -# Tests for mDNS and LLMNR settings -mkdir -p /run/systemd/resolved.conf.d -{ - echo "[Resolve]" - echo "MulticastDNS=no" - echo "LLMNR=no" -} >/run/systemd/resolved.conf.d/mdns-llmnr.conf -restart_resolved -# make sure networkd is not running. -systemctl stop systemd-networkd.service -assert_in 'no' "$(resolvectl mdns hoge)" -assert_in 'no' "$(resolvectl llmnr hoge)" -# Tests that reloading works -{ - echo "[Resolve]" - echo "MulticastDNS=yes" - echo "LLMNR=yes" -} >/run/systemd/resolved.conf.d/mdns-llmnr.conf -systemctl reload systemd-resolved.service -# defaults to yes (both the global and per-link settings are yes) -assert_in 'yes' "$(resolvectl mdns hoge)" -assert_in 'yes' "$(resolvectl llmnr hoge)" -# set per-link setting -resolvectl mdns hoge yes -resolvectl llmnr hoge yes -assert_in 'yes' "$(resolvectl mdns hoge)" -assert_in 'yes' "$(resolvectl llmnr hoge)" -resolvectl mdns hoge resolve -resolvectl llmnr hoge resolve -assert_in 'resolve' "$(resolvectl mdns hoge)" -assert_in 'resolve' "$(resolvectl llmnr hoge)" -resolvectl mdns hoge no -resolvectl llmnr hoge no -assert_in 'no' "$(resolvectl mdns hoge)" -assert_in 'no' "$(resolvectl llmnr hoge)" -# downgrade global setting to resolve -{ - echo "[Resolve]" - echo "MulticastDNS=resolve" - echo "LLMNR=resolve" -} >/run/systemd/resolved.conf.d/mdns-llmnr.conf -systemctl reload systemd-resolved.service -# set per-link setting -resolvectl mdns hoge yes -resolvectl llmnr hoge yes -assert_in 'resolve' "$(resolvectl mdns hoge)" -assert_in 'resolve' "$(resolvectl llmnr hoge)" -resolvectl mdns hoge resolve -resolvectl llmnr hoge resolve -assert_in 'resolve' "$(resolvectl mdns hoge)" -assert_in 'resolve' "$(resolvectl llmnr hoge)" -resolvectl mdns hoge no -resolvectl llmnr hoge no -assert_in 'no' "$(resolvectl mdns hoge)" -assert_in 'no' "$(resolvectl llmnr hoge)" -# downgrade global setting to no -{ - echo "[Resolve]" - echo "MulticastDNS=no" - echo "LLMNR=no" -} >/run/systemd/resolved.conf.d/mdns-llmnr.conf -systemctl reload systemd-resolved.service -# set per-link setting -resolvectl mdns hoge yes -resolvectl llmnr hoge yes -assert_in 'no' "$(resolvectl mdns hoge)" -assert_in 'no' "$(resolvectl llmnr hoge)" -resolvectl mdns hoge resolve -resolvectl llmnr hoge resolve -assert_in 'no' "$(resolvectl mdns hoge)" -assert_in 'no' "$(resolvectl llmnr hoge)" -resolvectl mdns hoge no -resolvectl llmnr hoge no -assert_in 'no' "$(resolvectl mdns hoge)" -assert_in 'no' "$(resolvectl llmnr hoge)" - -# Cleanup -rm -f /run/systemd/resolved.conf.d/mdns-llmnr.conf -ip link del hoge -ip link del hoge.foo - -### SETUP ### -# Configure network -hostnamectl hostname ns1.unsigned.test -cat >>/etc/hosts <<EOF + : "Setup - Configure network" + hostnamectl hostname ns1.unsigned.test + cat >>/etc/hosts <<EOF 10.0.0.1 ns1.unsigned.test fd00:dead:beef:cafe::1 ns1.unsigned.test 127.128.0.5 localhost5 localhost5.localdomain localhost5.localdomain4 localhost.localdomain5 localhost5.localdomain5 EOF -mkdir -p /run/systemd/network -cat >/run/systemd/network/10-dns0.netdev <<EOF + mkdir -p /run/systemd/network + cat >/run/systemd/network/10-dns0.netdev <<EOF [NetDev] Name=dns0 Kind=dummy EOF -cat >/run/systemd/network/10-dns0.network <<EOF + cat >/run/systemd/network/10-dns0.network <<EOF [Match] Name=dns0 @@ -213,12 +97,12 @@ DNSSEC=allow-downgrade DNS=10.0.0.1 DNS=fd00:dead:beef:cafe::1 EOF -cat >/run/systemd/network/10-dns1.netdev <<EOF + cat >/run/systemd/network/10-dns1.netdev <<EOF [NetDev] Name=dns1 Kind=dummy EOF -cat >/run/systemd/network/10-dns1.network <<EOF + cat >/run/systemd/network/10-dns1.network <<EOF [Match] Name=dns1 @@ -227,497 +111,659 @@ IPv6AcceptRA=no Address=10.99.0.1/24 DNSSEC=no EOF -systemctl edit --stdin --full --runtime --force "resolved-dummy-server.service" <<EOF + systemctl edit --stdin --full --runtime --force "resolved-dummy-server.service" <<EOF [Service] Type=notify Environment=SYSTEMD_LOG_LEVEL=debug ExecStart=/usr/lib/systemd/tests/unit-tests/manual/test-resolved-dummy-server 10.99.0.1:53 EOF -DNS_ADDRESSES=( - "10.0.0.1" - "fd00:dead:beef:cafe::1" -) + DNS_ADDRESSES=( + "10.0.0.1" + "fd00:dead:beef:cafe::1" + ) -mkdir -p /run/systemd/resolved.conf.d -{ - echo "[Resolve]" - echo "FallbackDNS=" - echo "DNSSEC=allow-downgrade" - echo "DNSOverTLS=opportunistic" -} >/run/systemd/resolved.conf.d/test.conf -ln -svf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf -# Override the default NTA list, which turns off DNSSEC validation for (among -# others) the test. domain -mkdir -p "/etc/dnssec-trust-anchors.d/" -echo local >/etc/dnssec-trust-anchors.d/local.negative - -# Copy over our knot configuration -mkdir -p /var/lib/knot/zones/ /etc/knot/ -cp -rfv /usr/lib/systemd/tests/testdata/knot-data/zones/* /var/lib/knot/zones/ -cp -fv /usr/lib/systemd/tests/testdata/knot-data/knot.conf /etc/knot/knot.conf -chgrp -R knot /etc/knot/ /var/lib/knot/ -chmod -R ug+rwX /var/lib/knot/ -chmod -R g+r /etc/knot/ - -# Sign the root zone -keymgr . generate algorithm=ECDSAP256SHA256 ksk=yes zsk=yes -# Create a trust anchor for resolved with our root zone -keymgr . ds | sed 's/ DS/ IN DS/g' >/etc/dnssec-trust-anchors.d/root.positive -# Create a bind-compatible trust anchor (for delv) -# Note: the trust-anchors directive is relatively new, so use the original -# managed-keys one until it's widespread enough -{ - echo 'managed-keys {' - keymgr . dnskey | sed -r 's/^\. DNSKEY ([0-9]+ [0-9]+ [0-9]+) (.+)$/. static-key \1 "\2";/g' - echo '};' -} >/etc/bind.keys -# Create an /etc/bind/bind.keys symlink, which is used by delv on Ubuntu -mkdir -p /etc/bind -ln -svf /etc/bind.keys /etc/bind/bind.keys - -# Start the services -systemctl unmask systemd-networkd -systemctl restart systemd-networkd -/usr/lib/systemd/systemd-networkd-wait-online --interface=dns1:routable --timeout=60 -systemctl reload systemd-resolved -systemctl start resolved-dummy-server - -# Create knot's runtime dir, since from certain version it's provided only by -# the package and not created by tmpfiles/systemd -if [[ ! -d /run/knot ]]; then - mkdir -p /run/knot - chown -R knot:knot /run/knot -fi -systemctl start knot -# Wait a bit for the keys to propagate -sleep 4 - -systemctl status resolved-dummy-server -networkctl status -resolvectl status -resolvectl log-level debug - -# Start monitoring queries -systemd-run -u resolvectl-monitor.service -p Type=notify resolvectl monitor -systemd-run -u resolvectl-monitor-json.service -p Type=notify resolvectl monitor --json=short - -# FIXME: knot, unfortunately, incorrectly complains about missing zone files for zones -# that are forwarded using the `dnsproxy` module. Until the issue is resolved, -# let's fall back to pre-processing the `zone-check` output a bit before checking it -# -# See: https://gitlab.nic.cz/knot/knot-dns/-/issues/913 -run knotc zone-check || : -sed -i '/forwarded.test./d' "$RUN_OUT" -[[ ! -s "$RUN_OUT" ]] -# We need to manually propagate the DS records of onlinesign.test. to the parent -# zone, since they're generated online -knotc zone-begin test. -if knotc zone-get test. onlinesign.test. ds | grep .; then - # Drop any old DS records, if present (e.g. on test re-run) - knotc zone-unset test. onlinesign.test. ds -fi -# Propagate the new DS records -while read -ra line; do - knotc zone-set test. "${line[0]}" 600 "${line[@]:1}" -done < <(keymgr onlinesign.test. ds) -knotc zone-commit test. - -knotc reload -sleep 2 - -### SETUP END ### - -: "--- nss-resolve/nss-myhostname tests" -# Sanity check -TIMESTAMP=$(date '+%F %T') -# Issue: https://github.com/systemd/systemd/issues/23951 -# With IPv6 enabled -run getent -s resolve ahosts ns1.unsigned.test -grep -qE "^fd00:dead:beef:cafe::1\s+STREAM\s+ns1\.unsigned\.test" "$RUN_OUT" -monitor_check_rr "$TIMESTAMP" "ns1.unsigned.test IN AAAA fd00:dead:beef:cafe::1" -# With IPv6 disabled -# Issue: https://github.com/systemd/systemd/issues/23951 -disable_ipv6 -run getent -s resolve ahosts ns1.unsigned.test -grep -qE "^10\.0\.0\.1\s+STREAM\s+ns1\.unsigned\.test" "$RUN_OUT" -(! grep -qE "fd00:dead:beef:cafe::1" "$RUN_OUT") -monitor_check_rr "$TIMESTAMP" "ns1.unsigned.test IN A 10.0.0.1" -enable_ipv6 - -# Issue: https://github.com/systemd/systemd/issues/18812 -# PR: https://github.com/systemd/systemd/pull/18896 -# Follow-up issue: https://github.com/systemd/systemd/issues/23152 -# Follow-up PR: https://github.com/systemd/systemd/pull/23161 -# With IPv6 enabled -run getent -s resolve ahosts localhost -grep -qE "^::1\s+STREAM\s+localhost" "$RUN_OUT" -run getent -s myhostname ahosts localhost -grep -qE "^::1\s+STREAM\s+localhost" "$RUN_OUT" -# With IPv6 disabled -disable_ipv6 -run getent -s resolve ahosts localhost -grep -qE "^127\.0\.0\.1\s+STREAM\s+localhost" "$RUN_OUT" -(! grep -qE "::1" "$RUN_OUT") -run getent -s myhostname ahosts localhost -grep -qE "^127\.0\.0\.1\s+STREAM\s+localhost" "$RUN_OUT" -enable_ipv6 - -# Issue: https://github.com/systemd/systemd/issues/25088 -run getent -s resolve hosts 127.128.0.5 -grep -qEx '127\.128\.0\.5\s+localhost5(\s+localhost5?\.localdomain[45]?){4}' "$RUN_OUT" -[ "$(wc -l <"$RUN_OUT")" -eq 1 ] - -# Issue: https://github.com/systemd/systemd/issues/20158 -run dig +noall +answer +additional localhost5. -grep -qEx 'localhost5\.\s+0\s+IN\s+A\s+127\.128\.0\.5' "$RUN_OUT" -[ "$(wc -l <"$RUN_OUT")" -eq 1 ] -run dig +noall +answer +additional localhost5.localdomain4. -grep -qEx 'localhost5\.localdomain4\.\s+0\s+IN\s+CNAME\s+localhost5\.' "$RUN_OUT" -grep -qEx 'localhost5\.\s+0\s+IN\s+A\s+127\.128\.0\.5' "$RUN_OUT" -[ "$(wc -l <"$RUN_OUT")" -eq 2 ] - -: "--- Basic resolved tests ---" -# Issue: https://github.com/systemd/systemd/issues/22229 -# PR: https://github.com/systemd/systemd/pull/22231 -FILTERED_NAMES=( - "0.in-addr.arpa" - "255.255.255.255.in-addr.arpa" - "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa" - "hello.invalid" - "hello.alt" -) + mkdir -p /run/systemd/resolved.conf.d + { + echo "[Resolve]" + echo "FallbackDNS=" + echo "DNSSEC=allow-downgrade" + echo "DNSOverTLS=opportunistic" + } >/run/systemd/resolved.conf.d/test.conf + ln -svf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf + # Override the default NTA list, which turns off DNSSEC validation for (among + # others) the test. domain + mkdir -p "/etc/dnssec-trust-anchors.d/" + echo local >/etc/dnssec-trust-anchors.d/local.negative + + # Copy over our knot configuration + mkdir -p /var/lib/knot/zones/ /etc/knot/ + cp -rfv /usr/lib/systemd/tests/testdata/knot-data/zones/* /var/lib/knot/zones/ + cp -fv /usr/lib/systemd/tests/testdata/knot-data/knot.conf /etc/knot/knot.conf + chgrp -R knot /etc/knot/ /var/lib/knot/ + chmod -R ug+rwX /var/lib/knot/ + chmod -R g+r /etc/knot/ + + : "Setup - Sign the root zone" + keymgr . generate algorithm=ECDSAP256SHA256 ksk=yes zsk=yes + # Create a trust anchor for resolved with our root zone + keymgr . ds | sed 's/ DS/ IN DS/g' >/etc/dnssec-trust-anchors.d/root.positive + # Create a bind-compatible trust anchor (for delv) + # Note: the trust-anchors directive is relatively new, so use the original + # managed-keys one until it's widespread enough + { + echo 'managed-keys {' + keymgr . dnskey | sed -r 's/^\. DNSKEY ([0-9]+ [0-9]+ [0-9]+) (.+)$/. static-key \1 "\2";/g' + echo '};' + } >/etc/bind.keys + # Create an /etc/bind/bind.keys symlink, which is used by delv on Ubuntu + mkdir -p /etc/bind + ln -svf /etc/bind.keys /etc/bind/bind.keys + + # Start the services + systemctl unmask systemd-networkd + systemctl restart systemd-networkd + /usr/lib/systemd/systemd-networkd-wait-online --interface=dns1:routable --timeout=60 + systemctl reload systemd-resolved + systemctl start resolved-dummy-server + + # Create knot's runtime dir, since from certain version it's provided only by + # the package and not created by tmpfiles/systemd + if [[ ! -d /run/knot ]]; then + mkdir -p /run/knot + chown -R knot:knot /run/knot + fi + systemctl start knot + # Wait a bit for the keys to propagate + sleep 4 + + systemctl status resolved-dummy-server + networkctl status + resolvectl status + resolvectl log-level debug + + : "Setup - Start monitoring queries" + systemd-run -u resolvectl-monitor.service -p Type=notify resolvectl monitor + systemd-run -u resolvectl-monitor-json.service -p Type=notify resolvectl monitor --json=short + + : "Setup - Check if all the zones are valid" + # FIXME: knot, unfortunately, incorrectly complains about missing zone files for zones + # that are forwarded using the `dnsproxy` module. Until the issue is resolved, + # let's fall back to pre-processing the `zone-check` output a bit before checking it + # + # See: https://gitlab.nic.cz/knot/knot-dns/-/issues/913 + run knotc zone-check || : + sed -i '/forwarded.test./d' "$RUN_OUT" + [[ ! -s "$RUN_OUT" ]] + # We need to manually propagate the DS records of onlinesign.test. to the parent + # zone, since they're generated online + knotc zone-begin test. + if knotc zone-get test. onlinesign.test. ds | grep .; then + # Drop any old DS records, if present (e.g. on test re-run) + knotc zone-unset test. onlinesign.test. ds + fi + + : "Setup - Propagate the new DS records" + while read -ra line; do + knotc zone-set test. "${line[0]}" 600 "${line[@]:1}" + done < <(keymgr onlinesign.test. ds) + knotc zone-commit test. + + knotc reload + sleep 2 + + : "SETUP END" +} + +# Test for resolvectl, resolvconf +manual_testcase_01_resolvectl() { + ip link add hoge type dummy + ip link add hoge.foo type dummy + + # Cleanup + # shellcheck disable=SC2317 + cleanup() { + rm -f /run/systemd/resolved.conf.d/mdns-llmnr.conf + ip link del hoge + ip link del hoge.foo + } + + trap cleanup RETURN + + resolvectl dns hoge 10.0.0.1 10.0.0.2 + resolvectl dns hoge.foo 10.0.0.3 10.0.0.4 + assert_in '10.0.0.1 10.0.0.2' "$(resolvectl dns hoge)" + assert_in '10.0.0.3 10.0.0.4' "$(resolvectl dns hoge.foo)" + resolvectl dns hoge 10.0.1.1 10.0.1.2 + resolvectl dns hoge.foo 10.0.1.3 10.0.1.4 + assert_in '10.0.1.1 10.0.1.2' "$(resolvectl dns hoge)" + assert_in '10.0.1.3 10.0.1.4' "$(resolvectl dns hoge.foo)" + if ! RESOLVCONF=$(command -v resolvconf 2>/dev/null); then + TMPDIR=$(mktemp -d -p /tmp resolvconf-tests.XXXXXX) + RESOLVCONF="$TMPDIR"/resolvconf + ln -s "$(command -v resolvectl 2>/dev/null)" "$RESOLVCONF" + fi + echo nameserver 10.0.2.1 10.0.2.2 | "$RESOLVCONF" -a hoge + echo nameserver 10.0.2.3 10.0.2.4 | "$RESOLVCONF" -a hoge.foo + assert_in '10.0.2.1 10.0.2.2' "$(resolvectl dns hoge)" + assert_in '10.0.2.3 10.0.2.4' "$(resolvectl dns hoge.foo)" + echo nameserver 10.0.3.1 10.0.3.2 | "$RESOLVCONF" -a hoge.inet.ipsec.192.168.35 + echo nameserver 10.0.3.3 10.0.3.4 | "$RESOLVCONF" -a hoge.foo.dhcp + assert_in '10.0.3.1 10.0.3.2' "$(resolvectl dns hoge)" + assert_in '10.0.3.3 10.0.3.4' "$(resolvectl dns hoge.foo)" + + # Tests for _localdnsstub and _localdnsproxy + assert_in '127.0.0.53' "$(resolvectl query _localdnsstub)" + assert_in '_localdnsstub' "$(resolvectl query 127.0.0.53)" + assert_in '127.0.0.54' "$(resolvectl query _localdnsproxy)" + assert_in '_localdnsproxy' "$(resolvectl query 127.0.0.54)" + + assert_in '127.0.0.53' "$(dig @127.0.0.53 _localdnsstub)" + assert_in '_localdnsstub' "$(dig @127.0.0.53 -x 127.0.0.53)" + assert_in '127.0.0.54' "$(dig @127.0.0.53 _localdnsproxy)" + assert_in '_localdnsproxy' "$(dig @127.0.0.53 -x 127.0.0.54)" +} + +# Tests for mDNS and LLMNR settings +manual_testcase_02_mdns_llmnr() { + ip link add hoge type dummy + ip link add hoge.foo type dummy + + # Cleanup + cleanup() { + rm -f /run/systemd/resolved.conf.d/mdns-llmnr.conf + ip link del hoge + ip link del hoge.foo + } -for name in "${FILTERED_NAMES[@]}"; do - (! run host "$name") - grep -qF "NXDOMAIN" "$RUN_OUT" -done - -# Follow-up -# Issue: https://github.com/systemd/systemd/issues/22401 -# PR: https://github.com/systemd/systemd/pull/22414 -run dig +noall +authority +comments SRV . -grep -qF "status: NOERROR" "$RUN_OUT" -grep -qE "IN\s+SOA\s+ns1\.unsigned\.test\." "$RUN_OUT" - -run resolvectl query -t SVCB svcb.test -grep -qF 'alpn="dot"' "$RUN_OUT" -grep -qF "ipv4hint=10.0.0.1" "$RUN_OUT" - -run resolvectl query -t HTTPS https.test -grep -qF 'alpn="h2,h3"' "$RUN_OUT" - -: "--- ZONE: unsigned.test. ---" -run dig @ns1.unsigned.test +short unsigned.test A unsigned.test AAAA -grep -qF "10.0.0.101" "$RUN_OUT" -grep -qF "fd00:dead:beef:cafe::101" "$RUN_OUT" -run resolvectl query unsigned.test -grep -qF "10.0.0.10" "$RUN_OUT" -grep -qF "fd00:dead:beef:cafe::101" "$RUN_OUT" -grep -qF "authenticated: no" "$RUN_OUT" -run dig @ns1.unsigned.test +short MX unsigned.test -grep -qF "15 mail.unsigned.test." "$RUN_OUT" -run resolvectl query --legend=no -t MX unsigned.test -grep -qF "unsigned.test IN MX 15 mail.unsigned.test" "$RUN_OUT" - - -: "--- ZONE: signed.test (static DNSSEC) ---" -# Check the trust chain (with and without systemd-resolved in between -# Issue: https://github.com/systemd/systemd/issues/22002 -# PR: https://github.com/systemd/systemd/pull/23289 -run_delv @ns1.unsigned.test signed.test -grep -qF "; fully validated" "$RUN_OUT" -run_delv signed.test -grep -qF "; fully validated" "$RUN_OUT" - -for addr in "${DNS_ADDRESSES[@]}"; do - run_delv "@$addr" -t A mail.signed.test + trap cleanup RETURN + + mkdir -p /run/systemd/resolved.conf.d + { + echo "[Resolve]" + echo "MulticastDNS=no" + echo "LLMNR=no" + } >/run/systemd/resolved.conf.d/mdns-llmnr.conf + restart_resolved + # make sure networkd is not running. + systemctl stop systemd-networkd.service + assert_in 'no' "$(resolvectl mdns hoge)" + assert_in 'no' "$(resolvectl llmnr hoge)" + # Tests that reloading works + { + echo "[Resolve]" + echo "MulticastDNS=yes" + echo "LLMNR=yes" + } >/run/systemd/resolved.conf.d/mdns-llmnr.conf + systemctl reload systemd-resolved.service + # defaults to yes (both the global and per-link settings are yes) + assert_in 'yes' "$(resolvectl mdns hoge)" + assert_in 'yes' "$(resolvectl llmnr hoge)" + # set per-link setting + resolvectl mdns hoge yes + resolvectl llmnr hoge yes + assert_in 'yes' "$(resolvectl mdns hoge)" + assert_in 'yes' "$(resolvectl llmnr hoge)" + resolvectl mdns hoge resolve + resolvectl llmnr hoge resolve + assert_in 'resolve' "$(resolvectl mdns hoge)" + assert_in 'resolve' "$(resolvectl llmnr hoge)" + resolvectl mdns hoge no + resolvectl llmnr hoge no + assert_in 'no' "$(resolvectl mdns hoge)" + assert_in 'no' "$(resolvectl llmnr hoge)" + # downgrade global setting to resolve + { + echo "[Resolve]" + echo "MulticastDNS=resolve" + echo "LLMNR=resolve" + } >/run/systemd/resolved.conf.d/mdns-llmnr.conf + systemctl reload systemd-resolved.service + # set per-link setting + resolvectl mdns hoge yes + resolvectl llmnr hoge yes + assert_in 'resolve' "$(resolvectl mdns hoge)" + assert_in 'resolve' "$(resolvectl llmnr hoge)" + resolvectl mdns hoge resolve + resolvectl llmnr hoge resolve + assert_in 'resolve' "$(resolvectl mdns hoge)" + assert_in 'resolve' "$(resolvectl llmnr hoge)" + resolvectl mdns hoge no + resolvectl llmnr hoge no + assert_in 'no' "$(resolvectl mdns hoge)" + assert_in 'no' "$(resolvectl llmnr hoge)" + # downgrade global setting to no + { + echo "[Resolve]" + echo "MulticastDNS=no" + echo "LLMNR=no" + } >/run/systemd/resolved.conf.d/mdns-llmnr.conf + systemctl reload systemd-resolved.service + # set per-link setting + resolvectl mdns hoge yes + resolvectl llmnr hoge yes + assert_in 'no' "$(resolvectl mdns hoge)" + assert_in 'no' "$(resolvectl llmnr hoge)" + resolvectl mdns hoge resolve + resolvectl llmnr hoge resolve + assert_in 'no' "$(resolvectl mdns hoge)" + assert_in 'no' "$(resolvectl llmnr hoge)" + resolvectl mdns hoge no + resolvectl llmnr hoge no + assert_in 'no' "$(resolvectl mdns hoge)" + assert_in 'no' "$(resolvectl llmnr hoge)" +} + +testcase_03_23951() { + : "--- nss-resolve/nss-myhostname tests" + # Sanity check + TIMESTAMP=$(date '+%F %T') + # Issue: https://github.com/systemd/systemd/issues/23951 + # With IPv6 enabled + run getent -s resolve ahosts ns1.unsigned.test + grep -qE "^fd00:dead:beef:cafe::1\s+STREAM\s+ns1\.unsigned\.test" "$RUN_OUT" + monitor_check_rr "$TIMESTAMP" "ns1.unsigned.test IN AAAA fd00:dead:beef:cafe::1" + # With IPv6 disabled + # Issue: https://github.com/systemd/systemd/issues/23951 + disable_ipv6 + run getent -s resolve ahosts ns1.unsigned.test + grep -qE "^10\.0\.0\.1\s+STREAM\s+ns1\.unsigned\.test" "$RUN_OUT" + (! grep -qE "fd00:dead:beef:cafe::1" "$RUN_OUT") + monitor_check_rr "$TIMESTAMP" "ns1.unsigned.test IN A 10.0.0.1" + enable_ipv6 +} + +testcase_04_18812() { + # Issue: https://github.com/systemd/systemd/issues/18812 + # PR: https://github.com/systemd/systemd/pull/18896 + # Follow-up issue: https://github.com/systemd/systemd/issues/23152 + # Follow-up PR: https://github.com/systemd/systemd/pull/23161 + # With IPv6 enabled + run getent -s resolve ahosts localhost + grep -qE "^::1\s+STREAM\s+localhost" "$RUN_OUT" + run getent -s myhostname ahosts localhost + grep -qE "^::1\s+STREAM\s+localhost" "$RUN_OUT" + # With IPv6 disabled + disable_ipv6 + run getent -s resolve ahosts localhost + grep -qE "^127\.0\.0\.1\s+STREAM\s+localhost" "$RUN_OUT" + (! grep -qE "::1" "$RUN_OUT") + run getent -s myhostname ahosts localhost + grep -qE "^127\.0\.0\.1\s+STREAM\s+localhost" "$RUN_OUT" + enable_ipv6 +} + +testcase_05_25088() { + # Issue: https://github.com/systemd/systemd/issues/25088 + run getent -s resolve hosts 127.128.0.5 + grep -qEx '127\.128\.0\.5\s+localhost5(\s+localhost5?\.localdomain[45]?){4}' "$RUN_OUT" + [ "$(wc -l <"$RUN_OUT")" -eq 1 ] +} + +testcase_06_20158() { + # Issue: https://github.com/systemd/systemd/issues/20158 + run dig +noall +answer +additional localhost5. + grep -qEx 'localhost5\.\s+0\s+IN\s+A\s+127\.128\.0\.5' "$RUN_OUT" + [ "$(wc -l <"$RUN_OUT")" -eq 1 ] + run dig +noall +answer +additional localhost5.localdomain4. + grep -qEx 'localhost5\.localdomain4\.\s+0\s+IN\s+CNAME\s+localhost5\.' "$RUN_OUT" + grep -qEx 'localhost5\.\s+0\s+IN\s+A\s+127\.128\.0\.5' "$RUN_OUT" + [ "$(wc -l <"$RUN_OUT")" -eq 2 ] +} + +testcase_07_22229() { + : "--- Basic resolved tests ---" + # Issue: https://github.com/systemd/systemd/issues/22229 + # PR: https://github.com/systemd/systemd/pull/22231 + FILTERED_NAMES=( + "0.in-addr.arpa" + "255.255.255.255.in-addr.arpa" + "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa" + "hello.invalid" + "hello.alt" + ) + + for name in "${FILTERED_NAMES[@]}"; do + (! run host "$name") + grep -qF "NXDOMAIN" "$RUN_OUT" + done + + # Follow-up + # Issue: https://github.com/systemd/systemd/issues/22401 + # PR: https://github.com/systemd/systemd/pull/22414 + run dig +noall +authority +comments SRV . + grep -qF "status: NOERROR" "$RUN_OUT" + grep -qE "IN\s+SOA\s+ns1\.unsigned\.test\." "$RUN_OUT" +} + +testcase_08_resolved() { + run resolvectl query -t SVCB svcb.test + grep -qF 'alpn="dot"' "$RUN_OUT" + grep -qF "ipv4hint=10.0.0.1" "$RUN_OUT" + + run resolvectl query -t HTTPS https.test + grep -qF 'alpn="h2,h3"' "$RUN_OUT" + + : "--- ZONE: unsigned.test. ---" + run dig @ns1.unsigned.test +short unsigned.test A unsigned.test AAAA + grep -qF "10.0.0.101" "$RUN_OUT" + grep -qF "fd00:dead:beef:cafe::101" "$RUN_OUT" + run resolvectl query unsigned.test + grep -qF "10.0.0.10" "$RUN_OUT" + grep -qF "fd00:dead:beef:cafe::101" "$RUN_OUT" + grep -qF "authenticated: no" "$RUN_OUT" + run dig @ns1.unsigned.test +short MX unsigned.test + grep -qF "15 mail.unsigned.test." "$RUN_OUT" + run resolvectl query --legend=no -t MX unsigned.test + grep -qF "unsigned.test IN MX 15 mail.unsigned.test" "$RUN_OUT" + + : "--- ZONE: signed.test (static DNSSEC) ---" + # Check the trust chain (with and without systemd-resolved in between + # Issue: https://github.com/systemd/systemd/issues/22002 + # PR: https://github.com/systemd/systemd/pull/23289 + run_delv @ns1.unsigned.test signed.test grep -qF "; fully validated" "$RUN_OUT" - run_delv "@$addr" -t AAAA mail.signed.test + run_delv signed.test grep -qF "; fully validated" "$RUN_OUT" -done -run resolvectl query mail.signed.test -grep -qF "10.0.0.11" "$RUN_OUT" -grep -qF "fd00:dead:beef:cafe::11" "$RUN_OUT" -grep -qF "authenticated: yes" "$RUN_OUT" - -run dig +short signed.test -grep -qF "10.0.0.10" "$RUN_OUT" -run resolvectl query signed.test -grep -qF "signed.test: 10.0.0.10" "$RUN_OUT" -grep -qF "authenticated: yes" "$RUN_OUT" -run dig @ns1.unsigned.test +short MX signed.test -grep -qF "10 mail.signed.test." "$RUN_OUT" -run resolvectl query --legend=no -t MX signed.test -grep -qF "signed.test IN MX 10 mail.signed.test" "$RUN_OUT" -# Check a non-existent domain -run dig +dnssec this.does.not.exist.signed.test -grep -qF "status: NXDOMAIN" "$RUN_OUT" -# Check a wildcard record -run resolvectl query -t TXT this.should.be.authenticated.wild.signed.test -grep -qF 'this.should.be.authenticated.wild.signed.test IN TXT "this is a wildcard"' "$RUN_OUT" -grep -qF "authenticated: yes" "$RUN_OUT" -# Check SRV support -run resolvectl service _mysvc._tcp signed.test -grep -qF "myservice.signed.test:1234" "$RUN_OUT" -grep -qF "10.0.0.20" "$RUN_OUT" -grep -qF "fd00:dead:beef:cafe::17" "$RUN_OUT" -grep -qF "authenticated: yes" "$RUN_OUT" - -# Test service resolve over Varlink -run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveService '{"name":"","type":"_mysvc._tcp","domain":"signed.test"}' -grep -qF '"services":[{"priority":10,"weight":5,"port":1234,"hostname":"myservice.signed.test","canonicalName":"myservice.signed.test","addresses":[{"ifindex":' "$RUN_OUT" -grep -qF '"family":10,"address":[253,0,222,173,190,239,202,254,0,0,0,0,0,0,0,23]' "$RUN_OUT" -grep -qF '"family":2,"address":[10,0,0,20]' "$RUN_OUT" -grep -qF '}]}],"txt":["This is TXT for myservice"],"canonical":{"name":null,"type":"_mysvc._tcp","domain":"signed.test"},"flags":' "$RUN_OUT" - -# without name -run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveService '{"type":"_mysvc._tcp","domain":"signed.test"}' -# without txt (SD_RESOLVE_NO_TXT) -run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveService '{"type":"_mysvc._tcp","domain":"signed.test","flags":64}' -(! grep -qF '"txt"' "$RUN_OUT") -# without address (SD_RESOLVE_NO_ADDRESS) -run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveService '{"type":"_mysvc._tcp","domain":"signed.test","flags":128}' -(! grep -qF '"addresses"' "$RUN_OUT") -# without txt and address -run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveService '{"type":"_mysvc._tcp","domain":"signed.test","flags":192}' -(! grep -qF '"txt"' "$RUN_OUT") -(! grep -qF '"addresses"' "$RUN_OUT") - -(! run resolvectl service _invalidsvc._udp signed.test) -grep -qE "invalidservice\.signed\.test' not found" "$RUN_OUT" -run resolvectl service _untrustedsvc._udp signed.test -grep -qF "myservice.untrusted.test:1111" "$RUN_OUT" -grep -qF "10.0.0.123" "$RUN_OUT" -grep -qF "fd00:dead:beef:cafe::123" "$RUN_OUT" -grep -qF "authenticated: yes" "$RUN_OUT" -# Check OPENPGPKEY support -run_delv -t OPENPGPKEY 5a786cdc59c161cdafd818143705026636962198c66ed4c5b3da321e._openpgpkey.signed.test -grep -qF "; fully validated" "$RUN_OUT" -run resolvectl openpgp mr.smith@signed.test -grep -qF "5a786cdc59c161cdafd818143705026636962198c66ed4c5b3da321e._openpgpkey.signed.test" "$RUN_OUT" -grep -qF "authenticated: yes" "$RUN_OUT" -# Check zone transfers (AXFR/IXFR) -# Note: since resolved doesn't support zone transfers, let's just make sure it -# simply refuses such requests without choking on them -# See: https://github.com/systemd/systemd/pull/30809#issuecomment-1880102804 -run dig @ns1.unsigned.test AXFR signed.test -grep -qE "SOA\s+ns1.unsigned.test. root.unsigned.test." "$RUN_OUT" -run dig AXFR signed.test -grep -qF "; Transfer failed" "$RUN_OUT" -run dig @ns1.unsigned.test IXFR=43 signed.test -grep -qE "SOA\s+ns1.unsigned.test. root.unsigned.test." "$RUN_OUT" -run dig IXFR=43 signed.test -grep -qF "; Transfer failed" "$RUN_OUT" - -# DNSSEC validation with multiple records of the same type for the same name -# Issue: https://github.com/systemd/systemd/issues/22002 -# PR: https://github.com/systemd/systemd/pull/23289 -check_domain() { - local domain="${1:?}" - local record="${2:?}" - local message="${3:?}" - local addr for addr in "${DNS_ADDRESSES[@]}"; do - run_delv "@$addr" -t "$record" "$domain" - grep -qF "$message" "$RUN_OUT" + run_delv "@$addr" -t A mail.signed.test + grep -qF "; fully validated" "$RUN_OUT" + run_delv "@$addr" -t AAAA mail.signed.test + grep -qF "; fully validated" "$RUN_OUT" done + run resolvectl query mail.signed.test + grep -qF "10.0.0.11" "$RUN_OUT" + grep -qF "fd00:dead:beef:cafe::11" "$RUN_OUT" + grep -qF "authenticated: yes" "$RUN_OUT" - run_delv -t "$record" "$domain" - grep -qF "$message" "$RUN_OUT" + run dig +short signed.test + grep -qF "10.0.0.10" "$RUN_OUT" + run resolvectl query signed.test + grep -qF "signed.test: 10.0.0.10" "$RUN_OUT" + grep -qF "authenticated: yes" "$RUN_OUT" + run dig @ns1.unsigned.test +short MX signed.test + grep -qF "10 mail.signed.test." "$RUN_OUT" + run resolvectl query --legend=no -t MX signed.test + grep -qF "signed.test IN MX 10 mail.signed.test" "$RUN_OUT" + # Check a non-existent domain + run dig +dnssec this.does.not.exist.signed.test + grep -qF "status: NXDOMAIN" "$RUN_OUT" + # Check a wildcard record + run resolvectl query -t TXT this.should.be.authenticated.wild.signed.test + grep -qF 'this.should.be.authenticated.wild.signed.test IN TXT "this is a wildcard"' "$RUN_OUT" + grep -qF "authenticated: yes" "$RUN_OUT" + # Check SRV support + run resolvectl service _mysvc._tcp signed.test + grep -qF "myservice.signed.test:1234" "$RUN_OUT" + grep -qF "10.0.0.20" "$RUN_OUT" + grep -qF "fd00:dead:beef:cafe::17" "$RUN_OUT" + grep -qF "authenticated: yes" "$RUN_OUT" - run resolvectl query "$domain" + # Test service resolve over Varlink + run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveService '{"name":"","type":"_mysvc._tcp","domain":"signed.test"}' + grep -qF '"services":[{"priority":10,"weight":5,"port":1234,"hostname":"myservice.signed.test","canonicalName":"myservice.signed.test","addresses":[{"ifindex":' "$RUN_OUT" + grep -qF '"family":10,"address":[253,0,222,173,190,239,202,254,0,0,0,0,0,0,0,23]' "$RUN_OUT" + grep -qF '"family":2,"address":[10,0,0,20]' "$RUN_OUT" + grep -qF '}]}],"txt":["This is TXT for myservice"],"canonical":{"name":null,"type":"_mysvc._tcp","domain":"signed.test"},"flags":' "$RUN_OUT" + + # without name + run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveService '{"type":"_mysvc._tcp","domain":"signed.test"}' + # without txt (SD_RESOLVE_NO_TXT) + run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveService '{"type":"_mysvc._tcp","domain":"signed.test","flags":64}' + (! grep -qF '"txt"' "$RUN_OUT") + # without address (SD_RESOLVE_NO_ADDRESS) + run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveService '{"type":"_mysvc._tcp","domain":"signed.test","flags":128}' + (! grep -qF '"addresses"' "$RUN_OUT") + # without txt and address + run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveService '{"type":"_mysvc._tcp","domain":"signed.test","flags":192}' + (! grep -qF '"txt"' "$RUN_OUT") + (! grep -qF '"addresses"' "$RUN_OUT") + + (! run resolvectl service _invalidsvc._udp signed.test) + grep -qE "invalidservice\.signed\.test' not found" "$RUN_OUT" + run resolvectl service _untrustedsvc._udp signed.test + grep -qF "myservice.untrusted.test:1111" "$RUN_OUT" + grep -qF "10.0.0.123" "$RUN_OUT" + grep -qF "fd00:dead:beef:cafe::123" "$RUN_OUT" grep -qF "authenticated: yes" "$RUN_OUT" -} + # Check OPENPGPKEY support + run_delv -t OPENPGPKEY 5a786cdc59c161cdafd818143705026636962198c66ed4c5b3da321e._openpgpkey.signed.test + grep -qF "; fully validated" "$RUN_OUT" + run resolvectl openpgp mr.smith@signed.test + grep -qF "5a786cdc59c161cdafd818143705026636962198c66ed4c5b3da321e._openpgpkey.signed.test" "$RUN_OUT" + grep -qF "authenticated: yes" "$RUN_OUT" + # Check zone transfers (AXFR/IXFR) + # Note: since resolved doesn't support zone transfers, let's just make sure it + # simply refuses such requests without choking on them + # See: https://github.com/systemd/systemd/pull/30809#issuecomment-1880102804 + run dig @ns1.unsigned.test AXFR signed.test + grep -qE "SOA\s+ns1.unsigned.test. root.unsigned.test." "$RUN_OUT" + run dig AXFR signed.test + grep -qF "; Transfer failed" "$RUN_OUT" + run dig @ns1.unsigned.test IXFR=43 signed.test + grep -qE "SOA\s+ns1.unsigned.test. root.unsigned.test." "$RUN_OUT" + run dig IXFR=43 signed.test + grep -qF "; Transfer failed" "$RUN_OUT" + + # DNSSEC validation with multiple records of the same type for the same name + # Issue: https://github.com/systemd/systemd/issues/22002 + # PR: https://github.com/systemd/systemd/pull/23289 + check_domain() { + local domain="${1:?}" + local record="${2:?}" + local message="${3:?}" + local addr + + for addr in "${DNS_ADDRESSES[@]}"; do + run_delv "@$addr" -t "$record" "$domain" + grep -qF "$message" "$RUN_OUT" + done + + run_delv -t "$record" "$domain" + grep -qF "$message" "$RUN_OUT" + + run resolvectl query "$domain" + grep -qF "authenticated: yes" "$RUN_OUT" + } + + check_domain "dupe.signed.test" "A" "; fully validated" + check_domain "dupe.signed.test" "AAAA" "; negative response, fully validated" + check_domain "dupe-ipv6.signed.test" "AAAA" "; fully validated" + check_domain "dupe-ipv6.signed.test" "A" "; negative response, fully validated" + check_domain "dupe-mixed.signed.test" "A" "; fully validated" + check_domain "dupe-mixed.signed.test" "AAAA" "; fully validated" + + # Test resolution of CNAME chains + TIMESTAMP=$(date '+%F %T') + run resolvectl query -t A cname-chain.signed.test + grep -qF "follow14.final.signed.test IN A 10.0.0.14" "$RUN_OUT" + grep -qF "authenticated: yes" "$RUN_OUT" + + monitor_check_rr "$TIMESTAMP" "follow10.so.close.signed.test IN CNAME follow11.yet.so.far.signed.test" + monitor_check_rr "$TIMESTAMP" "follow11.yet.so.far.signed.test IN CNAME follow12.getting.hot.signed.test" + monitor_check_rr "$TIMESTAMP" "follow12.getting.hot.signed.test IN CNAME follow13.almost.final.signed.test" + monitor_check_rr "$TIMESTAMP" "follow13.almost.final.signed.test IN CNAME follow14.final.signed.test" + monitor_check_rr "$TIMESTAMP" "follow14.final.signed.test IN A 10.0.0.14" + + # Non-existing RR + CNAME chain + #run dig +dnssec AAAA cname-chain.signed.test + #grep -qF "status: NOERROR" "$RUN_OUT" + #grep -qE "^follow14\.final\.signed\.test\..+IN\s+NSEC\s+" "$RUN_OUT" + + + : "--- ZONE: onlinesign.test (dynamic DNSSEC) ---" + # Check the trust chain (with and without systemd-resolved in between + # Issue: https://github.com/systemd/systemd/issues/22002 + # PR: https://github.com/systemd/systemd/pull/23289 + run_delv @ns1.unsigned.test sub.onlinesign.test + grep -qF "; fully validated" "$RUN_OUT" + run_delv sub.onlinesign.test + grep -qF "; fully validated" "$RUN_OUT" + + run dig +short sub.onlinesign.test + grep -qF "10.0.0.133" "$RUN_OUT" + run resolvectl query sub.onlinesign.test + grep -qF "sub.onlinesign.test: 10.0.0.133" "$RUN_OUT" + grep -qF "authenticated: yes" "$RUN_OUT" + run dig @ns1.unsigned.test +short TXT onlinesign.test + grep -qF '"hello from onlinesign"' "$RUN_OUT" + run resolvectl query --legend=no -t TXT onlinesign.test + grep -qF 'onlinesign.test IN TXT "hello from onlinesign"' "$RUN_OUT" -check_domain "dupe.signed.test" "A" "; fully validated" -check_domain "dupe.signed.test" "AAAA" "; negative response, fully validated" -check_domain "dupe-ipv6.signed.test" "AAAA" "; fully validated" -check_domain "dupe-ipv6.signed.test" "A" "; negative response, fully validated" -check_domain "dupe-mixed.signed.test" "A" "; fully validated" -check_domain "dupe-mixed.signed.test" "AAAA" "; fully validated" - -# Test resolution of CNAME chains -TIMESTAMP=$(date '+%F %T') -run resolvectl query -t A cname-chain.signed.test -grep -qF "follow14.final.signed.test IN A 10.0.0.14" "$RUN_OUT" -grep -qF "authenticated: yes" "$RUN_OUT" - -monitor_check_rr "$TIMESTAMP" "follow10.so.close.signed.test IN CNAME follow11.yet.so.far.signed.test" -monitor_check_rr "$TIMESTAMP" "follow11.yet.so.far.signed.test IN CNAME follow12.getting.hot.signed.test" -monitor_check_rr "$TIMESTAMP" "follow12.getting.hot.signed.test IN CNAME follow13.almost.final.signed.test" -monitor_check_rr "$TIMESTAMP" "follow13.almost.final.signed.test IN CNAME follow14.final.signed.test" -monitor_check_rr "$TIMESTAMP" "follow14.final.signed.test IN A 10.0.0.14" - -# Non-existing RR + CNAME chain -#run dig +dnssec AAAA cname-chain.signed.test -#grep -qF "status: NOERROR" "$RUN_OUT" -#grep -qE "^follow14\.final\.signed\.test\..+IN\s+NSEC\s+" "$RUN_OUT" - - -: "--- ZONE: onlinesign.test (dynamic DNSSEC) ---" -# Check the trust chain (with and without systemd-resolved in between -# Issue: https://github.com/systemd/systemd/issues/22002 -# PR: https://github.com/systemd/systemd/pull/23289 -run_delv @ns1.unsigned.test sub.onlinesign.test -grep -qF "; fully validated" "$RUN_OUT" -run_delv sub.onlinesign.test -grep -qF "; fully validated" "$RUN_OUT" - -run dig +short sub.onlinesign.test -grep -qF "10.0.0.133" "$RUN_OUT" -run resolvectl query sub.onlinesign.test -grep -qF "sub.onlinesign.test: 10.0.0.133" "$RUN_OUT" -grep -qF "authenticated: yes" "$RUN_OUT" -run dig @ns1.unsigned.test +short TXT onlinesign.test -grep -qF '"hello from onlinesign"' "$RUN_OUT" -run resolvectl query --legend=no -t TXT onlinesign.test -grep -qF 'onlinesign.test IN TXT "hello from onlinesign"' "$RUN_OUT" - -for addr in "${DNS_ADDRESSES[@]}"; do - run_delv "@$addr" -t A dual.onlinesign.test + for addr in "${DNS_ADDRESSES[@]}"; do + run_delv "@$addr" -t A dual.onlinesign.test + grep -qF "10.0.0.135" "$RUN_OUT" + run_delv "@$addr" -t AAAA dual.onlinesign.test + grep -qF "fd00:dead:beef:cafe::135" "$RUN_OUT" + run_delv "@$addr" -t ANY ipv6.onlinesign.test + grep -qF "fd00:dead:beef:cafe::136" "$RUN_OUT" + done + run resolvectl query dual.onlinesign.test grep -qF "10.0.0.135" "$RUN_OUT" - run_delv "@$addr" -t AAAA dual.onlinesign.test grep -qF "fd00:dead:beef:cafe::135" "$RUN_OUT" - run_delv "@$addr" -t ANY ipv6.onlinesign.test + grep -qF "authenticated: yes" "$RUN_OUT" + run resolvectl query ipv6.onlinesign.test grep -qF "fd00:dead:beef:cafe::136" "$RUN_OUT" -done -run resolvectl query dual.onlinesign.test -grep -qF "10.0.0.135" "$RUN_OUT" -grep -qF "fd00:dead:beef:cafe::135" "$RUN_OUT" -grep -qF "authenticated: yes" "$RUN_OUT" -run resolvectl query ipv6.onlinesign.test -grep -qF "fd00:dead:beef:cafe::136" "$RUN_OUT" -grep -qF "authenticated: yes" "$RUN_OUT" - -# Check a non-existent domain -# Note: mod-onlinesign utilizes Minimally Covering NSEC Records, hence the -# different response than with "standard" DNSSEC -run dig +dnssec this.does.not.exist.onlinesign.test -grep -qF "status: NOERROR" "$RUN_OUT" -grep -qF "NSEC \\000.this.does.not.exist.onlinesign.test." "$RUN_OUT" -# Check a wildcard record -run resolvectl query -t TXT this.should.be.authenticated.wild.onlinesign.test -grep -qF 'this.should.be.authenticated.wild.onlinesign.test IN TXT "this is an onlinesign wildcard"' "$RUN_OUT" -grep -qF "authenticated: yes" "$RUN_OUT" - -# Resolve via dbus method -TIMESTAMP=$(date '+%F %T') -run busctl call org.freedesktop.resolve1 /org/freedesktop/resolve1 org.freedesktop.resolve1.Manager ResolveHostname 'isit' 0 secondsub.onlinesign.test 0 0 -grep -qF '10 0 0 134 "secondsub.onlinesign.test"' "$RUN_OUT" -monitor_check_rr "$TIMESTAMP" "secondsub.onlinesign.test IN A 10.0.0.134" - - -: "--- ZONE: untrusted.test (DNSSEC without propagated DS records) ---" -# Issue: https://github.com/systemd/systemd/issues/23955 -# FIXME -resolvectl flush-caches -#run dig +short untrusted.test A untrusted.test AAAA -#grep -qF "10.0.0.121" "$RUN_OUT" -#grep -qF "fd00:dead:beef:cafe::121" "$RUN_OUT" -run resolvectl query untrusted.test -grep -qF "untrusted.test:" "$RUN_OUT" -grep -qF "10.0.0.121" "$RUN_OUT" -grep -qF "fd00:dead:beef:cafe::121" "$RUN_OUT" -grep -qF "authenticated: no" "$RUN_OUT" -run resolvectl service _mysvc._tcp untrusted.test -grep -qF "myservice.untrusted.test:1234" "$RUN_OUT" -grep -qF "10.0.0.123" "$RUN_OUT" -grep -qF "fd00:dead:beef:cafe::123" "$RUN_OUT" - -# Issue: https://github.com/systemd/systemd/issues/19472 -# 1) Query for a non-existing RR should return NOERROR + NSEC (?), not NXDOMAIN -# FIXME: re-enable once the issue is resolved -#run dig +dnssec AAAA untrusted.test -#grep -qF "status: NOERROR" "$RUN_OUT" -#grep -qE "^untrusted\.test\..+IN\s+NSEC\s+" "$RUN_OUT" -## 2) Query for a non-existing name should return NXDOMAIN, not SERVFAIL -#run dig +dnssec this.does.not.exist.untrusted.test -#grep -qF "status: NXDOMAIN" "$RUN_OUT" - -: "--- ZONE: forwarded.test (queries forwarded to our dummy test server) ---" -JOURNAL_CURSOR="$(mktemp)" -journalctl -n0 -q --cursor-file="$JOURNAL_CURSOR" - -# See "test-resolved-dummy-server.c" for the server part -(! run resolvectl query nope.forwarded.test) -grep -qF "nope.forwarded.test" "$RUN_OUT" -grep -qF "not found" "$RUN_OUT" - -# SERVFAIL + EDE code 6: DNSSEC Bogus -(! run resolvectl query edns-bogus-dnssec.forwarded.test) -grep -qE "^edns-bogus-dnssec.forwarded.test:.+: upstream-failure \(DNSSEC Bogus\)" "$RUN_OUT" -# Same thing, but over Varlink -(! run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveHostname '{"name" : "edns-bogus-dnssec.forwarded.test"}') -grep -qF "io.systemd.Resolve.DNSSECValidationFailed" "$RUN_OUT" -grep -qF '{"result":"upstream-failure","extendedDNSErrorCode":6}' "$RUN_OUT" -journalctl --sync -journalctl -u systemd-resolved.service --cursor-file="$JOURNAL_CURSOR" --grep "Server returned error: SERVFAIL \(DNSSEC Bogus\). Lookup failed." - -# SERVFAIL + EDE code 16: Censored + extra text -(! run resolvectl query edns-extra-text.forwarded.test) -grep -qE "^edns-extra-text.forwarded.test.+: SERVFAIL \(Censored: Nothing to see here!\)" "$RUN_OUT" -(! run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveHostname '{"name" : "edns-extra-text.forwarded.test"}') -grep -qF "io.systemd.Resolve.DNSError" "$RUN_OUT" -grep -qF '{"rcode":2,"extendedDNSErrorCode":16,"extendedDNSErrorMessage":"Nothing to see here!"}' "$RUN_OUT" -journalctl --sync -journalctl -u systemd-resolved.service --cursor-file="$JOURNAL_CURSOR" --grep "Server returned error: SERVFAIL \(Censored: Nothing to see here!\)" - -# SERVFAIL + EDE code 0: Other + extra text -(! run resolvectl query edns-code-zero.forwarded.test) -grep -qE "^edns-code-zero.forwarded.test:.+: SERVFAIL \(Other: 🐱\)" "$RUN_OUT" -(! run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveHostname '{"name" : "edns-code-zero.forwarded.test"}') -grep -qF "io.systemd.Resolve.DNSError" "$RUN_OUT" -grep -qF '{"rcode":2,"extendedDNSErrorCode":0,"extendedDNSErrorMessage":"🐱"}' "$RUN_OUT" -journalctl --sync -journalctl -u systemd-resolved.service --cursor-file="$JOURNAL_CURSOR" --grep "Server returned error: SERVFAIL \(Other: 🐱\)" - -# SERVFAIL + invalid EDE code -(! run resolvectl query edns-invalid-code.forwarded.test) -grep -qE "^edns-invalid-code.forwarded.test:.+: SERVFAIL \([0-9]+\)" "$RUN_OUT" -(! run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveHostname '{"name" : "edns-invalid-code.forwarded.test"}') -grep -qF "io.systemd.Resolve.DNSError" "$RUN_OUT" -grep -qE '{"rcode":2,"extendedDNSErrorCode":[0-9]+}' "$RUN_OUT" -journalctl --sync -journalctl -u systemd-resolved.service --cursor-file="$JOURNAL_CURSOR" --grep "Server returned error: SERVFAIL \(\d+\)" - -# SERVFAIL + invalid EDE code + extra text -(! run resolvectl query edns-invalid-code-with-extra-text.forwarded.test) -grep -qE '^edns-invalid-code-with-extra-text.forwarded.test:.+: SERVFAIL \([0-9]+: Hello \[#\]\$%~ World\)' "$RUN_OUT" -(! run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveHostname '{"name" : "edns-invalid-code-with-extra-text.forwarded.test"}') -grep -qF "io.systemd.Resolve.DNSError" "$RUN_OUT" -grep -qE '{"rcode":2,"extendedDNSErrorCode":[0-9]+,"extendedDNSErrorMessage":"Hello \[#\]\$%~ World"}' "$RUN_OUT" -journalctl --sync -journalctl -u systemd-resolved.service --cursor-file="$JOURNAL_CURSOR" --grep "Server returned error: SERVFAIL \(\d+: Hello \[\#\]\\$%~ World\)" - -### Test resolvectl show-cache -run resolvectl show-cache -run resolvectl show-cache --json=short -run resolvectl show-cache --json=pretty - -# Issue: https://github.com/systemd/systemd/issues/29580 (part #1) -dig @127.0.0.54 signed.test - -systemctl stop resolvectl-monitor.service -systemctl stop resolvectl-monitor-json.service - -# Issue: https://github.com/systemd/systemd/issues/29580 (part #2) -# -# Check for any warnings regarding malformed messages -(! journalctl -u resolvectl-monitor.service -u reseolvectl-monitor-json.service -p warning --grep malformed) -# Verify that all queries recorded by `resolvectl monitor --json` produced a valid JSON -# with expected fields -journalctl -p info -o cat _SYSTEMD_UNIT="resolvectl-monitor-json.service" | while read -r line; do - # Check that both "question" and "answer" fields are arrays + grep -qF "authenticated: yes" "$RUN_OUT" + + # Check a non-existent domain + # Note: mod-onlinesign utilizes Minimally Covering NSEC Records, hence the + # different response than with "standard" DNSSEC + run dig +dnssec this.does.not.exist.onlinesign.test + grep -qF "status: NOERROR" "$RUN_OUT" + grep -qF "NSEC \\000.this.does.not.exist.onlinesign.test." "$RUN_OUT" + # Check a wildcard record + run resolvectl query -t TXT this.should.be.authenticated.wild.onlinesign.test + grep -qF 'this.should.be.authenticated.wild.onlinesign.test IN TXT "this is an onlinesign wildcard"' "$RUN_OUT" + grep -qF "authenticated: yes" "$RUN_OUT" + + # Resolve via dbus method + TIMESTAMP=$(date '+%F %T') + run busctl call org.freedesktop.resolve1 /org/freedesktop/resolve1 org.freedesktop.resolve1.Manager ResolveHostname 'isit' 0 secondsub.onlinesign.test 0 0 + grep -qF '10 0 0 134 "secondsub.onlinesign.test"' "$RUN_OUT" + monitor_check_rr "$TIMESTAMP" "secondsub.onlinesign.test IN A 10.0.0.134" + + + : "--- ZONE: untrusted.test (DNSSEC without propagated DS records) ---" + # Issue: https://github.com/systemd/systemd/issues/23955 + # FIXME + resolvectl flush-caches + #run dig +short untrusted.test A untrusted.test AAAA + #grep -qF "10.0.0.121" "$RUN_OUT" + #grep -qF "fd00:dead:beef:cafe::121" "$RUN_OUT" + run resolvectl query untrusted.test + grep -qF "untrusted.test:" "$RUN_OUT" + grep -qF "10.0.0.121" "$RUN_OUT" + grep -qF "fd00:dead:beef:cafe::121" "$RUN_OUT" + grep -qF "authenticated: no" "$RUN_OUT" + run resolvectl service _mysvc._tcp untrusted.test + grep -qF "myservice.untrusted.test:1234" "$RUN_OUT" + grep -qF "10.0.0.123" "$RUN_OUT" + grep -qF "fd00:dead:beef:cafe::123" "$RUN_OUT" + + # Issue: https://github.com/systemd/systemd/issues/19472 + # 1) Query for a non-existing RR should return NOERROR + NSEC (?), not NXDOMAIN + # FIXME: re-enable once the issue is resolved + #run dig +dnssec AAAA untrusted.test + #grep -qF "status: NOERROR" "$RUN_OUT" + #grep -qE "^untrusted\.test\..+IN\s+NSEC\s+" "$RUN_OUT" + ## 2) Query for a non-existing name should return NXDOMAIN, not SERVFAIL + #run dig +dnssec this.does.not.exist.untrusted.test + #grep -qF "status: NXDOMAIN" "$RUN_OUT" + + : "--- ZONE: forwarded.test (queries forwarded to our dummy test server) ---" + JOURNAL_CURSOR="$(mktemp)" + journalctl -n0 -q --cursor-file="$JOURNAL_CURSOR" + + # See "test-resolved-dummy-server.c" for the server part + (! run resolvectl query nope.forwarded.test) + grep -qF "nope.forwarded.test" "$RUN_OUT" + grep -qF "not found" "$RUN_OUT" + + # SERVFAIL + EDE code 6: DNSSEC Bogus + (! run resolvectl query edns-bogus-dnssec.forwarded.test) + grep -qE "^edns-bogus-dnssec.forwarded.test:.+: upstream-failure \(DNSSEC Bogus\)" "$RUN_OUT" + # Same thing, but over Varlink + (! run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveHostname '{"name" : "edns-bogus-dnssec.forwarded.test"}') + grep -qF "io.systemd.Resolve.DNSSECValidationFailed" "$RUN_OUT" + grep -qF '{"result":"upstream-failure","extendedDNSErrorCode":6}' "$RUN_OUT" + journalctl --sync + journalctl -u systemd-resolved.service --cursor-file="$JOURNAL_CURSOR" --grep "Server returned error: SERVFAIL \(DNSSEC Bogus\). Lookup failed." + + # SERVFAIL + EDE code 16: Censored + extra text + (! run resolvectl query edns-extra-text.forwarded.test) + grep -qE "^edns-extra-text.forwarded.test.+: SERVFAIL \(Censored: Nothing to see here!\)" "$RUN_OUT" + (! run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveHostname '{"name" : "edns-extra-text.forwarded.test"}') + grep -qF "io.systemd.Resolve.DNSError" "$RUN_OUT" + grep -qF '{"rcode":2,"extendedDNSErrorCode":16,"extendedDNSErrorMessage":"Nothing to see here!"}' "$RUN_OUT" + journalctl --sync + journalctl -u systemd-resolved.service --cursor-file="$JOURNAL_CURSOR" --grep "Server returned error: SERVFAIL \(Censored: Nothing to see here!\)" + + # SERVFAIL + EDE code 0: Other + extra text + (! run resolvectl query edns-code-zero.forwarded.test) + grep -qE "^edns-code-zero.forwarded.test:.+: SERVFAIL \(Other: 🐱\)" "$RUN_OUT" + (! run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveHostname '{"name" : "edns-code-zero.forwarded.test"}') + grep -qF "io.systemd.Resolve.DNSError" "$RUN_OUT" + grep -qF '{"rcode":2,"extendedDNSErrorCode":0,"extendedDNSErrorMessage":"🐱"}' "$RUN_OUT" + journalctl --sync + journalctl -u systemd-resolved.service --cursor-file="$JOURNAL_CURSOR" --grep "Server returned error: SERVFAIL \(Other: 🐱\)" + + # SERVFAIL + invalid EDE code + (! run resolvectl query edns-invalid-code.forwarded.test) + grep -qE "^edns-invalid-code.forwarded.test:.+: SERVFAIL \([0-9]+\)" "$RUN_OUT" + (! run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveHostname '{"name" : "edns-invalid-code.forwarded.test"}') + grep -qF "io.systemd.Resolve.DNSError" "$RUN_OUT" + grep -qE '{"rcode":2,"extendedDNSErrorCode":[0-9]+}' "$RUN_OUT" + journalctl --sync + journalctl -u systemd-resolved.service --cursor-file="$JOURNAL_CURSOR" --grep "Server returned error: SERVFAIL \(\d+\)" + + # SERVFAIL + invalid EDE code + extra text + (! run resolvectl query edns-invalid-code-with-extra-text.forwarded.test) + grep -qE '^edns-invalid-code-with-extra-text.forwarded.test:.+: SERVFAIL \([0-9]+: Hello \[#\]\$%~ World\)' "$RUN_OUT" + (! run varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveHostname '{"name" : "edns-invalid-code-with-extra-text.forwarded.test"}') + grep -qF "io.systemd.Resolve.DNSError" "$RUN_OUT" + grep -qE '{"rcode":2,"extendedDNSErrorCode":[0-9]+,"extendedDNSErrorMessage":"Hello \[#\]\$%~ World"}' "$RUN_OUT" + journalctl --sync + journalctl -u systemd-resolved.service --cursor-file="$JOURNAL_CURSOR" --grep "Server returned error: SERVFAIL \(\d+: Hello \[\#\]\\$%~ World\)" +} + +testcase_09_resolvectl_showcache() { + ### Test resolvectl show-cache + run resolvectl show-cache + run resolvectl show-cache --json=short + run resolvectl show-cache --json=pretty +} + +testcase_10_resolvectl_json() { + # Issue: https://github.com/systemd/systemd/issues/29580 (part #1) + dig @127.0.0.54 signed.test + + systemctl stop resolvectl-monitor.service + systemctl stop resolvectl-monitor-json.service + + # Issue: https://github.com/systemd/systemd/issues/29580 (part #2) # - # The expression is slightly more complicated due to the fact that the "answer" field is optional, - # so we need to select it only if it's present, otherwise the type == "array" check would fail - echo "$line" | jq -e '[. | .question, (select(has("answer")) | .answer) | type == "array"] | all' -done + # Check for any warnings regarding malformed messages + (! journalctl -u resolvectl-monitor.service -u reseolvectl-monitor-json.service -p warning --grep malformed) + # Verify that all queries recorded by `resolvectl monitor --json` produced a valid JSON + # with expected fields + journalctl -p info -o cat _SYSTEMD_UNIT="resolvectl-monitor-json.service" | while read -r line; do + # Check that both "question" and "answer" fields are arrays + # + # The expression is slightly more complicated due to the fact that the "answer" field is optional, + # so we need to select it only if it's present, otherwise the type == "array" check would fail + echo "$line" | jq -e '[. | .question, (select(has("answer")) | .answer) | type == "array"] | all' + done +} # Test serve stale feature and NFTSet= if nftables is installed -if command -v nft >/dev/null; then +testcase_11_nft() { + if ! command -v nft >/dev/null; then + echo "nftables is not installed. Skipped serve stale feature and NFTSet= tests." + return 0 + fi + ### Test without serve stale feature ### NFT_FILTER_NAME=dns_port_filter @@ -833,70 +879,85 @@ if command -v nft >/dev/null; then rm -rf /run/systemd/system/system.slice.d nft flush ruleset -else - echo "nftables is not installed. Skipped serve stale feature and NFTSet= tests." -fi +} + +# Test resolvectl show-server-state +testcase_12_resolvectl2() { + run resolvectl show-server-state + grep -qF "10.0.0.1" "$RUN_OUT" + grep -qF "Interface" "$RUN_OUT" + + run resolvectl show-server-state --json=short + grep -qF "10.0.0.1" "$RUN_OUT" + grep -qF "Interface" "$RUN_OUT" + + run resolvectl show-server-state --json=pretty + grep -qF "10.0.0.1" "$RUN_OUT" + grep -qF "Interface" "$RUN_OUT" + + ### Test resolvectl statistics ### + run resolvectl statistics + grep -qF "Transactions" "$RUN_OUT" + grep -qF "Cache" "$RUN_OUT" + grep -qF "Failure Transactions" "$RUN_OUT" + grep -qF "DNSSEC Verdicts" "$RUN_OUT" + + run resolvectl statistics --json=short + grep -qF "transactions" "$RUN_OUT" + grep -qF "cache" "$RUN_OUT" + grep -qF "dnssec" "$RUN_OUT" + + run resolvectl statistics --json=pretty + grep -qF "transactions" "$RUN_OUT" + grep -qF "cache" "$RUN_OUT" + grep -qF "dnssec" "$RUN_OUT" + + ### Test resolvectl reset-statistics ### + run resolvectl reset-statistics + + run resolvectl reset-statistics --json=pretty + + run resolvectl reset-statistics --json=short + + test "$(resolvectl --json=short query -t AAAA localhost)" == '{"key":{"class":1,"type":28,"name":"localhost"},"address":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]}' + test "$(resolvectl --json=short query -t A localhost)" == '{"key":{"class":1,"type":1,"name":"localhost"},"address":[127,0,0,1]}' + + # Test ResolveRecord RR resolving via Varlink + test "$(varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveRecord '{"name":"localhost","type":1}' --json=short | jq -rc 'del(.rrs | .[] | .ifindex)')" == '{"rrs":[{"rr":{"key":{"class":1,"type":1,"name":"localhost"},"address":[127,0,0,1]},"raw":"CWxvY2FsaG9zdAAAAQABAAAAAAAEfwAAAQ=="}],"flags":786945}' + test "$(varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveRecord '{"name":"localhost","type":28}' --json=short | jq -rc 'del(.rrs | .[] | .ifindex)')" == '{"rrs":[{"rr":{"key":{"class":1,"type":28,"name":"localhost"},"address":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]},"raw":"CWxvY2FsaG9zdAAAHAABAAAAAAAQAAAAAAAAAAAAAAAAAAAAAQ=="}],"flags":786945}' + + # Ensure that reloading keeps the manually configured address + { + echo "[Resolve]" + echo "DNS=8.8.8.8" + } >/run/systemd/resolved.conf.d/reload.conf + resolvectl dns dns0 1.1.1.1 + systemctl reload systemd-resolved.service + resolvectl status + resolvectl dns dns0 | grep -qF "1.1.1.1" + # For some reason piping this last command to grep fails with: + # 'resolvectl[1378]: Failed to print table: Broken pipe' + # so use an intermediate file in /tmp/ + resolvectl >/tmp/output + grep -qF "DNS Servers: 8.8.8.8" /tmp/output + + # Check if resolved exits cleanly. + restart_resolved +} + +# PRE-SETUP +systemctl unmask systemd-resolved.service +systemctl enable --now systemd-resolved.service +systemctl service-log-level systemd-resolved.service debug + +# Need to be run before SETUP, otherwise things will break +manual_testcase_01_resolvectl +manual_testcase_02_mdns_llmnr + +# Run setup +setup -### Test resolvectl show-server-state ### -run resolvectl show-server-state -grep -qF "10.0.0.1" "$RUN_OUT" -grep -qF "Interface" "$RUN_OUT" - -run resolvectl show-server-state --json=short -grep -qF "10.0.0.1" "$RUN_OUT" -grep -qF "Interface" "$RUN_OUT" - -run resolvectl show-server-state --json=pretty -grep -qF "10.0.0.1" "$RUN_OUT" -grep -qF "Interface" "$RUN_OUT" - -### Test resolvectl statistics ### -run resolvectl statistics -grep -qF "Transactions" "$RUN_OUT" -grep -qF "Cache" "$RUN_OUT" -grep -qF "Failure Transactions" "$RUN_OUT" -grep -qF "DNSSEC Verdicts" "$RUN_OUT" - -run resolvectl statistics --json=short -grep -qF "transactions" "$RUN_OUT" -grep -qF "cache" "$RUN_OUT" -grep -qF "dnssec" "$RUN_OUT" - -run resolvectl statistics --json=pretty -grep -qF "transactions" "$RUN_OUT" -grep -qF "cache" "$RUN_OUT" -grep -qF "dnssec" "$RUN_OUT" - -### Test resolvectl reset-statistics ### -run resolvectl reset-statistics - -run resolvectl reset-statistics --json=pretty - -run resolvectl reset-statistics --json=short - -test "$(resolvectl --json=short query -t AAAA localhost)" == '{"key":{"class":1,"type":28,"name":"localhost"},"address":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]}' -test "$(resolvectl --json=short query -t A localhost)" == '{"key":{"class":1,"type":1,"name":"localhost"},"address":[127,0,0,1]}' - -# Test ResolveRecord RR resolving via Varlink -test "$(varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveRecord '{"name":"localhost","type":1}' --json=short | jq -rc 'del(.rrs | .[] | .ifindex)')" == '{"rrs":[{"rr":{"key":{"class":1,"type":1,"name":"localhost"},"address":[127,0,0,1]},"raw":"CWxvY2FsaG9zdAAAAQABAAAAAAAEfwAAAQ=="}],"flags":786945}' -test "$(varlinkctl call /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.ResolveRecord '{"name":"localhost","type":28}' --json=short | jq -rc 'del(.rrs | .[] | .ifindex)')" == '{"rrs":[{"rr":{"key":{"class":1,"type":28,"name":"localhost"},"address":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]},"raw":"CWxvY2FsaG9zdAAAHAABAAAAAAAQAAAAAAAAAAAAAAAAAAAAAQ=="}],"flags":786945}' - -# Ensure that reloading keeps the manually configured address -{ - echo "[Resolve]" - echo "DNS=8.8.8.8" -} >/run/systemd/resolved.conf.d/reload.conf -resolvectl dns dns0 1.1.1.1 -systemctl reload systemd-resolved.service -resolvectl status -resolvectl dns dns0 | grep -qF "1.1.1.1" -# For some reason piping this last command to grep fails with: -# 'resolvectl[1378]: Failed to print table: Broken pipe' -# so use an intermediate file in /tmp/ -resolvectl >/tmp/output -grep -qF "DNS Servers: 8.8.8.8" /tmp/output - -# Check if resolved exits cleanly. -restart_resolved +# Run tests +run_testcases touch /testok diff --git a/tools/command_ignorelist b/tools/command_ignorelist index af694c1..bbe19e2 100644 --- a/tools/command_ignorelist +++ b/tools/command_ignorelist @@ -525,3 +525,46 @@ udevadm.xml /refsect1[title="Options"]/refsect2[title="udevadm monitor\n op udevadm.xml /refsect1[title="Options"]/refsect2[title="udevadm test\n options\n devpath|file|unit\n "]/variablelist/varlistentry[term="-a"] vconsole.conf.xml /refsect1[title="Options"]/variablelist/varlistentry[term="KEYMAP="] vconsole.conf.xml /refsect1[title="Options"]/variablelist/varlistentry[term="FONT="] +file-hierarchy.xml /refsect1[title="General Structure"]/variablelist/varlistentry[term="/"] +file-hierarchy.xml /refsect1[title="General Structure"]/variablelist/varlistentry[term="/boot/"] +file-hierarchy.xml /refsect1[title="General Structure"]/variablelist/varlistentry[term="/efi/"] +file-hierarchy.xml /refsect1[title="General Structure"]/variablelist/varlistentry[term="/etc/"] +file-hierarchy.xml /refsect1[title="General Structure"]/variablelist/varlistentry[term="/home/"] +file-hierarchy.xml /refsect1[title="General Structure"]/variablelist/varlistentry[term="/root/"] +file-hierarchy.xml /refsect1[title="General Structure"]/variablelist/varlistentry[term="/srv/"] +file-hierarchy.xml /refsect1[title="General Structure"]/variablelist/varlistentry[term="/tmp/"] +file-hierarchy.xml /refsect1[title="Runtime Data"]/variablelist/varlistentry[term="/run/"] +file-hierarchy.xml /refsect1[title="Runtime Data"]/variablelist/varlistentry[term="/run/log/"] +file-hierarchy.xml /refsect1[title="Runtime Data"]/variablelist/varlistentry[term="/run/user/"] +file-hierarchy.xml /refsect1[title="Vendor-supplied Operating System Resources"]/variablelist/varlistentry[term="/usr/"] +file-hierarchy.xml /refsect1[title="Vendor-supplied Operating System Resources"]/variablelist/varlistentry[term="/usr/bin/"] +file-hierarchy.xml /refsect1[title="Vendor-supplied Operating System Resources"]/variablelist/varlistentry[term="/usr/include/"] +file-hierarchy.xml /refsect1[title="Vendor-supplied Operating System Resources"]/variablelist/varlistentry[term="/usr/lib/"] +file-hierarchy.xml /refsect1[title="Vendor-supplied Operating System Resources"]/variablelist/varlistentry[term="/usr/lib/arch-id/"] +file-hierarchy.xml /refsect1[title="Vendor-supplied Operating System Resources"]/variablelist/varlistentry[term="/usr/share/"] +file-hierarchy.xml /refsect1[title="Vendor-supplied Operating System Resources"]/variablelist/varlistentry[term="/usr/share/doc/"] +file-hierarchy.xml /refsect1[title="Vendor-supplied Operating System Resources"]/variablelist/varlistentry[term="/usr/share/factory/etc/"] +file-hierarchy.xml /refsect1[title="Vendor-supplied Operating System Resources"]/variablelist/varlistentry[term="/usr/share/factory/var/"] +file-hierarchy.xml /refsect1[title="Persistent Variable System Data"]/variablelist/varlistentry[term="/var/"] +file-hierarchy.xml /refsect1[title="Persistent Variable System Data"]/variablelist/varlistentry[term="/var/cache/"] +file-hierarchy.xml /refsect1[title="Persistent Variable System Data"]/variablelist/varlistentry[term="/var/lib/"] +file-hierarchy.xml /refsect1[title="Persistent Variable System Data"]/variablelist/varlistentry[term="/var/log/"] +file-hierarchy.xml /refsect1[title="Persistent Variable System Data"]/variablelist/varlistentry[term="/var/spool/"] +file-hierarchy.xml /refsect1[title="Persistent Variable System Data"]/variablelist/varlistentry[term="/var/tmp/"] +file-hierarchy.xml /refsect1[title="Virtual Kernel and API File Systems"]/variablelist/varlistentry[term="/dev/"] +file-hierarchy.xml /refsect1[title="Virtual Kernel and API File Systems"]/variablelist/varlistentry[term="/dev/shm/"] +file-hierarchy.xml /refsect1[title="Virtual Kernel and API File Systems"]/variablelist/varlistentry[term="/proc/"] +file-hierarchy.xml /refsect1[title="Virtual Kernel and API File Systems"]/variablelist/varlistentry[term="/proc/sys/"] +file-hierarchy.xml /refsect1[title="Virtual Kernel and API File Systems"]/variablelist/varlistentry[term="/sys/"] +file-hierarchy.xml /refsect1[title="Virtual Kernel and API File Systems"]/variablelist/varlistentry[term="/sys/fs/cgroup/"] +file-hierarchy.xml /refsect1[title="Compatibility Symlinks"]/variablelist/varlistentry[term="/bin/"] +file-hierarchy.xml /refsect1[title="Compatibility Symlinks"]/variablelist/varlistentry[term="/lib/"] +file-hierarchy.xml /refsect1[title="Compatibility Symlinks"]/variablelist/varlistentry[term="/lib64/"] +file-hierarchy.xml /refsect1[title="Compatibility Symlinks"]/variablelist/varlistentry[term="/var/run/"] +file-hierarchy.xml /refsect1[title="Home Directory"]/variablelist/varlistentry[term="~/.cache/"] +file-hierarchy.xml /refsect1[title="Home Directory"]/variablelist/varlistentry[term="~/.config/"] +file-hierarchy.xml /refsect1[title="Home Directory"]/variablelist/varlistentry[term="~/.local/bin/"] +file-hierarchy.xml /refsect1[title="Home Directory"]/variablelist/varlistentry[term="~/.local/lib/"] +file-hierarchy.xml /refsect1[title="Home Directory"]/variablelist/varlistentry[term="~/.local/lib/arch-id/"] +file-hierarchy.xml /refsect1[title="Home Directory"]/variablelist/varlistentry[term="~/.local/share/"] +file-hierarchy.xml /refsect1[title="Home Directory"]/variablelist/varlistentry[term="~/.local/state/"] diff --git a/units/user-runtime-dir@.service.in b/units/user-runtime-dir@.service.in index 5fb5cad..241e926 100644 --- a/units/user-runtime-dir@.service.in +++ b/units/user-runtime-dir@.service.in @@ -10,7 +10,7 @@ [Unit] Description=User Runtime Directory /run/user/%i Documentation=man:user@.service(5) -After=dbus.service +After=systemd-logind.service dbus.service IgnoreOnIsolate=yes [Service] diff --git a/units/user@.service.in b/units/user@.service.in index 5efb12a..5695465 100644 --- a/units/user@.service.in +++ b/units/user@.service.in @@ -11,7 +11,7 @@ Description=User Manager for UID %i Documentation=man:user@.service(5) BindsTo=user-runtime-dir@%i.service -After=user-runtime-dir@%i.service dbus.service systemd-oomd.service +After=systemd-logind.service user-runtime-dir@%i.service dbus.service systemd-oomd.service IgnoreOnIsolate=yes [Service] |