man: improve docs about systemd-notify invocations and NotifyAccess= settings

Fixes: #24516
This commit is contained in:
Lennart Poettering 2023-01-06 19:02:16 +01:00 committed by Luca Boccassi
parent 9826037476
commit b7d963e50a

View file

@ -46,27 +46,33 @@
to send as part of the status update.</para>
<para>Note that systemd will refuse reception of status updates from this command unless
<varname>NotifyAccess=</varname> is set for the service unit this command is called from.</para>
<varname>NotifyAccess=</varname> is appropriately set for the service unit this command is called
from. See
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
details.</para>
<para>Note that <function>sd_notify()</function> notifications may be attributed to units correctly only if either
the sending process is still around at the time PID 1 processes the message, or if the sending process is
explicitly runtime-tracked by the service manager. The latter is the case if the service manager originally forked
off the process, i.e. on all processes that match <varname>NotifyAccess=</varname><option>main</option> or
<varname>NotifyAccess=</varname><option>exec</option>. Conversely, if an auxiliary process of the unit sends an
<function>sd_notify()</function> message and immediately exits, the service manager might not be able to properly
attribute the message to the unit, and thus will ignore it, even if <varname>NotifyAccess=</varname><option>all
</option> is set for it. When <option>--no-block</option> is used, all synchronization for reception of notifications
is disabled, and hence the aforementioned race may occur if the invoking process is not the service manager or spawned
by the service manager.</para>
<para>Hence, <command>systemd-notify</command> will first attempt to invoke <function>sd_notify()</function>
pretending to have the PID of the invoking process. This will only succeed when invoked with sufficient privileges.
On failure, it will then fall back to invoking it under its own PID. This behaviour is useful in order that when
the tool is invoked from a shell script the shell process — and not the <command>systemd-notify</command> process
— appears as sender of the message, which in turn is helpful if the shell process is the main process of a service,
due to the limitations of <varname>NotifyAccess=</varname><option>all</option>. Use the <option>--pid=</option>
switch to tweak this behaviour.</para>
<para>Note that <function>sd_notify()</function> notifications may be attributed to units correctly only
if either the sending process is still around at the time PID 1 processes the message, or if the sending
process is explicitly runtime-tracked by the service manager. The latter is the case if the service
manager originally forked off the process, i.e. on all processes that match
<varname>NotifyAccess=</varname><option>main</option> or
<varname>NotifyAccess=</varname><option>exec</option>. Conversely, if an auxiliary process of the unit
sends an <function>sd_notify()</function> message and immediately exits, the service manager might not be
able to properly attribute the message to the unit, and thus will ignore it, even if
<varname>NotifyAccess=</varname><option>all</option> is set for it. To address this
<command>systemd-notify</command> will wait until the notification message has been processed by the
service manager. When <option>--no-block</option> is used, this synchronization for reception of
notifications is disabled, and hence the aforementioned race may occur if the invoking process is not the
service manager or spawned by the service manager.</para>
<para><command>systemd-notify</command> will first attempt to invoke <function>sd_notify()</function>
pretending to have the PID of the parent process of <command>systemd-notify</command> (i.e. the invoking
process). This will only succeed when invoked with sufficient privileges. On failure, it will then fall
back to invoking it under its own PID. This behaviour is useful in order that when the tool is invoked
from a shell script the shell process — and not the <command>systemd-notify</command> process — appears
as sender of the message, which in turn is helpful if the shell process is the main process of a service,
due to the limitations of <varname>NotifyAccess=</varname><option>all</option>. Use the
<option>--pid=</option> switch to tweak this behaviour.</para>
</refsect1>
<refsect1>
@ -95,7 +101,15 @@
command itself is used, and if <literal>parent</literal> is specified the calling process' PID is
used — even if it is the service manager. This is equivalent to <command>systemd-notify
MAINPID=$PID</command>. For details about the semantics of this option see
<citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem>
<citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
<para>If this switch is used in an <command>systemd-notify</command> invocation from a process that
shall become the new main process of a service — and which is not the process forked off by the
service manager (or the current main process) —, then it is essential to set
<varname>NotifyAccess=all</varname> in the service unit file, or otherwise the notification will be
ignored for security reasons. See
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details.</para></listitem>
</varlistentry>
<varlistentry>
@ -188,6 +202,7 @@ done</programlisting>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_booted</refentrytitle><manvolnum>3</manvolnum></citerefentry>
</para>