summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-x.semaphore/semaphore-runner.sh18
-rw-r--r--.semaphore/semaphore.yml2
-rw-r--r--README63
-rw-r--r--README.md1
-rw-r--r--TODO7
-rw-r--r--docs/sysvinit/meson.build2
-rw-r--r--factory/templates/meson.build2
-rw-r--r--hwdb.d/60-evdev.hwdb5
-rw-r--r--hwdb.d/60-input-id.hwdb5
-rw-r--r--hwdb.d/60-keyboard.hwdb5
-rw-r--r--hwdb.d/60-sensor.hwdb5
-rw-r--r--hwdb.d/70-mouse.hwdb5
-rw-r--r--hwdb.d/70-pointingstick.hwdb4
-rw-r--r--man/kernel-install.xml1
-rw-r--r--man/logind.conf.xml69
-rw-r--r--man/meson.build2
-rw-r--r--man/org.freedesktop.login1.xml30
-rw-r--r--man/systemd-analyze.xml10
-rw-r--r--man/systemd.net-naming-scheme.xml12
-rw-r--r--meson.build28
-rw-r--r--rules.d/meson.build2
-rw-r--r--shell-completion/bash/meson.build2
-rw-r--r--shell-completion/zsh/meson.build2
-rw-r--r--src/analyze/analyze.c2
-rw-r--r--src/basic/def.h2
-rw-r--r--src/basic/strv.c10
-rw-r--r--src/basic/strv.h2
-rw-r--r--src/core/load-fragment.c2
-rw-r--r--src/core/main.c14
-rw-r--r--src/core/manager.c73
-rw-r--r--src/core/manager.h2
-rw-r--r--src/core/meson.build4
-rw-r--r--src/firstboot/firstboot.c62
-rw-r--r--src/hwdb/hwdb.c2
-rw-r--r--src/journal-remote/meson.build2
-rwxr-xr-xsrc/kernel-install/kernel-install.in (renamed from src/kernel-install/kernel-install)16
-rw-r--r--src/kernel-install/meson.build6
-rw-r--r--src/libsystemd/meson.build2
-rw-r--r--src/libudev/meson.build2
-rw-r--r--src/login/logind-dbus.c5
-rw-r--r--src/login/logind.conf.in7
-rw-r--r--src/login/meson.build2
-rwxr-xr-xsrc/partition/test-repart.sh2
-rw-r--r--src/resolve/meson.build2
-rw-r--r--src/rpm/meson.build2
-rw-r--r--src/shared/devnode-acl.c23
-rw-r--r--src/shared/netif-naming-scheme.c1
-rw-r--r--src/shared/netif-naming-scheme.h30
-rw-r--r--src/shutdown/umount.c18
-rw-r--r--src/test/meson.build6
-rw-r--r--src/test/test-load-fragment.c16
-rw-r--r--src/test/test-manager.c29
-rw-r--r--src/timesync/meson.build2
-rw-r--r--src/udev/meson.build2
-rw-r--r--src/udev/udev-builtin-net_id.c11
-rw-r--r--src/udev/udev-event.c3
-rw-r--r--src/udev/udev-node.c134
-rw-r--r--src/udev/udev-node.h7
-rw-r--r--src/udev/udev-rules.c70
-rw-r--r--src/udev/udevadm-lock.c18
-rw-r--r--src/udev/udevd.c6
-rw-r--r--src/vconsole/meson.build2
-rw-r--r--sysctl.d/meson.build2
-rw-r--r--sysusers.d/meson.build2
-rw-r--r--test/test-network/conf/25-ip6tnl-tunnel-external.netdev (renamed from test/test-network/conf/25-ip6tnl-external.netdev)0
-rwxr-xr-xtest/test-network/systemd-networkd-tests.py2
-rwxr-xr-xtest/units/testsuite-58.sh20
-rwxr-xr-xtest/units/testsuite-64.sh8
-rw-r--r--tmpfiles.d/meson.build2
-rwxr-xr-xtools/check-help.sh14
-rwxr-xr-xtools/check-version.sh36
-rwxr-xr-xtools/meson-render-jinja2.py9
-rw-r--r--units/meson.build2
73 files changed, 595 insertions, 385 deletions
diff --git a/.semaphore/semaphore-runner.sh b/.semaphore/semaphore-runner.sh
index 6ccf271a82..ec95f65315 100755
--- a/.semaphore/semaphore-runner.sh
+++ b/.semaphore/semaphore-runner.sh
@@ -21,7 +21,7 @@ UBUNTU_RELEASE="$(lsb_release -cs)"
create_container() {
# Create autopkgtest LXC image; this sometimes fails with "Unable to fetch
# GPG key from keyserver", so retry a few times with different keyservers.
- for keyserver in "" "keys.gnupg.net" "keys.openpgp.org" "keyserver.ubuntu.com"; do
+ for keyserver in "keys.openpgp.org" "" "keyserver.ubuntu.com" "keys.gnupg.net"; do
for retry in {1..5}; do
sudo lxc-create -n "$CONTAINER" -t download -- -d "$DISTRO" -r "$RELEASE" -a "$ARCH" ${keyserver:+--keyserver "$keyserver"} && break 2
sleep $((retry*retry))
@@ -36,8 +36,16 @@ create_container() {
# enable source repositories so that apt-get build-dep works
sudo lxc-attach -n "$CONTAINER" -- sh -ex <<EOF
sed 's/^deb/deb-src/' /etc/apt/sources.list >> /etc/apt/sources.list.d/sources.list
-# wait until online
-while [ -z "\$(ip route list 0/0)" ]; do sleep 1; done
+# We might attach the console too soon
+while ! systemctl --quiet --wait is-system-running; do sleep 1; done
+# Manpages database trigger takes a lot of time and is not useful in a CI
+echo 'man-db man-db/auto-update boolean false' | debconf-set-selections
+# Speed up dpkg, image is thrown away after the test
+mkdir -p /etc/dpkg/dpkg.cfg.d/
+echo 'force-unsafe-io' > /etc/dpkg/dpkg.cfg.d/unsafe_io
+# For some reason, it is necessary to run this manually or the interface won't be configured
+# Note that we avoid networkd, as some of the tests will break it later on
+dhclient
apt-get -q --allow-releaseinfo-change update
apt-get -y dist-upgrade
apt-get install -y eatmydata
@@ -88,6 +96,10 @@ EOF
rm -rf debian/patches
# disable autopkgtests which are not for upstream
sed -i '/# NOUPSTREAM/ q' debian/tests/control
+ # TODO: rebooting via autopkgtest-reboot seems to be broken, disable these tests for now
+ sed -i -n '1,/Tests: boot-and-services/p;/Tests: udev/,$p' debian/tests/control
+ sed -i '/Tests: boot-and-services/d' debian/tests/control
+ sed -i '/Tests: boot-smoke/,$d' debian/tests/control
# enable more unit tests
sed -i '/^CONFFLAGS =/ s/=/= --werror -Dtests=unsafe -Dsplit-usr=true -Dslow-tests=true -Dfuzz-tests=true -Dman=true /' debian/rules
# no orig tarball
diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml
index bd5d135e9e..07742337e8 100644
--- a/.semaphore/semaphore.yml
+++ b/.semaphore/semaphore.yml
@@ -7,7 +7,7 @@ name: Debian autopkgtest (LXC)
agent:
machine:
type: e1-standard-2
- os_image: ubuntu1804
+ os_image: ubuntu2004
# Cancel any running or queued job for the same ref
auto_cancel:
diff --git a/README b/README
index 420276eda8..6eaba9b0f1 100644
--- a/README
+++ b/README
@@ -30,14 +30,21 @@ LICENSE:
LGPL-2.1-or-later for all code, exceptions noted in LICENSES/README.md
REQUIREMENTS:
- Linux kernel >= 3.15
- Linux kernel >= 4.2 for unified cgroup hierarchy support
- Linux kernel >= 4.10 for cgroup-bpf egress and ingress hooks
- Linux kernel >= 4.15 for cgroup-bpf device hook
- Linux kernel >= 4.17 for cgroup-bpf socket address hooks
- Linux kernel >= 5.3 for bounded-loops in BPF program
- Linux kernel >= 5.4 for signed Verity images support
- Linux kernel >= 5.7 for BPF links and the BPF LSM hook
+ Linux kernel ≥ 3.15
+ ≥ 4.5 for pids controller in cgroup v2
+ ≥ 4.6 for cgroup namespaces
+ ≥ 4.9 for RENAME_NOREPLACE support in vfat
+ ≥ 4.10 for cgroup-bpf egress and ingress hooks
+ ≥ 4.15 for cgroup-bpf device hook and cpu controller in cgroup v2
+ ≥ 4.17 for cgroup-bpf socket address hooks
+ ≥ 5.3 for bounded loops in BPF program
+ ≥ 5.4 for signed Verity images
+ ≥ 5.7 for BPF links and the BPF LSM hook
+
+ Kernel versions below 4.15 have significant gaps in functionality and
+ are not recommended for use with this version of systemd. Taint flag
+ 'old-kernel' will be set. Systemd will most likely still function, but
+ upstream support and testing are limited.
Kernel Config Options:
CONFIG_DEVTMPFS
@@ -330,24 +337,48 @@ SYSV INIT.D SCRIPTS:
Please see src/systemctl/systemd-sysv-install.SKELETON for how this
needs to look like, and provide an implementation at the marked places.
-WARNINGS:
+WARNINGS and TAINT FLAGS:
systemd will warn during early boot if /usr is not already mounted at
this point (that means: either located on the same file system as / or
already mounted in the initrd). While in systemd itself very little
- will break if /usr is on a separate, late-mounted partition, many of
- its dependencies very likely will break sooner or later in one form or
+ will break if /usr is on a separate late-mounted partition, many of its
+ dependencies very likely will break sooner or later in one form or
another. For example, udev rules tend to refer to binaries in /usr,
binaries that link to libraries in /usr or binaries that refer to data
files in /usr. Since these breakages are not always directly visible,
- systemd will warn about this, since this kind of file system setup is
- not really supported anymore by the basic set of Linux OS components.
-
- systemd requires that the /run mount point exists. systemd also
- requires that /var/run is a symlink to /run.
+ systemd will warn about this. Such setups are not really supported by
+ the basic set of Linux OS components. Taint flag 'split-usr' will be
+ set when this condition is detected.
For more information on this issue consult
https://www.freedesktop.org/wiki/Software/systemd/separate-usr-is-broken
+ systemd will warn if the filesystem is not usr-merged (i.e.: /bin, /sbin
+ and /lib* are not symlinks to their counterparts under /usr). Taint flag
+ 'unmerged-usr' will be set when this condition is detected.
+
+ For more information on this issue consult
+ https://www.freedesktop.org/wiki/Software/systemd/TheCaseForTheUsrMerge
+
+ systemd requires that the /run mount point exists. systemd also
+ requires that /var/run is a symlink to /run. Taint flag 'var-run-bad'
+ will be set when this condition is detected.
+
+ Systemd will also warn when the cgroup support is unavailable in the
+ kernel (taint flag 'cgroups-missing'), the system is using the old
+ cgroup hierarchy (taint flag 'cgroupsv1'), the hardware clock is
+ running in non-UTC mode (taint flag 'local-hwclock'), the kernel
+ overflow UID or GID are not 65534 (taint flags 'overflowuid-not-65534'
+ and 'overflowgid-not-65534'), the UID or GID range assigned to the
+ running systemd instance covers less than 0…65534 (taint flags
+ 'short-uid-range' and 'short-gid-range').
+
+ Taint conditions are logged during boot, but may also be checked at any
+ time with:
+
+ busctl get-property org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager Tainted
+
+VALGRIND:
To run systemd under valgrind, compile with meson option
-Dvalgrind=true and have valgrind development headers installed
(i.e. valgrind-devel or equivalent). Otherwise, false positives will be
diff --git a/README.md b/README.md
index 395f1eb333..f0ed551615 100644
--- a/README.md
+++ b/README.md
@@ -13,6 +13,7 @@ System and Service Manager
[![CentOS CI - CentOS 8](https://jenkins-systemd.apps.ocp.ci.centos.org/buildStatus/icon?subject=CentOS%20CI%20-%20CentOS%208&job=upstream-centos8)](https://jenkins-systemd.apps.ocp.ci.centos.org/job/upstream-centos8/)<br/>
[![CentOS CI - Arch](https://jenkins-systemd.apps.ocp.ci.centos.org/buildStatus/icon?subject=CentOS%20CI%20-%20Arch&job=upstream-vagrant-archlinux)](https://jenkins-systemd.apps.ocp.ci.centos.org/job/upstream-vagrant-archlinux/)<br/>
[![CentOS CI - Arch (sanitizers)](https://jenkins-systemd.apps.ocp.ci.centos.org/buildStatus/icon?subject=CentOS%20CI%20-%20Arch%20(sanitizers)&job=upstream-vagrant-archlinux-sanitizers)](https://jenkins-systemd.apps.ocp.ci.centos.org/job/upstream-vagrant-archlinux-sanitizers/)<br/>
+[![CentOS CI - Rawhide (SELinux)](https://jenkins-systemd.apps.ocp.ci.centos.org/buildStatus/icon?subject=CentOS%20CI%20-%20Rawhide%20(SELinux)&job=upstream-vagrant-rawhide-selinux)](https://jenkins-systemd.apps.ocp.ci.centos.org/view/Upstream/job/upstream-vagrant-rawhide-selinux/)<br/>
[![Fossies codespell report](https://fossies.org/linux/test/systemd-main.tar.gz/codespell.svg)](https://fossies.org/linux/test/systemd-main.tar.gz/codespell.html)</br>
[![Coverage Status](https://coveralls.io/repos/github/systemd/systemd/badge.svg?branch=main)](https://coveralls.io/github/systemd/systemd?branch=main)</br>
[![Packaging status](https://repology.org/badge/tiny-repos/systemd.svg)](https://repology.org/project/systemd/versions)
diff --git a/TODO b/TODO
index bfeb946997..05bbb0f31c 100644
--- a/TODO
+++ b/TODO
@@ -78,6 +78,13 @@ Janitorial Clean-ups:
Features:
+* get_color_mode() should probably check the $COLORTERM environment variable
+ which most terminal environments appear to set.
+
+* firstboot: maybe just default to C.UTF-8 locale if nothing is set, so that we
+ don't query this unnecessarily in entirely uninitialized
+ containers. (i.e. containers with empty /etc).
+
* systemd creds hookup with qemu fw_cfg. (Quite possibly might not need any
code at all, given the fw_cfg stuff are just files, but we should then
document how to use it). Goal: provide symmetric ways to pass creds to nspawn
diff --git a/docs/sysvinit/meson.build b/docs/sysvinit/meson.build
index cd3015ca4b..64476a5d76 100644
--- a/docs/sysvinit/meson.build
+++ b/docs/sysvinit/meson.build
@@ -4,6 +4,6 @@ custom_target(
'README',
input : 'README.in',
output : 'README',
- command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+ command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : conf.get('HAVE_SYSV_COMPAT') == 1,
install_dir : sysvinit_path)
diff --git a/factory/templates/meson.build b/factory/templates/meson.build
index 821f176a74..ece2c644ff 100644
--- a/factory/templates/meson.build
+++ b/factory/templates/meson.build
@@ -6,6 +6,6 @@ custom_target(
'locale.conf',
input : 'locale.conf.in',
output : 'locale.conf',
- command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+ command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : true,
install_dir : factory_etc_dir)
diff --git a/hwdb.d/60-evdev.hwdb b/hwdb.d/60-evdev.hwdb
index 9fcb4a3ddf..c97cd13557 100644
--- a/hwdb.d/60-evdev.hwdb
+++ b/hwdb.d/60-evdev.hwdb
@@ -3,11 +3,6 @@
# The lookup keys are composed in:
# 60-evdev.rules
#
-# Note: The format of the "evdev:" prefix match key is a contract between the
-# rules file and the hardware data, it might change in later revisions to
-# support more or better matches, it is not necessarily expected to be a stable
-# ABI.
-#
# Match string formats:
# evdev:<modalias>
# evdev:name:<device name>:dmi:<dmi string>
diff --git a/hwdb.d/60-input-id.hwdb b/hwdb.d/60-input-id.hwdb
index 2d5681dea6..802ed9a1e7 100644
--- a/hwdb.d/60-input-id.hwdb
+++ b/hwdb.d/60-input-id.hwdb
@@ -3,11 +3,6 @@
# The lookup keys are composed in:
# 60-input-id.rules
#
-# Note: The format of the "input-id:" prefix match key is a contract between
-# the rules file and the hardware data, it might change in later revisions to
-# support more or better matches, it is not necessarily expected to be a stable
-# ABI.
-#
# Match string formats:
# id-input:modalias:<modalias>
#
diff --git a/hwdb.d/60-keyboard.hwdb b/hwdb.d/60-keyboard.hwdb
index c196a1fd64..7c830fb9b1 100644
--- a/hwdb.d/60-keyboard.hwdb
+++ b/hwdb.d/60-keyboard.hwdb
@@ -13,11 +13,6 @@
# The lookup keys are composed in:
# 60-evdev.rules
#
-# Note: The format of the "evdev:" prefix match key is a contract between the
-# rules file and the hardware data, it might change in later revisions to
-# support more or better matches, it is not necessarily expected to be a stable
-# ABI.
-#
# Supported hardware matches are:
# - Generic input devices match:
# evdev:input:bZZZZvYYYYpXXXXeWWWW-VVVV
diff --git a/hwdb.d/60-sensor.hwdb b/hwdb.d/60-sensor.hwdb
index ea278913bc..b54539bf53 100644
--- a/hwdb.d/60-sensor.hwdb
+++ b/hwdb.d/60-sensor.hwdb
@@ -3,11 +3,6 @@
# The lookup keys are composed in:
# 60-sensor.rules
#
-# Note: The format of the "sensor:" prefix match key is a contract between the
-# rules file and the hardware data, it might change in later revisions to
-# support more or better matches, it is not necessarily expected to be a stable
-# ABI.
-#
# Match string formats:
# sensor:modalias:<parent modalias pattern>:dmi:<dmi pattern>
#
diff --git a/hwdb.d/70-mouse.hwdb b/hwdb.d/70-mouse.hwdb
index 723d145e34..4084019bde 100644
--- a/hwdb.d/70-mouse.hwdb
+++ b/hwdb.d/70-mouse.hwdb
@@ -6,11 +6,6 @@
# The lookup keys are composed in:
# 70-mouse.rules
#
-# Note: The format of the "mouse:" prefix match key is a contract between the
-# rules file and the hardware data, it might change in later revisions to
-# support more or better matches, it is not necessarily expected to be a stable
-# ABI.
-#
# Match key format:
# mouse:<subsystem>:v<vid>p<pid>:name:<name>:
#
diff --git a/hwdb.d/70-pointingstick.hwdb b/hwdb.d/70-pointingstick.hwdb
index 6039119b6a..00f28c6034 100644
--- a/hwdb.d/70-pointingstick.hwdb
+++ b/hwdb.d/70-pointingstick.hwdb
@@ -7,10 +7,6 @@
# The lookup keys are composed in:
# 60-evdev.rules
#
-# Note: The format of the "evdev:" prefix match key is a contract between the
-# rules file and the hardware data, it might change in later revisions to
-# support more or better matches, it is not necessarily a stable ABI.
-#
# Supported hardware matches are:
# - Generic input devices match:
# evdev:input:bZZZZvYYYYpXXXXeWWWW-VVVV
diff --git a/man/kernel-install.xml b/man/kernel-install.xml
index 974d6984de..5ae86aca18 100644
--- a/man/kernel-install.xml
+++ b/man/kernel-install.xml
@@ -166,6 +166,7 @@
</varlistentry>
<xi:include href="standard-options.xml" xpointer="help" />
+ <xi:include href="standard-options.xml" xpointer="version" />
</variablelist>
</refsect1>
diff --git a/man/logind.conf.xml b/man/logind.conf.xml
index 3045c1b9ba..fc838abee2 100644
--- a/man/logind.conf.xml
+++ b/man/logind.conf.xml
@@ -205,47 +205,34 @@
<term><varname>HandleLidSwitchExternalPower=</varname></term>
<term><varname>HandleLidSwitchDocked=</varname></term>
- <listitem><para>Controls how logind shall handle the
- system power, reboot and sleep keys and the lid switch to trigger
- actions such as system power-off, reboot or suspend. Can be one of
- <literal>ignore</literal>,
- <literal>poweroff</literal>,
- <literal>reboot</literal>,
- <literal>halt</literal>,
- <literal>kexec</literal>,
- <literal>suspend</literal>,
- <literal>hibernate</literal>,
- <literal>hybrid-sleep</literal>,
- <literal>suspend-then-hibernate</literal>,
- <literal>lock</literal>, and
- <literal>factory-reset</literal>.
- If <literal>ignore</literal>, logind will never handle these
- keys. If <literal>lock</literal>, all running sessions will be
- screen-locked; otherwise, the specified action will be taken
- in the respective event. Only input devices with the
- <literal>power-switch</literal> udev tag will be watched for
- key/lid switch events. <varname>HandlePowerKey=</varname>
- defaults to <literal>poweroff</literal>, <varname>HandleRebootKey=</varname>
- defaults to <literal>reboot</literal>, <varname>HandleSuspendKey=</varname>
- defaults to <literal>suspend</literal>, <varname>HandleHibernateKey=</varname>
- defaults to <literal>hibernate</literal>, <varname>HandlePowerKeyLongPress=</varname>
- defaults to <literal>ignore</literal>, <varname>HandleRebootKeyLongPress=</varname>
- defaults to <literal>poweroff</literal>, <varname>HandleSuspendKeyLongPress=</varname>
- defaults to <literal>hibernate</literal>, <varname>HandleHibernateKeyLongPress=</varname>
- defaults to <literal>ignore</literal>.
- <varname>HandleLidSwitch=</varname> defaults to
- <literal>suspend</literal>.
- <varname>HandleLidSwitchExternalPower=</varname> is completely
- ignored by default (for backwards compatibility) — an explicit
- value must be set before it will be used to determine
- behaviour. <varname>HandleLidSwitchDocked=</varname> defaults
- to <literal>ignore</literal>. If the system is inserted in a
- docking station, or if more than one display is connected, the
- action specified by <varname>HandleLidSwitchDocked=</varname>
- occurs; if the system is on external power the action (if any)
- specified by <varname>HandleLidSwitchExternalPower=</varname>
- occurs; otherwise the <varname>HandleLidSwitch=</varname>
- action occurs.</para>
+ <listitem><para>Controls how logind shall handle the system power, reboot and sleep keys and the lid
+ switch to trigger actions such as system power-off, reboot or suspend. Can be one of
+ <literal>ignore</literal>, <literal>poweroff</literal>, <literal>reboot</literal>,
+ <literal>halt</literal>, <literal>kexec</literal>, <literal>suspend</literal>,
+ <literal>hibernate</literal>, <literal>hybrid-sleep</literal>,
+ <literal>suspend-then-hibernate</literal>, <literal>lock</literal>, and
+ <literal>factory-reset</literal>. If <literal>ignore</literal>, <command>systemd-logind</command>
+ will never handle these keys. If <literal>lock</literal>, all running sessions will be screen-locked;
+ otherwise, the specified action will be taken in the respective event. Only input devices with the
+ <literal>power-switch</literal> udev tag will be watched for key/lid switch
+ events.</para>
+
+ <para><varname>HandlePowerKey=</varname> defaults to <literal>poweroff</literal>,
+ <varname>HandleRebootKey=</varname> defaults to <literal>reboot</literal>,
+ <varname>HandleSuspendKey=</varname> defaults to <literal>suspend</literal>,
+ <varname>HandleHibernateKey=</varname> defaults to <literal>hibernate</literal>,
+ <varname>HandlePowerKeyLongPress=</varname> defaults to <literal>ignore</literal>,
+ <varname>HandleRebootKeyLongPress=</varname> defaults to <literal>poweroff</literal>,
+ <varname>HandleSuspendKeyLongPress=</varname> defaults to <literal>hibernate</literal>,
+ <varname>HandleHibernateKeyLongPress=</varname> defaults to <literal>ignore</literal>.
+ <varname>HandleLidSwitch=</varname> defaults to <literal>suspend</literal>.
+ <varname>HandleLidSwitchExternalPower=</varname> is completely ignored by default (for backwards
+ compatibility) — an explicit value must be set before it will be used to determine
+ behaviour. <varname>HandleLidSwitchDocked=</varname> defaults to <literal>ignore</literal>. If the
+ system is inserted in a docking station, or if more than one display is connected, the action
+ specified by <varname>HandleLidSwitchDocked=</varname> occurs; if the system is on external power the
+ action (if any) specified by <varname>HandleLidSwitchExternalPower=</varname> occurs; otherwise the
+ <varname>HandleLidSwitch=</varname> action occurs.</para>
<para>A different application may disable logind's handling of system power and
sleep keys and the lid switch by taking a low-level inhibitor lock
diff --git a/man/meson.build b/man/meson.build
index 83b368115b..d9c706b4ab 100644
--- a/man/meson.build
+++ b/man/meson.build
@@ -30,7 +30,7 @@ custom_entities_ent = custom_target(
'custom-entities.ent',
input : 'custom-entities.ent.in',
output : 'custom-entities.ent',
- command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'])
+ command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'])
man_pages = []
html_pages = []
diff --git a/man/org.freedesktop.login1.xml b/man/org.freedesktop.login1.xml
index d25287b18b..8fc145d771 100644
--- a/man/org.freedesktop.login1.xml
+++ b/man/org.freedesktop.login1.xml
@@ -194,10 +194,20 @@ node /org/freedesktop/login1 {
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s HandlePowerKey = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly s HandlePowerKeyLongPress = '...';
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly s HandleRebootKey = '...';
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly s HandleRebootKeyLongPress = '...';
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s HandleSuspendKey = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly s HandleSuspendKeyLongPress = '...';
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s HandleHibernateKey = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly s HandleHibernateKeyLongPress = '...';
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s HandleLidSwitch = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s HandleLidSwitchExternalPower = '...';
@@ -242,6 +252,16 @@ node /org/freedesktop/login1 {
};
</programlisting>
+ <!--property HandlePowerKeyLongPress is not documented!-->
+
+ <!--property HandleRebootKey is not documented!-->
+
+ <!--property HandleRebootKeyLongPress is not documented!-->
+
+ <!--property HandleSuspendKeyLongPress is not documented!-->
+
+ <!--property HandleHibernateKeyLongPress is not documented!-->
+
<!--Autogenerated cross-references for systemd.directives, do not edit-->
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.login1.Manager"/>
@@ -418,10 +438,20 @@ node /org/freedesktop/login1 {
<variablelist class="dbus-property" generated="True" extra-ref="HandlePowerKey"/>
+ <variablelist class="dbus-property" generated="True" extra-ref="HandlePowerKeyLongPress"/>
+
+ <variablelist class="dbus-property" generated="True" extra-ref="HandleRebootKey"/>
+
+ <variablelist class="dbus-property" generated="True" extra-ref="HandleRebootKeyLongPress"/>
+
<variablelist class="dbus-property" generated="True" extra-ref="HandleSuspendKey"/>
+ <variablelist class="dbus-property" generated="True" extra-ref="HandleSuspendKeyLongPress"/>
+
<variablelist class="dbus-property" generated="True" extra-ref="HandleHibernateKey"/>
+ <variablelist class="dbus-property" generated="True" extra-ref="HandleHibernateKeyLongPress"/>
+
<variablelist class="dbus-property" generated="True" extra-ref="HandleLidSwitch"/>
<variablelist class="dbus-property" generated="True" extra-ref="HandleLidSwitchExternalPower"/>
diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml
index 7baa1794d7..97290d479b 100644
--- a/man/systemd-analyze.xml
+++ b/man/systemd-analyze.xml
@@ -819,10 +819,12 @@ $ systemd-analyze verify /tmp/source:alias.service
<listitem><para>Control verification of units and their dependencies and whether
<command>systemd-analyze verify</command> exits with a non-zero process exit status or not. With
<command>yes</command>, return a non-zero process exit status when warnings arise during verification
- of either the specified unit or any of its associated dependencies. This is the default. With
- <command>no</command>, return a non-zero process exit status when warnings arise during verification
- of only the specified unit. With <command>one</command>, return a non-zero process exit status when
- warnings arise during verification of either the specified unit or its immediate dependencies. </para></listitem>
+ of either the specified unit or any of its associated dependencies. With <command>no</command>,
+ return a non-zero process exit status when warnings arise during verification of only the specified
+ unit. With <command>one</command>, return a non-zero process exit status when warnings arise during
+ verification of either the specified unit or its immediate dependencies. If this option is not
+ specified, zero is returned as the exit status regardless whether warnings arise during verification
+ or not.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml
index 41408411fc..e5a3d7a313 100644
--- a/man/systemd.net-naming-scheme.xml
+++ b/man/systemd.net-naming-scheme.xml
@@ -403,6 +403,18 @@
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><constant>v251</constant></term>
+
+ <listitem><para>Since version <constant>v247</constant> we no longer set
+ <varname>ID_NET_NAME_SLOT</varname> if we detect that a PCI device associated with a slot is a PCI
+ bridge as that would create naming conflict when there are more child devices on that bridge. Now,
+ this is relaxed and we will use slot information to generate the name based on it but only if
+ the PCI device has multiple functions. This is safe because distinct function number is a part of
+ the device name for multifunction devices.</para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
<para>Note that <constant>latest</constant> may be used to denote the latest scheme known (to this
diff --git a/meson.build b/meson.build
index 0455d89b78..4a154850db 100644
--- a/meson.build
+++ b/meson.build
@@ -1826,6 +1826,8 @@ config_h = configure_file(
add_project_arguments('-include', 'config.h', language : 'c')
+jinja2_cmdline = [meson_render_jinja2, config_h, version_h]
+
############################################################
# binaries that have --help and are intended for use by humans,
@@ -2113,7 +2115,7 @@ endforeach
############################################################
-dbus_programs += executable(
+exe = executable(
'systemd',
systemd_sources,
include_directories : includes,
@@ -2124,6 +2126,8 @@ dbus_programs += executable(
install_rpath : rootlibexecdir,
install : true,
install_dir : rootlibexecdir)
+dbus_programs += exe
+public_programs += exe
meson.add_install_script(meson_make_symlink,
rootlibexecdir / 'systemd',
@@ -2680,7 +2684,7 @@ if conf.get('HAVE_LIBCRYPTSETUP') == 1
install : true,
install_dir : systemgeneratordir)
- executable(
+ public_programs += executable(
'systemd-cryptenroll',
systemd_cryptenroll_sources,
include_directories : includes,
@@ -3115,7 +3119,7 @@ if conf.get('ENABLE_RANDOMSEED') == 1
endif
if conf.get('ENABLE_FIRSTBOOT') == 1
- executable(
+ public_programs += executable(
'systemd-firstboot',
'src/firstboot/firstboot.c',
include_directories : includes,
@@ -3605,7 +3609,7 @@ if conf.get('ENABLE_NETWORKD') == 1
install : true,
install_dir : rootlibexecdir)
- executable(
+ public_programs += executable(
'systemd-networkd-wait-online',
systemd_networkd_wait_online_sources,
include_directories : includes,
@@ -3651,6 +3655,15 @@ executable(
install : true,
install_dir : rootlibexecdir)
+public_programs += custom_target(
+ 'kernel-install',
+ input : kernel_install_in,
+ output : 'kernel-install',
+ command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
+ install : want_kernel_install,
+ install_mode : 'rwxr-xr-x',
+ install_dir : bindir)
+
############################################################
runtest_env = custom_target(
@@ -3891,6 +3904,7 @@ endif
############################################################
check_help = find_program('tools/check-help.sh')
+check_version = find_program('tools/check-version.sh')
foreach exec : public_programs
name = exec.full_path().split('/')[-1]
@@ -3899,6 +3913,12 @@ foreach exec : public_programs
check_help,
args : exec.full_path(),
depends: exec)
+
+ test('check-version-' + name,
+ check_version,
+ args : [exec.full_path(),
+ meson.project_version()],
+ depends: exec)
endif
endforeach
diff --git a/rules.d/meson.build b/rules.d/meson.build
index e6533e001a..f725e14d95 100644
--- a/rules.d/meson.build
+++ b/rules.d/meson.build
@@ -51,7 +51,7 @@ foreach file : rules_in
file,
input : file + '.in',
output: file,
- command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+ command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : true,
install_dir : udevrulesdir)
endforeach
diff --git a/shell-completion/bash/meson.build b/shell-completion/bash/meson.build
index ae6a61e555..fb7314348a 100644
--- a/shell-completion/bash/meson.build
+++ b/shell-completion/bash/meson.build
@@ -14,7 +14,7 @@ custom_target(
'systemctl',
input : 'systemctl.in',
output : 'systemctl',
- command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+ command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : bashcompletiondir != 'no',
install_dir : bashcompletiondir)
diff --git a/shell-completion/zsh/meson.build b/shell-completion/zsh/meson.build
index bac531798c..b39f933ea4 100644
--- a/shell-completion/zsh/meson.build
+++ b/shell-completion/zsh/meson.build
@@ -9,7 +9,7 @@ custom_target(
'_systemctl',
input : '_systemctl.in',
output : '_systemctl',
- command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+ command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : zshcompletiondir != 'no',
install_dir : zshcompletiondir)
diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c
index 905ff2c27f..cb83e73877 100644
--- a/src/analyze/analyze.c
+++ b/src/analyze/analyze.c
@@ -90,7 +90,7 @@ PagerFlags arg_pager_flags = 0;
BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
const char *arg_host = NULL;
LookupScope arg_scope = LOOKUP_SCOPE_SYSTEM;
-RecursiveErrors arg_recursive_errors = RECURSIVE_ERRORS_YES;
+RecursiveErrors arg_recursive_errors = _RECURSIVE_ERRORS_INVALID;
bool arg_man = true;
bool arg_generators = false;
char *arg_root = NULL;
diff --git a/src/basic/def.h b/src/basic/def.h
index 54a82c7c49..0a1ae023a3 100644
--- a/src/basic/def.h
+++ b/src/basic/def.h
@@ -74,4 +74,4 @@
/* Path where systemd-oomd listens for varlink connections from user managers to report changes in ManagedOOM settings. */
#define VARLINK_ADDR_PATH_MANAGED_OOM_USER "/run/systemd/oom/io.system.ManagedOOM"
-#define KERNEL_BASELINE_VERSION "3.15"
+#define KERNEL_BASELINE_VERSION "4.15"
diff --git a/src/basic/strv.c b/src/basic/strv.c
index c4e3dad446..22f5402575 100644
--- a/src/basic/strv.c
+++ b/src/basic/strv.c
@@ -351,7 +351,7 @@ int strv_split_colon_pairs(char ***t, const char *s) {
return (int) n;
}
-char* strv_join_full(char * const *l, const char *separator, const char *prefix, bool unescape_separators) {
+char* strv_join_full(char * const *l, const char *separator, const char *prefix, bool escape_separator) {
char *r, *e;
size_t n, k, m;
@@ -361,7 +361,7 @@ char* strv_join_full(char * const *l, const char *separator, const char *prefix,
k = strlen(separator);
m = strlen_ptr(prefix);
- if (unescape_separators) /* If there separator is multi-char, we won't know how to escape it. */
+ if (escape_separator) /* If the separator was multi-char, we wouldn't know how to escape it. */
assert(k == 1);
n = 0;
@@ -369,7 +369,7 @@ char* strv_join_full(char * const *l, const char *separator, const char *prefix,
if (s != l)
n += k;
- bool needs_escaping = unescape_separators && strchr(*s, separator[0]);
+ bool needs_escaping = escape_separator && strchr(*s, *separator);
n += m + strlen(*s) * (1 + needs_escaping);
}
@@ -386,11 +386,11 @@ char* strv_join_full(char * const *l, const char *separator, const char *prefix,
if (prefix)
e = stpcpy(e, prefix);
- bool needs_escaping = unescape_separators && strchr(*s, separator[0]);
+ bool needs_escaping = escape_separator && strchr(*s, *separator);
if (needs_escaping)
for (size_t i = 0; (*s)[i]; i++) {
- if ((*s)[i] == separator[0])
+ if ((*s)[i] == *separator)
*(e++) = '\\';
*(e++) = (*s)[i];
}
diff --git a/src/basic/strv.h b/src/basic/strv.h
index 2a858326c6..6295058876 100644
--- a/src/basic/strv.h
+++ b/src/basic/strv.h
@@ -101,7 +101,7 @@ static inline char** strv_split_newlines(const char *s) {
* string in the vector is an empty string. */
int strv_split_colon_pairs(char ***t, const char *s);
-char* strv_join_full(char * const *l, const char *separator, const char *prefix, bool escape_separtor);
+char* strv_join_full(char * const *l, const char *separator, const char *prefix, bool escape_separator);
static inline char *strv_join(char * const *l, const char *separator) {
return strv_join_full(l, separator, NULL, false);
}
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index e0dc47ecd8..66e0c01c23 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -1000,7 +1000,7 @@ int config_parse_exec(
if (r < 0)
return ignore ? 0 : -ENOEXEC;
- r = unit_path_printf(u, word, &resolved);
+ r = unit_full_printf(u, word, &resolved);
if (r < 0) {
log_syntax(unit, ignore ? LOG_WARNING : LOG_ERR, filename, line, r,
"Failed to resolve unit specifiers in %s%s: %m",
diff --git a/src/core/main.c b/src/core/main.c
index 6567cdfb28..c6e9e9b034 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -1075,9 +1075,8 @@ static int help(void) {
" -h --help Show this help\n"
" --version Show version\n"
" --test Determine initial transaction, dump it and exit\n"
- " --system In combination with --test: operate as system service manager\n"
- " --user In combination with --test: operate as per-user service manager\n"
- " --no-pager Do not pipe output into a pager\n"
+ " --system Combined with --test: operate in system mode\n"
+ " --user Combined with --test: operate in user mode\n"
" --dump-configuration-items Dump understood unit configuration items\n"
" --dump-bus-properties Dump exposed bus properties\n"
" --bus-introspect=PATH Write XML introspection data\n"
@@ -1087,14 +1086,17 @@ static int help(void) {
" --crash-reboot[=BOOL] Reboot on crash\n"
" --crash-shell[=BOOL] Run shell on crash\n"
" --confirm-spawn[=BOOL] Ask for confirmation when spawning processes\n"
- " --show-status[=BOOL] Show status updates on the console during bootup\n"
- " --log-target=TARGET Set log target (console, journal, kmsg, journal-or-kmsg, null)\n"
- " --log-level=LEVEL Set log level (debug, info, notice, warning, err, crit, alert, emerg)\n"
+ " --show-status[=BOOL] Show status updates on the console during boot\n"
+ " --log-target=TARGET Set log target (console, journal, kmsg,\n"
+ " journal-or-kmsg, null)\n"
+ " --log-level=LEVEL Set log level (debug, info, notice, warning,\n"
+ " err, crit, alert, emerg)\n"
" --log-color[=BOOL] Highlight important log messages\n"
" --log-location[=BOOL] Include code location in log messages\n"
" --log-time[=BOOL] Prefix log messages with current time\n"
" --default-standard-output= Set default standard output for services\n"
" --default-standard-error= Set default standard error output for services\n"
+ " --no-pager Do not pipe output into a pager\n"
"\nSee the %s for details.\n",
program_invocation_short_name,
ansi_highlight(),
diff --git a/src/core/manager.c b/src/core/manager.c
index e92004edf3..2f60b14159 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -4370,71 +4370,58 @@ static int short_uid_range(const char *path) {
return !uid_range_covers(p, n, 0, 65535);
}
-char *manager_taint_string(Manager *m) {
- _cleanup_free_ char *destination = NULL, *overflowuid = NULL, *overflowgid = NULL;
- struct utsname uts;
- char *buf, *e;
- int r;
-
- /* Returns a "taint string", e.g. "local-hwclock:var-run-bad". Only things that are detected at
- * runtime should be tagged here. For stuff that is set during compilation, emit a warning in the
+char* manager_taint_string(const Manager *m) {
+ /* Returns a "taint string", e.g. "local-hwclock:var-run-bad". Only things that are detected at
+ * runtime should be tagged here. For stuff that is known during compilation, emit a warning in the
* configuration phase. */
assert(m);
- buf = new(char, sizeof("split-usr:"
- "cgroups-missing:"
- "cgrousv1:"
- "local-hwclock:"
- "var-run-bad:"
- "overflowuid-not-65534:"
- "overflowgid-not-65534:"
- "old-kernel:"
- "short-uid-range:"
- "short-gid-range:"));
- if (!buf)
- return NULL;
-
- e = buf;
- buf[0] = 0;
+ const char* stage[12] = {};
+ size_t n = 0;
if (m->taint_usr)
- e = stpcpy(e, "split-usr:");
+ stage[n++] = "split-usr";
+
+ _cleanup_free_ char *usrbin = NULL;
+ if (readlink_malloc("/bin", &usrbin) < 0 || !PATH_IN_SET(usrbin, "usr/bin", "/usr/bin"))
+ stage[n++] = "unmerged-usr";
if (access("/proc/cgroups", F_OK) < 0)
- e = stpcpy(e, "cgroups-missing:");
+ stage[n++] = "cgroups-missing";
if (cg_all_unified() == 0)
- e = stpcpy(e, "cgroupsv1:");
+ stage[n++] = "cgroupsv1";
if (clock_is_localtime(NULL) > 0)
- e = stpcpy(e, "local-hwclock:");
+ stage[n++] = "local-hwclock";
- r = readlink_malloc("/var/run", &destination);
- if (r < 0 || !PATH_IN_SET(destination, "../run", "/run"))
- e = stpcpy(e, "var-run-bad:");
+ _cleanup_free_ char *destination = NULL;
+ if (readlink_malloc("/var/run", &destination) < 0 ||
+ !PATH_IN_SET(destination, "../run", "/run"))
+ stage[n++] = "var-run-bad";
- r = read_one_line_file("/proc/sys/kernel/overflowuid", &overflowuid);
- if (r >= 0 && !streq(overflowuid, "65534"))
- e = stpcpy(e, "overflowuid-not-65534:");
- r = read_one_line_file("/proc/sys/kernel/overflowgid", &overflowgid);
- if (r >= 0 && !streq(overflowgid, "65534"))
- e = stpcpy(e, "overflowgid-not-65534:");
+ _cleanup_free_ char *overflowuid = NULL, *overflowgid = NULL;
+ if (read_one_line_file("/proc/sys/kernel/overflowuid", &overflowuid) >= 0 &&
+ !streq(overflowuid, "65534"))
+ stage[n++] = "overflowuid-not-65534";
+ if (read_one_line_file("/proc/sys/kernel/overflowgid", &overflowgid) >= 0 &&
+ !streq(overflowgid, "65534"))
+ stage[n++] = "overflowgid-not-65534";
+ struct utsname uts;
assert_se(uname(&uts) >= 0);
if (strverscmp_improved(uts.release, KERNEL_BASELINE_VERSION) < 0)
- e = stpcpy(e, "old-kernel:");
+ stage[n++] = "old-kernel";
if (short_uid_range("/proc/self/uid_map") > 0)
- e = stpcpy(e, "short-uid-range:");
+ stage[n++] = "short-uid-range";
if (short_uid_range("/proc/self/gid_map") > 0)
- e = stpcpy(e, "short-gid-range:");
+ stage[n++] = "short-gid-range";
- /* remove the last ':' */
- if (e != buf)
- e[-1] = 0;
+ assert(n < ELEMENTSOF(stage) - 1); /* One extra for NULL terminator */
- return buf;
+ return strv_join((char**) stage, ":");
}
void manager_ref_console(Manager *m) {
diff --git a/src/core/manager.h b/src/core/manager.h
index dc6718ada1..6f4bbb36ab 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -551,7 +551,7 @@ int manager_ref_uid(Manager *m, uid_t uid, bool clean_ipc);
void manager_unref_gid(Manager *m, gid_t gid, bool destroy_now);
int manager_ref_gid(Manager *m, gid_t gid, bool clean_ipc);
-char *manager_taint_string(Manager *m);
+char* manager_taint_string(const Manager *m);
void manager_ref_console(Manager *m);
void manager_unref_console(Manager *m);
diff --git a/src/core/meson.build b/src/core/meson.build
index f5e04b37ca..ee2f8774bf 100644
--- a/src/core/meson.build
+++ b/src/core/meson.build
@@ -151,7 +151,7 @@ load_fragment_gperf_gperf = custom_target(
'load-fragment-gperf.gperf',
input : 'load-fragment-gperf.gperf.in',
output: 'load-fragment-gperf.gperf',
- command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'])
+ command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'])
load_fragment_gperf_c = custom_target(
'load-fragment-gperf.c',
@@ -217,7 +217,7 @@ foreach item : in_files
file,
input : file + '.in',
output: file,
- command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+ command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : (dir == pkgsysconfdir) ? install_sysconfdir_samples : (dir != 'no'),
install_dir : dir)
endforeach
diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c
index d28a416e5d..39160182ef 100644
--- a/src/firstboot/firstboot.c
+++ b/src/firstboot/firstboot.c
@@ -984,37 +984,37 @@ static int help(void) {
printf("%s [OPTIONS...]\n\n"
"Configures basic settings of the system.\n\n"
- " -h --help Show this help\n"
- " --version Show package version\n"
- " --root=PATH Operate on an alternate filesystem root\n"
- " --image=PATH Operate on an alternate filesystem image\n"
- " --locale=LOCALE Set primary locale (LANG=)\n"
- " --locale-messages=LOCALE Set message locale (LC_MESSAGES=)\n"
- " --keymap=KEYMAP Set keymap\n"
- " --timezone=TIMEZONE Set timezone\n"
- " --hostname=NAME Set hostname\n"
- " --machine-ID=ID Set machine ID\n"
- " --root-password=PASSWORD Set root password from plaintext password\n"
- " --root-password-file=FILE Set root password from file\n"
- " --root-password-hashed=HASHED_PASSWORD Set root password from hashed password\n"
- " --root-shell=SHELL Set root shell\n"
- " --prompt-locale Prompt the user for locale settings\n"
- " --prompt-keymap Prompt the user for keymap settings\n"
- " --prompt-timezone Prompt the user for timezone\n"
- " --prompt-hostname Prompt the user for hostname\n"
- " --prompt-root-password Prompt the user for root password\n"
- " --prompt-root-shell Prompt the user for root shell\n"
- " --prompt Prompt for all of the above\n"
- " --copy-locale Copy locale from host\n"
- " --copy-keymap Copy keymap from host\n"
- " --copy-timezone Copy timezone from host\n"
- " --copy-root-password Copy root password from host\n"
- " --copy-root-shell Copy root shell from host\n"
- " --copy Copy locale, keymap, timezone, root password\n"
- " --setup-machine-id Generate a new random machine ID\n"
- " --force Overwrite existing files\n"
- " --delete-root-password Delete root password\n"
- " --welcome=no Disable the welcome text\n"
+ " -h --help Show this help\n"
+ " --version Show package version\n"
+ " --root=PATH Operate on an alternate filesystem root\n"
+ " --image=PATH Operate on an alternate filesystem image\n"
+ " --locale=LOCALE Set primary locale (LANG=)\n"
+ " --locale-messages=LOCALE Set message locale (LC_MESSAGES=)\n"
+ " --keymap=KEYMAP Set keymap\n"
+ " --timezone=TIMEZONE Set timezone\n"
+ " --hostname=NAME Set hostname\n"
+ " --machine-ID=ID Set machine ID\n"
+ " --root-password=PASSWORD Set root password from plaintext password\n"
+ " --root-password-file=FILE Set root password from file\n"
+ " --root-password-hashed=HASH Set root password from hashed password\n"
+ " --root-shell=SHELL Set root shell\n"
+ " --prompt-locale Prompt the user for locale settings\n"
+ " --prompt-keymap Prompt the user for keymap settings\n"
+ " --prompt-timezone Prompt the user for timezone\n"
+ " --prompt-hostname Prompt the user for hostname\n"
+ " --prompt-root-password Prompt the user for root password\n"
+ " --prompt-root-shell Prompt the user for root shell\n"
+ " --prompt Prompt for all of the above\n"
+ " --copy-locale Copy locale from host\n"
+ " --copy-keymap Copy keymap from host\n"
+ " --copy-timezone Copy timezone from host\n"
+ " --copy-root-password Copy root password from host\n"
+ " --copy-root-shell Copy root shell from host\n"
+ " --copy Copy locale, keymap, timezone, root password\n"
+ " --setup-machine-id Generate a new random machine ID\n"
+ " --force Overwrite existing files\n"
+ " --delete-root-password Delete root password\n"
+ " --welcome=no Disable the welcome text\n"
"\nSee the %s for details.\n",
program_invocation_short_name,
link);
diff --git a/src/hwdb/hwdb.c b/src/hwdb/hwdb.c
index e70354e444..17ac7e4fbe 100644
--- a/src/hwdb/hwdb.c
+++ b/src/hwdb/hwdb.c
@@ -73,7 +73,7 @@ static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
- while ((c = getopt_long(argc, argv, "ust:r:h", options, NULL)) >= 0)
+ while ((c = getopt_long(argc, argv, "sr:h", options, NULL)) >= 0)
switch (c) {
case 'h':
diff --git a/src/journal-remote/meson.build b/src/journal-remote/meson.build
index 4bbbc1431f..f81d906616 100644
--- a/src/journal-remote/meson.build
+++ b/src/journal-remote/meson.build
@@ -54,7 +54,7 @@ foreach tuple : in_files
file,
input : file + '.in',
output: file,
- command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+ command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : tuple[1],
install_dir : pkgsysconfdir)
endforeach
diff --git a/src/kernel-install/kernel-install b/src/kernel-install/kernel-install.in
index a09b998362..f6d262f522 100755
--- a/src/kernel-install/kernel-install
+++ b/src/kernel-install/kernel-install.in
@@ -23,11 +23,12 @@ skip_remaining=77
usage()
{
echo "Usage:"
- echo " $0 [OPTIONS...] add KERNEL-VERSION KERNEL-IMAGE [INITRD-FILE ...]"
- echo " $0 [OPTIONS...] remove KERNEL-VERSION"
- echo " $0 [OPTIONS...] inspect"
+ echo " kernel-install [OPTIONS...] add KERNEL-VERSION KERNEL-IMAGE [INITRD-FILE...]"
+ echo " kernel-install [OPTIONS...] remove KERNEL-VERSION"
+ echo " kernel-install [OPTIONS...] inspect"
echo "Options:"
- echo " -h, --help Print this help"
+ echo " -h, --help Print this help and exit"
+ echo " --version Print version string and exit"
echo " -v, --verbose Increase verbosity"
}
@@ -59,6 +60,13 @@ for i; do
fi
done
+for i; do
+ if [ "$i" = "--version" ]; then
+ echo "kernel-install {{PROJECT_VERSION}} ({{GIT_VERSION}})"
+ exit 0
+ fi
+done
+
export KERNEL_INSTALL_VERBOSE=0
if [ "$1" = "--verbose" ] || [ "$1" = "-v" ]; then
shift
diff --git a/src/kernel-install/meson.build b/src/kernel-install/meson.build
index abc3520b62..06c1c3aafb 100644
--- a/src/kernel-install/meson.build
+++ b/src/kernel-install/meson.build
@@ -1,10 +1,8 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
-if want_kernel_install
- install_data('kernel-install',
- install_mode : 'rwxr-xr-x',
- install_dir : bindir)
+kernel_install_in = files('kernel-install.in')
+if want_kernel_install
install_data('50-depmod.install',
'90-loaderentry.install',
install_mode : 'rwxr-xr-x',
diff --git a/src/libsystemd/meson.build b/src/libsystemd/meson.build
index 67b439a5dd..a86b8f896b 100644
--- a/src/libsystemd/meson.build
+++ b/src/libsystemd/meson.build
@@ -186,7 +186,7 @@ custom_target(
'libsystemd.pc',
input : 'libsystemd.pc.in',
output : 'libsystemd.pc',
- command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+ command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : pkgconfiglibdir != 'no',
install_dir : pkgconfiglibdir)
diff --git a/src/libudev/meson.build b/src/libudev/meson.build
index 2d51ff7c58..a831391cc1 100644
--- a/src/libudev/meson.build
+++ b/src/libudev/meson.build
@@ -38,7 +38,7 @@ custom_target(
'libudev.pc',
input : 'libudev.pc.in',
output : 'libudev.pc',
- command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+ command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : pkgconfiglibdir != 'no',
install_dir : pkgconfiglibdir)
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 1212a1ac53..a9da1e7731 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -3378,8 +3378,13 @@ static const sd_bus_vtable manager_vtable[] = {
SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("UserStopDelayUSec", "t", NULL, offsetof(Manager, user_stop_delay), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("HandlePowerKeyLongPress", "s", property_get_handle_action, offsetof(Manager, handle_power_key_long_press), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("HandleRebootKey", "s", property_get_handle_action, offsetof(Manager, handle_reboot_key), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("HandleRebootKeyLongPress", "s", property_get_handle_action, offsetof(Manager, handle_reboot_key_long_press), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("HandleSuspendKeyLongPress", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key_long_press), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("HandleHibernateKeyLongPress", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key_long_press), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("HandleLidSwitchExternalPower", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_ep), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
diff --git a/src/login/logind.conf.in b/src/login/logind.conf.in
index 926bd6cfe9..8ec979e0e8 100644
--- a/src/login/logind.conf.in
+++ b/src/login/logind.conf.in
@@ -23,13 +23,16 @@
#InhibitDelayMaxSec=5
#UserStopDelaySec=10
#HandlePowerKey=poweroff
+#HandlePowerKeyLongPress=ignore
+#HandleRebootKey=reboot
+#HandleRebootKeyLongPress=poweroff
#HandleSuspendKey=suspend
+#HandleSuspendKeyLongPress=hibernate
#HandleHibernateKey=hibernate
+#HandleHibernateKeyLongPress=ignore
#HandleLidSwitch=suspend
#HandleLidSwitchExternalPower=suspend
#HandleLidSwitchDocked=ignore
-#HandleRebootKey=reboot
-#HandleRebootKeyLongPress=poweroff
#PowerKeyIgnoreInhibited=no
#SuspendKeyIgnoreInhibited=no
#HibernateKeyIgnoreInhibited=no
diff --git a/src/login/meson.build b/src/login/meson.build
index 1a2d738e84..bd350569d5 100644
--- a/src/login/meson.build
+++ b/src/login/meson.build
@@ -80,7 +80,7 @@ foreach tuple : in_files
file,
input : file + '.in',
output: file,
- command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+ command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : tuple[2] and install,
install_dir : dir)
endforeach
diff --git a/src/partition/test-repart.sh b/src/partition/test-repart.sh
index 88b696ba01..89f6266539 100755
--- a/src/partition/test-repart.sh
+++ b/src/partition/test-repart.sh
@@ -201,7 +201,7 @@ $D/zzz7 : start= 6291416, size= 98304, type=0FC63DAF-8483-4772-8E79-3D
EOF
LOOP="$(losetup -P --show --find "$D/zzz")"
- "${udevadm:?}" wait --timeout 60 --initialized=yes --settle "${LOOP:?}"
+ "${udevadm:?}" wait --timeout 60 --settle "${LOOP:?}"
VOLUME="test-repart-$RANDOM"
diff --git a/src/resolve/meson.build b/src/resolve/meson.build
index b2da249c87..e11aefce7a 100644
--- a/src/resolve/meson.build
+++ b/src/resolve/meson.build
@@ -168,7 +168,7 @@ custom_target(
'resolved.conf',
input : 'resolved.conf.in',
output : 'resolved.conf',
- command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+ command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : conf.get('ENABLE_RESOLVE') == 1 and install_sysconfdir_samples,
install_dir : pkgsysconfdir)
diff --git a/src/rpm/meson.build b/src/rpm/meson.build
index 4bfeda8883..817665912a 100644
--- a/src/rpm/meson.build
+++ b/src/rpm/meson.build
@@ -18,7 +18,7 @@ foreach tuple : in_files
file,
input : file + '.in',
output : file,
- command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+ command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : tuple[1],
install_dir : tuple.length() > 2 ? tuple[2] : '',
build_by_default : true)
diff --git a/src/shared/devnode-acl.c b/src/shared/devnode-acl.c
index d2b78f392a..357efc1930 100644
--- a/src/shared/devnode-acl.c
+++ b/src/shared/devnode-acl.c
@@ -9,9 +9,9 @@
#include "device-util.h"
#include "devnode-acl.h"
#include "dirent-util.h"
-#include "escape.h"
#include "fd-util.h"
#include "format-util.h"
+#include "fs-util.h"
#include "set.h"
#include "string-util.h"
#include "util.h"
@@ -195,21 +195,18 @@ int devnode_acl_all(const char *seat,
dir = opendir("/run/udev/static_node-tags/uaccess");
if (dir) {
FOREACH_DIRENT(de, dir, return -errno) {
- _cleanup_free_ char *unescaped_devname = NULL;
- ssize_t l;
-
- l = cunescape(de->d_name, UNESCAPE_RELAX, &unescaped_devname);
- if (l < 0)
- return l;
-
- n = path_join("/dev", unescaped_devname);
- if (!n)
- return -ENOMEM;
+ r = readlinkat_malloc(dirfd(dir), de->d_name, &n);
+ if (r == -ENOENT)
+ continue;
+ if (r < 0) {
+ log_debug_errno(r,
+ "Unable to read symlink '/run/udev/static_node-tags/uaccess/%s', ignoring: %m",
+ de->d_name);
+ continue;
+ }
log_debug("Found static node %s for seat %s", n, seat);
r = set_consume(nodes, n);
- if (r == -EEXIST)
- continue;
if (r < 0)
return r;
}
diff --git a/src/shared/netif-naming-scheme.c b/src/shared/netif-naming-scheme.c
index a2bc4fa55a..e95072e048 100644
--- a/src/shared/netif-naming-scheme.c
+++ b/src/shared/netif-naming-scheme.c
@@ -23,6 +23,7 @@ static const NamingScheme naming_schemes[] = {
{ "v247", NAMING_V247 },
{ "v249", NAMING_V249 },
{ "v250", NAMING_V250 },
+ { "v251", NAMING_V251 },
/* … add more schemes here, as the logic to name devices is updated … */
EXTRA_NET_NAMING_MAP
diff --git a/src/shared/netif-naming-scheme.h b/src/shared/netif-naming-scheme.h
index 16b304ce10..5303348e06 100644
--- a/src/shared/netif-naming-scheme.h
+++ b/src/shared/netif-naming-scheme.h
@@ -22,20 +22,21 @@
* OS versions, but not fully stabilize them. */
typedef enum NamingSchemeFlags {
/* First, the individual features */
- NAMING_SR_IOV_V = 1 << 0, /* Use "v" suffix for SR-IOV, see 609948c7043a */
- NAMING_NPAR_ARI = 1 << 1, /* Use NPAR "ARI", see 6bc04997b6ea */
- NAMING_INFINIBAND = 1 << 2, /* Use "ib" prefix for infiniband, see 938d30aa98df */
- NAMING_ZERO_ACPI_INDEX = 1 << 3, /* Use zero acpi_index field, see d81186ef4f6a */
- NAMING_ALLOW_RERENAMES = 1 << 4, /* Allow re-renaming of devices, see #9006 */
- NAMING_STABLE_VIRTUAL_MACS = 1 << 5, /* Use device name to generate MAC, see 6d3646406560 */
- NAMING_NETDEVSIM = 1 << 6, /* Generate names for netdevsim devices, see eaa9d507d855 */
- NAMING_LABEL_NOPREFIX = 1 << 7, /* Don't prepend ID_NET_LABEL_ONBOARD with interface type prefix */
- NAMING_NSPAWN_LONG_HASH = 1 << 8, /* Shorten nspawn interfaces by including 24bit hash, instead of simple truncation */
- NAMING_BRIDGE_NO_SLOT = 1 << 9, /* Don't use PCI hotplug slot information if the corresponding device is a PCI bridge */
- NAMING_SLOT_FUNCTION_ID = 1 << 10, /* Use function_id if present to identify PCI hotplug slots */
- NAMING_16BIT_INDEX = 1 << 11, /* Allow full 16-bit for the onboard index */
- NAMING_REPLACE_STRICTLY = 1 << 12, /* Use udev_replace_ifname() for NAME= rule */
- NAMING_XEN_VIF = 1 << 13, /* GEnerate names for Xen netfront devices */
+ NAMING_SR_IOV_V = 1 << 0, /* Use "v" suffix for SR-IOV, see 609948c7043a */
+ NAMING_NPAR_ARI = 1 << 1, /* Use NPAR "ARI", see 6bc04997b6ea */
+ NAMING_INFINIBAND = 1 << 2, /* Use "ib" prefix for infiniband, see 938d30aa98df */
+ NAMING_ZERO_ACPI_INDEX = 1 << 3, /* Use zero acpi_index field, see d81186ef4f6a */
+ NAMING_ALLOW_RERENAMES = 1 << 4, /* Allow re-renaming of devices, see #9006 */
+ NAMING_STABLE_VIRTUAL_MACS = 1 << 5, /* Use device name to generate MAC, see 6d3646406560 */
+ NAMING_NETDEVSIM = 1 << 6, /* Generate names for netdevsim devices, see eaa9d507d855 */
+ NAMING_LABEL_NOPREFIX = 1 << 7, /* Don't prepend ID_NET_LABEL_ONBOARD with interface type prefix */
+ NAMING_NSPAWN_LONG_HASH = 1 << 8, /* Shorten nspawn interfaces by including 24bit hash, instead of simple truncation */
+ NAMING_BRIDGE_NO_SLOT = 1 << 9, /* Don't use PCI hotplug slot information if the corresponding device is a PCI bridge */
+ NAMING_SLOT_FUNCTION_ID = 1 << 10, /* Use function_id if present to identify PCI hotplug slots */
+ NAMING_16BIT_INDEX = 1 << 11, /* Allow full 16-bit for the onboard index */
+ NAMING_REPLACE_STRICTLY = 1 << 12, /* Use udev_replace_ifname() for NAME= rule */
+ NAMING_XEN_VIF = 1 << 13, /* Generate names for Xen netfront devices */
+ NAMING_BRIDGE_MULTIFUNCTION_SLOT = 1 << 14, /* Use PCI hotplug slot information associated with bridge, but only if PCI device is multifunction */
/* And now the masks that combine the features above */
NAMING_V238 = 0,
@@ -47,6 +48,7 @@ typedef enum NamingSchemeFlags {
NAMING_V247 = NAMING_V245 | NAMING_BRIDGE_NO_SLOT,
NAMING_V249 = NAMING_V247 | NAMING_SLOT_FUNCTION_ID | NAMING_16BIT_INDEX | NAMING_REPLACE_STRICTLY,
NAMING_V250 = NAMING_V249 | NAMING_XEN_VIF,
+ NAMING_V251 = NAMING_V250 | NAMING_BRIDGE_MULTIFUNCTION_SLOT,
EXTRA_NET_NAMING_SCHEMES
diff --git a/src/shutdown/umount.c b/src/shutdown/umount.c
index 3e9e241499..820aa8e286 100644
--- a/src/shutdown/umount.c
+++ b/src/shutdown/umount.c
@@ -352,9 +352,14 @@ static int md_list_get(MountPoint **head) {
if (r < 0)
return r;
+ /* Filter out partitions. */
+ r = sd_device_enumerator_add_match_property(e, "DEVTYPE", "disk");
+ if (r < 0)
+ return r;
+
FOREACH_DEVICE(e, d) {
_cleanup_free_ char *p = NULL;
- const char *dn;
+ const char *dn, *md_level;
MountPoint *m;
dev_t devnum;
@@ -362,6 +367,17 @@ static int md_list_get(MountPoint **head) {
sd_device_get_devname(d, &dn) < 0)
continue;
+ r = sd_device_get_property_value(d, "MD_LEVEL", &md_level);
+ if (r < 0) {
+ log_warning_errno(r, "Failed to get MD_LEVEL property for %s, ignoring: %m", dn);
+ continue;
+ }
+
+ /* MD "containers" are a special type of MD devices, used for external metadata.
+ * Since it doesn't provide RAID functionality in itself we don't need to stop it. */
+ if (streq(md_level, "container"))
+ continue;
+
p = strdup(dn);
if (!p)
return -ENOMEM;
diff --git a/src/test/meson.build b/src/test/meson.build
index 297a65d9af..11517c990b 100644
--- a/src/test/meson.build
+++ b/src/test/meson.build
@@ -56,6 +56,12 @@ tests += [
libblkid],
core_includes],
+ [files('test-manager.c'),
+ [libcore,
+ libshared],
+ [],
+ core_includes],
+
[files('test-emergency-action.c'),
[libcore,
libshared],
diff --git a/src/test/test-load-fragment.c b/src/test/test-load-fragment.c
index c3206e1e7a..9cbf22312f 100644
--- a/src/test/test-load-fragment.c
+++ b/src/test/test-load-fragment.c
@@ -10,6 +10,7 @@
#include "capability-util.h"
#include "conf-parser.h"
#include "fd-util.h"
+#include "fileio.h"
#include "format-util.h"
#include "fs-util.h"
#include "hashmap.h"
@@ -416,6 +417,21 @@ TEST(config_parse_exec) {
assert_se(r == 0);
assert_se(c1->command_next == NULL);
+ log_info("/* long arg */"); /* See issue #22957. */
+
+ char x[LONG_LINE_MAX-100], *y;
+ y = mempcpy(x, "/bin/echo ", STRLEN("/bin/echo "));
+ memset(y, 'x', sizeof(x) - STRLEN("/bin/echo ") - 1);
+ x[sizeof(x) - 1] = '\0';
+
+ r = config_parse_exec(NULL, "fake", 5, "section", 1,
+ "LValue", 0, x,
+ &c, u);
+ assert_se(r >= 0);
+ c1 = c1->command_next;
+ check_execcommand(c1,
+ "/bin/echo", NULL, y, NULL, false);
+
log_info("/* empty argument, reset */");
r = config_parse_exec(NULL, "fake", 4, "section", 1,
"LValue", 0, "",
diff --git a/src/test/test-manager.c b/src/test/test-manager.c
new file mode 100644
index 0000000000..89f9277b28
--- /dev/null
+++ b/src/test/test-manager.c
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "manager.h"
+#include "tests.h"
+
+TEST(manager_taint_string) {
+ Manager m = {};
+
+ _cleanup_free_ char *a = manager_taint_string(&m);
+ assert_se(a);
+ log_debug("taint string w/o split-usr: '%s'", a);
+ /* split-usr is the only one that is cached in Manager, so we know it's not present.
+ * The others are queried dynamically, so we'd need to duplicate the logic here
+ * to test for them. Let's do just one. */
+ assert_se(!strstr(a, "split-usr"));
+
+ if (cg_all_unified() == 0)
+ assert_se(strstr(a, "cgroupsv1"));
+ else
+ assert_se(!strstr(a, "cgroupsv1"));
+
+ m.taint_usr = true;
+ _cleanup_free_ char *b = manager_taint_string(&m);
+ assert_se(b);
+ log_debug("taint string w/ split-usr: '%s'", b);
+ assert_se(strstr(b, "split-usr"));
+}
+
+DEFINE_TEST_MAIN(LOG_DEBUG);
diff --git a/src/timesync/meson.build b/src/timesync/meson.build
index 8ecfbfab82..35467026a8 100644
--- a/src/timesync/meson.build
+++ b/src/timesync/meson.build
@@ -39,7 +39,7 @@ custom_target(
'timesyncd.conf',
input : 'timesyncd.conf.in',
output : 'timesyncd.conf',
- command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+ command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : conf.get('ENABLE_TIMESYNCD') == 1 and install_sysconfdir_samples,
install_dir : pkgsysconfdir)
diff --git a/src/udev/meson.build b/src/udev/meson.build
index 354b923291..79964a7d8e 100644
--- a/src/udev/meson.build
+++ b/src/udev/meson.build
@@ -166,7 +166,7 @@ custom_target(
'udev.pc',
input : 'udev.pc.in',
output : 'udev.pc',
- command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+ command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : pkgconfigdatadir != 'no',
install_dir : pkgconfigdatadir)
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
index 9e4297adaf..114fda663e 100644
--- a/src/udev/udev-builtin-net_id.c
+++ b/src/udev/udev-builtin-net_id.c
@@ -451,8 +451,15 @@ static int dev_pci_slot(sd_device *dev, const LinkInfo *info, NetNames *names) {
* devices that will try to claim the same index and that would create name
* collision. */
if (naming_scheme_has(NAMING_BRIDGE_NO_SLOT) && is_pci_bridge(hotplug_slot_dev)) {
- log_device_debug(dev, "Not using slot information because the PCI device is a bridge.");
- return 0;
+ if (naming_scheme_has(NAMING_BRIDGE_MULTIFUNCTION_SLOT) && !is_pci_multifunction(names->pcidev)) {
+ log_device_debug(dev, "Not using slot information because the PCI device associated with the hotplug slot is a bridge and the PCI device has single function.");
+ return 0;
+ }
+
+ if (!naming_scheme_has(NAMING_BRIDGE_MULTIFUNCTION_SLOT)) {
+ log_device_debug(dev, "Not using slot information because the PCI device is a bridge.");
+ return 0;
+ }
}
break;
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
index d9af8bfd20..78e8f3018c 100644
--- a/src/udev/udev-event.c
+++ b/src/udev/udev-event.c
@@ -966,9 +966,6 @@ static int update_devnode(UdevEvent *event) {
if (r < 0 && r != -ENOENT)
return log_device_error_errno(dev, r, "Failed to get devnode mode: %m");
}
- if (event->mode == MODE_INVALID && gid_is_valid(event->gid) && event->gid > 0)
- /* If group is set, but mode is not set, "upgrade" mode for the group. */
- event->mode = 0660;
bool apply_mac = device_for_action(dev, SD_DEVICE_ADD);
diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c
index c313181041..deacbc31c5 100644
--- a/src/udev/udev-node.c
+++ b/src/udev/udev-node.c
@@ -13,6 +13,7 @@
#include "device-private.h"
#include "device-util.h"
#include "dirent-util.h"
+#include "escape.h"
#include "fd-util.h"
#include "format-util.h"
#include "fs-util.h"
@@ -590,51 +591,30 @@ int udev_node_remove(sd_device *dev) {
return 0;
}
-int udev_node_apply_permissions(
- sd_device *dev,
+static int udev_node_apply_permissions_impl(
+ sd_device *dev, /* can be NULL, only used for logging. */
+ int node_fd,
+ const char *devnode,
bool apply_mac,
mode_t mode,
uid_t uid,
gid_t gid,
OrderedHashmap *seclabel_list) {
- const char *devnode, *subsystem;
bool apply_mode, apply_uid, apply_gid;
- _cleanup_close_ int node_fd = -1;
struct stat stats;
- dev_t devnum;
int r;
- assert(dev);
-
- r = sd_device_get_devname(dev, &devnode);
- if (r < 0)
- return log_device_debug_errno(dev, r, "Failed to get devname: %m");
- r = sd_device_get_subsystem(dev, &subsystem);
- if (r < 0)
- return log_device_debug_errno(dev, r, "Failed to get subsystem: %m");
- r = sd_device_get_devnum(dev, &devnum);
- if (r < 0)
- return log_device_debug_errno(dev, r, "Failed to get devnum: %m");
-
- if (streq(subsystem, "block"))
- mode |= S_IFBLK;
- else
- mode |= S_IFCHR;
-
- node_fd = sd_device_open(dev, O_PATH|O_CLOEXEC);
- if (node_fd < 0) {
- if (ERRNO_IS_DEVICE_ABSENT(node_fd)) {
- log_device_debug_errno(dev, node_fd, "Device node %s is missing, skipping handling.", devnode);
- return 0; /* This is necessarily racey, so ignore missing the device */
- }
-
- return log_device_debug_errno(dev, node_fd, "Cannot open node %s: %m", devnode);
- }
+ assert(node_fd >= 0);
+ assert(devnode);
if (fstat(node_fd, &stats) < 0)
return log_device_debug_errno(dev, errno, "cannot stat() node %s: %m", devnode);
+ /* If group is set, but mode is not set, "upgrade" mode for the group. */
+ if (mode == MODE_INVALID && gid_is_valid(gid) && gid > 0)
+ mode = 0660;
+
apply_mode = mode != MODE_INVALID && (stats.st_mode & 0777) != (mode & 0777);
apply_uid = uid_is_valid(uid) && stats.st_uid != uid;
apply_gid = gid_is_valid(gid) && stats.st_gid != gid;
@@ -708,3 +688,95 @@ int udev_node_apply_permissions(
return 0;
}
+
+int udev_node_apply_permissions(
+ sd_device *dev,
+ bool apply_mac,
+ mode_t mode,
+ uid_t uid,
+ gid_t gid,
+ OrderedHashmap *seclabel_list) {
+
+ const char *devnode;
+ _cleanup_close_ int node_fd = -1;
+ int r;
+
+ assert(dev);
+
+ r = sd_device_get_devname(dev, &devnode);
+ if (r < 0)
+ return log_device_debug_errno(dev, r, "Failed to get devname: %m");
+
+ node_fd = sd_device_open(dev, O_PATH|O_CLOEXEC);
+ if (node_fd < 0) {
+ if (ERRNO_IS_DEVICE_ABSENT(node_fd)) {
+ log_device_debug_errno(dev, node_fd, "Device node %s is missing, skipping handling.", devnode);
+ return 0; /* This is necessarily racey, so ignore missing the device */
+ }
+
+ return log_device_debug_errno(dev, node_fd, "Cannot open node %s: %m", devnode);
+ }
+
+ return udev_node_apply_permissions_impl(dev, node_fd, devnode, apply_mac, mode, uid, gid, seclabel_list);
+}
+
+int static_node_apply_permissions(
+ const char *name,
+ mode_t mode,
+ uid_t uid,
+ gid_t gid,
+ char **tags) {
+
+ _cleanup_free_ char *unescaped_filename = NULL;
+ _cleanup_close_ int node_fd = -1;
+ const char *devnode;
+ struct stat stats;
+ int r;
+
+ assert(name);
+
+ if (uid == UID_INVALID && gid == GID_INVALID && mode == MODE_INVALID && !tags)
+ return 0;
+
+ devnode = strjoina("/dev/", name);
+
+ node_fd = open(devnode, O_PATH|O_CLOEXEC);
+ if (node_fd < 0) {
+ if (errno != ENOENT)
+ return log_error_errno(errno, "Failed to open %s: %m", devnode);
+ return 0;
+ }
+
+ if (fstat(node_fd, &stats) < 0)
+ return log_error_errno(errno, "Failed to stat %s: %m", devnode);
+
+ if (!S_ISBLK(stats.st_mode) && !S_ISCHR(stats.st_mode)) {
+ log_warning("%s is neither block nor character device, ignoring.", devnode);
+ return 0;
+ }
+
+ if (!strv_isempty(tags)) {
+ unescaped_filename = xescape(name, "/.");
+ if (!unescaped_filename)
+ return log_oom();
+ }
+
+ /* export the tags to a directory as symlinks, allowing otherwise dead nodes to be tagged */
+ STRV_FOREACH(t, tags) {
+ _cleanup_free_ char *p = NULL;
+
+ p = path_join("/run/udev/static_node-tags/", *t, unescaped_filename);
+ if (!p)
+ return log_oom();
+
+ r = mkdir_parents(p, 0755);
+ if (r < 0)
+ return log_error_errno(r, "Failed to create parent directory for %s: %m", p);
+
+ r = symlink(devnode, p);
+ if (r < 0 && errno != EEXIST)
+ return log_error_errno(errno, "Failed to create symlink %s -> %s: %m", p, devnode);
+ }
+
+ return udev_node_apply_permissions_impl(NULL, node_fd, devnode, false, mode, uid, gid, NULL);
+}
diff --git a/src/udev/udev-node.h b/src/udev/udev-node.h
index a34af77146..86a829545a 100644
--- a/src/udev/udev-node.h
+++ b/src/udev/udev-node.h
@@ -15,6 +15,13 @@ int udev_node_apply_permissions(
uid_t uid,
gid_t gid,
OrderedHashmap *seclabel_list);
+int static_node_apply_permissions(
+ const char *name,
+ mode_t mode,
+ uid_t uid,
+ gid_t gid,
+ char **tags);
+
int udev_node_remove(sd_device *dev);
int udev_node_update(sd_device *dev, sd_device *dev_old);
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index b46cb0f906..1c20775f08 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -9,7 +9,6 @@
#include "device-private.h"
#include "device-util.h"
#include "dirent-util.h"
-#include "escape.h"
#include "fd-util.h"
#include "fileio.h"
#include "format-util.h"
@@ -30,6 +29,7 @@
#include "udev-builtin.h"
#include "udev-event.h"
#include "udev-netlink.h"
+#include "udev-node.h"
#include "udev-rules.h"
#include "udev-util.h"
#include "user-util.h"
@@ -2536,72 +2536,6 @@ int udev_rules_apply_to_event(
return 0;
}
-static int apply_static_dev_perms(const char *devnode, uid_t uid, gid_t gid, mode_t mode, char **tags) {
- char device_node[UDEV_PATH_SIZE], tags_dir[UDEV_PATH_SIZE], tag_symlink[UDEV_PATH_SIZE];
- _cleanup_free_ char *unescaped_filename = NULL;
- struct stat stats;
- int r;
-
- assert(devnode);
-
- if (uid == UID_INVALID && gid == GID_INVALID && mode == MODE_INVALID && !tags)
- return 0;
-
- strscpyl(device_node, sizeof(device_node), "/dev/", devnode, NULL);
- if (stat(device_node, &stats) < 0) {
- if (errno != ENOENT)
- return log_error_errno(errno, "Failed to stat %s: %m", device_node);
- return 0;
- }
-
- if (!S_ISBLK(stats.st_mode) && !S_ISCHR(stats.st_mode)) {
- log_warning("%s is neither block nor character device, ignoring.", device_node);
- return 0;
- }
-
- if (!strv_isempty(tags)) {
- unescaped_filename = xescape(devnode, "/.");
- if (!unescaped_filename)
- return log_oom();
- }
-
- /* export the tags to a directory as symlinks, allowing otherwise dead nodes to be tagged */
- STRV_FOREACH(t, tags) {
- strscpyl(tags_dir, sizeof(tags_dir), "/run/udev/static_node-tags/", *t, "/", NULL);
- r = mkdir_p(tags_dir, 0755);
- if (r < 0)
- return log_error_errno(r, "Failed to create %s: %m", tags_dir);
-
- strscpyl(tag_symlink, sizeof(tag_symlink), tags_dir, unescaped_filename, NULL);
- r = symlink(device_node, tag_symlink);
- if (r < 0 && errno != EEXIST)
- return log_error_errno(errno, "Failed to create symlink %s -> %s: %m",
- tag_symlink, device_node);
- }
-
- /* don't touch the permissions if only the tags were set */
- if (uid == UID_INVALID && gid == GID_INVALID && mode == MODE_INVALID)
- return 0;
-
- if (mode == MODE_INVALID)
- mode = gid_is_valid(gid) ? 0660 : 0600;
- if (!uid_is_valid(uid))
- uid = 0;
- if (!gid_is_valid(gid))
- gid = 0;
-
- r = chmod_and_chown(device_node, mode, uid, gid);
- if (r == -ENOENT)
- return 0;
- if (r < 0)
- return log_error_errno(r, "Failed to chown '%s' %u %u: %m", device_node, uid, gid);
- else
- log_debug("chown '%s' %u:%u with mode %#o", device_node, uid, gid, mode);
-
- (void) utimensat(AT_FDCWD, device_node, NULL, 0);
- return 0;
-}
-
static int udev_rule_line_apply_static_dev_perms(UdevRuleLine *rule_line) {
_cleanup_strv_free_ char **tags = NULL;
uid_t uid = UID_INVALID;
@@ -2626,7 +2560,7 @@ static int udev_rule_line_apply_static_dev_perms(UdevRuleLine *rule_line) {
if (r < 0)
return log_oom();
} else if (token->type == TK_A_OPTIONS_STATIC_NODE) {
- r = apply_static_dev_perms(token->value, uid, gid, mode, tags);
+ r = static_node_apply_permissions(token->value, mode, uid, gid, tags);
if (r < 0)
return r;
}
diff --git a/src/udev/udevadm-lock.c b/src/udev/udevadm-lock.c
index 3e5d7b356f..951711f120 100644
--- a/src/udev/udevadm-lock.c
+++ b/src/udev/udevadm-lock.c
@@ -144,6 +144,7 @@ static int find_devno(
const char *device,
bool backing) {
+ _cleanup_close_ int fd = -1;
dev_t devt, whole_devt;
struct stat st;
int r;
@@ -153,7 +154,11 @@ static int find_devno(
assert(*devnos || *n_devnos == 0);
assert(device);
- if (stat(device, &st) < 0)
+ fd = open(device, O_CLOEXEC|O_PATH);
+ if (fd < 0)
+ return log_error_errno(errno, "Failed to open '%s': %m", device);
+
+ if (fstat(fd, &st) < 0)
return log_error_errno(errno, "Failed to stat '%s': %m", device);
if (S_ISBLK(st.st_mode))
@@ -166,20 +171,13 @@ static int find_devno(
devt = st.st_dev;
else {
_cleanup_close_ int regfd = -1;
- struct stat st2;
/* If major(st.st_dev) is zero, this might mean we are backed by btrfs, which needs special
* handing, to get the backing device node. */
- regfd = open(device, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
+ regfd = fd_reopen(fd, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
if (regfd < 0)
- return log_error_errno(errno, "Failed to open '%s': %m", device);
-
- /* Extra safety: let's check we are still looking at the same file */
- if (fstat(regfd, &st2) < 0)
- return log_error_errno(errno, "Failed to stat '%s': %m", device);
- if (!stat_inode_same(&st, &st2))
- return log_error_errno(SYNTHETIC_ERRNO(ENXIO), "File '%s' was replaced while we were looking at it.", device);
+ return log_error_errno(regfd, "Failed to open '%s': %m", device);
r = btrfs_get_block_device_fd(regfd, &devt);
if (r == -ENOTTY)
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index 4a37a76924..078cd960b4 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -442,6 +442,12 @@ static int device_get_whole_disk(sd_device *dev, sd_device **ret_device, const c
if (r < 0)
return log_device_debug_errno(dev, r, "Failed to get sysname: %m");
+ /* Exclude the following devices:
+ * For "dm-", see the comment added by e918a1b5a94f270186dca59156354acd2a596494.
+ * For "md", see the commit message of 2e5b17d01347d3c3118be2b8ad63d20415dbb1f0,
+ * but not sure the assumption is still valid even when partitions are created on the md
+ * devices, surprisingly which seems to be possible, see PR #22973.
+ * For "drbd", see the commit message of fee854ee8ccde0cd28e0f925dea18cce35f3993d. */
if (STARTSWITH_SET(val, "dm-", "md", "drbd"))
goto irrelevant;
diff --git a/src/vconsole/meson.build b/src/vconsole/meson.build
index eb22358c20..bb3c3c5a03 100644
--- a/src/vconsole/meson.build
+++ b/src/vconsole/meson.build
@@ -4,6 +4,6 @@ custom_target(
'90-vconsole.rules',
input : '90-vconsole.rules.in',
output : '90-vconsole.rules',
- command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+ command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : conf.get('ENABLE_VCONSOLE') == 1,
install_dir : udevrulesdir)
diff --git a/sysctl.d/meson.build b/sysctl.d/meson.build
index 1745a13bfb..ecec903d1b 100644
--- a/sysctl.d/meson.build
+++ b/sysctl.d/meson.build
@@ -16,7 +16,7 @@ custom_target(
'50-coredump.conf',
input : '50-coredump.conf.in',
output : '50-coredump.conf',
- command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+ command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : conf.get('ENABLE_COREDUMP') == 1,
install_dir : sysctldir)
diff --git a/sysusers.d/meson.build b/sysusers.d/meson.build
index 73d507f1f1..608c4b744a 100644
--- a/sysusers.d/meson.build
+++ b/sysusers.d/meson.build
@@ -33,7 +33,7 @@ foreach tuple : in_files
file,
input : file + '.in',
output: file,
- command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+ command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : tuple[1],
install_dir : sysusersdir)
endforeach
diff --git a/test/test-network/conf/25-ip6tnl-external.netdev b/test/test-network/conf/25-ip6tnl-tunnel-external.netdev
index 68926cdd1e..68926cdd1e 100644
--- a/test/test-network/conf/25-ip6tnl-external.netdev
+++ b/test/test-network/conf/25-ip6tnl-tunnel-external.netdev
diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py
index 0a8349fd5b..d626e4b641 100755
--- a/test/test-network/systemd-networkd-tests.py
+++ b/test/test-network/systemd-networkd-tests.py
@@ -1711,7 +1711,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
'25-ip6tnl-tunnel-remote-any.netdev', '25-tunnel-remote-any.network',
'25-veth.netdev', '25-ip6tnl-slaac.network', '25-ipv6-prefix.network',
'25-ip6tnl-tunnel-local-slaac.netdev', '25-ip6tnl-tunnel-local-slaac.network',
- '25-ip6tnl-external.netdev', '26-netdev-link-local-addressing-yes.network')
+ '25-ip6tnl-tunnel-external.netdev', '26-netdev-link-local-addressing-yes.network')
start_networkd()
self.wait_online(['ip6tnl99:routable', 'ip6tnl98:routable', 'ip6tnl97:routable',
'ip6tnl-slaac:degraded', 'ip6tnl-external:degraded',
diff --git a/test/units/testsuite-58.sh b/test/units/testsuite-58.sh
index 21f762d399..8dadcc0a95 100755
--- a/test/units/testsuite-58.sh
+++ b/test/units/testsuite-58.sh
@@ -173,20 +173,22 @@ rm -r /tmp/testsuite-58.3-defs/
# testcase for #21817
mkdir -p /tmp/testsuite-58-issue-21817-defs/
truncate -s 100m /var/tmp/testsuite-58-issue-21817.img
-LOOP=$(losetup -P --show -f /var/tmp/testsuite-58-issue-21817.img)
-udevadm wait --timeout 60 --initialized=yes --settle "${LOOP:?}"
-printf 'size=50M,type=%s\n,\n' "${root_guid}" | sfdisk -X gpt "$LOOP"
+sfdisk /var/tmp/testsuite-58-issue-21817.img <<EOF
+label: gpt
+
+size=50M, type=${root_guid}
+,
+EOF
cat >/tmp/testsuite-58-issue-21817-defs/test.conf <<EOF
[Partition]
Type=root
EOF
-systemd-repart --pretty=yes --definitions /tmp/testsuite-58-issue-21817-defs/ "$LOOP"
-sfdisk --dump "$LOOP" | tee /tmp/testsuite-58-issue-21817.dump
-losetup -d "$LOOP"
+systemd-repart --pretty=yes --definitions /tmp/testsuite-58-issue-21817-defs/ --dry-run=no /var/tmp/testsuite-58-issue-21817.img
+sfdisk --dump /var/tmp/testsuite-58-issue-21817.img | tee /tmp/testsuite-58-issue-21817.dump
-grep -qiF "p1 : start= 2048, size= 102400, type=${root_guid}," /tmp/testsuite-58-issue-21817.dump
+grep -qiF "/var/tmp/testsuite-58-issue-21817.img1 : start= 2048, size= 102400, type=${root_guid}," /tmp/testsuite-58-issue-21817.dump
# Accept both unpadded (pre-v2.38 util-linux) and padded (v2.38+ util-linux) sizes
-grep -qE "p2 : start= 104448, size= (100319| 98304)," /tmp/testsuite-58-issue-21817.dump
+grep -qE "/var/tmp/testsuite-58-issue-21817.img2 : start= 104448, size= (100319| 98304)," /tmp/testsuite-58-issue-21817.dump
rm /var/tmp/testsuite-58-issue-21817.img /tmp/testsuite-58-issue-21817.dump
rm -r /tmp/testsuite-58-issue-21817-defs/
@@ -216,7 +218,7 @@ EOF
truncate -s 100m "/tmp/testsuite-58-sector-$1.img"
LOOP=$(losetup -b "$1" -P --show -f "/tmp/testsuite-58-sector-$1.img" )
- udevadm wait --timeout 60 --initialized=yes --settle "${LOOP:?}"
+ udevadm wait --timeout 60 --settle "${LOOP:?}"
systemd-repart --pretty=yes --definitions=/tmp/testsuite-58-sector/ --seed=750b6cd5c4ae4012a15e7be3c29e6a47 --empty=require --dry-run=no "$LOOP"
rm -rf /tmp/testsuite-58-sector
sfdisk --verify "$LOOP"
diff --git a/test/units/testsuite-64.sh b/test/units/testsuite-64.sh
index 44f362ec6f..5f50131dd5 100755
--- a/test/units/testsuite-64.sh
+++ b/test/units/testsuite-64.sh
@@ -168,7 +168,7 @@ $(printf 'name="test%d", size=2M\n' {1..50})
EOF
# Initial partition table
- sfdisk -q -X gpt "$blockdev" <"$partscript"
+ udevadm lock --device="$blockdev" sfdisk -q -X gpt "$blockdev" <"$partscript"
# Delete the partitions, immediately recreate them, wait for udev to settle
# down, and then check if we have any dangling symlinks in /dev/disk/. Rinse
@@ -177,8 +177,8 @@ EOF
# On unpatched udev versions the delete-recreate cycle may trigger a race
# leading to dead symlinks in /dev/disk/
for i in {1..100}; do
- sfdisk -q --delete "$blockdev"
- sfdisk -q -X gpt "$blockdev" <"$partscript"
+ udevadm lock --device="$blockdev" sfdisk -q --delete "$blockdev"
+ udevadm lock --device="$blockdev" sfdisk -q -X gpt "$blockdev" <"$partscript"
if ((i % 10 == 0)); then
udevadm wait --settle --timeout=30 "$blockdev"
@@ -281,7 +281,7 @@ testcase_btrfs_basic() {
echo "Multiple devices: using partitions, data: single, metadata: raid1"
uuid="deadbeef-dead-dead-beef-000000000001"
label="btrfs_mpart"
- sfdisk --wipe=always "${devices[0]}" <<EOF
+ udevadm lock --device="${devices[0]}" sfdisk --wipe=always "${devices[0]}" <<EOF
label: gpt
name="diskpart1", size=85M
diff --git a/tmpfiles.d/meson.build b/tmpfiles.d/meson.build
index b8d3919025..306e066f22 100644
--- a/tmpfiles.d/meson.build
+++ b/tmpfiles.d/meson.build
@@ -41,7 +41,7 @@ foreach pair : in_files
pair[0],
input : pair[0] + '.in',
output: pair[0],
- command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+ command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : enable_tmpfiles,
install_dir : tmpfilesdir)
else
diff --git a/tools/check-help.sh b/tools/check-help.sh
index 76ac292675..f97429364e 100755
--- a/tools/check-help.sh
+++ b/tools/check-help.sh
@@ -3,8 +3,8 @@
set -eu
set -o pipefail
-# Note: `grep ... >/dev/null` instead of just `grep -q` is used intentionally
-# here, since `grep -q` exits on the first match causing SIGPIPE being
+# Note: 'grep ... >/dev/null' instead of just 'grep -q' is used intentionally
+# here, since 'grep -q' exits on the first match causing SIGPIPE being
# sent to the sender.
BINARY="${1:?}"
@@ -24,11 +24,11 @@ fi
# --help prints something. Also catches case where args are ignored.
if ! "$BINARY" --help | grep . >/dev/null; then
- echo "$(basename "$BINARY") --help output is empty."
+ echo "$(basename "$BINARY") --help output is empty"
exit 2
fi
-# no --help output to stdout
+# no --help output to stderr
if "$BINARY" --help 2>&1 1>/dev/null | grep .; then
echo "$(basename "$BINARY") --help prints to stderr"
exit 3
@@ -39,3 +39,9 @@ if ! ("$BINARY" --no-such-parameter 2>&1 1>/dev/null || :) | grep . >/dev/null;
echo "$(basename "$BINARY") with an unknown parameter does not print to stderr"
exit 4
fi
+
+# --help and -h are equivalent
+if ! diff <("$BINARY" -h) <("$BINARY" --help); then
+ echo "$(basename "$BINARY") --help and -h are not identical"
+ exit 5
+fi
diff --git a/tools/check-version.sh b/tools/check-version.sh
new file mode 100755
index 0000000000..faefb46883
--- /dev/null
+++ b/tools/check-version.sh
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -eu
+set -o pipefail
+
+# Note: 'grep ... >/dev/null' instead of just 'grep -q' is used intentionally
+# here, since 'grep -q' exits on the first match causing SIGPIPE being
+# sent to the sender.
+
+BINARY="${1:?}"
+VERSION="${2:?}"
+export SYSTEMD_LOG_LEVEL=info
+
+if [[ ! -x "$BINARY" ]]; then
+ echo "$BINARY is not an executable"
+ exit 1
+fi
+
+# --version prints something. Also catches case where args are ignored.
+if ! "$BINARY" --version | grep . >/dev/null; then
+ echo "$(basename "$BINARY") --version output is empty"
+ exit 2
+fi
+
+# no --version output to stderr
+if "$BINARY" --version 2>&1 1>/dev/null | grep .; then
+ echo "$(basename "$BINARY") --version prints to stderr"
+ exit 3
+fi
+
+# project version appears in version output
+out="$("$BINARY" --version)"
+if ! grep -F "$VERSION" >/dev/null <<<"$out"; then
+ echo "$(basename "$BINARY") --version output does not match '$VERSION': $out"
+ exit 4
+fi
diff --git a/tools/meson-render-jinja2.py b/tools/meson-render-jinja2.py
index 89735c70ed..fbaae596de 100755
--- a/tools/meson-render-jinja2.py
+++ b/tools/meson-render-jinja2.py
@@ -28,9 +28,10 @@ def render(filename, defines):
if __name__ == '__main__':
defines = parse_config_h(sys.argv[1])
- output = render(sys.argv[2], defines)
- with open(sys.argv[3], 'w') as f:
+ defines.update(parse_config_h(sys.argv[2]))
+ output = render(sys.argv[3], defines)
+ with open(sys.argv[4], 'w') as f:
f.write(output)
f.write('\n')
- info = os.stat(sys.argv[2])
- os.chmod(sys.argv[3], info.st_mode)
+ info = os.stat(sys.argv[3])
+ os.chmod(sys.argv[4], info.st_mode)
diff --git a/units/meson.build b/units/meson.build
index 8a3bd0da51..e8f81f2230 100644
--- a/units/meson.build
+++ b/units/meson.build
@@ -276,7 +276,7 @@ foreach tuple : in_units
file,
input : file + '.in',
output : file,
- command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+ command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
install : install,
install_dir : systemunitdir)