Commit Graph
490 Commits
Author SHA1 Message Date
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
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 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
Luca Boccassi 4f7089f0c7 core: do not leak resources when handling stale alias state on reload
The fix for the corrupted state when units become aliased on reload
leaks the now-aliased unit's resources, which become untracked and
essentially lost.

While fixing the state corruption is of course necessary, leaking
processes/etc. is not ideal for a system and service manager, so
instead attempt to keep track of them by creating stub units
on-the-fly as replacements.
This way resources are not leaked, there are clear indications of
where they moved, and all state can be tracked as expected.

Ignore timers/sockets/paths as those are internal resources/triggers.

Follow-up for a77c7a8224
2026-05-12 23:38:52 +01: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
Chris Down a77c7a8224 core: Prevent corrupting units from stale alias state on daemon-reload
During daemon-reload (or daemon-reexec), when a unit becomes an alias to
another unit, deserialising the alias's stale serialised state can
corrupt the canonical unit's live runtime state.

Consider this scenario:

1. Before reload:
   - a.service is running
   - b.service was stopped earlier and is dead
   - Both exist as independent units

2. User creates an alias to migrate from b -> a:

   - `ln -s /run/systemd/system/a.service /etc/systemd/system/b.service`

3. daemon-reload triggers serialisation. State file contains both units:
   - a.service -> state=running, cgroup=/system.slice/a.service,
     PID=1234, ...
   - b.service -> state=dead, cgroup=(empty), no PIDs, ...

4. During deserialisation:
   - Processes a.service: loads Unit A, deserialises -> state=RUNNING
   - Processes b.service: manager_load_unit() detects symlink, returns
     Unit A
   - unit_deserialize_state(Unit A, ...) overwrites with b's dead state

5. The result is that:
   - Unit A incorrectly shows state=dead despite PID 1234 still running
   - If a.service has Upholds= dependents, catch-up logic sees
     a.service should be running but is dead
   - systemd starts a.service again -> PID 5678
   - Two instances run: PID 1234 (left-over) and PID 5678 (new)

This bug is deterministic when serialisation orders a.service before
b.service.

The root cause is that manager_deserialize_one_unit() calls
manager_load_unit(name, &u) which resolves aliases via
unit_follow_merge(), returning the canonical Unit object. However, the
code doesn't distinguish between two cases when u->id differs from the
requested name from the state file. In the corruption case, we're
deserialising an alias entry and unit_deserialize_state() blindly
overwrites the canonical unit's fields with stale data from the old,
independent unit. The serialised b.service then overwrites Unit A's
correct live state.

This commit first scans the serialised unit names, then adds a check
after manager_load_unit():

    if (!streq(u->id, name) && set_contains(serialized_units, u->id))
        ...

This detects when the loaded unit's canonical ID (u->id) differs from
the serialised name, indicating the name is now an alias for a different
unit and the canonical unit also has its own serialised state entry.

If the canonical unit does not have its own serialised state entry, we
keep the state entry. That handles cases where the old name is really
just a rename, and thus the old name is the only serialised state for
the unit. In that case there is no bug, because there is no separate
canonical state entry for the stale alias entry to overwrite.

Skipping is safe because:

1. The canonical unit's own state entry will be correctly deserialised
   regardless of order. This fix only prevents other stale alias entries
   from corrupting it.
2. unit_merge() has already transferred the necessary data. When
   b.service became an alias during unit loading, unit_merge() already
   migrated dependencies and references to the canonical unit.
3. After merging, the alias doesn't have its own runtime state. The
   serialised data represents b.service when it was independent, which
   is now obsolete once the canonical unit also has its own serialised
   entry.
4. All fields are stale. unit_deserialize_state() would overwrite state,
   timestamps, cgroup paths, pids, etc. There's no scenario where we
   want this data applied on top of the canonical unit's own serialised
   state.

This fix also correctly handles unit precedence. For example, imagine
this scenario:

1. `b.service` is a valid, running unit defined in `/run`.
2. The sysadmin creates `ln -s .../a.service /etc/.../b.service`.
3. On reload, the new symlink in `/etc` overrides the unit in `/run`.

The new perspective from the manager side is that `b.service` is now an
alias for `a.service`.

In this case, systemd correctly abandons the old b.service unit, because
that's the intended general semantics of unit file precedence. We also
do that in other cases, like when a unit file in /etc/systemd/system/
masks a vendor-supplied unit file in /lib/systemd/system/, or when an
admin uses systemctl mask to explicitly disable a unit.

In all these scenarios, the configuration with the highest precedence
(in /etc/) is treated as the new source of truth. The old unit's
definition is discarded, and its running processes are (correctly)
abandoned. In that respect we are not doing anything new here.

Some may ask why we shouldn't just ignore the symlink if we think this
case will come up. I think there are multiple very strong reasons not to
do so:

1. It violates unit precedence. The unit design is built on a strict
   precedence list. When an admin puts any file in /etc, they are
   intentionally overriding everything else. If manager_load_unit were
   to "ignore" this file based on runtime state, it would break this
   fundamental precedent.
2. It makes daemon-reload stateful. daemon-reload is supposed to be a
   simple, stateless operation, basically to read the files on disk and
   apply the new configuration. But doing this would make daemon-reload
   stateful, because we'd have to read the files on disk, but
   cross-reference the current runtime state, and...  maybe ignore some
   files. This is complex and unpredictable.
3. It also completely ignores the user intent. The admin clearly has
   tried to replace the old service with an alias. Ignoring their
   instruction is the opposite of what they want.

Fixes: https://github.com/systemd/systemd/issues/38817
Fixes: https://github.com/systemd/systemd/issues/37482
2026-04-02 22:58:19 +09:00
Zbigniew Jędrzejewski-Szmek d90858544c systemctl: rename enqueue-marked-jobs to enqueue-marked
Closes #40883. As described in the issue, it's not "jobs" that are
marked, and also the name is unnecessarilly long.

I think we don't need any compatibility measures here. At least in the
rpm world, package upgrade scripts go through the helper which is part
of the package so the new systemctl and the new helper are upgraded
together.
2026-03-03 15:26:45 +01:00
Mike Yuan 81f31dccb8 man/systemctl: deprecate --marked 2026-02-24 16:00:05 +01:00
Mike Yuan c008f88ded systemctl: introduce enqueue-marked-jobs verb, stop lumping it with distinct verbs 2026-02-24 16:00:05 +01:00
Mike Yuan a8ceed0000 Revert "systemctl: allow --marker with start/stop too"
This reverts commit 351b4dd123.

I'm pretty sure we should not create more of these multiplexer
interfaces, which in this specific also leads to a fair bit of
confusion: start/stop/reload-or-restart --marked all enqueue
all job types.

Instead, a dedicated verb will be introduced in later commits.
2026-02-24 15:48:53 +01:00
Luca Boccassi 351b4dd123 systemctl: allow --marker with start/stop too 2026-02-23 13:05:23 +00:00
Ulrich Ölmann dc3078e3a9 man/systemctl: fix typo 2026-01-03 04:45:30 +09:00
Lennart Poettering fc3adbbbcb man: always prefix links to uapi specs with their UAPI.XY spec number
Let's try to establish the spec numbers, by mentioning them in most doc
links.

Follow-up for: https://github.com/uapi-group/specifications/pull/187
2025-11-23 18:09:11 +01: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
Managor b1aa33ff91 systemctl.xml: unify ellipsis (#39586)
The reverts in #39423 brought this back. This PR will unify the page.
2025-11-06 10:34:57 +01:00
Frantisek Sumsal 3b4b3b8a95 Revert "Update systemctl.xml"
This reverts commit b0fe317d14.
This reverts commit 9f4f7f0372.
2025-10-23 15:42:28 +02:00
Managor b0fe317d14 Update systemctl.xml 2025-10-02 11:28:40 +02:00
Managor 9f4f7f0372 Update systemctl.xml 2025-10-02 11:28:40 +02:00
Lennart Poettering 6b02854f50 systemctl: add --kill-subgroup= switch for killing subcgroup 2025-07-08 03:14:53 +02:00
Lennart Poettering 0f23564ad4 pid1: add ability to kill processes in a subgroup of a unit
This is useful for things like machined, where the system machined wants
to manage a machine owned by the user somewhere down the tree.
2025-07-08 03:14:53 +02:00
Mike Yuan 1b9400f2ee core/transaction: add job mode "lenient" as an even weaker version of _FAIL 2025-06-30 13:10:42 +02:00
Zbigniew Jędrzejewski-Szmek b082968d19 man: better tags, more links, minor grammar and formatting improvements
Closes https://github.com/systemd/systemd/issues/35751.
2025-05-28 15:35:53 +02:00
Yu Watanabe 8e958263d0 man/systemctl: fix typo
Follow-up for 652e4dd743.
2025-05-16 17:49:14 +09:00
Yu Watanabe 5884fafcd7 systemctl: make systemctl clean --what= values more discoverable (#37418) 2025-05-14 02:16:47 +09:00
Jörg Behrmann 652e4dd743 man: note for systemctl clean --what that commas separate values 2025-05-13 17:20:37 +02:00
Jörg Behrmann 028de7292d man, systemctl: document --what=help 2025-05-13 17:19:39 +02:00
Jörg Behrmann 5689365a90 man: add missing fdstore in systemctl clean --what documentation 2025-05-13 17:19:02 +02:00
Lennart Poettering c8aff47a9c systemctl: add --verbose mode 2025-05-13 15:39:57 +02:00
Alexander Stepchenko 0cf03a36f2 man/systemctl: add preposition for clarity 2025-05-05 13:01:05 +02:00
Yu Watanabe f7586abfe0 man/systemctl: list-sockets command sorts the result
This updates the example output of list-sockets command.
2025-04-22 10:24:42 +09:00
Christian Hesse e1a932f3c5 man: mention special functionality for reload-or-restart with --marked (#37076)
We had a downstream discussion on what `systemctl reload-or-restart
--marked` does, until upstream chimed in and pointed on very special
behavior for that combination. 😜

The second references the first, but not vice versa. Let's fix this.
2025-04-10 18:19:00 +09:00
ver4a 1352eb059f Fix typo 2025-01-28 03:28:26 +09:00
Jan Engelhardt c592ebdf4f man: grammar fixes for introductory adverbs/phrases 2024-12-25 17:24:38 +01:00
Jan Engelhardt 44855c77a1 man: expand word contractions
For written text, contractions are not normally used.
2024-12-25 17:00:31 +01:00
Yu Watanabe 4ebbb5bfe8 man: asorted fixes
Closes #35307.
2024-11-24 01:11:42 +09:00
Zbigniew Jędrzejewski-Szmek fe45f8dc9b man: drop whitespace from final <programlisting> lines
In the troff output, this doesn't seem to make any difference. But in the
html output, the whitespace is sometimes preserved, creating an additional
gap before the following content. Drop it everywhere to avoid this.
2024-11-08 14:14:36 +01:00
Luca Boccassi 3509fe124d man: consolidate list of active unit states into a shared table
Avoids the need to maintain the same list over and over again, and
link it to the defition table in the implementation as a reminder
too
2024-10-04 12:22:55 +02:00
Luca Boccassi 5162829ec8 core: do BindMount/MountImage operations in async control process
These operations might require slow I/O, and thus might block PID1's main
loop for an undeterminated amount of time. Instead of performing them
inline, fork a worker process and stash away the D-Bus message, and reply
once we get a SIGCHILD indicating they have completed. That way we don't
break compatibility and callers can continue to rely on the fact that when
they get the method reply the operation either succeeded or failed.

To keep backward compatibility, unlike reload control processes, these
are ran inside init.scope and not the target cgroup. Unlike ExecReload,
this is under our control and is not defined by the unit. This is necessary
because previously the operation also wasn't ran from the target cgroup,
so suddenly forking a copy-on-write copy of pid1 into the target cgroup
will make memory usage spike, and if there is a MemoryMax= or MemoryHigh=
set and the cgroup is already close to the limit, it will cause an OOM
kill, where previously it would have worked fine.
2024-08-29 12:48:55 +01:00
Mike Yuan 988ca0953e man: use standard-options for --no-ask-password everywhere 2024-08-21 15:17:02 +02:00
Luca Boccassi 804874d26a logind: always check for inhibitor locks
Currently inhibitors are bypassed unless an explicit request is made to
check for them, or even in that case when the requestor is root or the
same uid as the holder of the lock.

But in many cases this makes it impractical to rely on inhibitor locks.
For example, in Debian there are several convoluted and archaic
workarounds that divert systemctl/reboot to some hacky custom scripts
to try and enforce blocking accidental reboots, when it's not expected
that the requestor will remember to specify the command line option
to enable checking for active inhibitor locks.

Also in many cases one wants to ensure that locks taken by a user are
respected by actions initiated by that same user.

Change logind so that inhibitors checks are not skipped in these
cases, and systemctl so that locks are checked in order to show a
friendly error message rather than "permission denied".

Add new block-weak and delay-weak modes that keep the previous
behaviour unchanged.
2024-07-25 12:22:36 +01:00
Mike Yuan 98aedce914 systemctl-enable: support reenable --now
Also, instead of silently continuing when template units
are specified with enable --now, print a warning and skip them.

Closes #31541
2024-07-09 16:46:13 +02:00
Mike Yuan 399646faac man/systemctl: --no-reload is honored by mask/unmask/preset too 2024-07-04 20:36:02 +02:00
Ludwig Nussel 0e10c3d872 logind: implement maintenance time
Update frameworks that work automatically in the background
occasionally need to schedule reboots. Systemd-logind already
provides a nice mechanism to schedule shutdowns, send notfications
and block logins short before the time. Systemd has a framework for
calendar events, so we may conveniently use logind to define a
maintenance time for reboots.

The existing ScheduleShutdown DBus method in logind expects a usec_t
with an absolute time. Passing USEC_INFINITY as magic value now tells
logind to take the time from the configured maintenance time if set.

"shutdown -r" leverages that and uses the maintenance time
automatically if configured. The one minute default is still used if
nothing was specified.

Similarly the new 'auto' setting for the --when parameter of systemctl
uses the maintenance time if configured or a one minute timer like the
shutdown command.
2024-06-20 14:37:42 +02:00
Colin Watson 566491c971 docs,man: Avoid some ambiguous uses of "may not"
Like much English text, the systemd documentation uses "may not" in the
sense of both "will possibly not" and "is forbidden to".  In many cases
this is OK because the context makes it clear, but in others I felt it
was possible to read the "is forbidden to" sense by mistake: in
particular, I tripped over "the target file may not exist" in
systemd.unit(5) before realizing the correct interpretation.

Use "might not" or "may choose not to" in these cases to make it clear
which sense we mean.
2024-05-08 17:14:32 +02:00
Mike Yuan 4f344de792 systemctl: do not fall back to StartUnit automatically for sleep operations
In the majority of cases, this is caused by
sleep_supported() returning error. Hence it's
very likely that it would fail again, so
the fallback is not really useful. Instead,
honor the --force option for these verbs.
2024-05-08 13:45:49 +08:00
Daan De Meyer 6be4dab095 systemctl: Implement --wait for kill command
TEST-26-SYSTEMCTL is racy as we call systemctl is-active immediately
after systemctl kill. Let's implement --wait for systemctl kill and
use it in TEST-26-SYSTEMCTL to avoid the race.
2024-05-01 09:40:32 +02:00
Lennart Poettering c104d7a74e man: document that "systemctl set-environment" cannot be used to unset env vars configured via config file
Fixes: #28167
2024-04-22 15:16:54 +02:00