Commit Graph
7210 Commits
Author SHA1 Message Date
dongshengyuan a6f7ded859 updatectl: fix feature JSON parsing
The feature JSON payload switched to `id`, `isEnabled`, and `appstream`,
and made `documentation` an array of URLs.
`updatectl` still parsed legacy table-derived names and a single URL.
This broke feature JSON parsing and made output inconsistent.
Features without documentation could also cause a null dereference.

Align `updatectl` with the current schema and preserve all
documentation URLs across sysupdate, D-Bus, and Varlink payloads.
Propagate condition evaluation errors through `condition_test_list()`
and `feature_is_suggested()`, with consistent JSON error handling and
tests.
The `suggested` field is now optional and always a boolean when
present; it is omitted rather than set to an error string when
SuggestOn*= conditions cannot be evaluated.
Add `suggested` metadata and document the field transition.

Follow-up for 3e34ccf6df.
Follow-up for 75a247d4de.
Follow-up for 40e727c93b.

Fixes #43603
2026-09-08 16:05:36 +02:00
Michael Vogt 7efa326b7a sysext: use [] in json mode when giving the extension status
The json mode was returning the string `none` when unmerged and
an array for merged extensions. Return an empty array instead.

Instead of branching on the output format, always add an empty strv
for an unmerged hierarchy: the table code renders an empty strv as
the ersatz string ("-") in text mode and as an empty array in json
mode. This also changes the human-readable output from "none" to "-".

It also updated the TEST-50-DISSECT.sysext.sh test. Technically
this is a compatbility break but its also arguably a bugfix.
2026-09-07 18:29:25 +02:00
Luca Boccassi 548f87538a measure: expose offline signing data in policy-digest output
The PolicyPCR digest is not always the complete input to an offline
signature. PolicyAuthorize also includes the hashed policy reference.
This is now required for NVPCRs to work in the initrd.

Expose the complete data as "tbs" (to-be-signed) and use it when ukify
matches offline signatures. Keep "pol" as the compatibility fallback.

Fixes: https://github.com/systemd/systemd/issues/43635

Follow-up for f0f3687700
2026-09-07 16:15:42 +01:00
Luca Boccassi bc17a73107 core: don't exit 0 when a failure action has nothing to propagate (#43647)
Fixes #43645.

`FailureAction=exit` propagates the exit status of the unit's main
process. When there is none, `emergency_action()` left `m->return_value`
at its initial 0, so the manager exited 0 for a unit that failed —
indistinguishable from an orderly shutdown to whoever supervises it.
2026-09-05 11:54:29 +01:00
Totoro f789245918 machine: preserve read-only clone mode for foreign UID images
machinectl clone --read-only ignored the requested read-only mode when
cloning a foreign-UID-owned directory because the unprivileged clone path
did not receive the read_only argument.

Pass the flag through and apply the immutable bit via the already-open
destination directory fd after copying. Keep this best-effort, matching
the ordinary directory clone fallback, so failure to set the attribute
does not turn a completed copy into a reported clone failure.

Add a regression test using foreign-0 rather than a fixed UID. Verify
the cloned image's ReadOnly property, copied contents and ownership, and
that the immutable directory rejects new entries. Run this subtest only
when file attributes and the existing rootless nspawn prerequisites are
available, leaving the other machined tests unchanged.
2026-09-05 08:34:55 +02:00
Totoro 0c8f57cae2 machine: propagate foreign image clone directory errors
unprivileged_clone() returns success when mountfsd_make_directory() fails.
Consequently, callers can report a successful clone even though the
destination directory was never created.

Return the original error instead of zero so the failed clone is
reported to the caller.

Add a regression test that places a regular file without an image suffix
at the destination path. Such a file is ignored by image discovery but
prevents directory creation. Check that cloning reports failure without
changing the file, then succeeds after the conflicting file is removed.
2026-09-05 08:32:02 +02:00
Totoro f4a7117af2 network: honor --root= for picked up credentials
network-generator writes generated command line configuration below
the alternate root passed with --root=, but network.* credentials
were copied to fixed host /run paths.

Build the credential target directories with arg_root before passing
them to pick_up_credentials(). This keeps normal boot behavior
unchanged while making credential output land in the requested root.
2026-09-04 14:22:25 +09:00
Yu Watanabe c21a49cd3d core/swap: don't resurrect swap units whose device link disappeared (#43443)
Fixes #43442.

A `.swap` unit can end up **active but unloadable, with no device**, and
stopping such a unit aborts PID 1.

### What it looks like

```
$ systemctl show 'dev-disk-byx2dpartlabel-primary.swap' -p LoadState,ActiveState,What
LoadState=not-found
ActiveState=active
What=                     # <-- no device

$ systemctl stop 'dev-disk-byx2dpartlabel-primary.swap'
systemd[1]: About to execute: /usr/sbin/swapoff        # <-- no argument
systemd[1]: Caught <ABRT>, from our own process.
systemd[1]: Freezing execution.
```

PID 1 stays alive but frozen, so the machine stops answering `systemctl`
and never reboots.

### How it happens
1. systemd creates one `.swap` unit per udev device link of every device
in `/proc/swaps`.
2. A device link gets repointed at another device while the swap stays
on. `/proc/swaps` doesn't change, so nothing re-examines the unit — it
stays active.
3. The next `daemon-reload` drops all units and rebuilds them.
Enumeration from `/proc/swaps` no longer produces this name, so only the
deserialization brings the unit back: by name, with no fragment on disk.
4. `swap_load()` only calls `swap_add_extras()` for units that loaded a
fragment or are backed by `/proc/swaps`, so this one gets neither a
`What=` nor a patched `ExecContext`.
5. `swap_coldplug()` restores its active state anyway.
6. Shutdown stops it. `unit_stop()` deliberately permits stopping units
whose load failed, so it reaches `exec_spawn()` and trips the
`PrivateVarTmp=` assertion in `exec_context_serialize()`.
2026-09-04 04:11:29 +09:00
Ivan Kruglov 369bb5862b test: add a test for issue #43645 2026-09-03 10:18:29 -07:00
Yu Watanabe 736cb91535 resolved: actually unregister DNS-SD services when the D-Bus client vanishes (#43578)
Since the D-Bus DNS-SD API was introduced in c3036641f0ed (v236),
`RegisterService()` has created an `sd_bus_track` object to destroy the
registered service when the registering client disconnects from the bus.
However, the track object is a `_cleanup_(sd_bus_track_unrefp)` local in
`bus_method_register_service()` that is never stored anywhere, so it is
destroyed again as soon as the method handler returns. The vanish
handler (`dnssd_registered_service_on_bus_track()`) has thus been dead
code for the past ~8 years.

The observable effect: services registered via D-Bus silently persist
after the client disconnects — unowned, advertised until resolved exits,
and impossible to re-register since the identifier stays taken
(`DNSSD_SERVICE_EXISTS`). At the same time, the registration doesn't
survive a resolved restart, so the current behavior is neither reliably
ephemeral nor reliably persistent. Noticed while reviewing a project
that (unknowingly relying on this bug) registers a service with a
one-shot `gdbus call` and expects it to persist.

This PR:
1. splits the goodbye/zone-removal logic out of
`bus_dnssd_method_unregister()` into a helper — the vanish path needs
the full teardown, not just `dnssd_registered_service_free()`, which
would leave the service's RRs published in the per-link mDNS zones;
2. stores the track object in `DnssdRegisteredService`, making client
tracking work as originally intended;
3. documents the lifetime semantics in `org.freedesktop.resolve1(5)`
(matching the equivalent Avahi D-Bus API, whose entry groups are
likewise bound to the client connection) and points to `*.dnssd` files
for registrations independent of a client's lifetime;
4. adds a TEST-75 case covering the connection-bound lifetime.

Note this is a behavioral change for fire-and-forget clients (one-shot
`busctl`/`gdbus` invocations). Arguably those were never working
reliably (registrations silently vanished on any resolved restart, and
stale entries blocked re-registration), but if this is deemed too risky,
the alternative would be to drop the dead tracking code and codify the
persist-until-exit behavior instead — I'd argue tracking as originally
intended is the better contract.

Verification: code compiles; the new integration test is included.
2026-09-03 06:14:31 +09:00
Yu Watanabe 26f4d56015 compress: fix unbounded buffer growth on truncated streams, and fuzz the decompressors (#43589) 2026-09-02 19:59:51 +09:00
Stefan Agner 6decadbebf test: silence SC2329 for indirectly invoked cleanup() functions
shellcheck 0.10+ reports SC2329 ("This function is never invoked") for
the per-testcase cleanup() functions in TEST-75-RESOLVED.sh, which are
only invoked indirectly via trap. The existing SC2317 markers don't
cover it, and inserting a new testcase shuffles which definitions the
heuristic fires on, making pre-existing findings show up as new in
differential CI runs. Extend the markers to SC2317,SC2329, matching
what testcase_dot_strict_per_link_verify() in this file and other test
units already do.
2026-09-02 10:41:54 +02:00
Stefan Agner 908c38f300 test: add test for DNS-SD D-Bus registration lifetime
Verify that a DNS-SD service registered via the D-Bus RegisterService()
call is bound to the lifetime of the client's bus connection: since
busctl disconnects right after the call returns, the service must be
unregistered again shortly after. Wait for resolved's vanish handler
log message as proof that the client tracking triggered the
unregistration, check that a subsequent UnregisterService() fails
specifically because the service is not known anymore, and verify that
the identifier can be registered again — previously it stayed taken by
the vanished client's service forever, failing with
DNSSD_SERVICE_EXISTS.

A dummy link with mDNS enabled makes sure the per-scope goodbye/zone
teardown path actually runs, and since resolved would be restarted
automatically if it crashed in it, letting the D-Bus level checks pass
vacuously, verify the InvocationID stayed the same throughout.
2026-09-02 10:41:54 +02:00
Armaan Sandhu 65c112007a fuzz: add a fuzzer for the qcow2 converter
systemd-importd runs qcow2_detect()/qcow2_convert() over images it has just
downloaded (see pull-raw.c), so the header, the L1/L2 tables and every offset
and cluster descriptor in them are attacker controlled. There is a manual test
for the happy path, but nothing that feeds it a malformed image.

The corpus is two images, a plain data cluster and a zlib-compressed one (i.e.
decompress_zlib_raw()), at the 512 byte minimum cluster size and trimmed to the
last byte the converter reads, so 2K each. A zero cluster and a QCOW3 header are
a flipped descriptor bit and a bumped version field away from these, so they are
left to the fuzzer rather than carried in the tree.
2026-09-01 11:41:19 -04:00
Armaan Sandhu 43cd946f98 fuzz: add a fuzzer for the decompression entrypoints
fuzz-compress only ever feeds the decompressors their own output: it compresses
the fuzzer input and then decompresses the result, so the stream the decoders
see is well formed by construction. The blobs they get in reality come out of
journal files, systemd-journal-remote streams, coredumps and downloaded images,
i.e. from wherever the data was written, which is not necessarily somewhere we
trust.

So hand them the fuzzer input directly instead, across all four entrypoints:
decompress_blob(), decompress_startswith(), decompress_stream(), and the
decompressor_detect()/decompressor_push() pair that systemd-importd feeds from
the network. The latter is pushed in chunks, so that the decoders see the same
fragmentation a real download produces. The decompressed size is capped, as an
unbounded decode of a hostile blob measures the allocator rather than the
decoder.

The corpus carries the two truncated stream headers that used to send
decompress_startswith() allocating until OOM, fixed in the previous commit.
2026-09-01 11:41:19 -04:00
RamsesandYu Watanabe 3da5c65d87 network: register already enslaved interfaces when their master appears (#43557)
When networkd starts or restarts, links are enumerated in ifindex
order. A slave enumerated before its master cannot register itself in
link_append_to_master(), as the master Link object does not exist yet.
The master then wrongly believes it has no slaves until the next
RTM_NEWLINK message for the slave arrives.

The stale slaves set affects operational state propagation
(degraded-carrier detection) and any code that inspects the slaves of
a master.
For instance, on restart, when networkd thinks that the master has no
slaves yet, we try to set the bond fail-over policy, which the kernel
then refuses because in reality the bond does have slaves.

To fix the issue, this updates the list of slaves after enumeration.

Co-authored-by: Yu Watanabe <watanabe.yu+github@gmail.com>
2026-09-01 18:28:43 +09:00
Christian Brauner 9b62fd169e Extend W^X memory protection mechanism for RestrictFileSystemAccess (#43511)
Currently `RestrictFileSystemAccess` isn't trying hard enough to enforce
W^X and thus there are still places where an executable and writable
mapping can be created:

* `/proc/<pid>/mem` `FOLL_FORCE` writes
* `PTRACE_POKE{TEXT,DATA}` `FOLL_FORCE` writes
* `MAP_PRIVATE | MAP_EXECUTABLE` memory mappings

Let's block all of these mechanisms. Do note that
`RestrictFileSystemAccess` is still in very active development and also
cannot meaningfully be used on general purpose distros and systems.

Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-09-01 07:12:13 +02:00
Christian Brauner 3674263071 test-bpf-restrict-fsaccess: add W^X and ptrace protection tests
Add tests for all new W^X protection mechanisms.

Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-08-31 23:33:40 +02:00
Christian Brauner 73e093d16d core: centralize RestrictFileSystemAccess= checks
Centralize the checks for RestrictFileSystemAccess= requirements.

Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-08-31 23:33:39 +02:00
Christian Brauner c35f061634 test-bpf-restrict-fsaccess: differentiate between a denial and an unrunnable probe
Make sure the tests can tell the difference between an actual denial and
a probe that simply cannot be run.

Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-08-31 23:33:39 +02:00
Chris Down df3c9c9ef0 test: Add a test for Type=dbus services surviving a broker restart 2026-09-01 03:03:46 +09:00
Yu Watanabe 39cf979007 Final batch of conversions to COMMAND and additions of --introspect-cli (#43558) 2026-08-29 04:26:12 +09:00
Zbigniew Jędrzejewski-Szmek 274d366eb3 report-sign-tpm2: convert to VERB_COMMAND and add --introspect-cli
The custom help() is replaced by a COMMAND() description, matching the
other report-sign services. The abstract is now wrapped at 80 columns
in the help output.
2026-08-28 14:50:10 +02:00
Zbigniew Jędrzejewski-Szmek 51636f3c39 repart: clamp copied timestamps to $SOURCE_DATE_EPOCH (#43545)
This greatly helps reproducibility, and we can actually achieve it with
https://github.com/dosfstools/dosfstools/commit/8da7bc93315c.
2026-08-28 13:22:41 +02:00
Martin Pitt 94bb5f8e4d repart: clamp copied timestamps to $SOURCE_DATE_EPOCH
Use the new copy timestamp clamping mechanism from the previous commit
to fix unreproducible wall-clock files in the generated images.

That covers both modes: online mode writes through the kernel, and
offline mode stages the tree in a temporary directory before handing it
to mkfs or mcopy. `mcopy -m` then carries the clamped mtimes into the
FAT.

This complements commit 34c3d57474 (directory times) and commit
f191ca982c (FAT insertion order).

Cover all combinations (online/offline, with and without epoch) in the
new `testcase_vfat_reproducibility()`. Update `testcase_make_symlinks()`
to cover the symlink creation/re-fix their parent directory code paths.

Sadly, images are still not reproducible byte for byte. Document
systemd-repart's $SOURCE_DATE_EPOCH handling and remaining
reproducibility issues in the manpage.
2026-08-28 11:16:29 +02:00
Zbigniew Jędrzejewski-Szmek 378e6c544b udevd: convert to VERB_COMMAND and add --introspect-cli
systemd-udevd is the same binary as udevadm, so the introspection data
describes both commands, from either name. The COMMAND intentionally
owns no verbs — all of udevadm's verbs are defined in udevadm.c right
after its own COMMAND, so that they are attributed to it.

The -V/--version output (GIT_VERSION) is preserved.
2026-08-28 09:59:16 +02:00
Zbigniew Jędrzejewski-Szmek d8b733d6dd udevadm-lock: use common verb help and add --introspect-cli
The custom help() is replaced by the common verb help, which derives the
synopsis, abstract, and option list from the verb declaration in
udevadm.c and the "udevadm-control" option namespace. The synopsis
makes use of the new nulstr-argspec functionality:
  > udevadm [OPTION…] lock [OPTION…] COMMAND
  > udevadm [OPTION…] lock [OPTION…] --print
2026-08-28 09:58:36 +02:00
Zbigniew Jędrzejewski-Szmek 0ba8647c6d udevadm-hwdb: use common verb help and add --introspect-cli
The custom help() is replaced by the common verb help, which derives the
synopsis, abstract, and option list from the verb declaration in udevadm.c
and the "udevadm-control" option namespace. The new VERB_DEPRECATED flag
is used.
2026-08-28 09:47:36 +02:00
Zbigniew Jędrzejewski-Szmek a35f5d5eba udevadm: convert to VERB_COMMAND and add --introspect-cli
The verbs declare their subcommand option namespaces, so the
introspection data describes the options of every subcommand, nested in
the verb objects.

The bare version number output (a dracut compatibility requirement) is
preserved for --version/-V and the "version" verb.

The "lock" verb's argument specification is simplified to "COMMAND" --
other verbs do not mention their options in the argspec either, and the
subcommand help states where the options may go.
2026-08-28 09:29:04 +02:00
felix h a11144d0a9 tree-wide: format man page references as foo(1) 2026-08-28 06:34:45 +09:00
Zbigniew Jędrzejewski-Szmek 3d0ef4aefe various: mark files with the usual license tags
For .clang-format and pytest.ini, MIT-0 is used because people might want
to copy those.
2026-08-28 06:26:09 +09:00
Luca Boccassi 85cdcad36b test: make boot mode work in unprivileged containers, take TEST_MKOSI_ARGS (#43531)
The final enablement pieces needed for coco tests in systemd CI. Runners
will be incus containers, these two commits enable running coco tests
with mkosi boot (where image is a directory), then start a confidential
guest with vmspawn as part of the test.
2026-08-27 13:44:47 +01:00
Luca Boccassi 2de150d7b7 Add experimental manpage marker, use it for sd-sysupdate and move it back to libexecdir (#43533) 2026-08-27 10:46:01 +01:00
Paul Meyer 5d8191da48 test: take extra mkosi options from TEST_MKOSI_ARGS
Add a TEST_MKOSI_ARGS environment variable whose contents are appended
to the mkosi invocation launching the test image, without affecting the
image build. This lets the environment adapt how tests are run, e.g.
pass --format=directory --output-dir=... to boot the test container
from a directory format output in environments that cannot dissect disk
images, such as unprivileged containers, where loop devices and udev
are not available.

Signed-off-by: Paul Meyer <katexochen0@gmail.com>
2026-08-27 10:00:30 +02:00
Paul Meyer 3904661440 test: make boot mode work in unprivileged containers
In a mount namespace owned by a non-initial user namespace, the kernel
only allows mounting a fresh proc or sysfs if the namespace already
contains a fully visible mount of the same filesystem type
(mount_too_revealing()). systemd-nspawn's pivoted root contains no such
mount, so booting the test container inside an unprivileged container
(e.g. a containerized CI runner) fails with EPERM when mounting /proc.

When running in a non-initial user namespace, satisfy the check by
binding a read-only instance of each into the container under /work.
Skipping the binds on regular privileged runs keeps the container
isolated from the host's proc and sysfs. Binding non-recursively keeps
foreign submounts (e.g. lxcfs overmounts) out, which would spoil full
visibility where they end up locked, and which read-only would not
cover.

Signed-off-by: Paul Meyer <katexochen0@gmail.com>
2026-08-27 10:00:30 +02:00
Yu Watanabe d649c186be test: support the new coredump services 2026-08-27 05:54:17 +09:00
dongshengyuan 2ff5250ae7 homework: skip LUKS fallocate for metadata operations
UpdateHomeEx needs to set up the home temporarily so that it can
write the refreshed identity records. Inspect and password changes use
the same setup path for metadata-oriented work.

For LUKS homes with luksDiscard=no, home_setup_luks() fully
allocates the backing image while setting it up. If diskSize=max was
previously written to a sparse image, this can fail with ENOSPC before
the user can disable auto-resize mode again.

Add a setup flag that lets metadata operations skip the full-image
fallocate step. Real create, activate, and resize paths keep the
existing allocation behavior.

Before, reproduced on Ubuntu 26.04 with /home on tmpfs:

  homectl create reprohomed \
          --storage=luks \
          --fs-type=btrfs \
          --disk-size=300M \
          --auto-resize-mode=shrink-and-grow \
          --luks-discard=no
  homectl update reprohomed --disk-size=max
  dd if=/dev/zero of=/var/tmp/homed-repro/filler bs=1M count=500
  systemctl restart systemd-homed.service
  homectl update reprohomed --auto-resize-mode=off

  Operation on home reprohomed failed:
  Not enough disk space for home reprohomed

Fixes #34527

Follow-up for: ab3b6fcb40
2026-08-27 04:54:38 +09:00
Luca Boccassi 35530fcf94 sysupdate: move back to libexecdir to mark as experimental
Fixes https://github.com/systemd/systemd/issues/43498
2026-08-26 19:51:31 +01:00
quanyeyang a9ff124143 repart: Keep new partitions after existing same-type partitions
When a partition is deleted from a table containing multiple partitions
of the same type, filling the resulting partition-number gap can place
a new partition before an existing partition matched to an earlier
definition. This changes definition matching on the next invocation and
breaks idempotency.

Keep new partitions after existing partitions of the same type. If no
partition table slot is available after them, fall back to the first
unused slot.

Which existing partition is matched to which definition is still
determined by partition type and partition number order, as documented,
and is unchanged by this.

Fixes #43449
2026-08-26 19:43:03 +01:00
Yu Watanabe 6fe09adf81 network: several follow-ups for proxy neighbor setting (#43408)
Follow-ups for 08bebda611.
2026-08-27 00:09:59 +09:00
Zbigniew Jędrzejewski-Szmek 34d4d50d08 Another batch of conversions to COMMAND and additions of --introspect-cli (#43512) 2026-08-26 15:22:50 +02:00
zouge666 eb020fc492 import: merge default OpenPGP keyrings
When an administrator installed a custom keyring under /etc,
signature verification selected it instead of the vendor keyring
under /usr. That could make vendor-signed system updates stop
verifying after adding local keys.

Collect all readable default keyrings, including the current and
legacy /etc paths, and pass temporary copies to GnuPG with
separate --keyring options. Keep SYSTEMD_OPENPGP_KEYRING as an
explicit override, add regression coverage for keyring
coexistence, override behavior, and current-path signing, and
silence the expected shellcheck false positive in the test
cleanup helper.

Closes: #40702
2026-08-26 11:35:55 +01:00
EJ Campbell 004db23cca test: run TEST-03-JOBS cycle starts at log level info
The transactions-with-cycles subtest starts 20 mutually cyclic
services, reads the manager's TransactionsWithOrderingCycle ids over
varlink, and then requires a journal entry matching "cycle starting
with" for every id. On a fedora rawhide CI run the entry for
transaction id 42 was missing for the entire boot and journalctl
printed "-- No entries --", failing the unit, while the manager had
correctly recorded all 20 ids. In the exported journal of that boot,
transaction 42 kept only its debug-level enqueue line

    transaction-cycle12.service: Trying to enqueue job
    transaction-cycle12.service/start/replace

while the other 19 transactions each also kept the three messages
that follow it ("Found ordering cycle", "Unable to break cycle
starting with", "unfixable cyclic ordering dependency"), and PID1's
next message, accepted about 2 ms after the enqueue line, shows
journald itself kept ingesting.

The messages were lost, not late. The test VM boots with
systemd.log_level=debug, and the 20 cyclic starts made PID1 emit
about 12,400 debug messages within 30 seconds, 4,100 of them in the
final second, during which journald stalled for 94 ms between two
consecutive entries. PID1 gives its journal socket a 10 ms send
timeout (src/basic/log.c), and a message whose send times out is
either dropped outright, because log_struct() ignores the sendmsg
result and falls back only on formatting errors, or, for the plain
log calls that do fall back to kmsg, reappears as _TRANSPORT=kernel
text stripped of its structured fields, where a TRANSACTION_ID=
match cannot find it. The asserted messages are log_struct() calls,
so they are in the dropped class. Either way the journalctl
assertion comes up empty. This is also why the "journalctl --sync"
added in ed0727fecd does not help here: it only flushes what journald
already received.

Run the whole section, including the daemon-reload, at log level
info, and drain what the earlier subtests queued at debug level with
one "journalctl --sync" before the first start. The daemon-reload is
itself a heavy debug emitter that returns before journald has
drained its burst, so opening the quiet window after it would leave
that backlog competing with the first cycle messages. The two
messages the subtest greps for are emitted at LOG_ERR ("Unable to
break cycle starting with") and LOG_WARNING ("Job ... deleted to
break ordering cycle starting with") in src/core/transaction.c, and
the ids are recorded into transactions_with_cycle on the same code
path directly before them, so the assertion keeps its full strength
while the debug flood that displaced it is gone.

A single at_exit handler installed at the start of the test restores
the boot-time log level when any subtest aborts, and cleans up the
transient unit the aborting subtest had in flight, guarded on the
unit file existing as in TEST-26-SYSTEMCTL.sh. It replaces the
per-subtest restart_randomized_delay_cleanup() handler, so the two
subtests that change the log level share one restore path.
2026-08-26 11:32:51 +01:00
Zbigniew Jędrzejewski-Szmek a4145b8ca3 shutdown: convert to VERB_COMMAND and add --introspect-cli
systemd-shutdown parsed a bunch of options, but had no way to print
them. Add the standard --help and --version options and the CLI
introspection.

parse_argv() is moved before the PID 1 check, so that the new options
also work when the binary is invoked manually. As PID 1 we can never
return from main() (the kernel would panic), so in that case parse
errors still freeze(), and the help output is followed by a freeze()
too. Ctrl-Alt-Delete and console reopening are re-enabled before
freezing, so that the freeze can be escaped through the kernel and the
error is visible, as before.

The --help/--version/introspect-cli option names are already listed in
the kernel command line exclusion list in proc-cmdline.c.
2026-08-26 12:25:22 +02:00
Zbigniew Jędrzejewski-Szmek 4f2b0e977c core: convert to VERB_COMMAND and add --introspect-cli
--introspect-cli follows the same deferred pattern as --help: parse_argv()
only records the action, and it is executed in the same place where
ACTION_HELP and ACTION_VERSION are handled.

The help is looked up by explicit name: in the multicall configuration
the systemd and systemd-executor commands share one binary, so the
"first COMMAND" default would depend on link order.

The "This program takes no positional arguments." line is dropped from
the help output — the default "[OPTION…]" synopsis already says so.
(And also, this is not quite true. It does take positional args when
called as init.)
2026-08-26 12:22:15 +02:00
Zbigniew Jędrzejewski-Szmek 044ebd7e54 executor: convert to VERB_COMMAND and add --introspect-cli
The help is looked up by explicit name: in the multicall configuration
the systemd and systemd-executor commands share one binary.
2026-08-26 12:15:35 +02:00
Zbigniew Jędrzejewski-Szmek 65510d4cba services: convert to VERB_COMMAND and add --introspect-cli
This converts systemd-homed, -hostnamed, -importd, -localed, -logind,
-machined, -networkd, -portebled, -resolved, -sysupdated, -timedated,
and -timesyncd.

The service name and description move from service_parse_argv() arguments
into a COMMAND() description that each daemon now defines. The
service_parse_argv() macro captures the calling binary's verb section,
where that COMMAND is found, while the options are still defined and
parsed in libshared, in the new "service" option namespace that each
COMMAND references. (The named namespace makes sure that options defined
by other translation units in libshared can never leak into the
services' parsers.)

The supported features are declared via option group filtering: each
COMMAND lists "Options" plus "Bus introspection" and/or "Runtime scope".
Unsupported options are now rejected by the parser as unknown options
(and are not shown in --help), replacing the runtime "This service does
not support …" errors.

The help output changes slightly: the "Bus introspection" and "Runtime
scope" option groups now get their own headings, and some descriptions
were reworded to the imperative form used elsewhere.
2026-08-26 12:15:25 +02:00
Zbigniew Jędrzejewski-Szmek 477d08b3a9 integritysetup: convert to VERB_COMMAND and add --introspect-cli
Standard parse_argv() func is added. --version is now accepted
(previously only the help forms were recognized, via argv_looks_like_help()).

The synopsis changes from "systemd-integritysetup COMMAND ..." to the
standard "systemd-integritysetup [OPTION…] COMMAND …", and the help output
gains an Options section. "help" as the first argument keeps working via
the hidden common help verb.

Previously, we'd just print help and exit with success if no arguments
were given. This seems unexpected and wrong. The program now prints the
usual error message:
  Command verb required (one of attach, detach, help).
2026-08-26 12:15:06 +02:00
totoro 2fa149f2c4 nspawn: set ping group range for userns containers
A newly created network namespace may disallow ICMP echo sockets for
unprivileged users even when their GIDs are mapped into the container.

When creating both user and network namespaces, initialize
net.ipv4.ping_group_range using the mapped GID range capped at INT32_MAX.
This follows the system-wide default from sysctl.d/50-default.conf while
respecting the user namespace mapping and the kernel's accepted limit.
Leave externally supplied network namespaces untouched and treat write
failures as non-fatal warnings.

Add regression coverage for the default 64K mapped range using the tools
already available in the minimal container image.

Fixes #41603
2026-08-26 11:45:35 +02:00
Ivan Kruglov ee138cb41e test: check that an orphaned swap unit isn't resurrected by a reload
Issue: https://github.com/systemd/systemd/issues/43442
2026-08-25 06:05:37 -07:00