Commit Graph
91823 Commits
Author SHA1 Message Date
Zbigniew Jędrzejewski-Szmek 244d9bb6c4 hostnamectl: drop space in synopsis
The standard spelling for args that can repeat is without the space.
2026-09-23 21:55:37 +02:00
Yu Watanabe fd1f164b1b mkosi: drop unnecessary packages
This partially reverts 77b3ddf2aa.

Testing with musl is now done by postmarketOS. Hence, these packages
are not necessary anymore.
2026-09-23 16:47:25 +02:00
Lennart Poettering 186a8486fc report: add backend for reporting temperature sensors 2026-09-23 16:31:41 +02:00
Armaan Sandhu 31bf94f87d siphash24: force inlining of the round
gcc does not inline sipround() at -O2: its size estimate lands just over
the default max-inline-insns-auto budget, so nm on libsystemd-shared.so
shows a local sipround symbol and each of the ten call sites pays a
call/ret plus a reload and store of the state through the pointer, around
six rounds of ~14 ALU ops. clang inlines it on its own, and gcc does too
at -O3 or with --param max-inline-insns-auto=30, so this is not a missed
optimization to report upstream but the inliner's size heuristic doing
what it is designed to do. The documented way to overrule it for one
function is always_inline.

The SipHash reference implementation this file is derived from inlines
the round manually, by writing it as a SIPROUND macro.

AMD Ryzen AI 7 350, gcc 16.2.1, -O2 -fstack-protector-strong
-fno-strict-aliasing, median of five runs:

    input     before      after     speedup
      8 B    61.3 ns     9.3 ns       6.63x
     16 B    54.6 ns    10.7 ns       5.11x
     24 B    50.0 ns    12.6 ns       3.98x
     40 B    49.4 ns    16.4 ns       3.01x
     64 B    53.2 ns    22.1 ns       2.41x
    128 B    67.8 ns    36.9 ns       1.84x
    512 B   157.7 ns   128.1 ns       1.23x
   4096 B   992.5 ns   964.5 ns       1.03x

The win is concentrated on short inputs because the bulk loop in
siphash24_compress() was the one place gcc did inline the round; the
prologue, the tail and all six rounds of siphash24_finalize() were not.
Short inputs are also what we overwhelmingly hash: hashmap and set keys,
unit names, paths, journal field names and data objects, bus match
strings. clang is unaffected.

Resulting hash values are unchanged; verified identical over every input
length from 0 to 128 bytes, and test-siphash24, test-hash-funcs,
test-hashmap and test-set pass.
2026-09-23 16:30:50 +02:00
Chris Coulson efe5e4d271 report: Add the session audit digest algorithm to the TPM2 signature
When generating a session audit digest, the algorithm isn't included in
the attestation. The algorithm is the auth digest algorithm that the TPM
session is created with, which is currently hardcoded as SHA-256.

This might not always be the case though, and verifiers shouldn't have
to guess what the digest algorithm is, so include the algorithm in the
report signature component.
2026-09-23 16:30:17 +02:00
theogeff e8142670aa report: add reportID field to reports
This uses a random high-entropy ID for reports, making it useful
when hashing the report for passing it to the Time Stamping
Authority. Reports are therefore guaranteed to be distinct from
one another.
2026-09-23 16:28:58 +02:00
Luca Boccassi 3f9d31fdc0 cryptenroll-varlink: Allow to display recovery-key before enrolling (#43687)
Closes https://github.com/systemd/systemd/issues/43676
2026-09-23 16:28:19 +02:00
Luca Boccassi d8cea1b942 sysinstall: optionally, pick target block device automatically (#43582) 2026-09-23 16:27:01 +02:00
Christian Hesse 327061908a mkosi: update arch commit reference to 4749b653ee7b9210bcd46fe43065508aa58b779a 2026-09-23 14:52:39 +02:00
Yu Watanabe 83cc7f7ea8 in-addr-util: several cleanups (#43656) 2026-09-23 19:23:00 +09:00
Yu Watanabe 2727a7fad4 network: drop pending requests (#43741)
Fixes #39460.
2026-09-23 19:21:10 +09:00
Lennart Poettering 641da198fd update TODO 2026-09-23 10:14:25 +02:00
Lennart Poettering 236e7d8a4c ci: testcase for new auto-pick mode of sysinstall 2026-09-23 10:14:25 +02:00
Lennart Poettering 0bb2f138f4 sysinstall: correct end marker log message
Copypasta...
2026-09-23 10:14:25 +02:00
Lennart Poettering 9b7f2c64b1 sysinstall: send out READY=1 when we start our thing
This is useful so that whoever invokes the tool knows that the general
parameters checked out, and the tool now proceeds with actually doing
the work.
2026-09-23 10:14:25 +02:00
Lennart Poettering ce8d684ed8 sysinstall: optionally, automatically pick target block device after a settle timeout
Let's make sysinstall useful for truly unattended installations, and let
it it automatically pick a target disk after some settlement time-out.
2026-09-23 10:14:25 +02:00
Lennart Poettering 647fa40327 blockdev-list: add blockdev_list_full() which allows passing in a pre-determined pair of root_devno/whole_root_devno 2026-09-23 10:08:36 +02:00
Lennart Poettering 48a9afb6ec blockdev-list: split BLOCKDEV_LIST_IGNORE_LOOP out of BLOCKDEV_LIST_IGNORE_VIRTUAL
So far BLOCKDEV_LIST_IGNORE_VIRTUAL filtered out everything below
/sys/devices/virtual/, which includes loopback devices. Loopback devices
are frequently used as stand-ins for real disks though (in tests, and
when installing to disk images), hence it's useful to be able to control
them independently of the other virtual devices (dm, md, zram, …).

Introduce a separate BLOCKDEV_LIST_IGNORE_LOOP flag for loopback
devices, and make BLOCKDEV_LIST_IGNORE_VIRTUAL only cover the non-loop
virtual devices. The only existing user (systemd-report) is updated to
pass both flags, so that its behaviour stays unchanged.
2026-09-23 10:08:36 +02:00
Julian Sparber 4b259b5630 test: cryptenroll-varlink: Add tests for handing in a recovery key
This adds two new tests to test the validation of the recovery key
passed to `Enroll()` and the generation of a recovery key by `MakeRecoveryKey()`.
2026-09-23 09:30:28 +02:00
Julian Sparber 9569d72182 cryptenroll-varlink: Add method to generate a recovery-key
We want users to use a recovery-key generated by systemd. Therefore
expose a method that let's clients generate a key that can be given to
the Enroll method. This way the key can be displayed before enrolling
it.
2026-09-23 09:30:28 +02:00
Julian Sparber c753849fd6 cryptenroll-varlink: Allow handing in a recovery key
In some cases we want users to copy the recovery key to a save location
before we enroll it, therefore allow clients to hand in a recovery key.
The next commit will add a varlink method to generate the recovery key.

Closes: https://github.com/systemd/systemd/issues/43676
2026-09-23 09:30:28 +02:00
Luca Boccassi 1c168322cf Improve error report when PCR changes (#43579)
When PCR is extended during a TPM2 operation, the internal counter of
the TPM2 will detect a new extension. systemd already retry this
operation several times, but sometimes the report will be an error, and
will refer to the wrong PCR.

This situation happends when IMA is enabled (when secure boot is active,
for example). PCR 10 will receive an extension for each new kernel
module that is loaded, logging in the journal errors that are recovered
later after a subsequent retry.
2026-09-23 09:28:35 +02:00
Daan De Meyer 0167e36e74 sd-future: rework cancellation, add slot callbacks and future groups
We replace the implicit single callback and wait-future indirection with
the usual slot design so independent fibers and future groups can track
the same future. We also opt to always have callbacks dispatch asynchronously,
including when they are registered after the future has already resolved.

We now require futures to be resolved before their final unref rather than
cancelling them implicitly. The idea is to catch bugs rather than leak futures.
A future should always be cancelled and awaited before it is cleaned up,
otherwise resources might leak if the stack is not unwound properly. We make
exceptions for futures that haven't started executing yet as there's no risk
of leaking resources there since there's no stack to unwind.

One issue with awaiting futures is that sd_fiber_await() returned both
errors and the future's result via the function's return value, meaning it
was impossible to distinguish future failures from interrupted waits (or
waits that failed for whatever other reason). This is generally not an issue
except in the cleanup functions, where we have to retry on interrupted waits
(the best example is a parent fiber waiting for a future being cancelled
itself, which should cancel the future it's waiting for and retry the wait).
So we introduce fiber_wait() which distinguishes between both values via
return value and output argument so the two can be distinguished from each
other.

Cleanup always consumes the caller's reference, including on invalid self or
cross-loop waits. The existing assertion still forbids dropping the last
reference to an unresolved future. The installed header documents this rule.

We introduce a new RUNNING fiber state to distinguish executing fibers from
non-executing fibers. We replace CANCELLED with queued resume results and
preserve interruptions across ordinary wakeups.

We add future groups with wait-all, wait-any and ignore-errors policies to
wait for multiple futures at once and migrate various existing call sites over
to them. Group size is a direct size_t query, treating NULL as an empty group.
Document all four policy combinations, including that IGNORE_ERRORS suppresses
fail-fast and parent cancellation without discarding the group's error result.

We also add defer futures and migrate bus, varlink, QMP and fiber I/O callers to
use them. Bus and QMP futures report -ENOPKG when no event loop is attached,
rather than passing NULL to sd_future_new() and returning -EINVAL.

Parent-await suppression is derived from the active wait's callback slot, so
groups use sd_fiber_await() without a separate await API or additional state.
Waits, group children and captured parents must use the same event loop.
Groups created on another loop have no parent, and a group releases its
parent reference when that fiber finishes.

Resolve SD_EVENT_DEFAULT in sd_future_new() so futures retain the actual
loop. Match group parents against that resolved loop as well; an unavailable
default returns -ENOPKG without creating an event loop implicitly.

Keep the public await entry point in fiber.c, sharing the slot-based wait with
cancellation cleanup through future-internal.h. Keep event/future integration
in event-future.c/h: priority inheritance uses the public fiber accessor, and
sd_future_new_defer() lives alongside the other event-backed constructors.
This avoids sd-event depending on sd-future private headers and removes the
redundant private defer wrapper.

Assert the non-failing slot-disabling and active-loop invariants instead of
returning early without completing callback dispatch.

Regression tests cover group error propagation and NULL-safe size queries,
interrupted waits, partial add-many rollback, groups outliving their parent,
and cancellation or timeout during nested event-loop waits, including
event-loop and descriptor cleanup. They also cover cross-loop parent isolation,
reference release on invalid cleanup calls, mixed WAIT_ANY outcomes, failed
child cancellation and policy changes on resolved groups. Additional tests
verify failed group-priority updates, slot priority during dispatch and exit,
and cancellation, timeout and spurious wakeups during bus and QMP calls. Late
replies must leave subsequent calls unaffected. Default-event tests cover
missing-loop errors, reference lifetime and parent capture by constructors.
Unattached bus and QMP clients are covered by missing-event-loop regressions.
Constructor tests verify inherited and default priorities for I/O, defer and
timer futures, plus defer argument validation and missing-default errors.

Signed-off-by: Daan De Meyer <daan@amutable.com>
2026-09-23 09:09:08 +02:00
Yu Watanabe de9ea9ea5d resolve: several cleanups for managing objects (#43629) 2026-09-23 15:54:02 +09:00
Heran Yang 2aed6d9ad7 network: find pending address in IPv4 ACD callback
When IPv4 ACD is enabled for a DHCPv4 address, the address remains in
the request queue until ACD succeeds. Hence, when ACD detects a
conflict, the address may not be present in link->addresses yet.

on_acd() currently looks up the address with address_get(), which only
searches link->addresses. This makes the callback return early and
prevents dhcp4_address_on_conflict() from sending DHCPDECLINE.

Use address_get_harder(), which also looks up pending address requests.

Fixes #39460
2026-09-23 14:35:58 +09:00
Yu Watanabe 830b60ae1f network: drop pending requests when a DHCP lease is lost or a client is stopped
When a DHCP lease is lost or a client is stopped, there may exist
requests not processed yet. We need to cancel them, otherwise an
address or route requested by the lost lease may be configured later.
2026-09-23 14:35:47 +09:00
Yu Watanabe 8698ce03d2 firewall-util: drop unnecessary restriction for the source address
Then, set assertions for the source address, as we already set non-NULL.
2026-09-23 13:53:23 +09:00
Yu Watanabe 5594d06b56 firewall-util: unify nft_message_append_setelem_iprange() and _ip6range() 2026-09-23 13:53:23 +09:00
Yu Watanabe 4ad65ce2f3 in-addr-util: drop unused in_addr_prefix_nth() 2026-09-23 13:53:23 +09:00
Yu Watanabe be21269a68 in-addr-util: reimplement in_addr_prefix_range()
Currently, in_addr_prefix_range() is the only user of in_addr_prefix_nth(),
and it is too generic and complicated.
Previously, in_addr_prefix_range() calls in_addr_prefix_nth() with 0 and 1.
The function in_addr_prefix_nth(0) is equivalent to in_addr_mask(), and
in_addr_prefix_nth(1) is equivalent to just increment the masked value
with 1.
So, let's reimplement the code without using in_addr_prefix_nth().
2026-09-23 13:53:23 +09:00
Yu Watanabe b4d5d083fd in-addr-util: drop unused in_addr_prefix_next() 2026-09-23 13:53:23 +09:00
Yu Watanabe 8dea243077 journalctl: make the read path 1.7x to 2.5x faster (#43663)
Three independent fixes to code on `journalctl`'s per-entry read and
output path. Each of them removes work that was never needed, rather
than trading away anything. There is no behaviour change: the output is
byte for byte identical for every format except `-o json`, where only
the order of the keys within each object can shift, which is already
nondeterministic between two runs of the unpatched binary (see the
correctness section below). Nothing about the formats, tunables or
public API changes.

Measured on a 730 MB journal spread over 100 files (roughly 2M entries):

| command | before | after | |
|---|---:|---:|---:|
| `journalctl -o cat` | 1.93s | 0.77s | **2.51x** |
| `journalctl --grep=<no match>` | 1.97s | 0.82s | **2.40x** |
| `journalctl -o export` | 4.06s | 1.73s | **2.35x** |
| `journalctl -n 100000 -o short` | 0.86s | 0.43s | **2.00x** |
| `journalctl -o json -n 200000` | 5.85s | 3.50s | 1.67x |
| `journalctl -o short` (the default) | 3.32s | 1.96s | **1.69x** |
| `journalctl -o verbose` | 5.99s | 3.61s | 1.66x |

### 1. `utf8_is_printable_newline()` decoded every character twice

`utf8_encoded_valid_unichar()` decodes the character internally in order
to validate it, and then throws the codepoint away. The caller
immediately called `utf8_encoded_to_unichar()` again to get the very
same codepoint back. So for every byte of every field printed, the UTF-8
decoder ran twice, only to answer whether the byte was a control
character.

This is fixed where it originates rather than at the call site:
`utf8_encoded_valid_unichar_full()` optionally returns the character it
had to decode anyway, so a caller that wants both the validity and the
value decodes once. On top of that, eight bytes are tested at once for
plain printable ASCII, which is what almost all journal content is. A
word that does not qualify falls through to the per character path
unchanged, so tabs, newlines and multibyte sequences behave exactly as
before.

On its own, against unmodified main: `-o export` 4.02s to 2.89s.

### 2. sd-journal read the clock once per journal file, per entry

`sd_journal_next()` sweeps every open journal file to find the next
entry, and `next_beyond_location()` rate limits its tail timestamp
refresh per file. Since `ratelimit_below()` reads the clock itself, a
journal spread over a hundred files meant a hundred `clock_gettime()`
calls for every single entry iterated, nearly all of them only to
conclude that the one second interval had not elapsed yet.

This was the single largest cost in `journalctl`. In a profile of `-o
export` it was over a fifth of the entire run, spent deciding not to do
the thing it was guarding.

Add `ratelimit_below_at()`, which takes the timestamp from the caller,
and read the clock once per sweep instead. `ratelimit_below()` keeps its
behaviour and becomes a wrapper.

The timestamp is now sampled once per sweep rather than once per file.
The interval being rate limited is one second and a sweep takes
microseconds, so this makes no practical difference.

On its own: `-o export` 4.02s to 2.93s, and `-o short` 3.30s to 2.14s.
This is the largest single contributor for the default output mode.

### 3. The JSON output built a fresh, unsized hashmap for every entry

`journal_entry_to_json()` creates an empty hashmap per entry and fills
it with that entry's fields, of which there are typically around twenty.
Because it starts empty it has to grow several times per entry, and
every growth rehashes everything inserted so far. `-o json` spent about
a quarter of its time in siphash, a third of that under
`resize_buckets()`.

Reserving room up front is a one line change.

On its own: `-o json -n 200000` 5.71s to 4.64s.
2026-09-23 13:52:44 +09:00
Yu Watanabe 1947733d74 nftables: allow to remove nftables table, rule, set, and so on (#43673)
This adds 'add' boolean parameter to sd_nfnl_nft_message_new_table() and
friends, so that we can remove nftables table and so on. In
test-firewall-util, before and after running test cases, remove the
garbage nftables test table.
2026-09-23 13:50:04 +09:00
Yu Watanabe c5bf6bac23 network: disable IPv4ACD when the address request is cancelled
If an address with IPv4ACD is requested, then sd_ipv4acd instance for
the address is configured. If the request is cancelled, we should
also disable the IPv4ACD instance.

Note, if the address is already configured, the IPv4ACD instance for the
address will be removed when the address is removed. See address_drop().
2026-09-23 13:39:40 +09:00
Yu Watanabe 4be31a9c35 network: add a configuration-source filter to link_drop_requests()
Preparation for later changes.
2026-09-23 13:39:40 +09:00
Yu Watanabe f30c9ea09c tar-util: several cleanups for ACL tag handling (#43684)
Prompted by 6df59b0753.
2026-09-23 12:52:20 +09:00
Yu Watanabe 724d18a22a analyze: introduce cpu-features command
This may be useful when configuring the ConditionCPUFeature= setting.
2026-09-23 12:51:26 +09:00
Yu Watanabe a4e4ced188 resolve: use custom hash_ops for managing Link objects 2026-09-23 11:38:15 +09:00
Yu Watanabe 7a19ecb825 resolve: several trivial cleanups for dnssd
- make several functions static,
- add serveral missing assertions,
- several coding style cleanups.
2026-09-23 11:38:15 +09:00
Yu Watanabe e677674522 resolve: use custom hash_ops for Manager.dnssd_registered_services 2026-09-23 11:38:15 +09:00
Yu Watanabe 3959ccbd32 resolve: drop unused argument t from mdns_service_update() 2026-09-23 11:38:15 +09:00
Yu Watanabe 923146d951 resolve: make several functions static 2026-09-23 11:38:15 +09:00
Yu Watanabe 02f65ebead resolve: stop timer event source and detach from browser when a dnssd service is removed
Otherwise, if the timer event source is enabled, a new query may be
invoked by the already removed service.

This also renames dns_remove_service() to dnssd_discovered_service_detach(),
and drops unused DnssdDiscoveredService.query.
2026-09-23 11:38:14 +09:00
Yu Watanabe 219abd95ae resolve: detach DnsServiceBrowser object from Manager when freed or disconnected
When a DnsServiceBrowser object is detached from the manager,
all queries, event sources, and then the reference to Manager should be
dropped. Otherwise, spurious query may be triggered for already
disconnected varlink.
2026-09-23 11:38:14 +09:00
Birk Skyum ef3e0ff7bb shutdown: preserve console graphics mode across the exitrd handoff
make_console_stdio() forces KD_TEXT while reopening /dev/console. When
systemd-shutdown enters the exitrd, this can expose the text console over
a retained graphical shutdown splash.

Let callers choose whether to switch to text mode, and preserve the mode
for the exitrd handoff. Keep the existing text-mode behavior for manager
reexecution and the crash shell. Restore text mode if executing /shutdown
fails and before reporting a fatal error and freezing.

Add an unsafe, nonparallel virtual-console regression test requiring
explicit opt-in and an already-owned inactive VT in a disposable VM.
Check graphics preservation and text restoration through a private
/dev/console bind mount, retain stderr diagnostics, and restore the saved
mode in the parent even if the child fails.
2026-09-23 11:36:55 +09:00
Yu Watanabe 137ce9b975 resolved: split oversized mDNS announcements across MTU-sized packets (#43667)
Split out of https://github.com/systemd/systemd/pull/42983

## Problem
`dns_scope_announce()` put the entire zone into a single reply packet —
for DNS-SD that is every PTR/SRV/TXT record of every published service.
With a few hundred services that grows far past the interface MTU, and
past what RFC 6762 section 17 allows: a Multicast DNS packet larger than
the MTU is sent using fragments, and such a packet "MUST NOT contain
more than one resource record".

## Fix
Pack an announcement into as many MTU-sized packets as needed. A record
that does not fit the MTU on its own is emitted alone in an oversized
packet relying on IP fragmentation — the case section 17 explicitly
allows — bounded by its hard 9000-byte ceiling including headers, which
also caps jumbo-frame links.

Without a usable interface MTU (no link on the scope, or `IFLA_MTU` not
read yet) packets are cut to the largest datagram a host of the family
must accept unfragmented — RFC 791's 576 bytes for IPv4, RFC 8200
section 5's 1280-byte minimum link MTU for IPv6 — rather than to that
ceiling, so an announcement is never fragmented merely because the MTU
was not known yet, and the lone-oversized-record path stays reachable.

A record that cannot be encoded at any size (an rdata past 64KiB, a
character string past 255 bytes) is skipped like one too large for the
ceiling rather than failing the whole announcement:
`dns_packet_append_rr()` rolls the packet back on every failure, so its
neighbours are unaffected either way.

The packing lives in `resolved-mdns.c` as
`mdns_announcement_packetize()`, taking an answer and the two size
bounds and returning finalized packets, so it is testable without a
scope, a link or a socket. Emission is best effort per packet — a failed
send no longer withholds the rest — and each pass logs the packet and
record counts it actually put on the wire.
2026-09-23 11:36:09 +09:00
Yu Watanabe 6f58da1791 test-firewall-util: clear test tables in intro() and outro()
Otherwise, the test may fail when there is a garbage in the nftables.
2026-09-23 09:15:58 +09:00
Yu Watanabe 0ba6d54ef7 firewall-util: introduce fw_nftables_del_table() 2026-09-23 09:15:58 +09:00
Yu Watanabe 534a25c885 sd-netlink: add boolean 'add' parameter to sd_nfnl_nft_message_new_table() and friends
Previously, only sd_nfnl_nft_message_new_setelems() takes the 'add'
flag. Let's all functions take the boolean parameter for consistency.
2026-09-23 09:15:58 +09:00
Yu Watanabe d47f1599b8 sd-netlink: add missing assertions 2026-09-23 09:15:58 +09:00