Commit Graph
1750 Commits
Author SHA1 Message Date
Zbigniew Jędrzejewski-Szmek efd63ddfbf shared/verbs: turn verb argument specification into nulstr
Like the command-level CommandDescription.argspec, a verb's argspec is now
a nulstr, so that a verb may declare multiple alternative usage lines. The
verbs help table renders one synopsis line per nulstr entry in the
synopsis cell.

All verb argument specifications must gain an explicit NUL suffix. This
is a lot of churn, but I think this needs to be done. For now, there'll
be only one user of the new functionality (i.e. a verb with more than
one argspec), but I think we'll eventually want to use this in other
places too.
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 3694241e3f shared/verbs: add helper to call command_print_help_full with name only
I didn't do this previously because I thought that there wouldn't
be too many callers. But it turns out that there're quite a few.
2026-08-26 12:14:50 +02:00
Zbigniew Jędrzejewski-Szmek 5f45122e75 shared/verbs: allow commands to filter option groups
So far, option groups were only used for display: when parsing options,
the group markers were ignored and all options within a namespace were
considered as potential matches. The group was reported in introspection
data and used as section seperator in help display. To allow a single
option namespace to be used for two commands, pipe through a nulstr with
option group names to look at when parsing options. The field is set in
the Command description and used in various option-handling contexts:
- when parsing and looking for an option, do not consider the entries
  that are in the group that is not listed in the nulstr,
- when listing options in help or introspection, skip over unlisted
  groups.

The verbs_find_verb and verbs_find_command helpers are adjusted to have
a consistent interface.
2026-08-25 09:33:59 +02:00
Zbigniew Jędrzejewski-Szmek 2364f0d7c8 systemctl: describe the halt/poweroff/reboot/shutdown compat commands
The custom halt_help() and shutdown_help() are replaced by COMMAND()
descriptions (one per command name, halt/poweroff/reboot sharing the
"halt" option namespace), and --introspect-cli is added to both parsers.
halt/poweroff/reboot now each reference their own man page name.
2026-08-25 09:33:51 +02:00
Zbigniew Jędrzejewski-Szmek 4cf46d47a2 shared/verbs: allow commands to specify footer highlighting
In practice I think this will ever only be used with ansi_highlight_red(),
but it's cleaner to add this generic extension rather than e.g. a boolean
highlight_footer_red.

The options is passed through via command_print_help_full(), not through
the COMMAND structure, which means that commands with 'help' verb are not
covered by this. The red footer highligting is used for legacy commands,
which don't have verbs, so I think this is OK. Making it generic and
covering 'help' verbs would require more refactoring, and I think it
doesn't make sense to add it until it's actually needed.
2026-08-24 13:46:21 +02:00
Zbigniew Jędrzejewski-Szmek 16d0cbf04b systemctl: convert to VERB_COMMAND and add --introspect-cli
The custom help() is replaced by a COMMAND() description, and
--introspect-cli is added. The generic help-verb check in the test is
filtered out, since systemctl's "help" verb shows unit manuals and fails
without arguments.
2026-08-24 13:45:11 +02:00
Yu Watanabe 90481c0b1b tree-wide: add missing assertions
Found by coccinelle.
2026-08-18 06:30:10 +09:00
Morteza Pourkazemi 5f0d98e728 Add ActivatingConcurrencyMax for slice startup pacing
Introduce Slice.ActivatingConcurrencyMax to limit how many units
within a slice hierarchy may be in activating state concurrently.

Expose the setting over D-Bus, support transient/property parsing,
enforce it during unit start dispatch, and re-check queued starts when
units leave activating state.

Document the new slice option and add a PID1 concurrency test covering
queued startup behavior.
2026-08-03 14:29:07 +09:00
Chris Down 7ce93b7fe0 properties: Skip unnecessary per property filtering (#43146)
In total this can save ~18% CPU on `systemctl show` nominal queries in
my tests.
2026-08-01 13:30:59 -07:00
Chris Down 5293068fb3 properties: Peek the variant value type once
bus_message_print_all_properties() peeks the variant type, but then the
print callback and the default bus_print_property() each peek the value
type again, so there can be up to two redundant calls per property. Peek
it once up front and pass it through.

With this, in my tests `systemctl show` over 160 units decreases in
instructions retired from 1167.6M to 1155.7M, so about 1%.
2026-07-31 16:51:08 -07:00
Chris Down 5663ddaed7 properties: Skip found set building for nominal case
bus_message_print_all_properties() inserts every name it walks into the
found-properties set, but the set is only used to report missing requested
properties at debug level.

Request the set from systemctl only when properties were specified and debug
logging is enabled, avoiding the unnecessary work in normal operation.

In my tests with `systemctl show` over 160 units this brings the
instructions retired from 1167.8M down to 992.6M, a reduction of 15.0%.
The output is unchanged.
2026-07-31 16:41:53 -07:00
Yu Watanabe 01e1303f9c Rename basic-forward.h, sd-forward.h, and shared-forward.h to forward.h
Follow-up for 74d392ed1b.
2026-07-15 02:18:05 +09:00
Yu Watanabe 4c0d8d9673 tree-wide: embed dlopen notes into individual executables
Previously, when a library was dynamically loaded via a helper function
inside libsystemd-shared.so, the resulting dlopen ELF note was not
propagated to the invoking executable's ELF metadata.

This commit explicitly annotates each executable with the relevant
dlopen ELF notes for any optional dependencies it might potentially
load. This ensures that package managers and build systems can properly
discover runtime dependencies that are triggered indirectly.
2026-07-10 16:35:19 +09:00
Yu Watanabe 1f76654f94 meson: automate .standalone variant generation via extended 'install' field
Extend the 'install' keyword for executable definitions to accept four
modes—'yes', 'no', 'both', and 'static'—to elegantly manage the creation
and installation of both shared and statically-linked (.standalone) binaries.

- 'yes' / 'no': Standard behavior (mapped to true/false).
- 'both': Installs both the shared and static variants.
- 'static': Installs the static variant under the original name, while
  suffixing the uninstalled shared variant with '.shared'.

With this change, any arbitrary executable can now have its `.standalone`
variant built on demand simply by invoking `ninja <target>.standalone`.
For example, `varlinkctl` did not previously support a standalone variant,
but it can now be built explicitly via `ninja varlinkctl.standalone`.

These `.standalone` binaries are not built by default unless explicitly
specified as a ninja target or enabled via `-Dstandalone-binaries=true`.
Thus, the default build time should remain unaffected.

This centralisation eliminates a massive amount of boilerplate and duplicated
target declarations across almost all subdirectories (e.g., systemd-repart,
systemd-tmpfiles, systemd-shutdown, and systemd-report tools).
2026-07-10 16:29:53 +09:00
Zbigniew Jędrzejewski-Szmek aad1e61010 meson: adjust naming of '*extract*' variables 2026-07-07 13:40:13 +02:00
Zbigniew Jędrzejewski-Szmek f00ccf93b7 meson: rename extract+objects to export+import
We have two concepts: a list of files that should be extracted from an
intermediate build artifact to be used in a later build artifact, and for a
given artifact, a list "donors". The first list was called "extract", because
it is passed to the .extract_objects() meson function, and the second was
called "objects", because that is the meson parameter to specify pre-built
objects files (6350d2dbd9). But this naming is
confusing: we don't care about the 'extract' step, this is something internal
to the build machinery. And 'objects' is a very generic term.

Let's use 'export' for the stuff that is "exported" for other binaries to use,
and 'import' to say where to import from. Those terms are symmetrical and the
association between them should be intuitive. (If you think the terms are
actually assymetrical, there are precedents for confusing the import with the
import sources. E.g. in modern English, turkeys are called so because they were
imported from the Americas and guineafowls were imported from Africa via
Türkiye and all that foreign stuff is alike.)
2026-07-07 13:40:13 +02:00
Yu Watanabe 5280cd7bdb tree-wide: check if necessary cflags dependencies are set
This makes each `foo_cflags` dependency define a `SYSTEMD_CFLAGS_MARKER_FOO`
macro, and checks if the macro is set when headers provided by external
libraries are included.

With this, we can fail fast at compile time if necessary `_cflags`
dependencies are omitted in meson.build. Missing dependencies found by this
mechanism have been added across the tree.
2026-07-03 21:50:45 +09:00
dongshengyuan 68b59ca74f systemctl: fix continue placement in clean-or-freeze error handling
When sd_bus_call() fails, the continue was inside the
'if (ret == EXIT_SUCCESS)' guard, so only the first failure skipped
adding the unit to the job waiter. On the second and subsequent
failures, the unit was still passed to bus_wait_for_units_add_unit()
despite no job being started, causing bus_wait_for_units_run() to
hang indefinitely.

Move continue outside the guard so any failure skips the waiter
registration. The guard still prevents ret from being overwritten by
a later error code.

Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
2026-06-25 16:40:28 +08:00
Lennart Poettering cc174775f5 core: add socket xattr settings for socket unit 2026-06-23 22:55:23 +02:00
Luca Boccassi 32a162dbb9 core: add method to enqueue multiple jobs in a single call (#42182)
Currently only a single job for a single unit can be enqueued
atomically,
so there is no guarantee that, e.g., starting a unit and its socket
at the same time will happen in the same transaction. That forces
callers to 'know' the right order in which to start new units being
installed, or failures will occur. It also means some ordering
constraints are ignored, in case the separate calls are done
in the wrong manual order.

Add a new EnqueueUnitJobMany() D-Bus method that takes a list of units
to start.
2026-06-22 21:35:17 +01:00
Luca Boccassi 8b25e0f85e systemctl: use new EnqueueUnitJobMany() when available
Fixes https://github.com/systemd/systemd/issues/7877
Replaces https://github.com/systemd/systemd/pull/7947
2026-06-22 21:19:16 +01:00
Luca Boccassi ee7c04873e systemctl: add --kernel-cmdline-reuse option
kexec-tools has a --reuse-cmdline option which is very convenient
when doing a lot of reboots, add the same to systemctl.
Dedup options, letting the last one wins in case of duplicates,
so that 'systemctl kexec --reuse-cmdline' can be chained many times
without continuosly expanding the cmdline with duplicates from
the boot entry.
2026-06-22 14:02:52 +01:00
Luca Boccassi 441514184f 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".

Follow-up for f1d345ed76
2026-06-11 09:43:09 +02:00
Rocker Zhang a52e0f87f5 systemctl: also attempt kexec image extraction on EINVAL
load_kexec_kernel() retries kexec_file_load() with an extracted kernel
(decompressed Image / ZBOOT PE / UKI) when the kernel rejects the image,
but it only does so when kexec_file_load() failed with ENOEXEC. On arm64
that retry never happens: arm64's image_probe()
(arch/arm64/kernel/kexec_image.c) returns -EINVAL on an ARM64_IMAGE_MAGIC
mismatch, whereas x86's bzImage64_probe() and the generic
kexec_image_probe_default() return -ENOEXEC. So `systemctl kexec` of a
UKI on arm64 skips the extraction path and falls back to the
/usr/sbin/kexec binary, which is no longer a dependency since e107c7ead0
("systemctl: replace kexec-tools dependency with direct kexec_file_load()
syscall") -- leaving kexec broken.

Accept EINVAL in addition to ENOEXEC. This is safe: the extraction in
kexec_maybe_decompress_kernel() re-gates on the actual file magic (MZ /
compression headers) and is a no-op returning 0 for anything else, so an
EINVAL that is not a format mismatch just falls through to the existing
fallback as before.

Fixing this in systemd (rather than only in the kernel) is appropriate:
systemd must keep working with already-shipped arm64 kernels whose
kexec_file_load() returns EINVAL for an unrecognized image magic.

Relates to: https://github.com/systemd/systemd/issues/28538

Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 19:00:58 +01:00
Daan De Meyer 74d392ed1b tree-wide: standardize header names across src/fundamental, src/basic and src/shared
Drop the -fundamental suffix from src/fundamental/ headers in favor of names
that match their src/basic/ or src/shared/ counterparts (e.g.
macro-fundamental.h -> macro.h, assert-fundamental.h -> assert-util.h,
cleanup-fundamental.h -> cleanup-util.h). Rename src/basic/{btrfs,label}.{c,h}
to use the -util suffix to match the existing shared/btrfs-util and
shared/label-util siblings. Rename src/shared/mkdir-label.{c,h} to mkdir.{c,h}
and src/shared/tmpfile-util-label.{c,h} to tmpfile-util.{c,h} to match the
corresponding src/basic names.

This saves us from having to come up with separate names for files that do
the same thing across tiers, and it makes it easier to move stuff between
src/fundamental, src/basic and src/shared: consumers just #include "foo.h"
and pick up whichever tier their -I path resolves to first, so call sites
don't need to be updated when an API moves between layers.

Where a higher-tier wrapper exists (e.g. src/basic/macro.h wrapping
src/fundamental/macro.h), the wrapper uses an explicit "../fundamental/foo.h"
or "../basic/foo.h" relative include for the lower-tier header. We can't use
GCC's #include_next directive for this — when the wrapper is reachable both
via same-dir-as-source lookup and via -I (e.g. -Isrc/shared) for the
directory it lives in, #include_next advances by exactly one slot in libcpp's
internal directory chain and lands on the same physical directory it was
already in, never reaching the lower-tier sibling (see make_cpp_dir() in
gcc/libcpp/files.cc:1986).

To make sure the right headers are always picked up, the include directories
are reordered so that e.g. src/shared always takes priority over src/basic and
similar for the other directories.

Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 10:33:03 +09:00
Daan De Meyer a14adac423 meson: drop libdl, threads, and librt dependencies
Our baseline glibc is 2.34, which merged libdl, libpthread (the
dependency('threads') target), and librt into libc. Empty .so/.a stubs
remain for backward compatibility with old binaries, but new builds
resolve dl_*, pthread_*, mq_*, timer_*, etc. directly from libc.
On musl the same libraries are likewise empty stubs.

Drop the libdl, threads, and librt entries from every meson.build, and
remove the now-stale 'Libs.private: -lrt -pthread' from libudev.pc.in
since both flags resolve to empty link-time stubs on glibc 2.34+ and
musl.

Verified with readelf -d that libsystemd.so, libudev.so, and systemd no
longer carry DT_NEEDED entries for libdl/libpthread/librt.
2026-05-18 21:17:38 +00:00
Zbigniew Jędrzejewski-Szmek 39a3647539 tree-wide: get rid of old dispatch_verb
Also rename dispatch_verb_with_args to dispatch_verb.
2026-05-16 18:37:10 +02:00
Zbigniew Jędrzejewski-Szmek cf88903637 tree-wide: get rid of most uses of ALIGN_PTR
This bothered me for a while, but I didn't think too much about it and just
copied the existing usage pattern. But it really doesn't make sense. We expect
the compiler to align the section properly. But if it didn't align it, applying
alignment after the fact would just cause our pointer to point to the middle
of the structure. That'd be even worse than a misaligned pointer.

Similarly, when doing pointer arithmetic, p++ should really result in a value
with the appropriate alignment. This is the basic principle of C pointer
addition. So we really shouldn't try to adjust the pointer ourselves. At most,
we can assert that it is indeed aligned in tests.
2026-05-16 18:32:14 +02:00
Zbigniew Jędrzejewski-Szmek 4a30028c85 fuzz-systemctl-parse-argv: update suppression of logging and resetting of state
There's certainly more than one way to skin this particular cat,
so I'm keeping this as a separate commit.
2026-05-14 09:38:10 +02:00
Zbigniew Jędrzejewski-Szmek 23ba690cca systemctl: convert shutdown_parse_argv to OPTION macros
Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 09:15:48 +02:00
Zbigniew Jędrzejewski-Szmek 45828705d6 systemctl: convert halt_parse_argv to OPTION macros
Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 09:15:48 +02:00
Zbigniew Jędrzejewski-Szmek 52185521f0 systemctl: convert verbs to VERB macros
systemctl_main() is moved to systemctl.c to allow fuzz-systemctl-parse-argv
to compile. It needs systemctl_help(), which needs the verb table, with the
expected groups. Once we provide that, the linker needs all the verb_*
functions. So add dummy implementations in fuzz-systemctl-parse-argv to
allow the link to happen.

The alternative would be to provide an empty option table, but that
seems to be more complicated, and also can simulate parsing of the whole
command line with the full verb set, so it seems better to test with the
real verb table.

$ nm build/fuzz-systemctl-parse-argv | rg 0000000000418885
0000000000418885 T verb_add_dependency
0000000000418885 T verb_bind
0000000000418885 T verb_cancel
0000000000418885 T verb_cat
0000000000418885 T verb_clean_or_freeze
0000000000418885 T verb_edit
0000000000418885 T verb_enable
0000000000418885 T verb_get_default
0000000000418885 T verb_import_environment
0000000000418885 T verb_is_active
0000000000418885 T verb_is_enabled
0000000000418885 T verb_is_failed
0000000000418885 T verb_is_system_running
0000000000418885 T verb_kill
0000000000418885 T verb_list_automounts
0000000000418885 T verb_list_dependencies
0000000000418885 T verb_list_jobs
0000000000418885 T verb_list_machines
0000000000418885 T verb_list_paths
0000000000418885 T verb_list_sockets
0000000000418885 T verb_list_timers
0000000000418885 T verb_list_unit_files
0000000000418885 T verb_list_units
0000000000418885 T verb_log_setting
0000000000418885 T verb_mount_image
0000000000418885 t verb_noop
0000000000418885 T verb_preset_all
0000000000418885 T verb_reset_failed
0000000000418885 T verb_service_log_setting
0000000000418885 T verb_service_watchdogs
0000000000418885 T verb_set_default
0000000000418885 T verb_set_environment
0000000000418885 T verb_set_property
0000000000418885 T verb_show
0000000000418885 T verb_show_environment
0000000000418885 T verb_start_special
0000000000418885 T verb_start_system_special
0000000000418885 T verb_switch_root
0000000000418885 T verb_trivial_method
0000000000418885 T verb_whoami
2026-05-14 09:13:20 +02:00
Zbigniew Jędrzejewski-Szmek 91249f8004 systemctl: convert parse_argv to OPTION macros
The verbs[] table still lives in systemctl-main.c — only the option parsing
side is migrated. systemctl_dispatch_parse_argv() gains a remaining_args
out-param so run() can pass the parsed positional args to systemctl_main(),
which dispatches via _dispatch_verb_with_args() instead of dispatch_verb().

The Options section of --help now renders from the OPTION declarations; the
verb sections still use raw printfs and will be converted alongside the
verbs[] migration.

Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 09:03:13 +02:00
Zbigniew Jędrzejewski-Szmek 137736dd64 systemctl: reorder cases in parse_argv() to match order in --help
Compatibility-only options (--fail, --irreversible, --ignore-dependencies,
--no-legend) are grouped at the end alongside the '.' / '?' error handlers.
The case 'P': … _fallthrough_; case 'p': pair is kept intact and placed at
-p's slot in --help, so -P sits immediately before -p in the source.

Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 09:03:13 +02:00
Zbigniew Jędrzejewski-Szmek f01b3122e3 systemctl: split out helper for --what and allow resetting
Analogous to parent commit.
2026-05-14 09:03:13 +02:00
Zbigniew Jędrzejewski-Szmek 04bf62b012 systemctl: split out helper for --type= and allow resetting
Analogous to grandparent commit.
2026-05-14 09:03:12 +02:00
Zbigniew Jędrzejewski-Szmek ae83ce85b9 systemctl: split out helper for --property=
We explicitly handled --property= in a specific way, so preserve
that behaviour.
2026-05-14 09:03:11 +02:00
Zbigniew Jędrzejewski-Szmek 979ecbb14e systemctl: split out helper for --state= and allow resetting
So far we'd reject --state=, but it seems nicer to make it reset the
setting as we generally do. The output variable is modified in place…
Option parsing isn't atomic anyway, so I think it's fine to to that.
2026-05-14 09:03:11 +02:00
Diego Viola 5d17215c7e treewide: fix typos in the entire codebase
Signed-off-by: Diego Viola <diego.viola@gmail.com>
2026-05-05 17:22:26 +02:00
Zbigniew Jędrzejewski-Szmek f7434671bd shared/help-util: automatically append ":" in sections 2026-05-05 11:14:33 +02:00
Lennart Poettering 44c8bce3a0 ac-power,notify,systemctl: port 3 tools over to new --help APIs
Let's port over a few tools, to showcase the new logic.
2026-04-24 15:04:16 +02:00
Lennart Poettering 812aa57d2c string-util: beef up string_is_safe()
This tightens the checks of string_is_safe() and then adds flags to
relax certain aspects of it.

This does alter the rules on certain strings we pass a bit. We mostly
tighten the rules (but I think it's find and good) but we relax them on
others.

I let claude review the changes in behaviour for the various call sites
that I made. It summarized things in this table:

  ╭───────────────────────────────────────────────────┬──────────────────────────────────────────────╮
  │ CALL SITE                                         │ EFFECTIVE DELTA                              │
  ├───────────────────────────────────────────────────┼──────────────────────────────────────────────┤
  │ src/basic/syslog-util  log_namespace_name_valid   │ +UTF-8 required (globs already blocked)      │
  │ src/bootctl  --efi-boot-option-description        │ RELAXED: '\' and quotes now permitted        │
  │ src/core/dbus-manager  pretimeout governor        │ +UTF-8, +no-globs                            │
  │ src/core/load-fragment  ExecStart= path           │ +UTF-8, +no-globs                            │
  │ src/core/main  pretimeout governor (kcmdline)     │ +UTF-8, +no-globs                            │
  │ src/core/service  sd_notify STATUS=               │ +no-globs (ASCII-only preserved)             │
  │ src/home/homectl  --<identity field>=             │ empty now REJECTED; +UTF-8                   │
  │ src/libsystemd-network  dhcp_option_parse_string  │ (equivalent, just explicit)                  │
  │ src/libsystemd-network  sd_dhcp_server boot_fname │ ""→NULL coerced; else equivalent             │
  │ src/libsystemd/journal  SYSLOG_IDENTIFIER fb      │ +UTF-8, +no-globs                            │
  │ src/libsystemd/sd-json  SD_JSON_STRICT strings    │ +UTF-8 required                              │
  │ src/login/logind  session desktop=                │ +UTF-8 required                              │
  │ src/pcrlock  EFI variable string                  │ +UTF-8                                       │
  │ src/pcrlock  EFI action string                    │ RELAXED: empty + '\' now ok; +UTF-8          │
  │ src/resolve  dns-delegate id (from filename)      │ +UTF-8, +no-globs                            │
  │ src/shared/boot-entry  boot_entry_token_valid     │ (equivalent)                                 │
  │ src/shared/conf-parser  section header            │ +UTF-8, +no-globs                            │
  │ src/shared/conf-parser  CONFIG_PARSE_STRING_SAFE  │ +UTF-8 required                              │
  │ src/shared/kbd-util  keymap_is_valid              │ (equivalent; folded into STRING_FILENAME)    │
  │ src/shared/tpm2  nvpcr name                       │ +UTF-8 required                              │
  │ src/shared/vconsole  x11 layout/model/variant/opt │ +UTF-8, +no-globs                            │
  │ src/systemctl  --kernel-cmdline=                  │ +0x7f DEL rejected; empty path split out     │
  │ src/veritysetup  salt=                            │ RELAXED: safety check removed entirely       │
  │ src/vmspawn  --ssh-key-type=                      │ +UTF-8 required                              │
  ╰───────────────────────────────────────────────────┴──────────────────────────────────────────────╯
2026-04-21 17:07:53 +02:00
Luca Boccassi 2e79f8aa41 systemctl: add --kernel-cmdline= argument
Allows appending kernel command line arguments, like
kexec-tool does. This is especially needed for the integration
tests, as mkosi adds a bunch of options that are needed for the
test suite to work, and it breaks without them.
2026-04-17 13:58:05 +01:00
Zbigniew Jędrzejewski-Szmek 1726224b07 many: final final set of coccinelle check-pointer-deref tweaks (#41595)
I promised in https://github.com/systemd/systemd/pull/41426 that its the
final update for coccinelle pointer deref checks. However it turned out
there is this coccinelle/parsing_hacks.h that I wasn't aware of. The
file missed some important things like _cleanup_(x) that prevented
coccinelle to check a bunch of functions.

This PR adds some missing defines to the parsing_hacks.h and fixes the
missing asserts(). I apologize that its a bit long (and frankly boring)
and that I missed this earlier.

The last commit contains one small behavior change (ret in
sd_varlink_idl_parse() is now really optional) but the big one is very
mechanical.
2026-04-13 13:59:24 +02:00
Arnout Engelen 086707ba79 run: allow setting output format
This is useful when moving from `--pty` or `--pipe` to using
`--verbose`: you can use `--verbose-output=cat` to get similar output on
stdout while still having all of the advantages of `--verbose` over the
other options.
2026-04-13 13:38:04 +02:00
Daan De Meyer e107c7ead0 systemctl: replace kexec-tools dependency with direct kexec_file_load() syscall
Replace the fork+exec of /usr/bin/kexec in load_kexec_kernel() with a
direct kexec_file_load() syscall, removing the runtime dependency on
kexec-tools for systemctl kexec.

The kexec_file_load() syscall (available since Linux 3.17) accepts
kernel and initrd file descriptors directly, letting the kernel handle
image parsing, segment setup, and purgatory internally. This is much
simpler than the older kexec_load() syscall which requires complex
userspace setup of memory segments and boot protocol structures — that
complexity is the raison d'être of kexec-tools.

The implementation follows the established libc wrapper pattern: a
missing_kexec_file_load() fallback in src/libc/kexec.c calls the
syscall directly when glibc doesn't provide a wrapper (which is
currently always the case). The syscall is not available on all
architectures — alpha, i386, ia64, m68k, mips, sh, and sparc lack
__NR_kexec_file_load — so the wrapper and caller are guarded with
HAVE_KEXEC_FILE_LOAD_SYSCALL to compile cleanly everywhere.

When kexec_file_load() rejects the kernel image with ENOEXEC (e.g. the
image is compressed or wrapped in a PE container that the kernel's kexec
handler doesn't understand natively), we attempt to unwrap/decompress
and retry. This is effectively the same decompression and extraction
logic that already lives in src/ukify/ukify.py (maybe_decompress() and
get_zboot_kernel()), now implemented in C so that systemctl can handle
it natively without shelling out to external tools:

 - Compressed kernels (Image.gz, Image.zst, Image.xz, Image.lz4): the
   format is detected by magic bytes (per RFC 1952, RFC 8878,
   tukaani.org xz spec, and lz4 frame format spec) and decompressed to
   a memfd using the existing decompress_stream_*() infrastructure plus
   the new gzip support from the previous commit. This is primarily
   needed on arm64 where kexec_file_load() only accepts raw Image files.
   On x86_64, bzImage is already the native format and works directly.

 - EFI ZBOOT PE images (vmlinuz.efi): detected by "MZ" + "zimg" magic
   at the start of the file. The compressed payload offset, size, and
   compression type are read from the ZBOOT header defined in
   linux/drivers/firmware/efi/libstub/zboot-header.S.

 - Unified Kernel Images (UKI): detected as PE files with a .linux
   section via the existing pe_is_uki() infrastructure. The .linux
   section (kernel) and optionally .initrd section are extracted to
   memfds. When a UKI provides an embedded initrd and the boot entry
   doesn't specify one separately, the embedded initrd is used.

The try-first-then-decompress approach means we never decompress
unnecessarily: on x86_64 the first kexec_file_load() call succeeds
immediately with the raw bzImage, and on architectures where the
kernel's kexec handler natively understands PE (like LoongArch with
kexec_efi_ops), ZBOOT/UKI images work without decompression too.

If kexec_file_load() is unavailable (architectures without the syscall)
or all attempts fail, we fall back to forking+execing the kexec binary.
This preserves compatibility on architectures like i386 and mips where
only the older kexec_load() syscall exists and kexec-tools is needed to
handle the complex userspace setup.

Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 11:13:04 +02:00
Michael Vogt bd141bd818 many: fix remaining check-pointer-deref issues
The updated parsing_hacks.h file uncovered a bunch of extra
things that the check-pointer-deref coccinelle script flags.

This commit fixes them to make the tree check-pointer-deref clean.
2026-04-12 15:27:15 +02:00
Zbigniew Jędrzejewski-Szmek 1008583c91 tree-wide: print error if table_print() fails
We generally want to print an error message if table_print()
fails. Add a helper function for this and use it consistently.
This does one of the three things depending on the call site:
- a no-change reformatting of the code
- change from a custom message to the generic one
- addition of the error message where previously none was printed

In the third case, the actual use impact is very small, since the
table formatting is very unlikely to fail. But if it did, we would
often return an error without any message whatsoever, which we
never want to do.
2026-04-03 13:05:03 +02:00
Zbigniew Jędrzejewski-Szmek 0ce5a8fb4e tree-wide: drop flush&check step after table printing
Almost all callers of table_print() specify stdout or NULL (equivalent
to stdout) as the output stream. Simplify things by not requiring the
the stream to be specified.

In almost all cases, the printing of the table is surrounded by normal
printfs() that don't do explicit flushing and for which we don't check
the output stream status. Let's simplify most callers and skip this
step. The reason is not so much to avoid the extra step itself, but
instead to avoid the _handling_ of the potential failure. We generally
only want to print an error message for ENOMEM and other "internal"
errors, so strictly speaking we should filter out the errors from the
stream. By skipping the flush&check step we implicitly do this.
2026-04-03 13:04:40 +02:00