]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
man: clarify that ExecCondition= skip triggers SuccessAction=
authorRocker Zhang <zhang.rocker.liyuan@gmail.com>
Fri, 15 May 2026 11:27:57 +0000 (19:27 +0800)
committerZbigniew Jędrzejewski-Szmek <zbyszek@amutable.com>
Wed, 27 May 2026 12:05:08 +0000 (14:05 +0200)
Unit-level Condition…= / Assert…= directives that fail prevent activation
entirely, so SuccessAction= / FailureAction= never fire. An ExecCondition=
skip in [Service] runs as part of the activation transition itself, so
the unit goes active → inactive and SuccessAction= is honored.

This asymmetry has tripped users up; document it explicitly in both
systemd.service(5) (ExecCondition= section) and systemd.unit(5)
(SuccessAction= / FailureAction= section) with cross-references.

Fixes: https://github.com/systemd/systemd/issues/42035
Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
man/systemd.service.xml
man/systemd.unit.xml

index 0c5f222bb7a09e8892805a3667a4aed90e4cf9e1..ed0f9476a00b95008dfe864ca98e6a7bf7c2a32a 100644 (file)
         signal, etc.), the unit will be considered failed (and remaining commands will be skipped). Exit code of 0 or
         those matching <varname>SuccessExitStatus=</varname> will continue execution to the next commands.</para>
 
+        <para>Note that an <varname>ExecCondition=</varname> skip is <emphasis>not</emphasis> equivalent to a
+        unit-level <varname>Condition…=</varname> or <varname>Assert…=</varname> check failing. Because
+        <varname>ExecCondition=</varname> runs as part of the activation transition, a skip causes the unit to
+        transition from <constant>active</constant> to <constant>inactive</constant>, and consequently
+        <varname>SuccessAction=</varname> (see
+        <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>) will be
+        honored. By contrast, <varname>Condition…=</varname> directives in the <literal>[Unit]</literal> section
+        prevent activation entirely and therefore do not trigger <varname>SuccessAction=</varname>.</para>
+
         <para>The same recommendations about not running long-running processes in <varname>ExecStartPre=</varname>
         also applies to <varname>ExecCondition=</varname>. <varname>ExecCondition=</varname> will also run the commands
         in <varname>ExecStopPost=</varname>, as part of stopping the service, in the case of any non-zero or abnormal
index 2990e658911529fa768375a2ab102fdd1b141f10..5d2f32dfcefac1bc03b8ab05a3b7fdb347bee9c4 100644 (file)
         allowed. In user mode, only <option>none</option>, <option>exit</option>, and
         <option>exit-force</option> are allowed. Both options default to <option>none</option>.</para>
 
+        <para>These actions are tied to the unit's state transitions and fire only when the unit actually
+        transitions out of an <constant>active</constant> or <constant>activating</constant> state. As a
+        consequence, <varname>Condition…=</varname> and <varname>Assert…=</varname> directives that fail do
+        <emphasis>not</emphasis> trigger <varname>SuccessAction=</varname> or
+        <varname>FailureAction=</varname>: they prevent activation in the first place, so no state transition
+        occurs. By contrast, the <varname>ExecCondition=</varname> directive in
+        <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+        runs as part of activation, so an <varname>ExecCondition=</varname> skip <emphasis>will</emphasis>
+        trigger <varname>SuccessAction=</varname>.</para>
+
         <para>If <option>none</option> is set, no action will be triggered. <option>reboot</option> causes a
         reboot following the normal shutdown procedure (i.e. equivalent to <command>systemctl
         reboot</command>).  <option>reboot-force</option> causes a forced reboot which will terminate all