* [PATCH v5 1/2] systemd: upgrade to 261.1
2026-07-22 13:16 [PATCH v5 0/2] systemd: upgrade to 261.1 and be compatible with rhel8 daniel.turull
@ 2026-07-22 13:16 ` daniel.turull
2026-07-22 13:16 ` [PATCH v5 2/2] systemd-tools-native: fix systemctl/hwdb --root on RHEL 8 hosts daniel.turull
1 sibling, 0 replies; 3+ messages in thread
From: daniel.turull @ 2026-07-22 13:16 UTC (permalink / raw)
To: daniel.turull, openembedded-core, ross.burton,
mathieu.dubois-briand
Cc: anders.heimer, qi.chen, alex.kanavin, richard.purdie,
joerg.sommer
From: Daniel Turull <daniel.turull@ericsson.com>
Changes: https://github.com/systemd/systemd/compare/v259.5...v261.1
https://github.com/systemd/systemd/blob/main/NEWS
- Drop backported patches no longer needed (libfido2_cflags,
tpm2-util PCR bank, fdset_new debug)
- Remove sysvinit-path/sysvrcnd-path meson options and
systemd-sysv-install skeleton (removed upstream in 260)
- Add explicit meson disables for auto-detected features in
systemd-systemctl-native to prevent host sysroot contamination
- Refresh 0003-Do-not-create-var-log-README.patch
Tested on qemu target with testsuite systemd.
Summary of changes in systemd from NEWS file:
* Drop legacy SysV init support: rc-local, sysv-generator, sysv-install
removed; services must ship native systemd unit files going forward.
* Deprecate non-system users/groups in udev and systemd-networkd
configs; usage still works but emits warnings and is scheduled for
removal.
* Raise dependency baselines:
- cryptsetup, elfutils, libblkid, libseccomp, glibc, libxcrypt,
OpenSSL, Python all require newer versions.
- Linux baseline moved from 5.4 to 5.10, recommended 5.14, with
6.6 needed for full functionality; compatibility code for older
kernels dropped.
- musl minimum bumped from 1.2.5 to 1.2.6 when building with
-Dlibc=musl.
* Rework dynamic linking: shift optional dependencies to dlopen() for
libgnutls, libmicrohttpd, libcurl, libcrypto, libssl, libfdisk,
libcryptsetup. libsystemd no longer guarantees a link to libm, so
consumers relying on transitive libm must link it explicitly.
* sd-varlink API: temporary enum extension in 260-rc1 changed numeric
values, reverted in -rc2. Binaries built against -rc1 headers must
be rebuilt to avoid ABI mismatches.
* systemd-logind D-Bus CanPowerOff/CanReboot/CanSuspend/... gain new
return values for inhibitors: "inhibited", "inhibitor-blocked",
"challenge-inhibitor-blocked". Consumers assuming only "yes"/"no"
need adjustment.
* Rename systemd-nspawn --user= to --uid=. The -u short option still
works. Old forms --user NAME/--user=NAME remain accepted but are
deprecated and emit a warning; bare --user now toggles user manager
scope instead of taking an argument.
* Varlink io.systemd.Unit: several configuration fields switched from
free-form strings to enums (ExecInputType, ExecOutputType,
ProtectHome, CGroupController, CollectMode, EmergencyAction,
JobMode). Wire format now uses underscores instead of dashes/plus
(e.g. "tty-force" -> "tty_force", "kmsg+console" -> "kmsg_console").
* Announced removal of experimental systemd-sysupdated D-Bus API in
favor of direct Varlink IPC to systemd-sysupdate; updatectl will be
reworked accordingly.
* TPM / CC measurement changes:
- systemd-stub now measures more artifacts into hardware CC
registers (e.g. TDX RTMRs) in addition to TPM, altering expected
CC values for devicetree, initrd, ucode addons, UKI profile.
- New verity TPM NvPCR added; various components measure dm-verity
images into it.
- New ConditionSecurity=measured-os, and improved SMBIOS measurements
in systemd-boot/systemd-stub.
- New systemd-pcrosseparator.service adds a PCR separator
measurement affecting PCRs 0-7,9,12-14 to isolate firmware vs OS
measurements.
* Boot and UKI tooling:
- systemd-stub introduces a "boot secret" passed via initrd for TPM
fallback key material in non-TPM environments.
- Keyboard layout and serial console are auto-propagated from UEFI
to Linux; LoaderKeyboardLayout EFI variable used as fallback
mapping.
- Unified handling of UKI sidecars and "extra" Type #1 stanzas for
confext/sysext/credentials.
- systemd-boot avoids auto-boot into non-default UKI profiles and
adds better fallback handling and new bootctl verbs/options.
* New IMDS subsystem:
- hwdb gains 40-imds.hwdb to detect major public clouds and describe
access to local IMDS endpoints.
- systemd-imdsd provides Varlink IPC for IMDS access; systemd-imds
imports IMDS data into credentials with measurements.
- Optional network lockdown for IMDS via -Dimds-network=, with a
"locked" default recommended for secure setups.
* New metrics / report framework:
- systemd-report defines a Varlink-based metrics aggregation API
under /run/systemd/report/.
- Initial endpoints from systemd-networkd and the service manager in
260; extended in 261 to system-wide and per-service/cgroup metrics,
with Varlink and HTTP upload support.
* New mstack feature:
- ".mstack/" directory layout defines overlayfs + bind mount stacks
for services/containers.
- RootMStack= unit setting and systemd-nspawn --mstack= support
invoking services and containers from self-describing mstack
images.
- importctl pull-oci stores OCI images as mstack images.
* Manager and resource-control enhancements:
- New per-unit settings: RootMStack=, PrivateUsers=managed,
MemoryTHP=, CPUSetPartition=, RestrictFileSystemAccess= (BPF LSM),
CPUPressureWatch=/CPUPressureThresholdSec=,
IOPressureWatch=/IOPressureThresholdSec=.
- New global knobs: DefaultMemoryZSwapWriteback=,
EventLoopRateLimitIntervalSec=/EventLoopRateLimitBurst=,
MinimumUptimeSec= (default 15s to avoid tight boot loops).
- fd-store persistence improvements: LUO/Kexec handover support in
PID1, FileDescriptorStorePreserve=on-success and user/manager
plumbing to keep memfds and other state across session restarts
and kexec.
* Varlink and IPC surface growth:
- New Varlink methods for shutdown (PowerOff, Reboot, SoftReboot,
Halt, Kexec) on io.systemd.Manager and io.systemd.Shutdown.
- io.systemd.Unit.StartTransient(), io.systemd.Manager.ListUnitsByNames(),
io.systemd.Job interface for job inspection/cancellation.
- systemd-networkd Varlink updates: Reload(), Link.Describe(),
Reconfigure(), Renew(), ForceRenew(), Up()/Down() and reporting
of interface bit rates.
- journalctl gains a Varlink GetEntries() interface.
- New sd-varlink APIs for sentinel handling and protocol upgrade,
plus wildcard type SD_VARLINK_ANY and per-UID connection limit
reduction.
* Scheduling and rollout knobs:
- CPUSchedulingPolicy=ext for SCHED_EXT.
- ConditionFraction= for percentage-based staged rollouts keyed by
machine ID and tag.
- ConditionMachineTag= and new Tags= in /etc/machine-info for
fleet-wide targeting via hostnamed.
* Filesystem, tmpfiles, sysusers:
- tmpfiles.d/root.conf sets / to mode 0555 in certain setups.
- systemd-tmpfiles gains --inline and new k/K directives for
capabilities.
- New initrd services systemd-sysext-sysroot.service and
systemd-confext-sysroot.service to merge extensions from initrd,
plus a kernel kill switch to fully disable sysext/confext.
* Networking and resolved:
- DHCP relay refactoring with sd-dhcp-relay backend; [DHCPServer]
options deprecated in favor of [Network]/[DHCPRelay] + networkd.conf
settings.
- systemd-networkd adds MultiPathRoute= improvements, ModemManager
"simple connect" integration, new offload controls in .link files,
new DHCPv4 server options, and various Varlink/JSON interface
updates.
- systemd-resolved adds JSON static RR drop-ins, per-interface cache
size tunables, improved DNSSEC handling for insecure answers,
better stale cache retention, and reload of /etc/hosts on
SIGHUP/Reload().
- resolvectl now talks via Varlink; nss-resolve gains interface
scoping via $SYSTEMD_NSS_RESOLVE_INTERFACE.
* Logging, coredumps, cryptsetup:
- coredumpctl info gains JSON output; crashing thread TID/name and
new COREDUMP_CODE field recorded.
- systemd-cryptsetup/libcryptsetup moved behind dlopen(); new
fixate-volume-key= support for binding crypttab entries to volume
keys; systemd-cryptenroll now defaults to RSA-OAEP+SHA-256 for
sealed keys.
- systemd-creds improves TPM2 PCR handling to avoid errors on non-TPM
systems.
* OOM and reliability:
- systemd-oomd gains OOM rulesets and "prekill hook" integration via
Varlink sockets.
- systemd-oomd and PID1 adopt pidfds in more places.
- systemd-run gets --output= to control verbose mode logging.
* Misc:
- RootImageOptions=/ExtensionImages=/MountImages= parsing changed so
last definition per partition wins, aligning with other option
semantics.
- systemd-sysext/confext refresh now suppresses unnecessary
umount/mount by default, with --always-refresh= to force a
refresh.
- getty@.service now has [Install] section and must be explicitly
enabled.
- runlevel[0-6].target can be restored when building with
-Dcompat-sysv-interfaces=yes, but SysV scripts themselves are
gone.
AI-Generated: Claude-opus-4.6
Signed-off-by: Daniel Turull <daniel.turull@ericsson.com>
---
..._259.5.bb => systemd-boot-native_261.1.bb} | 0
...md-boot_259.5.bb => systemd-boot_261.1.bb} | 0
...259.5.bb => systemd-tools-native_261.1.bb} | 0
meta/recipes-core/systemd/systemd.inc | 8 +-
...meson-use-libfido2_cflags-dependency.patch | 54 -----------
.../0003-Do-not-create-var-log-README.patch | 10 +-
...il-fix-PCR-bank-guessing-without-EFI.patch | 62 ------------
...-detailed-debug-logging-to-fdset_new.patch | 97 -------------------
.../{systemd_259.5.bb => systemd_261.1.bb} | 12 +--
9 files changed, 11 insertions(+), 232 deletions(-)
rename meta/recipes-core/systemd/{systemd-boot-native_259.5.bb => systemd-boot-native_261.1.bb} (100%)
rename meta/recipes-core/systemd/{systemd-boot_259.5.bb => systemd-boot_261.1.bb} (100%)
rename meta/recipes-core/systemd/{systemd-tools-native_259.5.bb => systemd-tools-native_261.1.bb} (100%)
delete mode 100644 meta/recipes-core/systemd/systemd/0001-meson-use-libfido2_cflags-dependency.patch
delete mode 100644 meta/recipes-core/systemd/systemd/0004-tpm2-util-fix-PCR-bank-guessing-without-EFI.patch
delete mode 100644 meta/recipes-core/systemd/systemd/0018-shared-fdset-add-detailed-debug-logging-to-fdset_new.patch
rename meta/recipes-core/systemd/{systemd_259.5.bb => systemd_261.1.bb} (99%)
diff --git a/meta/recipes-core/systemd/systemd-boot-native_259.5.bb b/meta/recipes-core/systemd/systemd-boot-native_261.1.bb
similarity index 100%
rename from meta/recipes-core/systemd/systemd-boot-native_259.5.bb
rename to meta/recipes-core/systemd/systemd-boot-native_261.1.bb
diff --git a/meta/recipes-core/systemd/systemd-boot_259.5.bb b/meta/recipes-core/systemd/systemd-boot_261.1.bb
similarity index 100%
rename from meta/recipes-core/systemd/systemd-boot_259.5.bb
rename to meta/recipes-core/systemd/systemd-boot_261.1.bb
diff --git a/meta/recipes-core/systemd/systemd-tools-native_259.5.bb b/meta/recipes-core/systemd/systemd-tools-native_261.1.bb
similarity index 100%
rename from meta/recipes-core/systemd/systemd-tools-native_259.5.bb
rename to meta/recipes-core/systemd/systemd-tools-native_261.1.bb
diff --git a/meta/recipes-core/systemd/systemd.inc b/meta/recipes-core/systemd/systemd.inc
index efd7826684..bb499a0587 100644
--- a/meta/recipes-core/systemd/systemd.inc
+++ b/meta/recipes-core/systemd/systemd.inc
@@ -15,14 +15,10 @@ LICENSE:libsystemd = "LGPL-2.1-or-later"
LIC_FILES_CHKSUM = "file://LICENSE.GPL2;md5=c09786363500a9acc29b147e6e72d2c6 \
file://LICENSE.LGPL2.1;md5=be0aaf4a380f73f7e00b420a007368f2"
-SRCREV = "b3d8fc43e9cb531d958c17ef2cd93b374bc14e8a"
-SRCBRANCH = "v259-stable"
+SRCREV = "eff9446d505d62c075bed37d606860b38cfe51fb"
+SRCBRANCH = "v261-stable"
SRC_URI = "git://github.com/systemd/systemd.git;protocol=https;branch=${SRCBRANCH};tag=v${PV}"
CVE_PRODUCT = "systemd"
CVE_STATUS[CVE-2019-3815] = "not-applicable-platform: only applied to RHEL"
-CVE_STATUS[CVE-2026-40223] = "fixed-version: fixed in 259.2"
-CVE_STATUS[CVE-2026-40224] = "fixed-version: fixed in 259.3"
-CVE_STATUS[CVE-2026-40225] = "fixed-version: fixed in 259.5"
-CVE_STATUS[CVE-2026-40226] = "fixed-version: fixed in 259.4"
diff --git a/meta/recipes-core/systemd/systemd/0001-meson-use-libfido2_cflags-dependency.patch b/meta/recipes-core/systemd/systemd/0001-meson-use-libfido2_cflags-dependency.patch
deleted file mode 100644
index 4bc1e10ee7..0000000000
--- a/meta/recipes-core/systemd/systemd/0001-meson-use-libfido2_cflags-dependency.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From 97142fd1db4124de5d5bdd3f49cc5a390286e522 Mon Sep 17 00:00:00 2001
-From: Dan McGregor <danmcgr@protonmail.com>
-Date: Wed, 11 Mar 2026 18:26:05 -0600
-Subject: [PATCH] meson: use libfido2_cflags dependency
-
-Add the libfido2 dependency to cryptenroll and cryptsetup's
-meson files. If libfido2's not installed in the default path
-the build wasn't finding its headers correctly.
-
-Signed-off-by: Dan McGregor <danmcgr@protonmail.com>
-Upstream-Status: Backport [https://github.com/systemd/systemd/commit/9ce905e35f690e7a10cd286be2b50594d0857f5e]
----
- src/cryptenroll/meson.build | 1 +
- src/cryptsetup/cryptsetup-tokens/meson.build | 2 +-
- src/cryptsetup/meson.build | 1 +
- 3 files changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/src/cryptenroll/meson.build b/src/cryptenroll/meson.build
-index 488ceea14d..11265c8b41 100644
---- a/src/cryptenroll/meson.build
-+++ b/src/cryptenroll/meson.build
-@@ -23,6 +23,7 @@ executables += [
- 'dependencies' : [
- libcryptsetup,
- libdl,
-+ libfido2_cflags,
- libopenssl,
- libp11kit_cflags,
- ],
-diff --git a/src/cryptsetup/cryptsetup-tokens/meson.build b/src/cryptsetup/cryptsetup-tokens/meson.build
-index 804e18bc67..0fd6309201 100644
---- a/src/cryptsetup/cryptsetup-tokens/meson.build
-+++ b/src/cryptsetup/cryptsetup-tokens/meson.build
-@@ -58,7 +58,7 @@ modules += [
- 'sources' : cryptsetup_token_systemd_fido2_sources,
- 'dependencies' : [
- libcryptsetup,
-- libfido2,
-+ libfido2_cflags,
- ],
- },
- template + {
-diff --git a/src/cryptsetup/meson.build b/src/cryptsetup/meson.build
-index d9778259c2..b36354fb0a 100644
---- a/src/cryptsetup/meson.build
-+++ b/src/cryptsetup/meson.build
-@@ -19,6 +19,7 @@ executables += [
- 'sources' : systemd_cryptsetup_sources,
- 'dependencies' : [
- libcryptsetup,
-+ libfido2_cflags,
- libmount_cflags,
- libopenssl,
- libp11kit_cflags,
diff --git a/meta/recipes-core/systemd/systemd/0003-Do-not-create-var-log-README.patch b/meta/recipes-core/systemd/systemd/0003-Do-not-create-var-log-README.patch
index 1d3c4f83c0..0128c83d9f 100644
--- a/meta/recipes-core/systemd/systemd/0003-Do-not-create-var-log-README.patch
+++ b/meta/recipes-core/systemd/systemd/0003-Do-not-create-var-log-README.patch
@@ -1,7 +1,7 @@
From a7f6a296707642d05463aec22ea3dfce7d06c989 Mon Sep 17 00:00:00 2001
From: Peter Kjellerstedt <pkj@axis.com>
Date: Tue, 21 Jan 2025 05:02:00 +0100
-Subject: [PATCH 03/16] Do not create /var/log/README
+Subject: [PATCH] Do not create /var/log/README
/var/log/README is a link to /usr/share/doc/systemd/README.logs. The
latter is packaged in systemd-doc and likely not installed, which leaves
@@ -15,19 +15,15 @@ Signed-off-by: Peter Kjellerstedt <peter.kjellerstedt@axis.com>
1 file changed, 3 deletions(-)
diff --git a/tmpfiles.d/legacy.conf.in b/tmpfiles.d/legacy.conf.in
-index cdef21fa9b..03798c953e 100644
+index cdef21fa9b..7890abcdef 100644
--- a/tmpfiles.d/legacy.conf.in
+++ b/tmpfiles.d/legacy.conf.in
-@@ -13,9 +13,6 @@
+@@ -13,6 +13,3 @@
d /run/lock 0755 root root -
L /var/lock - - - - ../run/lock
-{% if CREATE_LOG_DIRS %}
-L$ /var/log/README - - - - ../..{{DOC_DIR}}/README.logs
-{% endif %}
-
- {% if HAVE_SYSV_COMPAT %}
- # /run/lock/subsys is used for serializing SysV service execution, and
--
2.34.1
-
diff --git a/meta/recipes-core/systemd/systemd/0004-tpm2-util-fix-PCR-bank-guessing-without-EFI.patch b/meta/recipes-core/systemd/systemd/0004-tpm2-util-fix-PCR-bank-guessing-without-EFI.patch
deleted file mode 100644
index c590b01cd3..0000000000
--- a/meta/recipes-core/systemd/systemd/0004-tpm2-util-fix-PCR-bank-guessing-without-EFI.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From 3cef11c710e95bb5f891181e9b2a6d8f174712c3 Mon Sep 17 00:00:00 2001
-From: Patrick Wicki <patrick.wicki@subset.ch>
-Date: Fri, 20 Mar 2026 15:56:56 +0100
-Subject: [PATCH] tpm2-util: fix PCR bank guessing without EFI
-
-Since 7643e4a89 efi_get_active_pcr_banks() is used to determine the
-active PCR banks. Without EFI support, this returns -EOPNOTSUPP. This in
-turns leads to cryptenroll and cryptsetup attach failures unless the PCR
-bank is explicitly set, i.e.
-
-$ systemd-cryptenroll $LUKS_PART --tpm2-device=auto --tpm2-pcrs='7'
-[...]
-Could not read pcr values: Operation not supported
-
-But it works fine with --tpm2-pcrs='7:sha256'.
-
-Similarly, unsealing during cryptsetup attach also fails if the bank
-needs to be determined:
-
-Failed to unseal secret using TPM2: Operation not supported
-
-Catch the -EOPNOTSUPP and fallback to the guessing strategy.
-
-Upstream-Status: Backport [https://github.com/systemd/systemd/pull/41231]
-
-Signed-off-by: Patrick Wicki <patrick.wicki@siemens.com>
----
- src/shared/tpm2-util.c | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
-diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c
-index cf11b50695..c0590fe575 100644
---- a/src/shared/tpm2-util.c
-+++ b/src/shared/tpm2-util.c
-@@ -2702,11 +2702,11 @@ int tpm2_get_best_pcr_bank(
- uint32_t efi_banks;
- r = efi_get_active_pcr_banks(&efi_banks);
- if (r < 0) {
-- if (r != -ENOENT)
-+ if (!IN_SET(r, -ENOENT, -EOPNOTSUPP))
- return r;
-
- /* If variable is not set use guesswork below */
-- log_debug("Boot loader didn't set the LoaderTpm2ActivePcrBanks EFI variable, we have to guess the used PCR banks.");
-+ log_debug("Boot loader didn't set the LoaderTpm2ActivePcrBanks EFI variable or EFI support is unavailable, we have to guess the used PCR banks.");
- } else if (efi_banks == UINT32_MAX)
- log_debug("Boot loader set the LoaderTpm2ActivePcrBanks EFI variable to indicate that the GetActivePcrBanks() API is not available in the firmware. We have to guess the used PCR banks.");
- else {
-@@ -2811,11 +2811,11 @@ int tpm2_get_good_pcr_banks(
- uint32_t efi_banks;
- r = efi_get_active_pcr_banks(&efi_banks);
- if (r < 0) {
-- if (r != -ENOENT)
-+ if (!IN_SET(r, -ENOENT, -EOPNOTSUPP))
- return r;
-
- /* If the variable is not set we have to guess via the code below */
-- log_debug("Boot loader didn't set the LoaderTpm2ActivePcrBanks EFI variable, we have to guess the used PCR banks.");
-+ log_debug("Boot loader didn't set the LoaderTpm2ActivePcrBanks EFI variable or EFI support is unavailable, we have to guess the used PCR banks.");
- } else if (efi_banks == UINT32_MAX)
- log_debug("Boot loader set the LoaderTpm2ActivePcrBanks EFI variable to indicate that the GetActivePcrBanks() API is not available in the firmware. We have to guess the used PCR banks.");
- else {
diff --git a/meta/recipes-core/systemd/systemd/0018-shared-fdset-add-detailed-debug-logging-to-fdset_new.patch b/meta/recipes-core/systemd/systemd/0018-shared-fdset-add-detailed-debug-logging-to-fdset_new.patch
deleted file mode 100644
index 63fa7fefec..0000000000
--- a/meta/recipes-core/systemd/systemd/0018-shared-fdset-add-detailed-debug-logging-to-fdset_new.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From 0565f9f27323a8f9e62d85f2add542af99cea06a Mon Sep 17 00:00:00 2001
-From: AshishKumar Mishra <ashishkumar.mishra@bmwtechworks.in>
-Date: Wed, 21 Jan 2026 14:13:29 +0530
-Subject: [PATCH] systemd: Add detailed debug logging to fdset_new_fill()
-
-Currently, when fdset_new_fill() fails to open /proc/self/fd or
-encounters an error while processing individual file descriptors
-(such as fcntl or fstat failures), it returns a silent error code.
-
-For debugging rarely reproducible failures it becomes difficult to
-know the exact cause of failure
-This commit updates the function to use log_debug_errno() for all
-error paths and hence provides better visibility into why FD collection
-failed, including the path of the problematic FD (via fd_get_path)
-and its inode type.
-
-Upstream-Status: Backport [https://github.com/systemd/systemd/pull/40385]
-
-Signed-off-by: AshishKumar Mishra <ashishkumar.mishra@bmwtechworks.in>
----
- src/shared/fdset.c | 35 ++++++++++++++++++++++++++---------
- 1 file changed, 26 insertions(+), 9 deletions(-)
-
-diff --git a/src/shared/fdset.c b/src/shared/fdset.c
-index 832e7fda60..f340f41b0e 100644
---- a/src/shared/fdset.c
-+++ b/src/shared/fdset.c
-@@ -8,6 +8,7 @@
- #include "alloc-util.h"
- #include "async.h"
- #include "dirent-util.h"
-+#include "errno-util.h"
- #include "fd-util.h"
- #include "fdset.h"
- #include "log.h"
-@@ -179,9 +180,10 @@ int fdset_new_fill(
- d = opendir("/proc/self/fd");
- if (!d) {
- if (errno == ENOENT && proc_mounted() == 0)
-- return -ENOSYS;
-+ return log_debug_errno(SYNTHETIC_ERRNO(ENOSYS),
-+ "Failed to open /proc/self/fd/, /proc/ is not mounted.");
-
-- return -errno;
-+ return log_debug_errno(errno, "Failed to open /proc/self/fd/: %m ");
- }
-
- s = fdset_new();
-@@ -210,9 +212,14 @@ int fdset_new_fill(
- * been passed in can be collected and fds which have been created locally can be
- * ignored, under the assumption that only the latter have O_CLOEXEC set. */
-
-- fl = fcntl(fd, F_GETFD);
-- if (fl < 0)
-- return -errno;
-+ fl = RET_NERRNO(fcntl(fd, F_GETFD));
-+ if (fl < 0) {
-+ _cleanup_free_ char *path = NULL;
-+ (void) fd_get_path(fd, &path);
-+ return log_debug_errno(fl,
-+ "Failed to get flag of fd=%d (%s): %m ",
-+ fd, strna(path));
-+ }
-
- if (FLAGS_SET(fl, FD_CLOEXEC) != !!filter_cloexec)
- continue;
-@@ -221,13 +228,23 @@ int fdset_new_fill(
- /* We need to set CLOEXEC manually only if we're collecting non-CLOEXEC fds. */
- if (filter_cloexec <= 0) {
- r = fd_cloexec(fd, true);
-- if (r < 0)
-- return r;
-+ if (r < 0) {
-+ _cleanup_free_ char *path = NULL;
-+ (void) fd_get_path(fd, &path);
-+ return log_debug_errno(r,
-+ "Failed to set CLOEXEC flag fd=%d (%s): %m ",
-+ fd, strna(path));
-+ }
- }
-
- r = fdset_put(s, fd);
-- if (r < 0)
-- return r;
-+ if (r < 0) {
-+ _cleanup_free_ char *path = NULL;
-+ (void) fd_get_path(fd, &path);
-+ return log_debug_errno(r,
-+ "Failed to put fd=%d (%s) into fdset: %m ",
-+ fd, strna(path));
-+ }
- }
-
- *ret = TAKE_PTR(s);
---
-2.34.1
-
diff --git a/meta/recipes-core/systemd/systemd_259.5.bb b/meta/recipes-core/systemd/systemd_261.1.bb
similarity index 99%
rename from meta/recipes-core/systemd/systemd_259.5.bb
rename to meta/recipes-core/systemd/systemd_261.1.bb
index edb6410772..6775a2a205 100644
--- a/meta/recipes-core/systemd/systemd_259.5.bb
+++ b/meta/recipes-core/systemd/systemd_261.1.bb
@@ -36,9 +36,6 @@ SRC_URI += " \
file://systemd-pager.sh \
file://0001-binfmt-Don-t-install-dependency-links-at-install-tim.patch \
file://0003-Do-not-create-var-log-README.patch \
- file://0001-meson-use-libfido2_cflags-dependency.patch \
- file://0018-shared-fdset-add-detailed-debug-logging-to-fdset_new.patch \
- file://0004-tpm2-util-fix-PCR-bank-guessing-without-EFI.patch \
file://0005-boot-downgrade-EFI_MEMORY_ATTRIBUTE_PROTOCOL-warning.patch \
"
@@ -231,9 +228,6 @@ EXTRA_OEMESON += "-Dnobody-user=nobody \
-Ddbus=disabled \
-Dtests=false \
-Dlibc=${TCLIBC} \
- -Drc-local='' \
- -Dsysvinit-path='' \
- -Dsysvrcnd-path='' \
"
# Hardcode target binary paths to avoid using paths from sysroot or worse
@@ -587,6 +581,8 @@ FILES:${PN}-extra-utils = "\
${bindir}/systemd-cgtop \
${bindir}/systemd-stdio-bridge \
${base_sbindir}/mount.ddi \
+ ${base_sbindir}/mount.mstack \
+ ${base_sbindir}/mount.storage \
${systemd_system_unitdir}/initrd.target.wants/systemd-pcrphase-initrd.path \
${systemd_system_unitdir}/sysinit.target.wants/systemd-pcrphase.path \
${systemd_system_unitdir}/sysinit.target.wants/systemd-pcrphase-sysinit.path \
@@ -683,6 +679,7 @@ FILES:${PN} = " ${base_bindir}/* \
${datadir}/polkit-1 \
${datadir}/${BPN} \
${datadir}/factory \
+ ${datadir}/user-tmpfiles.d \
${sysconfdir}/credstore/ \
${sysconfdir}/credstore.encrypted/ \
${sysconfdir}/dbus-1/ \
@@ -692,6 +689,7 @@ FILES:${PN} = " ${base_bindir}/* \
${sysconfdir}/sysctl.d/ \
${sysconfdir}/systemd/ \
${sysconfdir}/tmpfiles.d/ \
+ ${sysconfdir}/user-tmpfiles.d/ \
${sysconfdir}/xdg/ \
${sysconfdir}/init.d/README \
${sysconfdir}/resolv-conf.systemd \
@@ -803,11 +801,13 @@ FILES:udev += "${base_sbindir}/udevd \
${nonarch_libdir}/udev/rules.d/60-persistent-storage.rules \
${nonarch_libdir}/udev/rules.d/60-persistent-storage-mtd.rules \
${nonarch_libdir}/udev/rules.d/60-persistent-storage-tape.rules \
+ ${nonarch_libdir}/udev/rules.d/60-tpm2-id.rules \
${nonarch_libdir}/udev/rules.d/60-persistent-v4l.rules \
${nonarch_libdir}/udev/rules.d/60-sensor.rules \
${nonarch_libdir}/udev/rules.d/60-serial.rules \
${nonarch_libdir}/udev/rules.d/61-autosuspend-manual.rules \
${nonarch_libdir}/udev/rules.d/64-btrfs.rules \
+ ${nonarch_libdir}/udev/rules.d/65-integration.rules \
${nonarch_libdir}/udev/rules.d/70-camera.rules \
${nonarch_libdir}/udev/rules.d/70-joystick.rules \
${nonarch_libdir}/udev/rules.d/70-memory.rules \
^ permalink raw reply related [flat|nested] 3+ messages in thread* [PATCH v5 2/2] systemd-tools-native: fix systemctl/hwdb --root on RHEL 8 hosts
2026-07-22 13:16 [PATCH v5 0/2] systemd: upgrade to 261.1 and be compatible with rhel8 daniel.turull
2026-07-22 13:16 ` [PATCH v5 1/2] systemd: upgrade to 261.1 daniel.turull
@ 2026-07-22 13:16 ` daniel.turull
1 sibling, 0 replies; 3+ messages in thread
From: daniel.turull @ 2026-07-22 13:16 UTC (permalink / raw)
To: daniel.turull, openembedded-core, ross.burton,
mathieu.dubois-briand
Cc: anders.heimer, qi.chen, alex.kanavin, richard.purdie,
joerg.sommer
From: Daniel Turull <daniel.turull@ericsson.com>
The native systemctl and systemd-hwdb tools run offline against the
target rootfs (--root $D) during do_rootfs. On build hosts with a
kernel older than 5.8 (e.g. RHEL 8, kernel 4.18) statx() does not
support STATX_MNT_ID, so path resolution fails with -EUNATCH. This
breaks the offline "systemctl --root" enable/preset invoked by the
postinst of any package shipping a systemd service, e.g.:
Failed to preset all units: Protocol driver not attached.
which in turn fails do_rootfs:
ERROR: Postinstall scriptlets of ['busybox-syslog',
'systemd-networkd'] have failed. [...] Deferring to first boot via
'exit 1' is no longer supported.
- Add Handle-missing-STATX_MNT_ID-on-older-kernels.patch, which reads
mnt_id from /proc/self/fdinfo (available since kernel 3.15) as a
fallback when statx() lacks STATX_MNT_ID, restoring the behaviour
removed upstream after systemd 259
- Apply it only to systemd-tools-native, where /proc/self/fdinfo is
guaranteed available; the target systemd recipe is untouched
Tested on rhel8.10, qemux86-64 with systemd testsuite.
RESULTS:
RESULTS - ping.PingTest.test_ping: PASSED (0.00s)
RESULTS - ssh.SSHTest.test_ssh: PASSED (0.48s)
RESULTS - systemd.SystemdBasicTests.test_systemd_basic: PASSED (0.48s)
RESULTS - systemd.SystemdBasicTests.test_systemd_failed: PASSED (0.95s)
RESULTS - systemd.SystemdBasicTests.test_systemd_list: PASSED (0.66s)
RESULTS - systemd.SystemdJournalTests.test_systemd_boot_time: PASSED (0.68s)
RESULTS - systemd.SystemdJournalTests.test_systemd_journal: PASSED (0.68s)
RESULTS - systemd.SystemdServiceTests.test_systemd_coredump_minidebuginfo: SKIPPED (0.00s)
RESULTS - systemd.SystemdServiceTests.test_systemd_disable_enable: SKIPPED (0.00s)
RESULTS - systemd.SystemdServiceTests.test_systemd_disable_enable_ro: SKIPPED (0.00s)
RESULTS - systemd.SystemdServiceTests.test_systemd_status: SKIPPED (0.00s)
RESULTS - systemd.SystemdServiceTests.test_systemd_stop_start: SKIPPED (0.00s)
SUMMARY:
core-image-minimal () - Ran 12 tests in 3.923s
core-image-minimal - OK - All required tests passed (successes=7, skipped=5, failures=0, errors=0)
Assisted-by: kiro:claude-opus-4.8
Signed-off-by: Daniel Turull <daniel.turull@ericsson.com>
---
.../systemd/systemd-tools-native_261.1.bb | 3 +
...issing-STATX_MNT_ID-on-older-kernels.patch | 160 ++++++++++++++++++
2 files changed, 163 insertions(+)
create mode 100644 meta/recipes-core/systemd/systemd/Handle-missing-STATX_MNT_ID-on-older-kernels.patch
diff --git a/meta/recipes-core/systemd/systemd-tools-native_261.1.bb b/meta/recipes-core/systemd/systemd-tools-native_261.1.bb
index 744e874a1a..4b088afc9f 100644
--- a/meta/recipes-core/systemd/systemd-tools-native_261.1.bb
+++ b/meta/recipes-core/systemd/systemd-tools-native_261.1.bb
@@ -6,6 +6,9 @@ SUMMARY = "native tools from systemd"
SRC_URI += "file://0001-hwdb-strip-the-root-from-filenames-when-generating-h.patch"
+# TODO: Remove STATX_MNT_ID patch once minimum supported build host kernel is >= 5.8 (RHEL 8 EOL: 2029)
+SRC_URI += "file://Handle-missing-STATX_MNT_ID-on-older-kernels.patch"
+
# We don't actually need jinja to generate code, but it's checked for at configure time
DEPENDS = "gperf-native python3-jinja2-native"
diff --git a/meta/recipes-core/systemd/systemd/Handle-missing-STATX_MNT_ID-on-older-kernels.patch b/meta/recipes-core/systemd/systemd/Handle-missing-STATX_MNT_ID-on-older-kernels.patch
new file mode 100644
index 0000000000..9d74872034
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/Handle-missing-STATX_MNT_ID-on-older-kernels.patch
@@ -0,0 +1,160 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Turull <daniel.turull@ericsson.com>
+Date: Mon, 23 Jun 2026 12:00:00 +0200
+Subject: [PATCH] Handle missing STATX_MNT_ID on older kernels
+
+On hosts lacking STATX_MNT_ID (kernel < 5.8, e.g. RHEL 8), native tools
+(systemctl --root, systemd-hwdb --root) fail during path resolution with
+-EUNATCH. Fix by adding fd_get_mount_id() to read mnt_id from
+/proc/self/fdinfo (available since kernel 3.15) and using it as a fallback
+when statx() does not return STATX_MNT_ID in fds_inode_and_mount_same() and
+chase_statx().
+
+This restores the /proc/self/fdinfo fallback that existed in systemd 259
+(fd_fdinfo_mnt_id in mountpoint-util.c) but was removed upstream in 260+.
+
+This patch is only applied to the native tools recipe
+(systemd-tools-native) where /proc/self/fdinfo is guaranteed available.
+Do NOT apply to the target systemd recipe.
+
+Upstream-Status: Inappropriate [oe specific]
+
+Assisted-by: kiro:claude-opus-4.6
+Signed-off-by: Daniel Turull <daniel.turull@ericsson.com>
+---
+ src/basic/chase.c | 20 ++++++++++++++-
+ src/basic/fd-util.c | 63 +++++++++++++++++++++++++++++++++++++++++++--
+ src/basic/fd-util.h | 1 +
+ 3 files changed, 82 insertions(+), 2 deletions(-)
+
+--- a/src/basic/fd-util.h 2026-06-25 14:01:12.009875526 +0200
++++ b/src/basic/fd-util.h 2026-06-25 14:01:20.909060415 +0200
+@@ -188,6 +188,7 @@ static inline int dir_fd_is_root_or_cwd(
+ }
+
+ int fds_inode_and_mount_same(int fd1, int fd2);
++int fd_get_mount_id(int fd, uint64_t *ret);
+
+ int resolve_xat_fdroot(int *fd, const char **path, char **ret_buffer);
+
+--- a/src/basic/fd-util.c 2026-06-25 14:01:12.011875567 +0200
++++ b/src/basic/fd-util.c 2026-06-25 14:01:40.007456905 +0200
+@@ -1082,6 +1082,38 @@ int path_is_root_at(int dir_fd, const ch
+ return fds_inode_and_mount_same(dir_fd, XAT_FDROOT);
+ }
+
++int fd_get_mount_id(int fd, uint64_t *ret) {
++ char path[STRLEN("/proc/self/fdinfo/") + DECIMAL_STR_MAX(int)];
++ _cleanup_close_ int real_fd = -EBADF;
++ _cleanup_free_ char *p = NULL;
++ uint64_t mnt_id;
++ int r;
++
++ assert(ret);
++
++ /* /proc/self/fdinfo/ requires a real fd; resolve AT_FDCWD/XAT_FDROOT via O_PATH. */
++ if (fd == AT_FDCWD || fd == XAT_FDROOT) {
++ real_fd = open(fd == XAT_FDROOT ? "/" : ".", O_PATH|O_CLOEXEC);
++ if (real_fd < 0)
++ return -errno;
++ fd = real_fd;
++ }
++
++ assert(fd >= 0);
++ xsprintf(path, "/proc/self/fdinfo/%i", fd);
++
++ r = get_proc_field(path, "mnt_id", &p);
++ if (r < 0)
++ return r;
++
++ r = safe_atou64(p, &mnt_id);
++ if (r < 0)
++ return r;
++
++ *ret = mnt_id;
++ return 0;
++}
++
+ int fds_inode_and_mount_same(int fd1, int fd2) {
+ struct statx sx1, sx2;
+ int r;
+@@ -1092,7 +1124,20 @@ int fds_inode_and_mount_same(int fd1, in
+ r = xstatx(fd1, /* path = */ NULL, AT_EMPTY_PATH,
+ STATX_TYPE|STATX_INO|STATX_MNT_ID,
+ &sx1);
+- if (r < 0)
++ if (r == -EUNATCH) {
++ uint64_t mnt_id;
++
++ /* Kernel lacks STATX_MNT_ID; fall back to /proc/self/fdinfo. */
++ r = xstatx(fd1, /* path = */ NULL, AT_EMPTY_PATH,
++ STATX_TYPE|STATX_INO, &sx1);
++ if (r < 0)
++ return r;
++ r = fd_get_mount_id(fd1, &mnt_id);
++ if (r < 0)
++ return r;
++ sx1.stx_mnt_id = mnt_id;
++ sx1.stx_mask |= STATX_MNT_ID;
++ } else if (r < 0)
+ return r;
+
+ if (fd1 == fd2) /* Shortcut things if fds are the same (only after validating the fd) */
+@@ -1101,7 +1146,19 @@ int fds_inode_and_mount_same(int fd1, in
+ r = xstatx(fd2, /* path = */ NULL, AT_EMPTY_PATH,
+ STATX_TYPE|STATX_INO|STATX_MNT_ID,
+ &sx2);
+- if (r < 0)
++ if (r == -EUNATCH) {
++ uint64_t mnt_id;
++
++ r = xstatx(fd2, /* path = */ NULL, AT_EMPTY_PATH,
++ STATX_TYPE|STATX_INO, &sx2);
++ if (r < 0)
++ return r;
++ r = fd_get_mount_id(fd2, &mnt_id);
++ if (r < 0)
++ return r;
++ sx2.stx_mnt_id = mnt_id;
++ sx2.stx_mask |= STATX_MNT_ID;
++ } else if (r < 0)
+ return r;
+
+ r = statx_mount_same(&sx1, &sx2);
+--- a/src/basic/chase.c 2026-06-25 14:01:12.013875609 +0200
++++ b/src/basic/chase.c 2026-06-25 14:01:47.117604514 +0200
+@@ -40,7 +40,9 @@
+ (CHASE_MUST_BE_DIRECTORY|CHASE_MUST_BE_REGULAR|CHASE_MUST_BE_SOCKET)
+
+ static int chase_statx(int fd, struct statx *ret) {
+- return xstatx_full(fd,
++ int r;
++
++ r = xstatx_full(fd,
+ /* path= */ NULL,
+ /* statx_flags= */ 0,
+ XSTATX_MNT_ID_BEST,
+@@ -48,6 +50,23 @@ static int chase_statx(int fd, struct st
+ /* optional_mask= */ 0,
+ /* mandatory_attributes= */ 0,
+ ret);
++ if (r == -EUNATCH) {
++ uint64_t mnt_id;
++
++ /* Kernel lacks STATX_MNT_ID; fall back to /proc/self/fdinfo. */
++ r = xstatx(fd, /* path= */ NULL, /* statx_flags= */ 0,
++ STATX_TYPE|STATX_UID|STATX_INO,
++ ret);
++ if (r < 0)
++ return r;
++ r = fd_get_mount_id(fd, &mnt_id);
++ if (r < 0)
++ return r;
++ ret->stx_mnt_id = mnt_id;
++ ret->stx_mask |= STATX_MNT_ID;
++ }
++
++ return r;
+ }
+
+ static int chase_openat2(int root_fd, int dir_fd, const char *path, ChaseFlags chase_flags) {
^ permalink raw reply related [flat|nested] 3+ messages in thread