Config...erUnit(3pm)
๐ธ Config::Model::models::Systemd::Section::TimerUnit ๐ธ
okay bestie so you opened the manual page for Config::Model::models::Systemd::Section::TimerUnit โ yes that's the whole name, it's lowkey a whole paragraph, and yes it's a (3pm) Perl module page. Don't panic. We're gonna walk through every single option together, no skips, no "eh you get the idea". ๐ซถ
โจ NAME โจ
Config::Model::models::Systemd::Section::TimerUnit โ it's a Configuration class for Systemd::Section::TimerUnit. ๐
๐ฆ DESCRIPTION ๐ฆ
These are the Configuration classes used by Config::Model. That's the whole vibe check. Periodt. ๐
๐ Elements ๐
Everything below is an element you can set. Buckle up, there's a bunch, and honestly they're all kinda dramatic. ๐
๐ Description ๐
A brief, meaningful, human-readable text that identifies the unit. systemd (and any UIs that are paying attention) may use this as a user-visible label for the unit โ so this string should identify the unit, not just describe it, despite the name being Description. ๐
Also: don't just repeat the unit name in it. That's giving nothing.
Good examples, the icons that ate: "Apache HTTP Server", "Postfix Mail Server".
Bad examples, no cap: "high-performance lightweight HTTP server" (too generic), or "Apache" (meaningless to people who don't know the Apache HTTP server project โ and it duplicates the unit name, embarrassing).
systemd may use this string as a noun in status messages, like:
"Starting Description...""Started Description.""Reached target Description.""Failed to start Description."
So to survive that, it should be capitalized, and it should not be a full sentence, not a phrase with a verb conjugated in the present continuous, and not end in a full stop. Bad examples include "exiting the container", "updating the database once per day.", or "OpenSSH server second instance daemon". ๐
Optional. Type uniline.
๐ Documentation ๐
A space-separated list of URIs referencing documentation for this unit or its configuration. ๐ฆ
Accepted are only URIs of these types: http://, https://, file:, info:, man:. For more info about the syntax of these URIs, see uri(7).
List them in order of relevance, most relevant first. It's a good idea to start with documentation that explains what the unit's purpose is, then how it's configured, then any other related documentation. ๐
This option may be specified more than once, in which case the specified list of URIs is merged.
Assigning the empty string to this option resets the list โ every prior assignment will have no effect. Gone. Poof. ๐ซ
Optional. Type list of uniline.
๐ Wants ๐
Configures (weak) requirement dependencies on other units.
This option may be specified more than once, or you can put multiple space-separated units in one option โ either way, dependencies for all listed names will be created. ๐
Dependencies of this type may also be configured outside of the unit configuration file by adding a symlink to a .wants/ directory accompanying the unit file. For details, see above.
Units listed in this option will be started if the configuring unit is. But โ and this is the whole point โ if the listed units fail to start or can't be added to the transaction, that has no impact on the validity of the transaction as a whole, and this unit will still be started. This is the recommended way to hook the start-up of one unit to the start-up of another unit. ๐
not me reminding you again: requirement dependencies do not influence the order in which services are started or stopped. That has to be configured independently with theAfterorBeforeoptions. โ ๏ธ
So if unit foo.service pulls in unit bar.service as configured with Wants, and no ordering is configured with After or Before, then both units will be started simultaneously and without any delay between them if foo.service is activated. Chaos, but make it efficient. ๐ฅ
Optional. Type list of uniline.
๐ Requires ๐
Similar to Wants, but it declares a stronger requirement dependency. ๐ช
Dependencies of this type may also be configured by adding a symlink to a .requires/ directory accompanying the unit file.
If this unit gets activated, the units listed will be activated as well. If one of the other units fails to activate, and an ordering dependency After on the failing unit is set, this unit will not be started. Besides โ with or without specifying After โ this unit will be stopped (or restarted) if one of the other units is explicitly stopped (or restarted). ๐ญ
Often it's a better choice to use Wants instead of Requires, in order to achieve a system that's more robust when dealing with failing services. fr fr.
Note that this dependency type does not imply that the other unit always has to be in active state when this unit is running. Specifically:
- Failing condition checks (such as
ConditionPathExists,ConditionPathIsSymbolicLink, โฆ โ see below) do not cause the start job of a unit with aRequiresdependency on it to fail. - Some unit types may deactivate on their own (for example, a service process may decide to exit cleanly, or a device may be unplugged by the user), which is not propagated to units having a
Requiresdependency.
Use the BindsTo dependency type together with After to ensure that a unit may never be in active state without a specific other unit also in active state (see below). โจ
Optional. Type list of uniline.
๐ฎ Requisite ๐ฎ
Similar to Requires. However โ plot twist โ if the units listed here are not started already, they will not be started, and the starting of this unit will fail immediately. ๐
Requisite does not imply an ordering dependency, even if both units are started in the same transaction. Hence this setting should usually be combined with After, to ensure this unit isn't started before the other unit.
When Requisite=b.service is used on a.service, this dependency will show as RequisiteOf=a.service in the property listing of b.service. And heads up: RequisiteOf dependency cannot be specified directly. ๐
Optional. Type list of uniline.
๐ BindsTo ๐
Configures requirement dependencies, very similar in style to Requires. However, this dependency type is stronger: in addition to the effects of Requires โ which already stops (or restarts) the configuring unit when a listed unit is explicitly stopped (or restarted) โ it also does so when a listed unit stops unexpectedly (which includes when it fails). ๐ซข
Units can suddenly, unexpectedly enter inactive state for different reasons:
- the main process of a service unit might terminate on its own choice,
- the backing device of a device unit might be unplugged,
- or the mount point of a mount unit might be unmounted without involvement of the system and service manager.
When used in conjunction with After on the same unit, the behaviour of BindsTo is even stronger. In this case, the unit bound to strictly has to be in active state for this unit to also be in active state. This not only means a unit bound to another unit that suddenly enters inactive state, but also one that is bound to another unit that gets skipped due to an unmet condition check (such as ConditionPathExists, ConditionPathIsSymbolicLink, โฆ โ see below) will be stopped, should it be running. Hence, in many cases it's best to combine BindsTo with After. ๐
When BindsTo=b.service is used on a.service, this dependency will show as BoundBy=a.service in the property listing of b.service. And BoundBy dependency cannot be specified directly. ๐ซ
Optional. Type list of uniline.
๐งฉ PartOf ๐งฉ
Configures dependencies similar to Requires, but limited to stopping and restarting of units. When systemd stops or restarts the units listed here, the action is propagated to this unit. ๐ฆ
Note that this is a one-way dependency โ changes to this unit do not affect the listed units. It's giving unbothered. ๐
When PartOf=b.service is used on a.service, this dependency will show as ConsistsOf=a.service in the property listing of b.service. And ConsistsOf dependency cannot be specified directly. ๐ซ
Optional. Type list of uniline.
๐ธ Upholds ๐ธ
Configures dependencies similar to Wants, but as long as this unit is up, all units listed in Upholds are started whenever found to be inactive or failed, and no job is queued for them. โจ
While a Wants dependency on another unit has a one-time effect when this unit is started, a Upholds dependency on it has a continuous effect, constantly restarting the unit if necessary. This is an alternative to the Restart setting of service units, to ensure they are kept running whatever happens. ๐ฅ
The restart happens without delay, and the usual per-unit rate-limit applies.
When Upholds=b.service is used on a.service, this dependency will show as UpheldBy=a.service in the property listing of b.service.
Optional. Type uniline.
โ๏ธ Conflicts โ๏ธ
A space-separated list of unit names. Configures negative requirement dependencies. If a unit has a Conflicts requirement on a set of other units, then starting it will stop all of them, and starting any of them will stop it. Mutual destruction, but make it systemd. ๐ฅ
Note that this setting does not imply an ordering dependency, similarly to the Wants and Requires dependencies described above. This means that to ensure the conflicting unit is stopped before the other unit is started, an After or Before dependency must be declared. It doesn't matter which of the two ordering dependencies is used, because stop jobs are always ordered before start jobs โ see the discussion in Before/After below. ๐
If unit A that conflicts with unit B is scheduled to be started at the same time as B, the transaction will either:
- fail (in case both are required parts of the transaction), or
- be modified to be fixed (in case one or both jobs are not a required part of the transaction).
In the latter case, the job that is not required will be removed, or in case both are not required, the unit that conflicts will be started and the unit that is conflicted is stopped. ๐ฅ
Optional. Type list of uniline.
โณ Before โณ
These two settings expect a space-separated list of unit names. They may be specified more than once, in which case dependencies for all listed names are created.
Those two settings configure ordering dependencies between units. ๐ฆ
If unit foo.service contains the setting Before=bar.service and both units are being started, bar.service's start-up is delayed until foo.service has finished starting up.
After is the inverse of Before โ i.e. while Before ensures that the configured unit is started before the listed unit begins starting up, After ensures the opposite, that the listed unit is fully started up before the configured unit is started.
okay bestie we're not even done with Before yet, there's so much more of this page to go โ hold my matcha, part 2 incoming ๐ต๐
Ordering deps, shutdown edition โ bestie, remember how start-up order works? Now flip it. When two units that have an ordering dependency between them get shut down, the inverse of the start-up order is applied. So if a unit is configured with After on another unit, the former gets stopped before the latter if both are being shut down. ๐
And if you've got two units with any ordering dependency at all โ doesn't matter if it's After or Before, doesn't matter which of the two is being shut down โ as long as one is shutting down and the other is starting up, the shutdown is ordered before the start-up. Every single case. No exceptions, no cap. ๐ฅ
If two units have no ordering dependencies between them? They get shut down or started up simultaneously, and no ordering takes place at all. They just vibe in parallel. โจ
Now, when exactly has a unit "finished starting up"? Depends on the unit type, but the big one: for service units, start-up counts as completed for the purposes of Before/After when all its configured start-up commands have been invoked and they either failed or reported start-up success. And yes, that includes ExecStartPost (or ExecStopPost for the shutdown case). ๐ซถ
Big note: these settings are independent of and orthogonal to the requirement dependencies configured by Requires, Wants, Requisite, or BindsTo. Super common pattern: put a unit name in both After and Wants. In that case the listed unit gets started before the unit that's configured with these options. Cute, right? ๐ธ
Another note: Before dependencies on device units have no effect and are not supported. Devices generally become available as a result of an external hotplug event, and systemd creates the corresponding device unit without delay. That's just how it is, babe. Optional. Type list of uniline.
๐ After ๐
These two settings expect a space-separated list of unit names. You can specify them more than once, and in that case dependencies for all the listed names get created. Yes, multiply. Slay. โจ
So these two settings configure ordering dependencies between units. Say unit foo.service contains Before=bar.service and both are being started โ then bar.service's start-up is delayed until foo.service has finished starting up. After is the inverse of Before. Meaning: while Before makes sure the configured unit starts before the listed unit even begins starting up, After makes sure the opposite โ the listed unit is fully started up before the configured unit starts. ๐
When two units with an ordering dependency between them are shut down, the inverse of the start-up order is applied. I.e. if a unit is configured with After on another unit, the former is stopped before the latter if both are shut down. Given two units with any ordering dependency between them, if one unit is shut down and the other is started up, the shutdown is ordered before the start-up. It does not matter if the ordering dependency is After or Before, in this case. It also does not matter which of the two is shut down, as long as one is shut down and the other is started up; the shutdown is ordered before the start-up in all cases. If two units have no ordering dependencies between them, they are shut down or started up simultaneously, and no ordering takes place. It depends on the unit type when precisely a unit has finished starting up. Most importantly, for service units start-up is considered completed for the purpose of Before/After when all its configured start-up commands have been invoked and they either failed or reported start-up success. Note that this includes ExecStartPost (or ExecStopPost for the shutdown case). ๐
Note that those settings are independent of and orthogonal to the requirement dependencies as configured by Requires, Wants, Requisite, or BindsTo. It is a common pattern to include a unit name in both the After and Wants options, in which case the unit listed will be started before the unit that is configured with these options.
Note that Before dependencies on device units have no effect and are not supported. Devices generally become available as a result of an external hotplug event, and systemd creates the corresponding device unit without delay. Optional. Type list of uniline.
๐ฆ OnFailure ๐ฆ
A space-separated list of one or more units that get activated when this unit enters the "failed" state. Optional. Type uniline. ๐
๐ OnSuccess ๐
A space-separated list of one or more units that get activated when this unit enters the "inactive" state. Optional. Type uniline. ๐ธ
๐ PropagatesReloadTo ๐
A space-separated list of one or more units to which reload requests from this unit shall be propagated to, or units from which reload requests shall be propagated to this unit, respectively. Issuing a reload request on a unit will automatically also enqueue reload requests on all units that are linked to it using these two settings. Optional. Type uniline. ๐
๐ซถ ReloadPropagatedFrom ๐ซถ
A space-separated list of one or more units to which reload requests from this unit shall be propagated to, or units from which reload requests shall be propagated to this unit, respectively. Issuing a reload request on a unit will automatically also enqueue reload requests on all units that are linked to it using these two settings. Optional. Type uniline. โจ
๐ PropagatesStopTo ๐
A space-separated list of one or more units to which stop requests from this unit shall be propagated to, or units from which stop requests shall be propagated to this unit, respectively. Issuing a stop request on a unit will automatically also enqueue stop requests on all units that are linked to it using these two settings. Optional. Type uniline. ๐
โญ StopPropagatedFrom โญ
A space-separated list of one or more units to which stop requests from this unit shall be propagated to, or units from which stop requests shall be propagated to this unit, respectively. Issuing a stop request on a unit will automatically also enqueue stop requests on all units that are linked to it using these two settings. Optional. Type uniline.
๐ง JoinsNamespaceOf ๐ง
For units that start processes (such as service units), this lists one or more other units whose network and/or temporary file namespace to join. If this is specified on a unit (say, a.service has JoinsNamespaceOf=b.service), then the inverse dependency (JoinsNamespaceOf=a.service for b.service) is implied. It's giving mutual. ๐
This only applies to unit types which support the PrivateNetwork, NetworkNamespacePath, PrivateIPC, IPCNamespacePath, and PrivateTmp directives (see systemd.exec(5) for details). If a unit that has this setting set is started, its processes will see the same /tmp/, /var/tmp/, IPC namespace and network namespace as one listed unit that is started. If multiple listed units are already started and these do not share their namespace, then it is not defined which namespace is joined. ๐ (Translation: don't rely on it, bestie.)
Note that this setting only has an effect if PrivateNetwork/NetworkNamespacePath, PrivateIPC/IPCNamespacePath and/or PrivateTmp is enabled for both the unit that joins the namespace and the unit whose namespace is joined. Optional. Type uniline.
๐ RequiresMountsFor ๐
Takes a space-separated list of absolute paths. It automatically adds dependencies of type Requires and After for all mount units required to access the specified path. ๐๏ธ
Mount points marked with noauto are not mounted automatically through local-fs.target, but they are still honored for the purposes of this option โ i.e. they will be pulled in by this unit. Optional. Type uniline.
๐ WantsMountsFor ๐
Same as RequiresMountsFor, but it adds dependencies of type Wants instead of Requires. Optional. Type uniline. (Softer energy, same idea. ๐ซถ)
๐ OnSuccessJobMode ๐
Takes a value of fail, replace, replace-irreversibly, isolate, flush, ignore-dependencies or ignore-requirements. OnFailureJobMode defaults to replace, OnSuccessJobMode defaults to fail.
Specifies how the units listed in OnSuccess/OnFailure will be enqueued. See systemctl(1)'s --job-mode= option for details on the possible values. If this is set to isolate, only a single unit may be listed in OnSuccess/OnFailure. Optional. Type uniline. โ ๏ธ
๐ฅ OnFailureJobMode ๐ฅ
Takes a value of fail, replace, replace-irreversibly, isolate, flush, ignore-dependencies or ignore-requirements. OnFailureJobMode defaults to replace, OnSuccessJobMode defaults to fail.
Specifies how the units listed in OnSuccess/OnFailure will be enqueued. See systemctl(1)'s --job-mode= option for details on the possible values. If this is set to isolate, only a single unit may be listed in OnSuccess/OnFailure. Optional. Type uniline.
Note:OnFailureJobModeis migrated with$unitand with: -$unit=>- OnFailureIsolate
๐ IgnoreOnIsolate ๐
Takes a boolean argument. If true, this unit will not be stopped when isolating another unit. Defaults to false for service, target, socket, timer, and path units, and true for slice, scope, device, swap, mount, and automount units. Optional. Type boolean. ๐ก๏ธ
๐ StopWhenUnneeded ๐
Takes a boolean argument. If true, this unit will be stopped when it is no longer used. Note that, in order to minimize the work to be executed, systemd will not stop units by default unless they are conflicting with other units, or the user explicitly requested their shut down. If this option is set, a unit will be automatically cleaned up if no other active unit requires it. Defaults to false. Optional. Type boolean. ๐งน
upstream_default value :
no
๐ RefuseManualStart ๐
Takes a boolean argument. If true, this unit can only be activated or deactivated indirectly. In this case, explicit start-up or termination requested by the user is denied โ however, if it is started or stopped as a dependency of another unit, start-up or termination will succeed. โจ
This is mostly a safety feature to make sure the user doesn't accidentally activate units that aren't intended to be activated explicitly, and doesn't accidentally deactivate units that aren't intended to be deactivated. These options default to false. Optional. Type boolean. ๐
โ๏ธ
๐ฆ RefuseManualStop ๐ฆ
Takes a boolean argument. If true, this unit can only be activated or deactivated indirectly. In this case, explicit start-up or termination requested by the user is denied โ however, if it is started or stopped as a dependency of another unit, start-up or termination will succeed.
This is mostly a safety feature to make sure the user doesn't accidentally activate units that aren't intended to be activated explicitly, and doesn't accidentally deactivate units that aren't intended to be deactivated. These options default to false. Optional. Type boolean. ๐ซถ
AllowIsolate ๐
Takes a boolean argument. If "true", this unit can be used with the systemctl isolate command โ otherwise that whole request gets refused, no cap. ๐
Lowkey it's a good idea to leave this disabled unless you're dealing with target units that are gonna act like runlevels in SysV init systems. It's just a precaution so you don't end up in an unusable system state. ๐
This option defaults to "false". Optional. Type boolean.
DefaultDependencies โจ
Takes a boolean argument. If "yes" (which is the default, bestie), a few default dependencies get implicitly created for the unit. Which ones actually show up depends on the unit type. ๐ฆ
For example, for service units, these dependencies make sure the service only starts after basic system initialization is done, and gets properly terminated on system shutdown. See the respective man pages for the full tea. ๐ต
Generally? Only services involved with early boot or late shutdown should set this to "no". It is highly recommended to leave this option enabled for the majority of common units. And heads up โ setting it to "no" doesn't kill all implicit dependencies, just the non-essential ones. Optional. Type boolean.
SurviveFinalKillSignal ๐
Takes a boolean argument. Defaults to "no". If "yes", processes belonging to this unit will not be sent the final SIGTERM and SIGKILL signals during the final phase of the system shutdown process. ๐ญ
This functionality replaces the older mechanism that let a program set argv[0][0] = '@' as described at systemd and Storage Daemons for the Root File System (https://systemd.io/ROOT_STORAGE_DAEMONS), which however continues to be supported. Optional. Type boolean.
upstream_default value:
no
CollectMode ๐ง
Tweaks the "garbage collection" algorithm for this unit. Takes one of "inactive" or "inactive-or-failed".
If set to "inactive", the unit gets unloaded if it's in the "inactive" state AND it's not referenced by clients, jobs, or other units โ however it is not unloaded if it's in the "failed" state. In "failed" mode, failed units are not unloaded until the user invoked systemctl reset-failed on them to reset the "failed" state, or ran an equivalent command.
This behaviour gets altered if you set this option to "inactive-or-failed": in that case, the unit gets unloaded even if it's in a "failed" state, so explicitly resetting the "failed" state is not necessary. ๐
Not me warning you: if this mode is used, unit results (like exit codes, exit signals, consumed resources, โฆ) are flushed out immediately after the unit completed โ except for whatever is stored in the logging subsystem. ๐ซ
Defaults to "inactive". Optional. Type enum. choice: 'inactive', 'inactive-or-failed'.
FailureActionExitStatus ๐
Controls the exit status to propagate back to an invoking container manager (for a system service) or service manager (for a user manager) when "FailureAction" / "SuccessAction" are set to "exit" or "exit-force" and the action is triggered. โจ
By default, the exit status of the main process of the triggering unit (if that applies) gets propagated. Takes a value in the range 0โฆ255, or the empty string to request default behaviour. Optional. Type uniline.
SuccessActionExitStatus ๐ธ
Controls the exit status to propagate back to an invoking container manager (for a system service) or service manager (for a user manager) when "FailureAction" / "SuccessAction" are set to "exit" or "exit-force" and the action is triggered. โจ
By default, the exit status of the main process of the triggering unit (if that applies) gets propagated. Takes a value in the range 0โฆ255, or the empty string to request default behaviour. Optional. Type uniline.
JobTimeoutSec โฐ
"JobTimeoutSec" specifies a timeout for the whole job that starts running when the job is queued. "JobRunningTimeoutSec" specifies a timeout that starts running when the queued job is actually started. And if either limit is reached, the job gets cancelled โ the unit however will not change state, or even enter the "failed" mode. ๐
Both settings take a time span with the default unit of seconds, but other units may be specified, see systemd.time(7). The default is "infinity" (job timeouts disabled), except for device units where "JobRunningTimeoutSec" defaults to "DefaultDeviceTimeoutSec".
Note: these timeouts are independent from any unit-specific timeouts (for example, the timeout set with "TimeoutStartSec" in service units). The job timeout has no effect on the unit itself. Or in other words: unit-specific timeouts are useful to abort unit state changes, and revert them โ the job timeout set with this option however is useful to abort only the job waiting for the unit state to change. ๐
Optional. Type uniline.
JobRunningTimeoutSec โฐ
"JobTimeoutSec" specifies a timeout for the whole job that starts running when the job is queued. "JobRunningTimeoutSec" specifies a timeout that starts running when the queued job is actually started. And if either limit is reached, the job gets cancelled โ the unit however will not change state, or even enter the "failed" mode. ๐
Both settings take a time span with the default unit of seconds, but other units may be specified, see systemd.time(7). The default is "infinity" (job timeouts disabled), except for device units where "JobRunningTimeoutSec" defaults to "DefaultDeviceTimeoutSec".
Note: these timeouts are independent from any unit-specific timeouts (for example, the timeout set with "TimeoutStartSec" in service units). The job timeout has no effect on the unit itself. Or in other words: unit-specific timeouts are useful to abort unit state changes, and revert them โ the job timeout set with this option however is useful to abort only the job waiting for the unit state to change. ๐
Optional. Type uniline.
JobTimeoutAction ๐
"JobTimeoutAction" optionally configures an additional action to take when the timeout is hit, see description of "JobTimeoutSec" and "JobRunningTimeoutSec" above. It takes the same values as "FailureAction" / "SuccessAction". Defaults to "none".
"JobTimeoutRebootArgument" configures an optional reboot string to pass to the reboot(2) system call.
Optional. Type uniline.
JobTimeoutRebootArgument ๐
"JobTimeoutAction" optionally configures an additional action to take when the timeout is hit, see description of "JobTimeoutSec" and "JobRunningTimeoutSec" above. It takes the same values as "FailureAction" / "SuccessAction". Defaults to "none".
"JobTimeoutRebootArgument" configures an optional reboot string to pass to the reboot(2) system call.
Optional. Type uniline.
StartLimitAction ๐ฅ
Configure an additional action to take if the rate limit configured with "StartLimitIntervalSec" and "StartLimitBurst" is hit. Takes the same values as the "FailureAction" / "SuccessAction" settings. If "none" is set, hitting the rate limit will trigger no action except that the start will not be permitted. Defaults to "none". ๐
Optional. Type enum. choice: 'exit', 'exit-force', 'halt', 'halt-force', 'halt-immediate', 'kexec', 'kexec-force', 'none', 'poweroff', 'poweroff-force', 'poweroff-immediate', 'reboot', 'reboot-force', 'reboot-immediate', 'soft-reboot', 'soft-reboot-force'.
SourcePath ๐
A path to a configuration file this unit has been generated from. This is primarily useful for implementation of generator tools that convert configuration from an external configuration file format into native unit files. ๐ ๏ธ
This functionality should not be used in normal units, bestie. Fr fr. ๐ โโ๏ธ
Optional. Type uniline.
ConditionArchitecture ๐ฅ๏ธ
Check whether the system is running on a specific architecture. Takes one of "x86", "x86-64", "ppc", "ppc-le", "ppc64", "ppc64-le", "ia64", "parisc", "parisc64", "s390", "s390x", "sparc", "sparc64", "mips", "mips-le", "mips64", "mips64-le", "alpha", "arm", "arm-be", "arm64", "arm64-be", "sh", "sh64", "m68k", "tilegx", "cris", "arc", "arc-be", or "native". ๐
Use systemd-analyze(1) for the complete list of known architectures. โจ
The architecture is determined from the information returned by uname(2) and is thus subject to personality(2). Note that a "Personality" setting in the same unit file has no effect on this condition. A special architecture name "native" is mapped to the architecture the system manager itself is compiled for. The test may be negated by prepending an exclamation mark. ๐ฅ
Optional. Type list of enum.
ConditionFirmware ๐ง
Check whether the system's firmware is of a certain type. The following values are possible: โจ
Optional. Type list of uniline.
ConditionVirtualization ๐
Check whether the system is executed in a virtualized environment, and optionally test whether it's a specific implementation. ๐
Takes either:
- a boolean value, to check if being executed in any virtualized environment, or
- one of
"vm"and"container", to test against a generic type of virtualization solution, or - one of
"qemu","kvm","amazon","zvm","vmware","microsoft","oracle","powervm","xen","bochs","uml","bhyve","qnx","apple","sre","openvz","lxc","lxc-libvirt","systemd-nspawn","docker","podman","rkt","wsl","proot","pouch","acrn"to test against a specific implementation, or "private-users", to check whether we are running in a user namespace. ๐
See systemd-detect-virt(1) for a full list of known virtualization technologies and their identifiers. If multiple virtualization technologies are nested, only the innermost is considered. The test may be negated by prepending an exclamation mark. โจ
Optional. Type list of uniline.
ConditionHost ๐ธ
"ConditionHost" may be used to match against the hostname, machine ID, boot ID or product UUID of the host. ๐ซถ
This either takes a hostname string (optionally with shell style globs) which is tested against the locally set hostname as returned by gethostname(2), or a 128bit ID or UUID, formatted as string. The latter is compared against machine ID, boot ID and the firmware product UUID if there is any. See machine-id(5) for details about the machine ID. The test may be negated by prepending an exclamation mark. ๐
Optional. Type list of uniline.
ConditionKernelCommandLine ๐ป
"ConditionKernelCommandLine" may be used to check whether a specific kernel command line option is set (or, if prefixed with the exclamation mark, unset). ๐
The argument must either be:
- a single word, or
- an assignment (i.e. two words, separated by
"=").
In the former case, the kernel command line is searched for the word appearing as is, or as left hand side of an assignment. In the latter case, the exact assignment is looked for with right and left hand side matching. ๐
This operates on the kernel command line communicated to userspace via "/proc/cmdline", except when the service manager is invoked as payload of a container manager, in which case the command line of PID 1 is used instead (i.e. "/proc/1/cmdline"). ๐
Optional. Type list of uniline.
๐ฆ ConditionKernelVersion
ooh okay, this one checks whether the kernel version โ yes, the one uname -r spits out โ matches a certain expression. Or if it's prefixed with an exclamation mark, it does not match. Slay.
The argument has to be a list of (potentially quoted) expressions. Every expression kicks off with one of:
=or!=โ for string comparisons<,<=,==,<>,>=,>โ for version comparisons$=,!$=โ for a shell-style glob match
If you don't specify an operator at all, $= is implied. no cap.
โ ๏ธ bestie, listen. Using the kernel version string to figure out which features a kernel supports is unreliable, and the reason is literally that everyone backports drivers, features and fixes from newer upstream kernels into older versions their distro ships. So this check is inherently unportable and should not be used for units that might end up on different distributions. ๐
- Optional. Type
list of uniline.
๐ ConditionVersion
same energy as above, but for a software version. Checks whether a software version matches a certain expression, or โ exclamation mark prefix โ does not match.
The first argument is the software whose version has to be checked. Currently kernel, systemd and glibc are supported. If you omit this argument, kernel is implied. ๐
The second argument must be a list of (potentially quoted) expressions. Each expression starts with one of:
=or!=โ string comparisons<,<=,==,<>,>=,>โ version comparisons$=,!$=โ shell-style glob match
No operator given? $= is implied, periodt.
- Optional. Type
list of uniline.
๐ ConditionCredential
this one checks whether a credential with the specified name was passed into the service manager. The details about credentials live in System and Service Credentials at https://systemd.io/CREDENTIALS โ go read it, it's giving.
- Used in services for the system service manager โ you can conditionalize services based on system credentials passed in.
- Used in services for the per-user service manager โ you can conditionalize services based on credentials passed into the
unit@.serviceservice instance belonging to the user.
The argument must be a valid credential name. That's it, that's the whole vibe.
- Optional. Type
list of uniline.
๐ ConditionEnvironment
checks whether a specific environment variable is set in the service manager's environment block. Prepend an exclamation mark and it flips: now it's checking that the variable is unset. ๐ซถ
The argument can be either:
- a single word โ check if the variable with that name is defined in the environment block, or
- an assignment (
name=value) โ check if the variable with that exact value is defined.
๐จ super important, don't miss this: the environment block of the service manager itself is what gets checked. Not any variables you defined withEnvironmentorEnvironmentFile, as described above. nope, those don't count.
This is particularly useful when the service manager runs inside a containerized environment, or as a per-user service manager, so you can check for variables passed in by the enclosing container manager or PAM. iconic.
- Optional. Type
list of uniline.
๐ ConditionSecurity
checks whether the given security technology is enabled on the system. Currently, the following values are recognized:
The test may be negated by prepending an exclamation mark.
- Optional. Type
list of uniline.
๐ ConditionCapability
check whether the given capability exists in the capability bounding set of the service manager. And bestie, be so fr: this does not check whether the capability is actually available in the permitted or effective sets. For that whole story, see capabilities(7).
Pass a capability name such as CAP_MKNOD, possibly prefixed with an exclamation mark to negate the check. simple as.
- Optional. Type
list of uniline.
๐ฅ ConditionACPower
checks whether the system has AC power, or is exclusively battery powered, at the moment the unit gets activated. Takes a boolean argument.
- set to
trueโ condition holds only if at least one AC connector of the system is connected to a power source, or if no AC connectors are known. - set to
falseโ condition holds only if there is at least one AC connector known and all AC connectors are disconnected from a power source. - Optional. Type
list of uniline.
๐ง ConditionNeedsUpdate
takes one of /var/ or /etc/ as argument, possibly prefixed with a ! (to invert the condition). This condition lets you conditionalize units on whether the specified directory requires an update โ which is the case when /usr/'s modification time is newer than the stamp file .updated inside that specified directory. ๐ฐ๏ธ
Why do we care? Because it's useful for implementing offline updates of the vendor operating system resources in /usr/ that require updating of /etc/ or /var/ on the next following boot. Units using this condition should order themselves before systemd-update-done.service(8), so they're sure to run before the stamp file's modification time gets reset, indicating a completed update.
If the systemd.condition_needs_update= option is specified on the kernel command line (it takes a boolean), it will override the result of this condition check, taking precedence over any file modification time checks. And heads up: if that kernel command line option is used, systemd-update-done.service will not have immediate effect on any following ConditionNeedsUpdate checks โ not until the system is rebooted without that kernel command line option specified anymore. ๐ญ
Note that to make this scheme effective, the timestamp of /usr/ should be explicitly updated after its contents are modified. The kernel will automatically update the modification timestamp on a directory only when immediate children of a directory are modified; a modification of nested files will not automatically result in the mtime of /usr/ being updated. lowkey sneaky of the kernel.
Also note: if the update method includes a call to execute appropriate post-update steps itself, it should not touch the timestamp of /usr/. In a typical distribution packaging scheme, packages will do any required update steps as part of the installation or upgrade, to make package contents immediately usable. ConditionNeedsUpdate should be used with other update mechanisms where such an immediate update does not happen.
- Optional. Type
list of enum.
๐ธ ConditionFirstBoot
takes a boolean argument. This condition lets you conditionalize units on whether the system is booting up for the first time. Roughly, that means /etc/ was unpopulated when the system started booting โ for the whole lore drop, see "First Boot Semantics" in machine-id(5). First Boot is considered finished (so this condition will evaluate as false) after the manager has finished the startup phase. โจ
This condition may be used to populate /etc/ on the first boot after a factory reset, or when a new system instance boots up for the first time.
Note that the service manager itself will perform setup steps during First Boot: it will initialize machine-id(5) and preset all units, enabling or disabling them according to the systemd.preset(5) settings. Additional setup may be performed via units with ConditionFirstBoot=yes.
For robustness, units with ConditionFirstBoot=yes should order themselves before first-boot-complete.target and pull in this passive target with Wants. This ensures that in a case of an aborted first boot, these units will be re-run during the next system startup. ๐ซก
If the systemd.condition_first_boot= option is specified on the kernel command line (it takes a boolean), it will override the result of this condition check, taking precedence over /etc/machine-id existence checks.
- Optional. Type
list of boolean.
๐ ConditionPathExists
check for the existence of a file. If the specified absolute path name does not exist, the condition will fail. And if the absolute path name passed to ConditionPathExists is prefixed with an exclamation mark (!), the test is negated, and the unit is only started if the path does not exist.
- Optional. Type
list of uniline.
๐ ConditionPathExistsGlob
ConditionPathExistsGlob is similar to ConditionPathExists, but it checks for the existence of at least one file or directory matching the specified globbing pattern. ๐
- Optional. Type
list of uniline.
๐ ConditionPathIsDirectory
ConditionPathIsDirectory is similar to ConditionPathExists but verifies that a certain path exists and is a directory.
- Optional. Type
list of uniline.
๐ฆ ConditionPathIsSymbolicLink
ConditionPathIsSymbolicLink is similar to ConditionPathExists but verifies that a certain path exists and is a symbolic link. ๐
- Optional. Type
list of uniline.
๐ ConditionPathIsMountPoint
ConditionPathIsMountPoint is similar to ConditionPathExists but verifies that a certain path exists and is a mount point. that's it, that's the check.
- Optional. Type
list of uniline.
๐ง ConditionPathIsReadWrite
ConditionPathIsReadWrite is similar to ConditionPathExists but verifies that the underlying file system is readable and writable โ i.e. not mounted read-only. no frozen fs energy here, we move. โ๏ธ
- Optional. Type
list of uniline.
๐ ConditionPathIsEncrypted
ConditionPathIsEncrypted is similar to ConditionPathExists but verifies that the underlying file system's backing block device is encrypted using dm-crypt/LUKS. ๐
โ ๏ธ okay the caveats, write these down: this check does not cover ext4 per-directory encryption, and only detects block level encryption. Moreover, if the specified path resides on a file system on top of a loopback block device, only encryption above the loopback device is detected. It is not detected whether the file system backing the loopback block device is encrypted. so it's giving layers, and we only see one of them.
- Optional. Type
list of uniline.
๐งฆ ConditionPathIsSocket
ConditionPathIsSocket is similar to ConditionPathExists but verifies that a certain path exists and is a socket.
- Optional. Type
list of uniline.
๐ท ConditionDirectoryNotEmpty
ConditionDirectoryNotEmpty is similar to ConditionPathExists but verifies that a certain path exists and is a non-empty directory. no empty folders allowed bestie, this one wants โจcontentโจ.
- Optional. Type
list of uniline.
๐ ConditionFileNotEmpty
ConditionFileNotEmpty is similar to ConditionPathExists but verifies that a certain path exists and refers to a regular file with a non-zero size.
- Optional. Type
list of uniline.
โก ConditionFileIsExecutable
ConditionFileIsExecutable is similar to ConditionPathExists but verifies that a certain path exists, is a regular file, and is marked executable. chmod +x core. ๐
- Optional. Type
list of uniline.
๐ ConditionUser
ConditionUser takes a numeric UID, a UNIX user name, or the special value @system. This condition may be used to check whether the service manager is running as the given user. The special value @system can be used to check if the user id is within the system user range. ๐
Real talk though: this option is not useful for system services, because the system manager exclusively runs as the root user, and thus the test result is constant. like, it's always gonna say the same thing, so why bother.
- Optional. Type
list of uniline.
๐ธ ConditionGroup ๐ธ
Okay so ConditionGroup is basically the glow-up twin of ConditionUser ๐ but instead of the user it checks the service manager's real or effective group, or any of its auxiliary groups, against the group or GID you specified. Match = pass, no cap.
โ ๏ธ Heads up bestie: this setting does not support the special value @system. Don't even try it ๐
Optional. Type: list of uniline. โจ
๐ง ConditionControlGroupController ๐ง
This one's asking: are the cgroup controllers you want (think cpu and friends) actually available for use on this system? And like, are we on the legacy v1 hierarchy or the modern v2 one? Vibe check on the cgroups fr fr ๐
You can pass multiple controllers with a space separating them โ and in that case the condition only passes if all of the listed controllers are available. Controllers that systemd doesn't know about are just... ignored, we move on โจ
Valid controllers are:
cpuiomemorypids
Even if a controller is available in the kernel, it might not actually be available if it got disabled on the kernel command line with cgroup_disable=controller. Rude but true ๐ญ
Alternatively you can pass two special strings โ v1 and v2 โ with no controller names at all:
v2passes if the unified v2 cgroup hierarchy is usedv1passes if the legacy v1 hierarchy or the hybrid hierarchy is used
๐ Not me having to say this but: legacy and hybrid hierarchies have been deprecated. See systemd(1) for more info.
Optional. Type: list of uniline. ๐
๐ ConditionMemory ๐
Verify that the specified amount of system memory is available to the current system, periodt. Takes a memory size in bytes as its argument, optionally prefixed with a comparison operator:
<<==(or==)!=(or<>)>=>
On bare-metal systems it compares the amount of physical memory in the system against the size you gave, following whichever comparison operator you used. In containers? It compares the amount of memory assigned to the container instead. Different context, different rules ๐
Optional. Type: list of uniline. ๐ธ
๐ฆ ConditionCPUs ๐ฆ
Verify that the specified number of CPUs is available to the current system. Takes a number of CPUs as the argument, optionally prefixed with a comparison operator โ same lineup as before:
<<==(or==)!=(or<>)>=>
It compares the number of CPUs in the CPU affinity mask configured for the service manager itself against the number you specified, adhering to your chosen operator.
On physical systems, the number of CPUs in the service manager's affinity mask usually matches the number of physical CPUs โ but in special and virtual environments it might differ. Specifically, in containers the affinity mask usually matches the number of CPUs assigned to the container, not the physically available ones. It's giving "technically true" energy โจ
Optional. Type: list of uniline. ๐ซถ
๐ ConditionCPUFeature ๐
Verify that a given CPU feature is available via the CPUID instruction. Real talk: this condition only does something on i386 and x86-64 processors. On any other processors, it's assumed the CPU does not support the given feature. ๐ญ
It checks the leaves 1, 7, 0x80000001, and 0x80000007.
Valid values are โ and this is the full list, every single one, no skipping:
fpu, vme, de, pse, tsc, msr, pae, mce, cx8, apic, sep, mtrr, pge, mca, cmov, pat, pse36, clflush, mmx, fxsr, sse, sse2, ht, pni, pclmul, monitor, ssse3, fma3, cx16, sse4_1, sse4_2, movbe, popcnt, aes, xsave, osxsave, avx, f16c, rdrand, bmi1, avx2, bmi2, rdseed, adx, sha_ni, syscall, rdtscp, lm, lahf_lm, abm, constant_tsc.
Optional. Type: list of uniline. ๐
๐ ConditionOSRelease ๐
Verify that a specific key=value pair is set in the host's os-release(5). So niche, so useful ๐
Matching styles available to you:
- Exact string matching with
=and!= - Relative comparisons for versioned parameters (e.g.
VERSION_ID) with<,<=,==,<>,>=,> - Shell-style wildcard comparisons with
*,?,[]โ using$=for match and!$=for non-match
If the given key is not found in the file, the match is done against an empty value. iykyk ๐
Optional. Type: list of uniline. โญ
๐ญ ConditionMemoryPressure ๐ญ
Verify that the overall system (memory, CPU or IO) pressure is below or equal to a threshold. This setting takes a threshold value as its argument.
You can specify it as a simple percentage value, suffixed with % โ in which case the pressure gets measured as an average over the last five minutes before the attempt to start the unit is performed.
Alternatively, the average timespan can also be specified using / as a separator โ for example: 10%/1min. The supported timespans match what the kernel provides, and are limited to:
10sec1min5min
The full PSI gets checked first, and if it's not found, some gets checked. For the full lore, see the documentation on PSI (Pressure Stall Information) at https://docs.kernel.org/accounting/psi.html โจ
Optionally, the threshold value can be prefixed with the slice unit under which the pressure will be checked, followed by a :. If you don't specify the slice unit, the overall system pressure is measured instead of a particular cgroup's.
Optional. Type: list of uniline. ๐
๐ ConditionCPUPressure ๐
Verify that the overall system (memory, CPU or IO) pressure is below or equal to a threshold โ yes, the CPU flavour of the pressure trio, same energy different name ๐ This setting takes a threshold value as its argument.
It can be specified as a simple percentage value, suffixed with %, in which case the pressure will be measured as an average over the last five minutes before the attempt to start the unit is performed.
Alternatively, the average timespan can also be specified using / as a separator, for example: 10%/1min. The supported timespans match what the kernel provides, and are limited to 10sec, 1min and 5min. The full PSI will be checked first, and if not found, some will be checked. For more details, see the documentation on PSI (Pressure Stall Information) at https://docs.kernel.org/accounting/psi.html.
Optionally, the threshold value can be prefixed with the slice unit under which the pressure will be checked, followed by :. If the slice unit is not specified, the overall system pressure will be measured instead of a particular cgroup's.
Optional. Type: list of uniline. ๐ธ
๐ ConditionIOPressure ๐
Verify that the overall system (memory, CPU or IO) pressure is below or equal to a threshold. Threshold value goes in as the argument, bestie.
Simple percentage value suffixed with %? Then the pressure gets measured as an average over the last five minutes before the unit start attempt happens. Want a specific window instead? Use / as a separator to give the average timespan, e.g. 10%/1min. The supported timespans match what the kernel provides and are limited to 10sec, 1min and 5min. The full PSI is checked first โ if that's not found, some gets checked. More details live in the PSI (Pressure Stall Information) docs at https://docs.kernel.org/accounting/psi.html.
Optional twist: prefix the threshold value with the slice unit under which the pressure should be checked, then a :. Leave the slice unit out and you're measuring overall system pressure, not one particular cgroup's.
Optional. Type: list of uniline. ๐ง
๐ ConditionKernelModuleLoaded ๐
Test whether the specified kernel module has been loaded and is already fully initialized. Both. Not one or the other. Fully cooked โ
Optional. Type: list of uniline. โจ
๐ฅ AssertArchitecture ๐ฅ
Similar to the ConditionArchitecture, ConditionVirtualization, โฆ condition settings described above, these settings add assertion checks to the start-up of the unit. But here's the plot twist: unlike the condition settings, any assertion setting that is not met results in failure of the start job โ which means this is logged loudly. Screaming, even. ๐ญ
๐ข Important: hitting a configured assertion does not cause the unit to enter the failed state (or in fact result in any state change of the unit at all). It affects only the job queued for it. Iconic but specific.
Use assertion expressions for units that cannot operate when specific requirements are not met, and when this is something the administrator or user should look into.
Optional. Type: uniline. ๐
๐ซถ AssertVirtualization ๐ซถ
Similar to the ConditionArchitecture, ConditionVirtualization, โฆ condition settings described above, these settings add assertion checks to the start-up of the unit. However, unlike the conditions settings, any assertion setting that is not met results in failure of the start job (which means this is logged loudly). Note that hitting a configured assertion does not cause the unit to enter the failed state (or in fact result in any state change of the unit), it affects only the job queued for it. Use assertion expressions for units that cannot operate when specific requirements are not met, and when this is something the administrator or user should look into.
Optional. Type: uniline. ๐
๐ฆ AssertHost ๐ฆ
Similar to the ConditionArchitecture, ConditionVirtualization, โฆ condition settings described above, these settings add assertion checks to the start-up of the unit. However, unlike the conditions settings, any assertion setting that is not met results in failure of the start job (which means this is logged loudly). Note that hitting a configured assertion does not cause the unit to enter the failed state (or in fact result in any state change of the unit), it affects only the job queued for it. Use assertion expressions for units that cannot operate when specific requirements are not met, and when this is something the administrator or user should look into.
Optional. Type: uniline. โญ
๐ธ AssertKernelCommandLine ๐ธ
Similar to the ConditionArchitecture, ConditionVirtualization, โฆ condition settings described above, these settings add assertion checks to the start-up of the unit. However, unlike the conditions settings, any assertion setting that is not met results in failure of the start job (which means this is logged loudly). Note that hitting a configured assertion does not cause the unit to enter the failed state (or in fact result in any state change of the unit), it affects only the job queued for it. Use assertion expressions for units that cannot operate when specific requirements are not met, and when this is something the administrator or user should look into.
Optional. Type: uniline. ๐
๐ AssertKernelVersion ๐
Similar to the ConditionArchitecture, ConditionVirtualization, โฆ condition settings described above, these settings add assertion checks to the start-up of the unit. However, unlike the conditions settings, any assertion setting that is not met results in failure of the start job (which means this is logged loudly). Note that hitting a configured assertion does not cause the unit to enter the failed state (or in fact result in any state change of the unit), it affects only the job queued for it. Use assertion expressions for units that cannot operate when specific requirements are not met, and when this is something the administrator or user should look into.
Optional. Type: uniline. ๐
Okay so real talk: this whole squad of settings is the assertion squad, and they're built exactly like the ConditionArchitecture, ConditionVirtualization, โฆ condition settings we talked about above โจ โ they add assertion checks to the start-up of the unit. That part is giving copy-paste energy on purpose, bestie.
But here's the plot twist that changes everything ๐: with the condition settings, a miss just quietly says "nvm, skipping." With assertions? A miss means the start job fails, and it's logged loudly ๐๐ข no subtlety, no chill, the journal is screaming.
And now the part everyone gets wrong, so listen up ๐:
Hitting a configured assertion does not cause the unit to enter the "failed" state. It does not result in any state change of the unit at all, actually. It affects only the job queued for it. That's it, that's the whole thing. ๐ซถ
So when do you reach for these? Use assertion expressions for units that cannot operate when specific requirements are not met โ and specifically when that's something the administrator or user should look into ๐. It's the "hey, this is broken and you need to know about it" lever, not the "meh, skip it" lever. iykyk.
So every single one of the following is Optional. Type uniline. โ that's the tag, that's the vibe, it never changes. And every single one does the exact same job described above: assertion check at start-up, fail the job (loudly) but not the unit. Let's go down the list ๐ธ๐ฆ:
AssertVersionโ assertion check on start-up, and if it's not met the start job fails loudly. Same deal as the paragraph above, bestie. Optional. Type uniline.AssertCredentialโ yep, another assertion check bolted onto start-up. Not met? Job fails, journal yells, unit is unbothered. Optional. Type uniline.AssertEnvironmentโ assertion check on start-up, exactly like the ones above. Only the queued job takes the L. Optional. Type uniline.AssertSecurityโ assertion check, start-up, loud failure of the job, zero state change to the unit. Same energy, new name. Optional. Type uniline.AssertCapabilityโ you already know the drill ๐ assertion check on start-up; unmet means the job fails loudly and nothing else happens. Optional. Type uniline.AssertACPowerโ asserting away, start-up edition. If it doesn't hold, the job fails (loudly!!), the unit stays right where it was. Optional. Type uniline.AssertNeedsUpdateโ another member of the assertion squad with the identical behaviour described up top. Job fails, unit doesn't. Optional. Type uniline.AssertFirstBootโ assertion check at start-up, same rules as the whole group. Unmet = job failure, logged loudly, no state change anywhere. Optional. Type uniline.AssertPathExistsโ assertion check, start-up, and if it's not satisfied the job fails loudly while the unit literally does not care. Optional. Type uniline.AssertPathExistsGlobโ same assertion-check situation as every sibling above it. Job takes the failure, the unit takes nothing. Optional. Type uniline.AssertPathIsDirectoryโ assertion check on start-up, identical mechanics to the paragraph above. Fail loudly, change nothing about the unit. Optional. Type uniline.AssertPathIsSymbolicLinkโ assertion check, start-up, unmet โ failed job, loud journal, untouched unit. Copy that. Optional. Type uniline.AssertPathIsMountPointโ yeah bestie, it's the same assertion-check behaviour as the rest of the family. Only the queued job is affected. Optional. Type uniline.AssertPathIsReadWriteโ assertion check at start-up, exactly as described above. Not met = loud job failure, no unit state change. Optional. Type uniline.AssertPathIsEncryptedโ last one in the lineup and ngl it's the same story ๐ assertion check on start-up; unmet means the job fails loudly and the unit stays completely unchanged. Optional. Type uniline.
okay so these next ones โ the whole Assertโฆ fam โ are literally the chaotic cousin of the Conditionโฆ settings ๐
They work just like ConditionArchitecture, ConditionVirtualization, โฆ (all those condition settings described above): they add assertion checks to the start-up of the unit. But. Unlike the condition settings, if an assertion setting is not met, the start job fails โ and it fails loudly, like the logs are screaming, that's on purpose (it's logged loudly ๐ข).
And here's the part everyone gets wrong, so listen up ๐ซถ: hitting a configured assertion does not make the unit enter the failed state. It also doesn't cause any state change of the unit at all. All it touches is the job queued for it. That's it. That's the whole drama.
Use assertion expressions for units that truly cannot operate when specific requirements aren't met โ and when that's something the administrator or user should look into ๐
Every single one of the settings below: Optional. Type uniline. Same deal, different vibe check โจ
AssertPathIsSocketโ asserting that path is giving socket ๐งฆ. Miss the check and the start job eats the L, loudly โ but the unit itself does not gofailedand its state doesn't budge, only the queued job is affected. Optional. Typeuniline.AssertDirectoryNotEmptyโ directory's not empty, or else ๐ฅ. Unmet = the start job fails and it's logged loudly. Nofailedstate on the unit, no state change, just the queued job catching feelings. Optional. Typeuniline.AssertFileNotEmptyโ file has content, bestie, no zero-byte nonsense ๐. Fail the assert and the start job fails loudly; unit state stays exactly where it was and only the queued job is affected. Optional. Typeuniline.AssertFileIsExecutableโ is it executable? It better be ๐ . Not met โ start job fails, logged loudly. Unit does not enterfailed, unit state doesn't change, only the queued job takes the hit. Optional. Typeuniline.AssertUserโ checking for the user ๐. Unmet assertion = loud start job failure. The unit itself stays unbothered and unchanged (nofailed, no state change) โ it's only the job queued for it. Optional. Typeuniline.AssertGroupโ but make it groups ๐. Same energy as the rest of these: assertion not met, start job fails loudly, unit state does not change at all, only the queued job is affected. Optional. Typeuniline.AssertControlGroupControllerโ the cgroup controller vibe check ๐ฆ. Miss it and the start job fails loudly โ nofailedstate for the unit, zero state change, literally only the job queued for it. Optional. Typeuniline.AssertMemoryโ memory requirement check โจ. Unmet means the start job fails (loudly, logged loudly, we're all hearing about it), but the unit itself doesn't enterfailedand doesn't change state โ just the queued job. Optional. Typeuniline.AssertCPUsโ how many CPUs we got, fr fr ๐. Not met โ start job failure, logged loudly. Unit: unchanged, nofailed, no state change. Job: affected. Optional. Typeuniline.AssertCPUFeatureโ does the CPU have the feature? ๐. Unmet assertion = start job fails loudly, and that's the only thing that changes โ the unit doesn't hitfailed, its state doesn't move, only the queued job is affected. Optional. Typeuniline.AssertOSReleaseโ OS release requirements, periodt โญ. Failing it fails the start job loudly. The unit itself is fine, un-failed, unchanged in state; only the queued job is affected. Optional. Typeuniline.AssertMemoryPressureโ memory pressure check ๐ญ. Same rules as every assert above: unmet โ the start job fails loudly, no unitfailedstate, no unit state change, only the queued job. Optional. Typeuniline.AssertCPUPressureโ CPU pressure check ๐ฅ. Unmet = the start job fails with a loud log. The unit does not enterfailedand no state change happens โ it only affects the job queued for it. Optional. Typeuniline.AssertIOPressureโ IO pressure check ๐. Not met โ start job failure, logged loudly. Unit state: untouched, notfailed, no change. Only the queued job is affected. Optional. Typeuniline.AssertKernelModuleLoadedโ is the kernel module loaded, bestie? ๐ง. Fail it and the start job fails loudly โ the unit doesn't flip tofailedand nothing about its state changes, it's only the job queued for it. Optional. Typeuniline.
StartLimitIntervalโ Deprecated ๐ Optional. Typeuniline.
and we're still not done โ keep scrolling ๐ซถ
๐ฉน OnFailureIsolate
Deprecated bestie, it's over ๐
Optional. Type uniline.
๐ฅ FailureAction
Okay so this one sets the action to take when the unit stops and lands in a failed state or an inactive state. It takes exactly one of: none, reboot, reboot-force, reboot-immediate, poweroff, poweroff-force, poweroff-immediate, exit, exit-force, soft-reboot, soft-reboot-force, kexec, kexec-force, halt, halt-force and halt-immediate. In system mode all options are allowed. In user mode, only none, exit, and exit-force are allowed. Both options default to none.
Now the lore, one by one:
noneโ nothing gets triggered, we're just chillin โจrebootโ causes a reboot following the normal shutdown procedure (that's equivalent tosystemctl reboot)reboot-forceโ causes a forced reboot which will terminate all processes forcibly but should cause no dirty file systems on reboot (equivalent tosystemctl reboot -f)reboot-immediateโ causes immediate execution of thereboot(2)system call, and this might result in data loss (equivalent tosystemctl reboot -ff) ๐ญpoweroff,poweroff-force,poweroff-immediate,kexec,kexec-force,halt,halt-forceandhalt-immediateโ same deal, they have the effect of powering down the system, executing kexec, and halting the system respectively, with similar semantics ๐ซถexitโ causes the manager to exit following the normal shutdown procedureexit-forceโ causes it to terminate without shutting down servicessoft-rebootโ will trigger a userspace reboot operation ๐soft-reboot-forceโ does that too, but does not go through the shutdown transaction beforehand
When exit or exit-force is used, by default the exit status of the main process of the unit (if this applies) is returned from the service manager. However, this may be overridden with FailureActionExitStatus/SuccessActionExitStatus, see below ๐
Optional. Type enum. choice: 'exit', 'exit-force', 'halt', 'halt-force', 'halt-immediate', 'kexec', 'kexec-force', 'none', 'poweroff', 'poweroff-force', 'poweroff-immediate', 'reboot', 'reboot-force', 'reboot-immediate', 'soft-reboot', 'soft-reboot-force'.
๐ SuccessAction
Same energy, different trigger: configure the action to take when the unit stops and enters a failed state or inactive state. It takes one of none, reboot, reboot-force, reboot-immediate, poweroff, poweroff-force, poweroff-immediate, exit, exit-force, soft-reboot, soft-reboot-force, kexec, kexec-force, halt, halt-force and halt-immediate. In system mode, all options are allowed. In user mode, only none, exit, and exit-force are allowed. Both options default to none.
And the meanings, again, because you deserve the full menu ๐:
noneโ no action will be triggered, iconic behaviour honestlyrebootโ causes a reboot following the normal shutdown procedure (i.e. equivalent tosystemctl reboot)reboot-forceโ causes a forced reboot which will terminate all processes forcibly but should cause no dirty file systems on reboot (i.e. equivalent tosystemctl reboot -f)reboot-immediateโ causes immediate execution of thereboot(2)system call, which might result in data loss (i.e. equivalent tosystemctl reboot -ff) ๐poweroff,poweroff-force,poweroff-immediate,kexec,kexec-force,halt,halt-forceandhalt-immediateโ have the effect of powering down the system, executing kexec, and halting the system respectively, with similar semanticsexitโ causes the manager to exit following the normal shutdown procedureexit-forceโ causes it to terminate without shutting down servicessoft-rebootโ will trigger a userspace reboot operationsoft-reboot-forceโ does that too, but does not go through the shutdown transaction beforehand
When exit or exit-force is used, by default the exit status of the main process of the unit (if this applies) is returned from the service manager. However, this may be overridden with FailureActionExitStatus/SuccessActionExitStatus, see below. ๐
Optional. Type enum. choice: 'exit', 'exit-force', 'halt', 'halt-force', 'halt-immediate', 'kexec', 'kexec-force', 'none', 'poweroff', 'poweroff-force', 'poweroff-immediate', 'reboot', 'reboot-force', 'reboot-immediate', 'soft-reboot', 'soft-reboot-force'.
๐ฆ StartLimitBurst
Configure unit start rate limiting, bestie. Units which are started more than burst times within an interval time span are not permitted to start any more. Use StartLimitIntervalSec to configure the checking interval and StartLimitBurst to configure how many starts per interval are allowed.
interval is a time span with the default unit of seconds, but other units may be specified, see systemd.time(7). The special value infinity can be used to limit the total number of start attempts, even if they happen at large time intervals. Defaults to DefaultStartLimitIntervalSec in manager configuration file, and may be set to 0 to disable any kind of rate limiting. burst is a number and defaults to DefaultStartLimitBurst in manager configuration file.
These configuration options are particularly useful in conjunction with the service setting Restart (see systemd.service(5)); however, they apply to all kinds of starts (including manual ones), not just those triggered by the Restart logic. โจ
Note that units which are configured forRestart, and which reach the start limit, are not attempted to be restarted anymore; however, they may still be restarted manually or from a timer or socket at a later point, after the interval has passed. From that point on, the restart logic is activated again.systemctl reset-failedwill cause the restart rate counter for a service to be flushed, which is useful if the administrator wants to manually start a unit and the start limit interferes with that.
Rate-limiting is enforced after any unit condition checks are executed, and hence unit activations with failing conditions do not count towards the rate limit.
When a unit is unloaded due to the garbage collection logic (see above) its rate limit counters are flushed out too. This means that configuring start rate limiting for a unit that is not referenced continuously has no effect. ๐
This setting does not apply to slice, target, device, and scope units, since they are unit types whose activation may either never fail, or may succeed only a single time.
Optional. Type uniline.
โณ StartLimitIntervalSec
Same story, same rules. Configure unit start rate limiting โ units which are started more than burst times within an interval time span are not permitted to start any more. Use StartLimitIntervalSec to configure the checking interval and StartLimitBurst to configure how many starts per interval are allowed.
interval is a time span with the default unit of seconds, but other units may be specified, see systemd.time(7). The special value infinity can be used to limit the total number of start attempts, even if they happen at large time intervals. Defaults to DefaultStartLimitIntervalSec in manager configuration file, and may be set to 0 to disable any kind of rate limiting. burst is a number and defaults to DefaultStartLimitBurst in manager configuration file.
These configuration options are particularly useful together with the service setting Restart (see systemd.service(5)); however, they apply to all kinds of starts (including manual), not just those triggered by the Restart logic. ๐
Note that units which are configured forRestart, and which reach the start limit, are not attempted to be restarted anymore; however, they may still be restarted manually or from a timer or socket at a later point, after the interval has passed. From that point on, the restart logic is activated again.systemctl reset-failedwill cause the restart rate counter for a service to be flushed, which is useful if the administrator wants to manually start a unit and the start limit interferes with that.
Rate-limiting is enforced after any unit condition checks are executed, and hence unit activations with failing conditions do not count towards the rate limit.
When a unit is unloaded due to the garbage collection logic (see above) its rate limit counters are flushed out too. This means that configuring start rate limiting for a unit that is not referenced continuously has no effect. ๐ฆ
This setting does not apply to slice, target, device, and scope units, since they are unit types whose activation may either never fail, or may succeed only a single time.
Optional. Type uniline.
๐ RebootArgument
Configure the optional argument for the reboot(2) system call if StartLimitAction or FailureAction is a reboot action. This works just like the optional argument to systemctl reboot command. ๐
Optional. Type uniline.
๐ SEE ALSO ๐
cme
and that's a wrap on the whole page, bestie!! ๐ซถโจ this was perl v5.40.1, dated 2026-03-22, and it lives in the Config...erUnit(3pm) era of the User Contributed Perl Documentation. go forth and configure your units, no cap ๐
๐
๐ฆ where this page comes from
- ubuntu stonking: libconfig-model-systemd-perl 0.260.1-1 ยท LGPL-2.1-only
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms