Commit Graph
420 Commits
Author SHA1 Message Date
Lennart Poettering 0df41e9329 cryptenroll: expose enrollment as an io.systemd.CryptEnroll Varlink service
Add a Varlink interface for systemd-cryptenroll, building on the EnrollContext
introduced previously. A single Enroll method covers password, recovery-key and
FIDO2 enrollment; PKCS#11 and TPM2 are not exposed for now (they are not
part of the EnrollMechanism allowlist, so the generic InvalidParameter error
applies). A ListSlots method enumerates the currently enrolled keyslots.

The dispatcher populates the same EnrollContext the command line uses and then
runs the shared enroll_now()/prepare_luks()/wipe_slots() paths, so both
front-ends behave identically. FIDO2 enrollment that requires user presence
reports an imminent touch via a non-terminating "state":"touch" reply when the
caller passes 'more'. Credential material (password, FIDO2 PIN, recovery key)
is handled as sensitive, and key files may be passed either by path or as an
fd index.

The server is allocated root-only plus caller's-own-UID, with the listening
socket created in 0644 mode.

Replaces: #31096
2026-06-27 17:28:39 +02:00
Yu Watanabe d983d231eb resolvectl: use more varlink (#41840)
There are already varlink methods for `ResolveHostname`,
`ResolveAddress`, and `ResolveRecord`. Use those in `resolvectl` instead
of the dbus equivalents.
2026-06-27 12:21:19 +09:00
Nick Rosbrook 35d611622a resolvectl: use varlink instead of dbus for ResolveHostname 2026-06-26 16:03:18 -04:00
Philip Withnall 2d201a107b sysupdate: Add basic varlink interface scaffolding
This adds the scaffolding for being able to call sysupdate via varlink,
but it doesn’t yet define or implement any methods. Those will come in
following commits.

The existing `systemd-sysupdate.service` and `systemd-sysupdate.timer`
(which periodically ran `systemd-sysupdate update`) have been renamed
to `systemd-sysupdate-update.{service,timer}` to make way for a new
`systemd-sysupdate@.service` and `systemd-sysupdate.socket` file to
handle varlink activation.

Compatibility symlinks have been added for them.
2026-06-26 13:01:31 +01:00
Lennart Poettering 46ece03c99 vmspawn: deliver credentials via initrd cpio under SEV-SNP (#42272)
Re-enables `--set-credential=` / `--load-credential=` under
`--coco=sev-snp` by packaging credentials into a cpio appended to the
initrd, mirroring what `systemd-stub` does for ESP-sourced credentials.
The initrd is covered by the launch measurement via `kernel-hashes=on`,
so the credentials are too.

Tested end-to-end on an SNP-capable host: credentials passed via
`--set-credential=` land in `/run/credentials/@encrypted/` inside the
guest.
2026-06-25 22:08:08 +02:00
Lennart Poettering d36bdc9467 sysupdate: notify hook subscribers after a successful update
Define a new io.systemd.SysUpdate.Notify Varlink interface with a single
OnCompletedUpdate() method, and after sysupdate successfully installs an
update, invoke that method on every socket linked into
/run/systemd/sysupdate/notify/ via varlink_execute_directory(). This
gives other components a hook to react to applied updates (e.g. recompute
a TPM policy, link a freshly downloaded kernel, refresh extensions).

The notification carries the component name, the installed version and the
list of updated resources (transfer id + on-disk path). Subscribers are
free to ignore the parameters and just treat the call as a trigger.

Setting SYSTEMD_SYSUPDATE_FORCE_NOTIFY=1 forces the notification to be sent
even when no update was applied (in which case no resource list is included),
so follow-up work can be triggered unconditionally.

Fixes: #35988
2026-06-24 13:05:33 +02:00
Paul Meyer 62fde7bc06 shared: add userspace cpio writer for credentials
Add a small newc-format cpio encoder that builds an archive with each
credential as a file under .extra/system_credentials/<id>.cred and
writes it to a temp file. This mirrors what systemd-stub produces from
ESP credentials, so PID1's import_credentials_boot() picks them up
unchanged via the new /.extra/system_credentials/ initrd path.

Motivated by vmspawn under SEV-SNP, where SMBIOS credentials aren't
covered by the launch measurement and are discarded by PID1 in
confidential guests, so they must be delivered via the measured initrd
instead. The writer lives in src/shared/ so other host-side tooling
can reuse it.

Signed-off-by: Paul Meyer <katexochen0@gmail.com>
2026-06-24 12:47:42 +02:00
Paul Meyer 52017193e2 shared: add configfs-tsm attestation report helper
Add tsm_report_acquire(), a thin wrapper around the kernel's
/sys/kernel/config/tsm/report/ configfs interface for fetching a
confidential-computing attestation report (SEV-SNP, TDX, ...), including
a caller supplied input.

Signed-off-by: Paul Meyer <katexochen0@gmail.com>
2026-06-22 20:42:35 +02:00
Lennart Poettering 7683c3281c report: turn systemd-report itself into a varlink service
Add a Varlink API for requesting a report.
2026-06-19 05:23:18 +02:00
Lennart Poettering 3c2f7c6002 report: add support for optionally signing reports
These signatures can be provided by arbitrary Varlink backends symlinked
into /run/systemd/report/sign.

Also add a proper Varlink IDL for the upload interface, since we are
extended it now.
2026-06-19 05:23:18 +02:00
Chitoku 85afe8e82d vsock-util: allow VMADDR_CID_ANY as local CID if enabled in hwdb
On Hyper-V guests, `VMADDR_CID_ANY` is valid as per implementation in
kernel driver: net/vmw_vsock/hyperv_transport.c.

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

Follow-up for 83359c4da0
2026-06-13 15:54:50 +02:00
Daan De Meyer 1d102a663e meson: Add libucontext to libshared_deps
Fixes #42236
2026-05-21 19:41:37 +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
Daan De Meyer 7d822ca8af bpf-util: rename from bpf-dlopen, unify version-specific symbol handling
Renames src/shared/bpf-dlopen.{c,h} to src/shared/bpf-util.{c,h} and
folds the former src/shared/bpf-compat.h (struct forward decl and
compat_bpf_map_create() helper) into the new header.

Aligns dlopen_bpf() with the standard wrapper pattern: drops the
manual dlopen_safe()/dlsym_many_or_warn()/TAKE_PTR(dl) plumbing and
the bespoke 'cached' int in favor of dlopen_many_sym_or_warn() inside
a FOREACH_STRING() soname-fallback loop.

Unifies declaration of the version-specific symbols (bpf_create_map,
bpf_map_create, bpf_object__next_map, bpf_token_create) into a single
DISABLE_WARNING_REDUNDANT_DECLS block in the header, and alphabetically
merges the DLSYM_PROTOTYPE list. DLSYM_OPTIONAL is used to load each
one — call sites already handle NULL (compat_bpf_map_create() and the
sym_bpf_object__next_map guard in userns-restrict.c). bpf_token_create
additionally defaults to a missing_bpf_token_create() stub returning
-ENOSYS, so callers can branch on the errno instead of NULL-checking
the pointer.

Updates test-bpf-token to match: drops the compile-time
LIBBPF_MAJOR_VERSION ≥ 1.5 gate and the direct <bpf/bpf.h> include in
favor of dlopen_bpf() + sym_bpf_token_create(), and treats -ENOSYS as
the test-skip path (covering both 'libbpf too old' and 'kernel lacks
BPF_TOKEN_CREATE support').
2026-05-18 21:17:38 +00:00
Luca Boccassi 79ac52b810 Add helpers for talking to /dev/liveupdate
This character device is the main kernel interface to deal with the
Live Update Orchestrator (LUO) feature. Add some basic wrappers for
the ioctls.

https://docs.kernel.org/userspace-api/liveupdate.html
2026-05-15 13:46:08 +01:00
Christian Brauner efb0a0fa7a shared: move storage-util to libshared
The storage backend providers (block, fs) and storagectl currently each
extract storage-util.c into their target. Several upcoming consumers
(machine-util's BindVolume parser, vmspawn's hotplug glue, machinectl's
new bind-volume verbs) need the StorageProvider type/string-table
helpers and a future shared Acquire client helper.

Move storage-util.{c,h} to src/shared so libshared exports the symbols
once and every consumer (storage providers, storagectl, libshared
itself) picks them up by linking libshared. Drop the now-redundant
'extract'/'objects' wiring in src/storage/meson.build.

No code changes; this is purely a relocation.

Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-06 10:30:16 +02:00
Zbigniew Jędrzejewski-Szmek 937129d1f6 Merge facts into metrics and add systemd-report generate/upload (#41688) 2026-05-05 20:55:36 +02:00
Michael Vogt 628ab0040e report: fold io.systemd.Basic facts into metrics
We removed the concept of facts, so we need to update the existing
io.systemd.Basic facts provider to metrics. This commit does just
that. Its mostly mechanical.

This also means that facts.{c,h} and varlink-io.systemd.Facts.{c,h}
are gone now.
2026-05-05 18:13:28 +02:00
Lennart Poettering 087fa20166 shared: add io.systemd.StorageProvider Varlink interface
Generic Varlink API for services that hand out file descriptors to
storage volumes. Three methods: Acquire() returns an fd for a named
volume (optionally creating it from a template), ListVolumes()
enumerates available volumes, ListTemplates() enumerates supported
creation templates. Volume types follow kernel inode-type naming:
blk (block device), reg (regular file), dir (directory).

Intent is that multiple providers can sit behind AF_UNIX sockets in a
well-known directory and be consumed uniformly by nspawn, vmspawn,
the service manager (BindVolume=) and similar tools.
2026-04-29 12:25:46 +02:00
Michael Vogt 9c39db197b varlink: add new io.systemd.Job interface
This commit creates a new varlink-io.systemd.Job.c file and puts
the job related varlink types into this file. Those will be
used by the upcoming io.systemd.Unit.StartTransient.

Note that the property names follow the D-Bus naming to make a
future "systemctl show" transition from D-Bus -> varlink easier.

Thanks to @ikruglov for suggesting this preparation commit and
to Lennart for suggesting the D-Bus compatibility considerations.
2026-04-27 13:49:19 +02:00
Zbigniew Jędrzejewski-Szmek b045a2fa6f add helpers for unified --help formatting (#41805)
I see --help output formatting as contiuation of @keszybz's work on
options.[ch], hence let's start to add some really basic infrastructure
to unify the --help output more.
2026-04-25 11:23:18 +02:00
Lennart Poettering bbf197cda6 help-util: add helpers for generating uniform --help texts
Let's introduce some helpers for generating uniform --help texts with
some minimal ANSI styling.

This shortens the help() functions generally, and allows us to change
the style at a single, central place.

This mostly just follows our current styling for --help, but it makes
two updates to it:

1. The command line summary at the very top of the --help text is now
   prefixes with a grey ">" character to indicate it's a command line.

2. The human language introductionary description/abstract right after
   that command line is set in italics, to emphasize it's not dry,
   technical, structural information, but more human friendly prose.
2026-04-24 15:04:16 +02:00
Christian Brauner 67cd0977cd vmspawn-varlink: drop AcquireQMP stub and QemuMachineInstance interface
The AcquireQMP() method was a placeholder that always returned
EOPNOTSUPP, reserving room for a future id-rewriting QMP multiplex
proxy. The broader direction is for systemd-vmspawn to remain the single
source of truth for VM control rather than exposing raw QMP to clients.

Since AcquireQMP was the only method on io.systemd.QemuMachineInstance
(and AlreadyAcquired was its only error), remove the whole interface
along with the stub, and update the controlAddress field comment in
io.systemd.Machine to stop referencing it.

Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-04-24 14:39:25 +02:00
Christian Brauner 258c667845 shared: extract disk-spec parsing into machine-util
Move the ImageFormat / DiskType enums and their string tables out of
vmspawn's private settings header into a new src/shared/machine-util,
and add parse_disk_spec() — the colon-prefix loop that turns
"[FORMAT:][DISKTYPE:]PATH" into the two enums plus a normalized path.

No behavior change for vmspawn. A follow-up machinectl attach-disk
change accepts the same syntax and consumes the shared helper.

Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-04-24 14:39:24 +02:00
Daan De Meyer 8c3f64e61f tree-wide: Load libcrypto and libssl via dlopen()
Until now OpenSSL was linked into every binary and library that needed
cryptography, pulling libcrypto (and, for resolved, libssl) into the
address space of services that never touch them at runtime. This commit
moves all OpenSSL usage behind the same dlopen helper pattern that we
already use for other optional libraries (libpam, libseccomp, libxz, …)
so libcrypto/libssl are only loaded on demand.

The bulk of the work lives in src/shared/crypto-util.{c,h} (libcrypto)
and src/shared/ssl-util.{c,h} (libssl), which replace the previous
src/shared/openssl-util.{c,h}:

 - crypto-util.{c,h} declares every libcrypto function we call via
   DLSYM_PROTOTYPE() and resolves them inside dlopen_libcrypto().

 - ssl-util.{c,h} holds the libssl-specific DLSYM_PROTOTYPEs,
   dlopen_libssl(), and the SSL_freep cleanup helper, so translation
   units that only need libcrypto do not pull in libssl declarations.

 - Callers refer to the symbols through sym_* aliases rather than the
   original names.

 - Convenience macros that used to be provided by the OpenSSL headers
   (OPENSSL_free, BN_num_bytes, the sk_TYPE_* helpers, …) are
   reimplemented as sym_* wrappers so no code path needs to fall back
   to the linker-resolved symbols.

 - All _cleanup_ helpers are redefined in terms of the sym_* variants
   (EVP_PKEY_freep, X509_freep, BIO_freep, …) so cleanup attributes
   keep working without pulling in libcrypto symbols at link time.

 - The public crypto-util.c entry points (openssl_pubkey_from_pem,
   openssl_digest_many, openssl_hmac_many, openssl_cipher_many,
   kdf_ss_derive, kdf_kb_hmac_derive, rsa_* / ecc_* helpers,
   pubkey_fingerprint, digest_and_sign, pkcs7_new, x509_fingerprint,
   openssl_extract_public_key, pkey_generate_volume_keys, the load_*
   helpers, …) now call dlopen_libcrypto() at entry before touching any
   sym_* pointer.

The call sites across the tree have been converted to call
dlopen_libcrypto()/dlopen_libssl() at the appropriate entry point
before their first sym_* use, and to use sym_* variants throughout:

 - bootctl, sbsign, measure, pcrlock, pcrextend, tpm2-setup, repart,
   cryptsetup, cryptenroll, homectl, homed, homework, keyutil,
   sysupdate, creds, import, dissect-image, pe-binary, pkcs11-util,
   pkcs7-util, tpm2-util, creds-util. resolved additionally dlopens
   libssl for DoT.

The meson build files are updated to depend on libopenssl_cflags (a
new partial dependency that exposes include paths and compile flags
only, not the linker flags) instead of libopenssl for every target that
previously linked against OpenSSL. Nothing links against libcrypto or
libssl directly anymore.

A new src/sbsign/authenticode.c hosts the Authenticode ASN.1 type
definitions that used to live inline in sbsign.c. The OpenSSL
ASN1_SEQUENCE / ASN1_CHOICE / IMPLEMENT_ASN1_FUNCTIONS macros expand to
code that references libcrypto symbols directly, so to keep this
translation unit unlinked from libcrypto we redirect ASN1_item_* to
the sym_* variants via #define and wrap the ASN1_*_it() getters (which
appear as constant function pointers in static initializers) in small
trampoline functions that forward to the sym_* pointers at runtime.

test-dlopen-so gains assertions for dlopen_libcrypto and dlopen_libssl
so the dlopen contract is exercised in CI, and the openssl-specific
test was renamed from test-openssl.c to test-crypto-util.c to match
the new header naming.
2026-04-24 06:32:42 +02:00
Daan De Meyer 909efb6f2e shared: load libgnutls and libmicrohttpd via dlopen
Convert the GnuTLS and libmicrohttpd usage in journal-remote to the
dlopen pattern used by other optional shared libraries. A new
src/shared/gnutls-util.{h,c} declares the GnuTLS entry points via
DLSYM_PROTOTYPE and resolves them in dlopen_gnutls(); microhttpd-util
is moved from src/journal-remote to src/shared and gains analogous
DLSYM_PROTOTYPEs plus dlopen_microhttpd(). Callers in journal-gatewayd,
journal-remote-main and microhttpd-util itself call the sym_* wrappers
and invoke dlopen_gnutls()/dlopen_microhttpd() at their entry points.

setup_gnutls_logger() no longer fails when libgnutls is missing at
runtime; it logs a notice and returns 0 so journal-gatewayd starts up
without TLS dependencies installed.

The meson files gain libgnutls_cflags and libmicrohttpd_cflags partial
dependencies that expose include paths and compile flags only. Every
systemd-journal-{gatewayd,remote,upload} target switches to the cflags
variant, dropping the direct libgnutls/libmicrohttpd link. The
gatewayd->remote object-sharing dance for microhttpd-util.o goes away
since the code now lives in libshared.

test-dlopen-so gains assertions for dlopen_gnutls and dlopen_microhttpd.
2026-04-23 06:41:05 +02:00
Daan De Meyer d49f3f287a dlopen: take log_level argument and log in fallback stubs
Every dlopen_xxx() helper now takes an int log_level argument. It is
passed through to dlopen_many_sym_or_warn() (which in turn propagates it
to dlopen_verbose() for the library-not-installed case), and is used by
the fallback stub when support for the library is not compiled in to
emit a "<lib> support is not compiled in." message at the caller's level.
Callers pass LOG_DEBUG when gracefully degrading, or a higher level when
the failure should surface, and no longer need to log redundantly at the
call site.

As part of this, dlopen_bpf_full() (which already took a log_level) is
merged into dlopen_bpf() rather than keeping both.

The static inline fallbacks used to live in the headers, which required
pulling log.h in from every header that declared a dlopen_xxx(). Move
them into the .c files instead: the declaration is always outside the
#if HAVE_XXX block, the impl sits outside the outer #if HAVE_XXX wrap
with its own internal #if HAVE_XXX/#else/#endif, and apparmor-util.c,
idn-util.c, libmount-util.c and pam-util.c are now always compiled so
they can host their stubs.
2026-04-22 17:41:42 +02:00
Daan De Meyer a066396fbc fdisk-util: load libfdisk via dlopen
Convert fdisk-util to the dlopen pattern used by other optional shared
libraries in libshared. Declare the libfdisk API entry points with
DLSYM_PROTOTYPE, resolve them in a dlopen_fdisk() helper, and call the
sym_* wrappers from the homework, sysupdate and repart binaries that
use them.

With this in place fdisk-util can live in libshared itself, linked only
against libfdisk's headers (via libfdisk_cflags). The libshared_fdisk
convenience library and the libfdisk link dependency on systemd-homework,
systemd-sysupdate, systemd-repart and systemd-repart.standalone go away.

Also add a dlopen_fdisk() check to test-dlopen-so.
2026-04-21 07:53:53 +02:00
Daan De Meyer c99e93ce0a shared/curl-util: load libcurl via dlopen
Convert curl-util to the dlopen pattern used by other optional shared
libraries in libshared (libarchive, pcre2, idn, ...). Declare the curl
API entry points with DLSYM_PROTOTYPE, resolve them in a dlopen_curl()
helper, and call the sym_* wrappers from callers. curl_glue_new() now
loads the library on first use, so consumers going through CurlGlue
pick this up automatically; journal-upload and report-upload call
dlopen_curl() directly since they use curl without the glue layer.

With this in place curl-util can live in libshared itself, linked only
against libcurl's headers (via libcurl_cflags). The libcurlutil_static
convenience library and the libcurl link dependency on systemd-imdsd,
systemd-pull, systemd-journal-upload and systemd-report go away.

Also move the easy_setopt() helper macro next to the DLSYM declarations
so all consumers use a single sym-prefixed definition, and add a
dlopen_curl() check to test-dlopen-so.
2026-04-20 21:13:58 +02:00
Zbigniew Jędrzejewski-Szmek b87bc17bf3 report: add ability to upload reports over http (#41440) 2026-04-16 22:35:05 +02:00
Zbigniew Jędrzejewski-Szmek b63373a656 meson: use a convenience lib for curl-util.c
Previously we compiled curl-util.c at least two times, and then also
shared it using the extract+object. Let's build a static "convenience lib"
for it.

(Using extract+object everywhere is not possible because the different
places where it is used are conditionalized independently so we don't
have a single "source" that is always available.)
2026-04-16 17:21:56 +02:00
Zbigniew Jędrzejewski-Szmek cdc8aadaed shared: move src/import/curl-util.h to src/shared/
Move more common definitions in the header file instead of repeating
them in bunch of places. src/import/curl-util.[ch] is renamed so that
it's shared more naturally with other components.
2026-04-15 21:27:39 +02:00
Christian Brauner 50dd55bb6e shared: add QMP client library
Async QMP client for talking to QEMU's machine monitor from
libsystemd-shared. The I/O core (buffered read/write, output queue,
event source management) follows sd-varlink's patterns.

State machine:

  INITIAL -> GREETING_RECEIVED -> CAPABILITIES_SENT -> RUNNING
                                                          |
                                                          v
                                                     DISCONNECTED

The QMP handshake (greeting + qmp_capabilities) is driven transparently
by qmp_client_invoke() through an internal qmp_client_ensure_running()
helper, matching sd-bus's bus_ensure_running() pattern. Callers never
wait for it explicitly.

qmp_client_invoke() is the only command interface: asynchronous, with
per-command callback. Slots are tracked in a Set keyed by id; replies
are dispatched by id match. SCM_RIGHTS fd passing is bundled through
QmpClientArgs and the QMP_CLIENT_ARGS_FD macro.

qmp_client_process() and qmp_client_wait() are exposed publicly,
mirroring sd_varlink_process() and sd_varlink_wait(). Callers that
need to drive the client synchronously — e.g. feature probing before
entering the sd_event main loop — can loop on them exactly like
varlink_call_internal() does on its varlink equivalents.

Other features:

- Buffered stream reader for QMP's \r\n-delimited JSON, handling
  multi-read responses (query-qmp-schema is ~200 KiB).
- Fdset id allocation via qmp_client_next_fdset_id().
- Synthetic SHUTDOWN event on unexpected disconnect.
- Disconnect detection with callback notification and pending-command
  cleanup.
- -ENOBUFS from the 16 MiB input-buffer cap is treated as recoverable
  (not a transport error).

Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-04-15 10:14:47 +02:00
Christian Brauner 49e2af9277 shared: add varlink interface definitions for machine instance control
Add three varlink interface definitions for the machine instance control
hierarchy:

- io.systemd.MachineInstance: generic operations applicable to both
  containers and VMs (PowerOff, Reboot, Pause, Resume, QueryStatus,
  SubscribeEvents). nspawn could implement this same interface later.

- io.systemd.VirtualMachineInstance: VM-specific but VMM-agnostic
  operations. Empty for now, future home for AddBlockDevice and similar.

- io.systemd.QemuMachineInstance: QEMU-specific operations. Defines
  AcquireQMP() for protocol upgrade to a direct QMP connection.

The "Instance" suffix avoids collision with machined's existing
io.systemd.Machine interface.

Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-04-15 10:14:47 +02:00
Michael Vogt d1d72563e0 logind: add io.systemd.Shutdown varlink Shutdown interface
The shutdown interface is currently only exposed via dbus. This commit
adds a comparable varlink implementation. It is inspired by the existing
dbus methods and implements PowerOff, Reboot, Halt, Kexec, SoftReboot.

It is (intentional) simpler than the dbus for now, i.e. strictly root
only. To match dbus we will need to the functionality
of verify_shutdown_creds() which is dbus-ish right now and would
need some refactor.

For the same reason it does not do the Can* methods - we will need
the verify_shutdown_creds() equivalent first.
2026-04-07 20:38:40 +02:00
Daan De Meyer 1e084aad7d shared: move machine registration to shared machine-register.{c,h}
Move register_machine() and unregister_machine() from
vmspawn-register.{c,h} into shared machine-register.{c,h} so both
nspawn and vmspawn can use the same implementation.

The unified register_machine() uses varlink first (for richer
features like SSH support and unit allocation) with a D-Bus
RegisterMachineWithNetwork fallback for older machined. The
interface adds a class parameter ("vm" or "container") and
local_ifindex for nspawn's network interface support.

The unified unregister_machine() similarly tries varlink first
(io.systemd.Machine.Unregister) before falling back to D-Bus.

Both register_machine() and unregister_machine() only log at debug
level internally, leaving error/notice logging to callers.

Add register_machine_with_fallback() which tries system and/or user
scope registration based on a RuntimeScope parameter
(_RUNTIME_SCOPE_INVALID for both), and
unregister_machine_with_fallback() as its counterpart. Both use
RET_GATHER() to collect errors from each scope.

Make --register= a tristate (yes/no/auto) defaulting to auto. When
set to auto, registration failures are logged at notice level and
ignored. When set to yes, failures are fatal.

Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 17:13:40 +02:00
Yaping Li f60d5985e5 report: implement facts interface 2026-04-01 15:34:45 +02:00
Lennart Poettering eb6e5b07f1 imds: add new systemd-imdsd.service that makes IMDS data accessible locally
This service's job is to talk to a VM associated IMDS service provided
by the local Cloud. It tries to abstract the protocol differences
various IMDS implementations implement, but does *not* really try to
abstract more than a few basic fields of the actual IMDS metadata.

IMDS access is wrapped in a Varlink API that local clients can talk to.

If possible this makes use of the IMDS endpoint information that has
been added to hwdb in the preceeding commit. However, endpoint info can
also be provided via kernel command line and credentials. For debugging
purposes we also accept them via environment variables and command line
arguments.

This adds a concept of early-boot networking, just enough to be able to
talk to the IMDS service. It is minimally configurable via a kernel
cmdline option (and a build-time option): the user may choose between
"locked" and "unlocked" mode. In the former mode direct access to IMDS via
HTTPS is blocked via a prohibit route (and thus all IMDS communication
has to be done via systemd-imdsd@.service). In the latter case no such
lockdown takes place, and IMDS may be acquired both via this new service
and directly. The latter is typically a good idea for compatibility with
current systems, the former is preferable for secure installations.

Access to IMDS fields is controlled via PK.
2026-03-26 10:54:15 +01:00
Lennart Poettering dc91cb82da vmspawn: split out swtpm-setup logic, and beef it up a bit 2026-03-24 14:42:39 +01:00
Lennart Poettering e7a176fe46 Define options and verbs through "magic macros" (#40880)
This is an another alternative for #40656, based on @poettering's
suggestion to use an ELF section.

The output of --help is generated using format-table, but the details of
the formatting a bit off: different sections in the table (verbs, option
groups) are not aligned to the same column. Our current table formatting
doesn't make this easy. If somebody has an idea how to do this without
too much pain, please make suggestions.

Another thing that I didn't know how to do nicely, was to use the two
columns of separation. But maybe this doesn't matter. If we switch to
one column everywhere, I don't think people will care.

Example output:
```console
$ build/systemd-id128 -h | cat    
systemd-id128 [OPTIONS...] COMMAND

Generate and print 128-bit identifiers.

Commands:
  new                Generate a new ID
  machine-id         Print the ID of current machine
  boot-id            Print the ID of current boot
  invocation-id      Print the ID of current invocation
  var-partition-uuid Print the UUID for the /var/ partition
  show [NAME|UUID]   Print one or more UUIDs
  help               Show this help

Options:
  -h --help            Show this help
     --version         Show package version
     --no-pager        Do not start a pager
     --no-legend       Do not show headers and footers
     --json=FORMAT     Output inspection data in JSON (takes one of pretty,
                       short, off)
  -j                   Equivalent to --json=pretty (on TTY) or --json=short
                       (otherwise)
  -p --pretty          Generate samples of program code
  -P --value           Only print the value
  -a --app-specific=ID Generate app-specific IDs
  -u --uuid            Output in UUID format

See the systemd-id128(1) man page for details.
```

The output wraps automatically with terminal width. If the terminal is
extremely narrow, ellipsization occurs. I think this doesn't matter
and/or is actually a feature. Such narrow terminals mostly occur in
testing, so it doesn't matter what exactly we do, as long as it is
something somewhat reasonable.

Anyway, I think this is enough as PoC. Please compare this with the
previous approach. /cc @behrmann, @YHNdnzj, @poettering

The three binaries that are converted have options, verbs, optional
arguments, and options terminate option parsing, so most of the
functionality is there. One thing that I didn't implement that was
present in previous PRs is "namespaces", i.e. multiple parsers in the
same source file. I expect that we can handle this similarly to option
groups.
2026-03-23 22:17:05 +01:00
Zbigniew Jędrzejewski-Szmek eafd3e6a7d Add "option parser" infrastracture that helps with cmdline option parsing
The basic idea is that we'll have "one source of truth" for the list of
options. Currently, this is split between:
  1. struct option options[] array for long options
  2. the short option parameter to getopt_long()
  3. --help
so it is easy to forget to add or update one of those places where
appropriate.

An option is defined through a macro that includes the option short
and long codes, and also the metavar and help. Those four items can
be used to generate the help string automatically.

The code is easier to read when various parts are written in the same
order.

We can define common options through a macro in the header file,
reducing boilerplate repeated in different files. Over time, if we
discover that the same pattern is used in multiple files, we can add
another "common option".

The macro is defined in a way that the editor can indent it like a
normal case statement.

The error message for ambiguous options is formatted a bit differently:
$ systemd-id128 --no-
systemd-id128: option '--no-' is ambiguous; possibilities: '--no-pager' '--no-legend'
$ build/systemd-id128 --no-
option '--no-' is ambiguous; possibilities: --no-pager, --no-legend

I think the formatting without commas is ugly, but OTOH, the quotes
around option names are superfluous, real option names are easy to
distinguish.
2026-03-20 17:26:52 +01:00
Michael Vogt 9a708c5115 shared: extract socket_forward_new() helper from socket-proxyd
This commit extracts the socket forwarding code from the existing
socket-proxyd into a new shared helper that will be used by the
varlinkctl protocol upgrade support code and is used as is in
the socket-proxyd.c.

It tries to keep the changes as small as possible, its mostly
renaming like:
* connection_create_pipes -> socket_forward_create_pipes
* connection_shovel -> socket_forward_shovel
* connection_enable_event_sources -> socket_forward_enable_event_sources
* traffic_cb -> socket_forward_traffic_cb

and a new socket_forward_new() that creates/starts the forwarding.

All log_error_errno() got downgraded to log_debug_errno().
2026-03-20 10:13:34 +01:00
Yu Watanabe b6919c737a network: rename io.systemd.Network.LinkUp()/LinkDown()
Then, this also moves their implementations to networkd-link-varlink.c.
2026-02-24 23:56:20 +09:00
Michael Vogt a109189fab journalctl: add new varlink read service to get entries
We already have some varlink support for the journal to perform
some actions like `Rotate`. It would be nice to be able to query
the journal via varlink too so this commit adds a new varlinkctl
based journal service that exposes a single GetEntries() call
to retrieve journal entries. Basic filtering is supported and
we can expand the API as needed.

This is a separate `io.systemd.JournalControl` [1] service from the
existing `io.systemd.Journald` to decouple read and write (thanks
to Lennart for suggesting this).

This also extracts some shared helper so that we do not duplicate
code when generating the json or when adding the filters.

[1] The name mirrors the bootctl->io.systemd.BootControl naming.
2026-02-21 13:02:38 +01:00
Lennart Poettering 8343032a86 mstack: introduce "mstack" concept 2026-02-19 15:05:15 +01:00
Lennart Poettering 3f31c8ff46 pkcs7-util: add helpers for extracting signer info from PKCS7 signatures
Once we start measuring Verity volumes as we activate them we want to
include information about the signature keys used, so that we can have
distinct ones for confext and for sysext and ther purposes and thus have
a cryptograpically protected hint about the kind of image we have
activated in the event log.

Ideally we'd measure a fingerprint of the signing certificate here, but
we don't have that here typically (as PKCS7 signatures used here
typically do not embed that), hence use the next best thing: the issuer
name and the serial number.
2026-02-17 22:00:14 +01:00
Mike Yuan 89769fb4ad shared: conditionalize build of apparmor-util.c in meson 2026-02-16 09:44:53 +01:00
Matteo Croce c1bf450fa0 oomd: implement a prekill varlink event
When a cgroup is selected for termination, send varlink messages
to hooks registered in `/run/systemd/oomd.prekill-hooks/`.
oomd waits up to `PreKillHookTimeoutSec=` seconds for response
before proceeding with the kill.
2026-02-09 02:05:57 +01:00
Zbigniew Jędrzejewski-Szmek e047394797 [metrics] Introduce metrics API (#39202)
See the [design
doc](https://github.com/systemd/systemd/issues/38023#issue-3192567450)
by @ikruglov

This PR introduces the metrics API framework, adds some basic system
wide/per unit/service metrics, and a basic CLI. The PR is broken into
two commits as described below.

### Deviations from the original design
- Introduced top level field "object" for ease of filtering. Instead of
having `fields: { unit: "foo", unit_type: "service" }`, we now have
`object: foo.service` as the top level field.


### First commit

The first commit includes:
- Metrics API definitions
- Code to set up the varlink server
- The describe method which shows all the metrics families
- The list method which lists all the metrics
- Type definitions related to MetricFamily
- Common code to build json objects

### Second commit
The second commit adds some basic metrics, a basic CLI (systemd-report)
which
lists the metrics, and integration tests.

**System wide metrics:**
- units_by_type_total
- units_by_state_total

**Two per unit metrics:**
- unit_active_state
- unit_load_state

**A service state metric:**
- nrestarts

### Sample outputs

**units_by_type_total**:

```
{
        "name" : "io.systemd.Manager.units_by_type_total",
        "value" : 52,
        "fields" : {
                "type" : "target"
        }
}
{
        "name" : "io.systemd.Manager.units_by_type_total",
        "value" : 82,
        "fields" : {
                "type" : "device"
        }
}
{
        "name" : "io.systemd.Manager.units_by_type_total",
        "value" : 2,
        "fields" : {
                "type" : "automount"
        }
}
```
**units_by_state_total**:
```
{
        "name" : "io.systemd.Manager.units_by_state_total",
        "value" : 216,
        "fields" : {
                "state" : "active"
        }
}
{
        "name" : "io.systemd.Manager.units_by_state_total",
        "value" : 0,
        "fields" : {
                "state" : "reloading"
        }
}
{
        "name" : "io.systemd.Manager.units_by_state_total",
        "value" : 120,
        "fields" : {
                "state" : "inactive"
        }
}
```
**unit_active_state**:
```
{
        "name" : "io.systemd.Manager.unit_active_state",
        "object" : "multi-user.target",
        "value" : "active"
}
{
        "name" : "io.systemd.Manager.unit_active_state",
        "object" : "systemd-sysusers.service",
        "value" : "inactive"
}
```
**unit_load_state**:
```
{
        "name" : "io.systemd.Manager.unit_load_state",
        "object" : "multi-user.target",
        "value" : "loaded"
}

```
**nrestarts**:
```
{
        "name" : "io.systemd.Manager.nrestarts",
        "object" : "user@0.service",
        "value" : 0
}
{
        "name" : "io.systemd.Manager.nrestarts",
        "object" : "user-runtime-dir@0.service",
        "value" : 0
}
```
2026-02-04 16:31:55 +01:00