Commit Graph
1114 Commits
Author SHA1 Message Date
Simon Lucido d667b6b97f core: add ReloadCount to Manager and bump on successful reload
Introduce a counter that tracks how many configuration reloads have
been successfully completed by the manager. The increment lives in
manager_reload() right after the "point of no return", so failed
reload attempts that bail out earlier (e.g. during serialization)
do not bump the counter.

It is accessible as a new ReloadCount property to
org.freedesktop.systemd1.Manager (D-Bus) and ReloadCount to
io.systemd.Manager.Describe (Varlink).

Also add an integration test for ReloadCount
that verifies that the new ReloadCount property increments by one per
daemon-reload, accumulates correctly across multiple reloads, and that
D-Bus and Varlink return identical values. Also tests that the counter
reset after a reexec.

Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Simon Lucido <simonlucido@meta.com>
2026-05-03 10:23:55 +01:00
Michael Vogt 913b81735e core: add io.systemd.Unit.StartTransient() to the varlink API
This commit adds a simple version of io.systemd.Unit.StartTransient
for varlink. It is similar to the dbus version, but there is a key
difference:
1. Instead of building the unit from key/value properties it
   takes a json object in the "service" parameter. It is also
   only implementing a minimal set of what can be done with a
   service (for now)
2. No aux units (for now)
3. When called with --more the varlink socket can notify about
   unit job and state changes controlled via a bool on the
   varlink call inputs: notify{Job,Unit}Changes

We use the new io.systemd.Job interface when outputing the
io.systemd.Unit.StartTransient result as it makes the output
nice and mirrors the input.

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

Because UnitContext is now also used for the inputs we need
to make a bunch of fields `SD_VARLINK_NULLABLE` so that the
input is even accepted. This does not affect the output, it
is still fully populated, just the schema. The ID of UnitContext
is still required.

Thanks to ikruglov and Lennart for their excellent feedback on
this.
2026-04-27 13:49:24 +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
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
Lennart Poettering aa0da09127 stat-util: also add stat_verify_char() and use it everywhere 2026-04-13 13:20:43 +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
Daan De Meyer 594659da06 core: Add I/O pressure support 2026-04-09 22:47:10 +02:00
Daan De Meyer 316d17fcbd core: Add support for CPU pressure notifications
Works the same way as memory pressure notifications. Code is refactored
to work on enum arrays to reduce duplication.
2026-04-09 22:47:10 +02:00
Nikolas Kyx 1f6935145d manager: Add DefaultMemoryZSwapWriteback
Allow setting system-wide MemoryZSwapWriteback in system.conf

Resolves: #41320
2026-04-02 20:04:30 +01:00
Michael Vogt 57e5c9eea6 core: make check-pointer-deref clean
Add the needed assert changes to make the code clean
for the new check-pointer-deref script.
2026-03-30 14:18:56 +02:00
Michael Vogt 114c89cc94 core: allow unset pidref in manager_log_caller
This commit allows unset pidref when calling manager_log_caller().
With that we can log manager calls even if we cannot resolve the
caller. Currently when we cannot resolve the caller we are just
not logging anything. With this commit we at least log the call
(even though we don't know what caller it was).

Thanks to keszybz for the suggestion.
2026-03-21 22:40:52 +01:00
Mike Yuan fff07be411 core/service: support credential refreshing on reload
Closes #21099
2026-02-10 21:54:12 +01:00
Alessandro Astone 87840e144b login: Add XDG_SESSION_EXTRA_DEVICE_ACCESS variable for additional access
A session created with XDG_SESSION_EXTRA_DEVICE_ACCESS will be granted
additional powers.
Exactly which powers are granted is going to be defined by udevd.
2026-02-06 16:20:18 +01:00
Zbigniew Jędrzejewski-Szmek 64eb78135c shared/install: rework error propagation again
The immediate impulse for this change is the fedora scriptlet which called:
  /usr/lib/systemd/systemd-update-helper install-system-units cryptsetup-pre.target cryptsetup.target getty@.service ... system-systemd\x2dcryptsetup.slice system-systemd\x2dveritysetup.slice ...
which called
  systemctl preset cryptsetup-pre.target cryptsetup.target getty@.service ... system-systemd\x2dcryptsetup.slice system-systemd\x2dveritysetup.slice ...
which threw an error that system-systemdx2dcryptsetup.slice does not exist
and did nothing at all. (The backslash is consumed by the shell.)
The obvious fix here is to figure out more levels of escaping… But we should
do something more robust in such cases.

If we fail in processing of a single unit, let preset all continue processing
units, report the failure through 'changes'. At the end, return failure. In
general, for operations which operate on a list of units specified by the user,
fail the whole operation if any of the individual operations failed. The only
operation where we don't do this is 'preset-all'.

$ SYSTEMD_LOG_LEVEL=debug build/systemctl --root=/ preset asdf1.servie asdf2.path; echo $?
Cannot find unit asdf1.servie.service.
Cannot find unit asdf2.path.
Failed to preset unit: Unit asdf1.servie.service does not exist
Failed to preset unit: Unit asdf2.path does not exist
1

While at it, fix double logging in the manager: dump_unit_changes() already
logs about errors, so the manager should only log on success.
2026-01-29 08:49:44 +01:00
Michal Sekletar bcbf80c43d core: only activate transaction that contain useful jobs
If no real jobs were added to the transaction, do not activate it.
The JOB_NOP anchor does not perform any useful work and activating
such transaction only wastes resources.

Fixes #9751
2026-01-15 12:53:50 +01:00
Daan De Meyer 52ecf376fa tree-wide: Migrate to pidref_safe_fork()
Let's migrate all remaining callers of safe_fork()
to pidref_safe_fork() and get rid of safe_fork().
2026-01-02 20:08:41 +01:00
Mike Yuan 79e6bfb1e6 core/manager: use UNIT_IS_ACTIVE_OR_RELOADING rather than hardcoding service states
except for SERVICE_EXITED which has to be checked manually.
2025-12-19 02:18:44 +01:00
Mike Yuan f145fc8c7e core/manager: constify DEFAULT_TASKS_MAX 2025-12-18 17:37:25 +01:00
Yu Watanabe 93378148d4 tree-wide: normalize comment style 2025-12-15 08:50:13 +09:00
Daan De Meyer 27217200f6 core: Rename error sd_bus_error parameters to reterr_error 2025-11-26 16:22:50 +09:00
Daan De Meyer 9a6a8f35eb tree-wide: Small fixes for various clang-tidy warnings 2025-11-26 16:22:00 +09:00
Yu Watanabe fd7d749494 core: add varlink Reload/Reexecute methods (#39561)
Same as the D-Bus ones
2025-11-15 04:17:01 +09:00
Yu Watanabe be33b202e6 core: record transactions that have seen ordering cycles and expose them via IPC (#39210)
Closes #3829.
2025-11-14 00:41:46 +09:00
Luca Boccassi 55a1b36e91 core: add varlink Reload/Reexecute methods
Same as the D-Bus ones
2025-11-13 00:07:23 +00:00
Luca Boccassi 00c084fe02 core: prepare reload/reexec for varlink 2025-11-13 00:06:36 +00:00
Yu Watanabe 3866923a68 musl: core: there is one less usable signal when built with musl
musl internally reserves one more signal, hence we can only use 29
signals.
2025-11-13 08:02:05 +09:00
Mike Yuan 58686034eb core: expose transactions with ordering cycle
Closes #3829
Alternative to #35417

I don't think the individual "WasOnDependencyCycle" attrs on units
are particularly helpful and comprehensible, as it's really about
the dep relationship between them. And as discussed, the dependency
cycle is not something persistent, rather local to the currently
loaded set of units and shall be reset with daemon-reload (see also
https://github.com/systemd/systemd/issues/35642#issuecomment-2591296586).

Hence, let's report system state as degraded and point users to
the involved transactions when ordering cycles are encountered instead.
Combined with log messages added in 6912eb315f
it should achieve the goal of making ordering cycles more observable,
while avoiding all sorts of subtle bookkeeping in the service manager.
The degraded state can be reset via the existing ResetFailed() manager-wide
method.
2025-11-12 23:47:39 +01:00
Mike Yuan d3da74696b core: record transactions that have seen ordering cycles 2025-11-12 23:47:39 +01:00
Mike Yuan 0d9e79d5ca core/transaction: assign unique ids to transactions and encode them in log
Preparation for later commits, but I think this one makes
a ton of sense on its own. When debug logging is enabled
it's otherwise difficult to dig up the portion of journal
for transaction construction.
2025-11-12 23:47:38 +01:00
Yu Watanabe 6431f2e072 musl: time-util: introduce get_tzname() helper function
musl leaves the DST timezone name unset if there is no DST.
The helper function maps that back to no DST.
2025-11-13 03:13:55 +09:00
Daniel Foster c7a444a9c1 tree-wide: extend $LISTEN_FDS protocol with $LISTEN_PIDFDID
Although extremely unlikely, there is a race present in solely checking the
$LISTEN_PID environment variable, due to PID recycling. Fix that by introducing
$LISTEN_PIDFDID, which contains the 64-bit ID of a pidfd for the child process
that is not subject to recycling.
2025-10-22 09:34:14 +02:00
Mike Yuan 4f8c1de213 core/manager: honor show_status_overridden in manager_watch_jobs_next_time()
Prompted by #39029
2025-09-20 00:01:54 +02:00
Mike Yuan d25c8ee7f9 core: console status fixes (#39029) 2025-09-19 20:30:11 +02:00
Lennart Poettering 9ecc969855 core: fix status output suppression
This fixes two things: first of all it ensures we take the override
status output field properly into account, instead of going directly to
the regular one.

Moreover, it ensures that we bypass auto for both notice + emergency,
since both have the same "impact", and, don't limit this for notice
only.
2025-09-19 17:32:48 +02:00
Lennart Poettering 4d8c5c657a build: make libaudit dep dlopen() 2025-09-19 16:30:13 +02:00
Yu Watanabe 7184f8366f firewall-util: drop FirewallContext
After iptables support is dropped, FirewallContext is a trivial
wrapper of sd_netlink. Let's drop it and directly use sd_netlink.
2025-09-19 15:33:17 +09:00
Zbigniew Jędrzejewski-Szmek 66b2d758c5 various: add a fixed name to log about plugin execution
Function execute_directories logged in a way that was meaningless
without additional context:
  systemd[1]: No executables found.
In execute_strv this was partially rectified by extracting the directory
name from one of the directories and using this as the identifier. But
the directory name is not always meaningful, and can also be set from
an environment variable. Let's simplify things by providing a fixed name
that can be used consistently in all log messages. In particular this will
make error messages easier to understand if users report just the error
without additional context.
2025-09-03 08:56:23 +02:00
Grimmauld 30bbdf0771 core: add 'DefaultRestrictSUIDSGID' config option
closes #37602

On typical systems, only few services need to create SUID/SGID files.
This often is limited to the user explicitly setting suid/sgid, the
`systemd-tmpfiles*` services, and the package manager. Allowing a default
to globally restrict creation of suid/sgid files makes it easier to apply
this restriction precisely.
2025-07-09 11:08:34 +02:00
Mike Yuan 1b4ab5a209 core/socket: introduce DeferTrigger= and DeferTriggerMaxSec=
Alternative to b50f6dbe57

The commit naively returned early from socket_enter_running(), which however
is quite problematic, as the socket will be woken up over and over again
without doing a thing, until we eventually hit Poll/TriggerLimit*=.
On top of that it requires hacks to hold the start job for initrd-switch-root.service
up. Overall I doubt that is the right approach.

Let's instead hook this into our job engine, and try to activate
the service again when some other units are stopped. If all installed
jobs have been run yet we're still seeing the conflict or the manually
selected timeout is reached, fail the socket as before.
2025-06-30 13:10:43 +02:00
Valentin David 0dc39dffbd Use paths specified from environment variables for /etc configuration files
Some configuration files that need updates are directly under in /etc. To
update them atomically, we need write access to /etc. For Ubuntu Core this is
an issue as /etc is not writable. Only a selection of subdirectories can be
writable. The general solution is symlinks or bind mounts to writable places.
But for atomic writes in /etc, that does not work. So Ubuntu has had a patch
for that that did not age well.

Instead we would like to introduce some environment variables for alternate
paths.

 * SYSTEMD_ETC_HOSTNAME: /etc/hostname
 * SYSTEMD_ETC_MACHINE_INFO: /etc/machine-info
 * SYSTEMD_ETC_LOCALTIME: /etc/localtime
 * SYSTEMD_ETC_LOCALE_CONF: /etc/locale.conf
 * SYSTEMD_ETC_VCONSOLE_CONF: /etc/vconsole.conf
 * SYSTEMD_ETC_ADJTIME: /etc/adjtime

While it is for now expected that there is a symlink from the standard, we
still try to read them from that alternate path. This is important for
`/etc/localtime`, which is a symlink, so we cannot have an indirect symlink or
bind mount for it.

Since machine-id is typically written only once and not updated. This commit
does not cover it. An initrd can properly create it and bind mount it.
2025-06-23 15:32:11 +02:00
Mike Yuan 85352c095e various: turn off SO_PASSRIGHTS where fds are not expected 2025-06-17 13:16:44 +02:00
Lennart Poettering d65dc4c593 core: break lines in some overly long function calls 2025-06-06 09:04:45 +02:00
Zbigniew Jędrzejewski-Szmek 42ba99748d various: do not include file names directly in error messages
git grep -l 'Failed to open /'|xargs sed -r -i 's|"Failed to open (/[^ ]+): %m"|"Failed to open %s: %m", "\1"|g'
git grep -l $'Failed to open \'/'|xargs sed -r -i $'s|"Failed to open \'(/[^ ]+)\': %m"|"Failed to open %s: %m", "\\1"|g'
git grep -l "Failed to open /"|xargs sed -r -i $'s|"Failed to open (/[^ ]+), ignoring: %m"|"Failed to open %s, ignoring: %m", "\\1"|g'
+ some manual fixups.
2025-06-02 11:10:38 +02:00
Dusty Mabe bdd852a199 src/core/manager.c: log preset activity on first boot
This gives us a little more information about what units were enabled
or disabled on that first boot and will be useful for OS developers
tracking down the source of unit state.

An example with this enabled looks like:

```
NET: Registered PF_VSOCK protocol family
systemd[1]: Applying preset policy.
systemd[1]: Unit /etc/systemd/system/dnsmasq.service is masked, ignoring.
systemd[1]: Unit /etc/systemd/system/systemd-repart.service is masked, ignoring.
systemd[1]: Removed '/etc/systemd/system/sockets.target.wants/systemd-resolved-monitor.socket'.
systemd[1]: Removed '/etc/systemd/system/sockets.target.wants/systemd-resolved-varlink.socket'.
systemd[1]: Created symlink '/etc/systemd/system/multi-user.target.wants/var-mnt-workdir.mount' → '/etc/systemd/system/var-mnt-workdir.mount'.
systemd[1]: Created symlink '/etc/systemd/system/multi-user.target.wants/var-mnt-workdir\x2dtmp.mount' → '/etc/systemd/system/var-mnt-workdir\x2dtmp.mount'.
systemd[1]: Created symlink '/etc/systemd/system/afterburn-sshkeys.target.requires/afterburn-sshkeys@core.service' → '/usr/lib/systemd/system/afterburn-sshkeys@.service'.
systemd[1]: Created symlink '/etc/systemd/system/sockets.target.wants/systemd-resolved-varlink.socket' → '/usr/lib/systemd/system/systemd-resolved-varlink.socket'.
systemd[1]: Created symlink '/etc/systemd/system/sockets.target.wants/systemd-resolved-monitor.socket' → '/usr/lib/systemd/system/systemd-resolved-monitor.socket'.
systemd[1]: Populated /etc with preset unit settings.
```

Considering it only happens on first boot and not on every boot I think
the extra information is worth the extra verbosity in the logs just for
that boot.
2025-05-27 05:53:36 +09:00
Daan De Meyer 6ae1ba8a84 core: Clean up includes
Follow up for 836e4e7ea8
2025-05-22 09:41:18 +02:00
Daan De Meyer 836e4e7ea8 core: Clean up includes
Split out of #37344.
2025-05-22 09:37:20 +02:00
Daan De Meyer cdd5fac068 tree-wide: Include <libaudit.h> via libaudit-util.h
Let's keep the ifdeffery for the include in one place.
2025-05-21 14:05:56 +02:00
Luca Boccassi 6946eed3fa core: Also refresh confext extensions when reloading notify-reload service (#33995)
`ExtensionImages=` and `ExtensionDirectories=` now let you specify
vpick-named extensions; however, since they just get set up once when
the service is started, you can't see newer versions without restarting
the service entirely. Here, also reload confext extensions when you
reload a service. This allows you to deploy a new version of some
configuration and have it picked up at reload time without interruption
to your workload.

Right now, we would only reload confext extensions and leave the sysext
ones behind, since it didn't seem prudent to swap out what is likely
program code at reload. This is made possible by only going for the
`SYSTEMD_CONFEXT_HIERARCHIES` overlays (which only contains `/etc`).

This PR:
- Adjusts `service.c` to also refresh extensions when needed. 
- Adds integration tests to check that a confext reload actually
occurred.
- Adds to the `systemd.exec` man pages to document this behavior.

This is a follow up to #24864 and #31364. Thank you to @bluca and
@goenkam for help in getting this up.
2025-05-20 11:27:34 +01:00
maia x.andLuca Boccassi dfdeb0b1cb core: reload confexts when reloading notify-reload services
`ExtensionImages=` and `ExtensionDirectories=` now let you specify
vpick-named extensions; however, since they just get set up once when
the service is started, you can't see newer versions without restarting
the service entirely.  Here, also reload confext extensions when you
reload a service. This allows you to deploy a new version of some
configuration and have it picked up at reload time without interruption
to your workload.

Right now, we would only reload confext extensions and leave the sysext
ones behind, since it didn't seem prudent to swap out what is likely
program code at reload. This is made possible by only going for the
`SYSTEMD_CONFEXT_HIERARCHIES` overlays (which only contains `/etc`).

Implementation wise, this uses the new kernel API and two collaborating
child processes under the host & child namespaces in order to gather the
right FDs needed:

  - (1) In child, set up the extension images and directories in a slave
	mountns, and obtain their FDs.
  - (2) Fork into a grandchild under target process namespace, and do a
        "fake" unmount to obtain the FD of the underlying target folder
	say /etc).
  - (3) In the child again, set up new overlay under host NS rights.

We do not want to do I/O heavy jobs inline in PID1 blocking the state
machine, so add separate async states to handle this case.

Co-authored-by: Luca Boccassi <luca.boccassi@gmail.com>
2025-05-19 13:36:21 +01:00
Mike Yuan 741a184a31 core/manager: do not pop gc_unit_queue before unit_gc_sweep()
Follow-up for 52e3671bf7

unit_gc_sweep() might try to add the unit to gc queue again.
While that becomes no-op as Unit.in_gc_queue is not cleared
yet, it induces minor inconsistency of states.
2025-05-18 05:33:09 +09:00