Luca Boccassi [Mon, 15 Jun 2026 20:33:08 +0000 (21:33 +0100)]
core: add version and structure to LUO json payload
We might want to add more state to the LUO session json payload,
so add a version (to allow clean compat breaks if needed) and nest
the current fdstore contents under a 'units' object, so that more
top-level data can be added in the future without breaking
backward compatibility.
Luca Boccassi [Mon, 15 Jun 2026 20:34:56 +0000 (21:34 +0100)]
core: only attempt to deserialize state from LUO on boot
Avoid trying to query for our LUO session on reexec/softreboot/reload/etc.
Currently /dev/liveupdate is only accessible to root so it's not a big
issue, but this might change in the future, so make sure nobody can
play games with us.
Luca Boccassi [Thu, 4 Jun 2026 19:20:51 +0000 (20:20 +0100)]
obs: prepare ParticleOS images in workflow
Link ParticleOS images in the workflow subproject for the PR,
so that they can be enabled with a click when needed.
But keep disabled by default, as they take a lot of resources,
especially disk space.
dongshengyuan [Tue, 16 Jun 2026 01:07:25 +0000 (09:07 +0800)]
gpt-auto-generator: fix error propagation in add_root_mount()
When generator_write_initrd_root_device_deps() fails, the error was
swallowed by returning 0 (success) instead of r. The two subsequent
calls in the same block correctly return r on failure.
Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com> Co-developed-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
dongshengyuan [Tue, 16 Jun 2026 02:38:17 +0000 (10:38 +0800)]
mount: log control command before clearing it in mount_sigchld_event()
control_command and control_command_id were cleared before being passed
to unit_log_process_exit(), so the log always showed an invalid/unknown
command name.
Move both clears after the log call, matching the ordering in
socket_sigchld_event() and service_sigchld_event().
Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com> Co-developed-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Daan De Meyer [Mon, 15 Jun 2026 09:06:42 +0000 (09:06 +0000)]
loop-util: shortcut block device fd when it carries no partition table
663f0bf5cb stopped reusing the original block device fd whenever
partition scanning was requested (LO_FLAGS_PARTSCAN) but couldn't be
enabled on the device, so that nested partition tables on devices the
kernel won't scan (e.g. the pmOS/android case) get exposed via a real
loop device.
However that also forced a pointless loop device for any partition that
carries a file system directly, e.g. a btrfs subvolume mounted via
MountImages=. For multi-device btrfs this is fatal: the kernel rejects
seeing the same member via both the original partition and the loop
device, and the mount fails.
A loop device is only ever needed here to expose a nested partition
table. So only refuse the shortcut when the device actually carries one,
probed via gpt_probe(), instead of whenever partition scanning is
disabled. Devices carrying a file system directly (or nothing) take the
shortcut as before.
Add an integration test to cover the failure scenario of the original
issue.
Fixes: https://github.com/systemd/systemd/issues/42520
Replaces: https://github.com/systemd/systemd/pull/42576
Follow-up for 663f0bf5cb79ecaf6dd71441ecdc9dc401e7eae6
Co-Authored-By: Luca Boccassi <luca.boccassi@gmail.com> Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>
Luca Boccassi [Mon, 15 Jun 2026 21:05:18 +0000 (22:05 +0100)]
report: place Upload() on io.systemd.Report.Uploader rather than io.systemd.Report interface (#42584)
We really want to use io.systemd.Report for the interface provided by
systemd-report itself, not by its backend. hence, rename the interface
that uploading plugins shall implement to io.systemd.Report.Uploader.
Note that we ideally should have a varlink interface definition for that
interface. if we had, we'd have noticed that earlier.
let's name the dir "/run/systemd/report.upload/" (rather than
"/run/systemd/metrics-upload/"). After all, these are reports that we
upload, not indiviudual metrics. And it would be particular confusing
since the dir to pick up metrics is called /run/systemd/report/, rather
than /run/systemd/metrics/. Hence the thing that deals with reports is
nmamed metrics, and the thing that deals in metrics is named reports...
report: place Upload() on io.systemd.Report.Uploader rather than io.systemd.Report interface
We really want to use io.systemd.Report for the interface
provided by systemd-report itself, not by its backend. hence, rename the
interface that uploading plugins shall implement to
io.systemd.Report.Uploader.
Note that we ideally should have a varlink interface definition for that
interface. if we had, we'd have noticed that earlier.
Daan De Meyer [Mon, 15 Jun 2026 07:55:22 +0000 (07:55 +0000)]
udev: only trigger the boot-disk loop device for optical drives
probe_gpt_boot_disk_needs_loop() sets ID_PART_GPT_AUTO_ROOT_DISK_NEEDS_LOOP
for any whole disk that holds the boot ESP/XBOOTLDR but whose partition table
the kernel cannot parse. Until now the udev rule turned that into a
systemd-loop@.service for every block device.
That is too broad: device-mapper devices also report kernel partition
scanning as disabled, but their partitions are managed in userspace by kpartx
(see 66-kpartx.rules). Setting up a loop device on top of them re-exposes the
same partition table a second time and only causes trouble.
Restrict the rule to optical drives, the one class that genuinely needs a
kernel-side loop device (El Torito GPT sector size mismatch, or drives that do
not support partition scanning) and that has no userspace partition manager of
its own.
Co-developed-by: Claude Fable 5 <noreply@anthropic.com>
Daan De Meyer [Mon, 15 Jun 2026 07:45:46 +0000 (07:45 +0000)]
udev-builtin-blkid: keep probing the boot disk when it needs a loop device
Since 4e0eabd40118 ("udev: also trigger loop device for boot disk when
partition scanning is unsupported"), builtin_blkid() bails out entirely as
soon as probe_gpt_boot_disk_needs_loop() reports that a loop device is
needed, skipping all superblock probing. As a result whole-disk properties
such as ID_PART_TABLE_UUID and ID_FS_* are no longer set.
This regresses any whole disk whose partitions the kernel cannot expose
itself but which is otherwise perfectly probeable, most notably
device-mapper multipath disks: kernel partition scanning is disabled on them
(their partitions are managed in userspace by kpartx), so they are now
flagged as needing a loop device and lose their ID_PART_TABLE_UUID.
The early return was never necessary. The original intent was only to skip
root partition discovery on the device, and that already happens on the loop
device instead: find_gpt_root() bails when the kernel can't scan partitions,
blkid probes at the device's own logical sector size so a GPT written for a
different sector size is simply not detected, and PART_ENTRY_* is only
emitted for partitions the kernel actually registered, of which a
loop-needing whole disk has none. So keep probing the device for its
whole-disk properties unconditionally and let partition and root discovery
happen on the loop device.
Co-developed-by: Claude Fable 5 <noreply@anthropic.com>
dongshengyuan [Mon, 15 Jun 2026 08:28:02 +0000 (16:28 +0800)]
portable: fix double-free in normalize_portable_changes()
Now that the fast path performs a deep copy identical to the general
loop (when n_changes_attached==0, found stays false for all entries),
the block is redundant. Remove it and let the general loop handle this
case.
Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com> Co-developed-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
dongshengyuan [Mon, 15 Jun 2026 07:43:51 +0000 (15:43 +0800)]
random-seed: fix wrong error variable in log_error_errno()
At line 285, ftruncate() failure was logged using 'r' which is 0
from the preceding successful loop_write() call. log_error_errno(0, ...)
triggers an assertion crash in developer builds (ASSERT_NON_ZERO) and
silently returns success in release builds, swallowing the ftruncate error.
Replace with errno which is set by ftruncate() on failure.
Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com> Co-developed-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Yu Watanabe [Mon, 15 Jun 2026 04:03:00 +0000 (13:03 +0900)]
musl: fix build on 32-bit architecture
```
../src/boot/test-efi-string.c: In function 'test_xvasprintf_status':
../src/boot/test-efi-string.c:744:34: error: format '%zi' expects argument of type 'signed size_t', but argument 4 has type 'long int' [-Werror=format=]
744 | test_printf_one("%i %i %zi", INT_MIN, INT_MAX, SSIZE_MAX);
| ~~^
| |
| int
| %li
cc1: some warnings being treated as errors
ninja: subcommand failed
```
Valentin David [Sun, 7 Jun 2026 10:46:09 +0000 (12:46 +0200)]
repart: Rescan after writing partition table on factory reset
If a partition gets removed due to factory reset, we will recreate it
as blkpg later. So it needs to get removed. So rescan is needed to be
done after we write the partition table for factory reset.
Luca Boccassi [Thu, 11 Jun 2026 15:55:45 +0000 (16:55 +0100)]
core: clear pending_reload_message_vl on manager varlink teardown
manager_varlink_done() tore down the varlink server without dropping the
queued reload reply, unlike bus_done_api() which unrefs
pending_reload_message_dbus. Unref it here too, so the slot consistently
mirrors the D-Bus side at teardown.
Yu Watanabe [Thu, 11 Jun 2026 02:02:40 +0000 (11:02 +0900)]
network: ignore stale interface renames
After enumeration, networkd may receive RTM_NEWLINK messages carrying a
stale interface name. This can happen when interface rename notifications
are queued before link enumeration and processed afterwards.
Previously, networkd could become confused by such a message and put the
corresponding Link into the failed state. Avoid this by checking whether
the new interface name is already in use by another interface and ignoring
the rename if so.
Yu Watanabe [Thu, 11 Jun 2026 02:06:09 +0000 (11:06 +0900)]
network: use hashmap_remove_value() on updating mapping for Link objects
E.g. on issue #20203, we may wrongly remove entry for another interface.
Let's mitigate issue on such situation for safety, though this does not
solve the issue.
The check introduced by the commit is racy, as when format_ifname() is
called, the interface may be already renamed (again) to another name.
This is typically problematic when we swap interface names:
```
ip link set aaa name tmpname
ip link set bbb name aaa
ip link set tmpname bbb
```
When networkd received the notification about name change aaa -> tmpname,
the interface is already renamed from tmpname to bbb. So, the reverted
logic skips updating Link.ifname:
```
aaa: New interface name 'tmpname' received from the kernel does not correspond with the name currently configured on the actual interface 'bbb'. Ignoring.
```
On the second notification about name change bbb -> aaa, networkd fails to
update the mapping Manager.links_by_name, as we skipped previous renaming
and the mapping still has an outdated entry for 'aaa'.
```
bbb: Interface name change detected, renamed to aaa.
aaa: Failed to manage link by its new name: File exists
aaa: Could not process link message: File exists
aaa: Failed
aaa: State changed: configured -> failed
```
By reverting the commit, the issue is fixed. But the commit intended to
fix another issue #20203. So this reintroduces #20203. Let's fix it
in a later commit.
dongshengyuan [Fri, 12 Jun 2026 05:41:33 +0000 (13:41 +0800)]
journal: fix byte-order conversion in journal_file_append_data()
head_data_offset is declared as le64_t in journal-def.h, so it must be
assigned with htole64(p), not le64toh(p). All other le64_t field
assignments in this file (hash, next_hash_offset) consistently use
htole64().
On little-endian systems this makes no difference, but on big-endian
systems the field->data link would be stored with incorrect byte order,
corrupting journal file traversal.
Ivan Kruglov [Wed, 10 Jun 2026 15:12:50 +0000 (08:12 -0700)]
pcrextend: skip measurement gracefully when the TPM can't be used
So far --graceful only short-circuited when no TPM was present at all (the
!tpm2_is_mostly_supported() check). If a TPM is present but can't actually be
used for the measurement we want, the measurement still failed hard. For
systemd-pcrextend instances ordered before sysinit.target this pushes the
system to degraded and blocks boot, which defeats the purpose of --graceful.
Make the two extend helpers report every "TPM is present-or-absent but cannot
be used for this measurement" condition with a single errno, -EOPNOTSUPP: no
usable PCR bank, no TPM device, missing crypto (e.g. AES-128-CFB), no NvPCR
support, and OpenSSL-less builds. tpm2_context_new_or_warn() reports a missing
device as -ENOENT, so each helper translates that to -EOPNOTSUPP at the call
site, keeping every errno single-meaning.
Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>
Luke Na [Fri, 12 Jun 2026 09:22:22 +0000 (09:22 +0000)]
po: Translated using Weblate (Chinese (Simplified) (zh_CN))
Currently translated at 100.0% (285 of 285 strings)
Co-authored-by: Luke Na <narukeu@outlook.com>
Translate-URL: https://translate.fedoraproject.org/projects/systemd/main/zh_CN/
Translation: systemd/main
Luke Na [Fri, 12 Jun 2026 07:36:36 +0000 (07:36 +0000)]
po: Translated using Weblate (Chinese (Simplified) (zh_CN))
Currently translated at 100.0% (285 of 285 strings)
Co-authored-by: Luke Na <narukeu@outlook.com>
Translate-URL: https://translate.fedoraproject.org/projects/systemd/main/zh_CN/
Translation: systemd/main
Nick Rosbrook [Sun, 10 May 2026 14:49:36 +0000 (10:49 -0400)]
test: fix check for updatectl
The have_updatectl variable is meant to gracefully handle the case where
updatectl is missing. But, because the script runs with -e, it fails
immediately in that case instead. Moreover, expanding $have_updatectl
when it is present actually executes updatectl, rather than simply
checking for its existence.
Re-factor this check so that it does handle a missing updatectl.
Yu Watanabe [Thu, 11 Jun 2026 01:18:33 +0000 (10:18 +0900)]
sd-netlink: fix use-after-free
When a slot is disconnected, previously we tried to remove the slot from
the hashmap with a wrong key. Hence, the pointer to the freed slot object
remained in the hashmap.
Luca Boccassi [Wed, 10 Jun 2026 13:17:11 +0000 (14:17 +0100)]
sd-varlink: disable event source in varlink_server_socket_free()
The cleanup destructor for VarlinkServerSocket only freed ss->address and
the struct, leaking ss->event_source. If sd_varlink_server_listen_address()
hits OOM at free_and_strdup() after the io-source was already armed, the
source stays registered in the event loop with userdata pointing at the
freed socket. Disable it before freeing; the call is a no-op when the
source was never armed, so the other freep sites are unaffected.
Luca Boccassi [Wed, 10 Jun 2026 15:17:02 +0000 (16:17 +0100)]
bus-map-properties: reject wrong variant type
bus_message_map_all_properties() fed the peer-supplied wire signature straight
into the variant dispatch and never compared it against the declared
prop->signature, so map_basic() wrote at the wire type's native width into a
slot sized for the declared type (over-wide numeric writes, peer-controlled
pointers into char** slots later freed by strv_free()). Compare against
prop->signature and skip the variant on mismatch.
This is in practice not a problem as the servers are trusted, and this
only affects clients.
The Bearers and Ports entries in the WWAN modem property maps declared
signatures "a{sv}" and "a{su}", but the callbacks read "ao" and "a(su)".
The mismatch was harmless while the declared signature was never checked,
but becomes a dropped property once it is enforced. Declare the actual
signatures.
Luca Boccassi [Wed, 10 Jun 2026 17:56:38 +0000 (18:56 +0100)]
analyze: fix SoftRebootsCount property signature
The SoftRebootsCount entry in the boot-times map declared signature "t" but the
manager exports it as "u". The mismatch was harmless while the declared signature
was never checked, but becomes a dropped property once it is enforced. Declare "u".
Luca Boccassi [Wed, 10 Jun 2026 17:25:33 +0000 (18:25 +0100)]
analyze: fix SystemCallFilter property signature
The SystemCallFilter entry in the security info map declared signature "(as)" but
its property_read_system_call_filter callback reads a "(bas)" (the manager exports
it as "(bas)"), matching the sibling RestrictAddressFamilies entry. The mismatch was
harmless while the declared signature was never checked, but becomes a dropped
property once it is enforced. Declare "(bas)".
Luca Boccassi [Wed, 10 Jun 2026 15:53:21 +0000 (16:53 +0100)]
systemctl: fix InvocationID property signature
The InvocationID entry in status_map declared signature "s" but its bus_map_id128
callback reads an "ay" (the manager exports it as "ay"), matching the other
bus_map_id128 callers. The mismatch was harmless while the declared signature was
never checked, but becomes a dropped property once it is enforced. Declare "ay".
The log message is informational only, same as the count of killed
processes, so we can safely use cgroup.kill when available instead
of manually recursing through the cgroup tree.
Luca Boccassi [Tue, 9 Jun 2026 10:26:16 +0000 (11:26 +0100)]
Translations update from Fedora Weblate (#42525)
Translations update from [Fedora
Weblate](https://translate.fedoraproject.org) for
[systemd/main](https://translate.fedoraproject.org/projects/systemd/main/).
Paul Meyer [Sun, 7 Jun 2026 17:18:33 +0000 (19:18 +0200)]
man: fix systemd-stub .hwids section to be a singleton
Only .dtbauto and .efifw may appear more than once, .hwids is a
singleton per the UKI specification and the stub reads a single .hwids
section (per profile), matching hardware IDs against entries within it.
Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Paul Meyer <katexochen0@gmail.com>
Liu Zhangjian [Mon, 8 Jun 2026 09:00:03 +0000 (17:00 +0800)]
resolve: use correct hostname for Cloudflare DNS-over-TLS
The Cloudflare DNS-over-TLS service should use 'one.one.one.one'
as the TLS hostname, not 'cloudflare-dns.com' (which is only
correct for DNS-over-HTTPS).
This matches Cloudflare's official documentation:
https://developers.cloudflare.com/1.1.1.1/encryption/dns-over-tls/
Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
Fixes #42287
Signed-off-by: Liu Zhangjian <liuzhangjian@uniontech.com>
Icenowy Zheng [Wed, 3 Jun 2026 16:35:41 +0000 (00:35 +0800)]
boot: enable only IMAFDCZicsrZifencei for RISC-V
The UEFI specification only defines A/C/I/M/Zicsr/Zifencei as mandatory
extensions in boot services. However, on systems with everything built
with F/D support, its difficult to disable F/D without changing a
toolchain. In addition, both EDK2 and U-Boot enable F/D on boot,
although they neither enable nor disable V. EDK2 comments even claim the
enablement of FPU is "to be compliant with UEFI spec" despite the spec
requires dynamic detection before using F/D.
Add corresponding -march flags to prevent systemd-boot from using other
extensions on RISC-V, and a comment for the temporary enablement of F/D.
Yu Watanabe [Mon, 8 Jun 2026 07:45:56 +0000 (16:45 +0900)]
Translations update from Fedora Weblate (#42503)
Translations update from [Fedora
Weblate](https://translate.fedoraproject.org) for
[systemd/main](https://translate.fedoraproject.org/projects/systemd/main/).
A S Alam [Sun, 7 Jun 2026 14:06:49 +0000 (14:06 +0000)]
po: Translated using Weblate (Punjabi)
Currently translated at 32.6% (93 of 285 strings)
Co-authored-by: A S Alam <aalam@users.noreply.translate.fedoraproject.org>
Translate-URL: https://translate.fedoraproject.org/projects/systemd/main/pa/
Translation: systemd/main
Charles Lee [Sun, 7 Jun 2026 14:06:35 +0000 (14:06 +0000)]
po: Translated using Weblate (Chinese (Simplified) (zh_CN))
Currently translated at 100.0% (285 of 285 strings)
Co-authored-by: Charles Lee <lchopn@gmail.com>
Translate-URL: https://translate.fedoraproject.org/projects/systemd/main/zh_CN/
Translation: systemd/main