Commit Graph
7412 Commits
Author SHA1 Message Date
Zbigniew Jędrzejewski-Szmek cca9a12e5c core,shared: support the ConfigurationDirectory= flags field over D-Bus (#43633) 2026-10-19 10:13:46 +02:00
Lennart Poettering d7024404a0 sysupdate: allow feature, transfer, component definitions to be provided by a varlink backend in addition to files (#43657)
In some cases it might make sense to provide
features/transfers/components in a more dynamic fashion. Let's add a
concept of "sysupdate provider" backends, that can provide such
definitions at runtime.

Fixes: #33351 
Fixes: #30695
2026-10-19 09:44:00 +02:00
Yu Watanabe cb070c87eb storage-fs: Support for "dir" volumes in the user service (#44271)
This utilizes the `mkdir_foreign_at` helper function to create
foreign-owned directories. I extended it to `mkdir_foreign_at_full` to
allow for creating btrfs subvolumes too (thanks for merging #43869 to
enable this).

When a read-only directory is requested, the system instance can create
a read-only mount and return a file descriptor to that.
The unprivileged user instance can't do that, so it just returns the
directory file descriptor. An alternative would be to not allow for
read-only requests, but its not like we're consulting polkit for user
session requests.
2026-10-19 14:20:15 +09:00
Yu Watanabe ba73e2469b coredumpctl: introduce new option -l/--full 2026-10-19 08:29:15 +09:00
Yu Watanabe 7f4df15d19 Recommend namespacing for tags and adjust deduplication rules (#43728) 2026-10-19 07:51:15 +09:00
Skye Soss 57d059ccec storage-fs: support directory volumes in user mode
Use mkdir_foreign_at_full() to create directory volumes from the user
instance. Unlike the system instance, read-only directories can't be
enforced by the storage instance, but are still supported.
2026-10-18 09:05:16 -05:00
Zbigniew Jędrzejewski-Szmek 2b395f0df4 hostname-util: let the last specified value win when parsing machine tags
When duplicates were present, the existing code picked the
lexicographically earliest entry. This is strange, no other code
that combines list in systemd behaves in this way. This really looks
like an accident of implementation.

In graceful mode, rework the parsing to take the key=value pair that is
specified last. Also, rework the code to use a hashmap. This allows the
graceful and non-graceful paths to be unified into a single pass.
In graceful mode a conflicting tag is replaced by the entry specified
later, in strict mode refused. Every valid tag counts towards
MACHINE_TAGS_MAX.

(The O(n²) complexity in sorting of the tags wasn't great. The tag list is
bounded to 1024 items, so this wasn't _too_ bad, but the approach with the
hashmap is not much more complicated and has better computational
complexity, now the dominant part is O(n×log n) sort that happens later.)

For systemd-firstboot this means that a conflicting tag repeated in
--machine-tags= or in the firstboot.machine-tags credential is now an
error. The duplicated description of tag syntax in systemd-firstboot man
page is replaced by a reference. It was already inaccurate previously,
after not having been adjust for key=value.
2026-10-18 15:50:29 +02:00
Ivan Kruglov 7197de996d core: report unit sub-state in metrics (#44231) 2026-10-18 08:00:33 +02:00
Lennart Poettering 049c05df44 cryptenroll-varlink: Automatically determine node when not set (#44175)
If the user doesn't set the node parameter, determine the node backing
/var/. This is usefull for installers or any UI that want to operated on
the
current system.
2026-10-18 07:36:16 +02:00
Lennart Poettering 9de39b045c test: cover provider: URLs and io.systemd.ResourceProvider in TEST-72-SYSUPDATE 2026-10-17 18:02:40 +02:00
Lennart Poettering f5cb62ebe6 test: cover component providers in TEST-72-SYSUPDATE 2026-10-17 18:02:40 +02:00
Lennart Poettering 15f480fbf4 test: cover MaxVersion= on transfers and the component-level version settings 2026-10-17 18:02:40 +02:00
Lennart Poettering e95b944162 test: verify validatefs xattr enforcement when mounting DDIs
Tamper with the validatefs xattrs of the various file systems in the
test image, and check that systemd-dissect refuses to mount the image
then, unless validation is turned off via $SYSTEMD_DISSECT_VALIDATEFS=0.
Also check that a bare file system image extracted from the image is
refused as long as it carries GPT or non-root mount point constraints.
2026-10-17 17:44:29 +02:00
Ivan Kruglov 8948eb15d9 test: preserve host NSS configuration in userdbctl tests (#44247)
On openSUSE, `/etc/nsswitch.conf` may be absent, with glibc falling back
to `/usr/etc/nsswitch.conf`. The bind mount added in #44086 creates an
empty destination file on the host, blocking that fallback and causing
subsequent TEST-74-AUT-UTILS tests to fail with:

```
++ id -gn nobody
id: ‘nobody’: no such user
+++ testcase_exec_properties FAILED +++
```

Bind over `/usr/etc/nsswitch.conf` when `/etc/nsswitch.conf` is absent,
avoiding changes to the host configuration.
2026-10-17 11:44:49 +02:00
Michael Vogt 09c03b3e46 core: report unit sub-state in metrics
The report metrics currently report various useful unit state. It
does not report the SubState currently though. Having it is useful
to determine if e.g. a oneshot unit that has RemainAfterExit=yes
is still running or has exited. So this commit adds it as a
field `sub_state` to the io.systemd.Manager.UnitActiveState metric.
2026-10-17 10:53:28 +02:00
umutcagand ef23a1e3fd core,shared: support ConfigurationDirectory flags over D-Bus
Expose ConfigurationDirectorySymlink with the same a(sst) signature as
the other directory types and route transient ConfigurationDirectory=
assignments through the tuple parser. Keep the name and signature for
uniform client handling; its destination is always empty because
configuration directories do not support symlinks.

Preserve the plain as property for ordinary names and empty assignments.
Emit empty arrays for resets of all five directory types, including the
four types whose client previously discarded empty assignments.

Show tuple flags in systemctl, retaining unknown 64-bit values numerically
for compatibility with newer managers. Document literal-colon escaping,
which now needs an extra level for transient ConfigurationDirectory=,
and the changed output/reset behavior in NEWS.

Read client messages back to check property names, signatures, fields and
empty arrays. Cover flags, raw D-Bus validation and reload/restart path
round-trips in TEST-23, resetting failed transient units during cleanup.

Fixes #43611.
2026-10-17 11:24:21 +03:00
Julian Sparber bce0aaf66b test: Ensure the default node is picked up for cryptenroll-varlink
When no node is provided cryptenroll should pick up the default node:
backing /var/. Add a test to make sure it works.
2026-10-17 09:04:32 +02:00
Ivan Kruglov c9cccc338f test: preserve host NSS configuration in userdbctl tests
On openSUSE, /etc/nsswitch.conf may be absent and glibc falls back to
/usr/etc/nsswitch.conf. Binding over the absent path creates an empty
file on the host, disabling that fallback and breaking subsequent nobody
lookups.

Bind over the fallback configuration when /etc/nsswitch.conf is absent.
2026-10-17 08:15:45 +02:00
Lennart Poettering db34d7f479 report: add a simple geoip source 2026-10-17 07:52:31 +02:00
Lennart Poettering 993e61d19c test: add tests for systemd-report-diskhealth
Check the generic disk metrics against sysfs and the udev database in
TEST-74, and the NVMe health metrics against the QEMU emulated NVMe
controllers in TEST-64, including the case of shared namespaces.
2026-10-16 16:10:23 +02:00
Lennart Poettering 847afbf137 TEST-80-NOTIFYACCESS: don't rely on UNIT= for PID 1 reload handler warnings
The test runs with debug logging, so PID 1 logs a lot. If journald's
native socket is congested, PID 1's log write fails with EAGAIN and it
falls back to /dev/kmsg. Messages logged that way lack the structured
UNIT= field (and _PID=), and hence are not matched by "journalctl -u".

This happened in CI: the "lacks handler for reload signal" warning for
notify-reload-toggle-handler.service ended up in the journal with
_TRANSPORT=kernel, and the -u lookup failed.

Match on SYSLOG_IDENTIFIER=systemd plus the message text instead, which
includes the unit name as prefix on both transports.
2026-10-16 15:37:34 +02:00
Jelle van der Waa a7142e4cb3 test: Fix logind-test-user session flake
On the Arch Linux the logind tests sometimes flake on logind-test-user
session still being active. This is possibly caused by getty getting
re-activated on tty2 during the long timeouts waiting on the user
session to fully get removed. To prevent this remove the
getty@tty2.service.d override as soon as possible and that should fix
the test failure shown below:

[   69.641642] TEST-35-LOGIN.sh[1014]: + echo 'Session of the '\''logind-test-user'\'' is already present.'
[   69.642207] TEST-35-LOGIN.sh[1014]: Session of the 'logind-test-user' is already present.
[   69.642947] TEST-35-LOGIN.sh[1014]: + exit 1
2026-10-16 14:20:14 +01:00
Daan De Meyer 08190bcf15 nss-systemd: add $SYSTEMD_NSS_SERVER_SIDE_NSS (#44086)
nss-systemd always passes USERDB_EXCLUDE_NSS to userdb. That flag skips
the io.systemd.NameServiceSwitch and io.systemd.Multiplexer services. A
sandbox can bind mount the host's userdb sockets into
/run/systemd/userdb/,
but nss-systemd in that sandbox still cannot resolve the host's regular
users and groups.

Add $SYSTEMD_NSS_SERVER_SIDE_NSS. If it is set, nss-systemd queries the
server-side NSS services too. Client-side NSS stays off, because
nss-systemd itself runs as a glibc NSS module.
2026-10-16 14:46:06 +02:00
Luca Boccassi c952ba1351 core/varlink: support all service Exec* fields in io.systemd.Unit.StartTransient (#44222)
io.systemd.Unit.StartTransient currently supports only ExecStart. Add
support
for ExecCondition, ExecStartPre, ExecStartPost, ExecReload,
ExecReloadPost,
ExecStop, and ExecStopPost.

Extract shared command construction into exec_command_new() and use it
in
both the D-Bus and Varlink paths.

Add integration coverage for command execution during startup, reload,
and
shutdown, plus invalid paths and conflicting flags for all eight fields.
2026-10-16 10:25:09 +01:00
Daan De Meyer d8ae13c929 vmspawn: SecureBoot support on arm64, some related fixes (#44194) 2026-10-16 09:16:59 +02:00
Ivan Kruglov dd1e457c90 test: cover service Exec* fields in Varlink StartTransient 2026-10-15 22:17:23 +02:00
Lennart Poettering d26d3c4dd6 test: drop ConditionSecurity= of the TPM2 report signer in TEST-70
systemd-report-sign-tpm2.socket carries ConditionSecurity=measured-uki,
which does not necessarily hold in the test VM. If it doesn't the socket
is silently skipped, systemd-report only finds the plain software
signer, and the report-sign subtest fails because it gets no TPM2
signature record back.

The same applies to systemd-pcrlock.socket, whose Varlink interface the
TPM2 backend reads the event log from. So far this only worked because
TEST-70-TPM2.pcrlock.sh ran first and left the socket up.

Patch out the condition of both via drop-ins for the duration of the
test, like TEST-70-TPM2.pcrextend.sh and
TEST-70-TPM2.cryptsetup-measure.sh already do for
systemd-pcrextend.socket.

Follow-up for 768b6f21ec.
2026-10-15 22:13:24 +02:00
Ivan Kruglov cb987c164b core/varlink: accept the TasksMax scale member in StartTransient (#44183)
Follow-up to #42921, implementing the conclave rule that all output
fields must be consumable on input.

`Unit.List()` emits the `CGroupTasksMax` pair in full, but
`StartTransient()` refused a
supplied `scale` and pointed at `TasksMaxScale` instead, so its own
output was not valid
input. This takes the pair as emitted.

The denominator is not fixed, which is why the pair has to be accepted
as given rather
than normalized to one scale on input:

| configured via | internal pair |
| --- | --- |
| `TasksMaxScale` (Varlink) | `{permyriad, 10000}` |
| `TasksMaxScale` (D-Bus) | `{v, UINT32_MAX}` |
| unit file `TasksMax=50%` | `{5000, 10000}` |

Accepting only `10000` would still refuse the output of any
D-Bus-configured unit. The
pair is stored as given and normalized only for the transient fragment,
which carries
permyriad percent — the same thing the D-Bus setter does.

Two deliberate details:

- The pair form accepts 0% and 100%, which `TasksMaxScale` rejects.
`config_parse_tasks_max()` parses both through `parse_permyriad()`, so a
unit file can
hold them, they appear on the read side, and they therefore have to be
settable.
`TasksMaxScale` keeps its D-Bus-mirroring bounds, so the asymmetry is
between the
  round-trip form and the convenience form.
- A scaled value above 100% is now reported against `CGroup.TasksMax`
instead of the whole
`context`, because it is caught at apply time rather than while
dispatching the object.

`TasksMaxScale` is unchanged and stays input only, which the rule
permits: multiple input
forms are fine as long as the output is normalized, and only `TasksMax`
is emitted.

Note that a daemon-reload still goes through the fragment, so a relative
limit is coarsened
to permyriad precision there. That is pre-existing and applies to the
D-Bus path equally;
the in-memory pair, and so `List()`, keeps what was set.

TEST-74 covers the pair as input, a reply fed straight back, the D-Bus
denominator, the 0%
and 100% cases, and the above-100% rejection.
2026-10-15 19:56:38 +02:00
Daan De Meyer 4639273402 Various journal refactoring (#44209) 2026-10-15 15:00:51 +02:00
Daan De Meyer 010d16adad fuzz: add a fuzzer for journal files
No fuzzer passes malformed journal files to the code that reads them.
fuzz-journal-remote only reads back the files that it wrote itself.

Add fuzz-journal-file, which writes the input to a file and reads it
through sd-journal: forwards and backwards, by timestamp, cursor, match,
and unique value, and through field enumeration. It also runs
journal_file_verify() on the file. The corpus has a compact and a
regular file with twelve entries each, one of them with a compressed
field.
2026-10-15 13:27:38 +02:00
Zbigniew Jędrzejewski-Szmek b44cca76b9 Relax parsing of address families (#43691) 2026-10-15 12:10:26 +02:00
Zbigniew Jędrzejewski-Szmek 571710fada doc: add document stating how we assign NV indexes (#33394)
(TCG is considering to assign us an NV index range, this is a
placeholder document that they can reference in their registry
eventually. Should not be merged like this until TCG folks are happy)
2026-10-15 12:07:50 +02:00
Luca Boccassi 174c449571 varlinkctl: Rework handling of empty reply params (#43884)
Previously, `varlinkctl call` would print nothing for an empty reply,
and `varlinkctl --exec call` would abort with an assertion failure. This
PR makes varlinkctl consistently output `{}` for cases where the reply
parameters are empty/null/absent.
2026-10-15 11:28:08 +02:00
Daan De Meyer 7741b0012e nss-systemd: add $SYSTEMD_NSS_SERVER_SIDE_NSS
nss-systemd always passes USERDB_EXCLUDE_NSS to userdb. That flag skips
the io.systemd.NameServiceSwitch and io.systemd.Multiplexer services. A
sandbox can bind mount the host's userdb sockets into /run/systemd/userdb/,
but nss-systemd in that sandbox still cannot resolve the host's regular
users and groups.

Add $SYSTEMD_NSS_SERVER_SIDE_NSS. If it is set, nss-systemd queries the
server-side NSS services too. Client-side NSS stays off, because
nss-systemd itself runs as a glibc NSS module.
2026-10-15 09:36:02 +02:00
Lars Sjöstrom 44a8ea4e86 core/varlink: accept the TasksMax scale member in StartTransient
The read side emits the CGroupTasksMax pair in full, but StartTransient()
refused a supplied "scale", so the output of Unit.List() was not valid
input again. Take the pair as it is emitted instead.

The denominator depends on how the unit was configured: 10000 via
TasksMaxScale and the unit-file percent syntax, UINT32_MAX via the D-Bus
TasksMaxScale setter. Accepting only one of them would still refuse the
other, so the value/scale pair is taken as given and normalized just for
the fragment, which carries permyriad percent.

UINT32_RATIO_TO_PERMYRIAD() bounds the denominator at UINT32_MAX, which no
producer exceeds. That bound matters: cgroup_tasks_max_resolve() resolves
the pair through system_tasks_max_scale(), whose overflow guard returns
UINT64_MAX once the numerator passes UINT64_MAX/system_tasks_max(). A
larger pair would apply no limit at all while the fragment recorded a
percentage.

Unlike TasksMaxScale, the pair form accepts 0% and 100%:
config_parse_tasks_max() parses both through parse_permyriad(), so they
reach the read side and have to be settable again. TasksMaxScale keeps
its D-Bus-mirroring bounds.

A scaled value above 100% is now reported against CGroup.TasksMax rather
than the whole context, because it is caught when the property is
applied rather than while the object is dispatched.
2026-10-15 09:29:10 +02:00
Ivan Kruglov 4934ddfe81 test: review follow ups #44191 (#44199)
Review follow-ups for https://github.com/systemd/systemd/pull/44191.
2026-10-15 09:24:31 +02:00
Lennart Poettering 705d85f1d5 tpm2-util: allocate pcrlock NV indexes from our newly assigned range 2026-10-15 08:53:27 +02:00
Adrian Vovk 8904b844a4 tests: Adapt to changes in varlinkctl's behavior
varlinkctl no longer stays silent if an object is empty, and that broke
some tests
2026-10-15 02:35:32 -04:00
Martin Pitt 4eda0eb363 vmspawn: support firmware with a host-side UEFI variable store
On aarch64 there is no SMM to protect Secure Boot variables from the
guest, so Fedora ships aarch64 Secure Boot capable firmware only with
the `host-uefi-vars` feature: it keeps its variables in QEMU's uefi-vars
device instead of pflash. vmspawn previously skipped these firmware
descriptors, so `--secure-boot=yes` failed on aarch64:

> Skipping /usr/share/qemu/firmware/91-edk2-aarch64-qemuvars-sb.json,
> firmware does not have an NVRAM template.
> Failed to find OVMF config: No such file or directory

Select such firmware if its descriptor declares a variable store
template, and give it the `uefi-vars` device. This is backed by a JSON
state file with the same semantics as the pflash NVRAM state. Its
`--efi-nvram-state=auto` path gets a different suffix, so that switching
between the two firmware types never feeds a state file to the wrong
one.

Descriptors are still picked in sort order, so when pflash firmware
satisfies the requested features and is sorted first (as with Fedora's
x86 descriptors), it does not change behaviour.

Signed-off-by: Martin Pitt <martin@amutable.com>
2026-10-15 06:41:05 +02:00
Martin Pitt 5ecc970280 vmspawn: enable SMM only for firmware that requires it
vmspawn enabled SMM for all Secure Boot firmware, and restricted the
pflash variable store to SMM accesses for all firmware on architectures
with SMM. Firmware built without SMM support, such as Fedora's
non-Secure Boot OVMF builds, then can't write its variables: QEMU drops
all of its writes to the variable store, so e.g. boot options never
persist.

The `requires-smm` feature of the firmware descriptor declares whether
firmware needs SMM [1]. Enable SMM and restrict the variable store to
SMM accesses only for such firmware. libvirt does the same.

[1] [1] https://gitlab.com/qemu-project/qemu/-/blob/master/docs/interop/firmware.json

Signed-off-by: Martin Pitt <martin@amutable.com>
2026-10-15 06:41:04 +02:00
Martin Pitt bbebfca887 vmspawn: show QEMU's output when it fails during setup
With a console PTY, QEMU's stdio is the PTY since bde83a9e1e. Nothing
reads it before the PTY forwarder starts after the QMP device setup.
When QEMU refuses to start, e.g. due to an unknown device, its error
message got lost, and vmspawn only reported "QMP connection dropped
during feature probing".

If vmspawn fails before the forwarder starts, copy QEMU's buffered
console output to stderr.

Signed-off-by: Martin Pitt <martin@amutable.com>
2026-10-15 06:41:04 +02:00
Adrian Vovk 34db99971e sd-varlink: Return empty object for missing params
Previously, sd-varlink was inconsistent about what it did with
empty/missing/null parameters in a Varlink call or reply: when
dispatching to a callback, it would always construct an empty object and
hand over the empty object to the handler (good!). But when returning
the value directly (i.e. with sd_varlink_call), it would return NULL
when parameters were omitted and a JSON null when the paramerters were
null.

This inconsistency is a violation of UAPI.20, which states that
receivers of Varlink messages MUST treat omitted/null/empty parameters
on Varlink calls and replies equivalently, where senders only SHOULD
prefer to omit the parameters.

This commit makes sd-varlink normalize the parameters to an empty object
whenever it is null or omitted, which brings sd-varlink into compliance
with this rule in UAPI.20
2026-10-14 17:42:31 -04:00
Lennart Poettering 7f073ff56f test: give the firmware more time to find the boot-time drive in TEST-87
The firmware subtest of TEST-87-AUX-UTILS-VM.vmspawn-drives.sh boots
the Secure Boot OVMF build with SMM in a nested VM. On a slow CI runner
the firmware took ~33s to set the RTC and ~45s to bring up the console,
so the 60s timeout for the BdsDxe "UEFI Misc Device" line expired
before BDS got to try the drive, failing the test even though nothing
was wrong.

Bump the timeout to 300s. The test still bails out as soon as the line
shows up, so this only costs time when things are actually broken.
2026-10-14 20:57:29 +02:00
Ivan Kruglov 6e4ac3929b test: clarify the non-transient dependency rejection comment 2026-10-14 18:10:27 +02:00
Ivan Kruglov 83643c9254 test: create a fixture for transient unit dependencies
The dependency testcase references a unit that is never created after the
split. Start a local oneshot fixture and keep it active so the checks
exercise dependencies on an existing unit, with cleanup owned by the
same testcase.
2026-10-14 18:10:18 +02:00
Ivan Kruglov 4705e24b4e test: split TEST-74-AUX-UTILS.varlink-unit-* coverage tests into focused testcases
Separate EnqueueJob and StartTransient coverage into subtests and use run_testcases for independent fixtures and cleanup.
2026-10-14 17:33:04 +02:00
Zbigniew Jędrzejewski-Szmek 6b074171e7 TEST-07-PID1: check comma-separated lists in a unit file
The existing checks pass the comma-separated values via systemd-run -p,
which splits them on the client side, so the parsers in load-fragment.c
were not exercised. Load a unit file with comma-separated SystemCallFilter=,
SystemCallLog= and RestrictFileSystems= and check what the manager reports.
The names are reported sorted, so the expected output is deterministic.
2026-10-14 17:16:19 +02:00
Zbigniew Jędrzejewski-Szmek dc3acb87ad TEST-07-PID1: check manager-side normalization of address family names
systemd-run normalizes the names on the client side before sending them to
the manager, so talk to the manager directly to exercise the code in
dbus-execute.c: 'inet Unix' must end up as 'AF_INET AF_UNIX' in the
transient unit file and in the exposed property, and an unknown name must
be rejected with InvalidArgs.

busctl only reports the name of the error via BUSERROR=, so run it as a
service with NotifyAccess=main and check StatusBusError, like TEST-80 does.
2026-10-14 17:16:19 +02:00
Zbigniew Jędrzejewski-Szmek 244b2fe2c1 TEST-13-NSPAWN: check that --restrict-address-families= is enforced
The options added to the --volatile= checks only verify that the various
spellings are accepted. Add a dedicated testcase which checks that the
restriction actually applies: ip(8) needs an AF_NETLINK socket, so it must
fail when netlink is not permitted and succeed when it is, regardless of how
the list is spelled.
2026-10-14 17:16:19 +02:00
Zbigniew Jędrzejewski-Szmek 1d5c1d1bf9 Allow commas in SystemCallLog=/RestrictFileSystems=/RestrictNetworkInterfaces=
The previous commits made SystemCallFilter= and RestrictAddressFamilies=
accept commas as separators, and the shared serialization helper in
bus-unit-util.c now splits on commas for all the filter-list settings it
handles. That left unit files and 'systemctl set-property'/'systemd-run
-p' disagreeing for the remaining three settings. Accept commas in the
unit file parsers too, and update the documentation.

Note that a comma is a valid character in a network interface name, so an
interface with a comma in its name needs to be quoted or escaped. Add a
hint in the man page. Such names should be exceedingly rare so this
shouldn't matter in practice.

The manager writes transient settings back into a drop-in which is parsed
again on daemon-reload. Quote the interface names there, so that a name
containing a comma (or a quote or backslash, which are valid in interface
names too) survives the round trip.
2026-10-14 17:16:19 +02:00