man: sd_notify() race is gone with sd_notify_barrier()

Add note for change of behaviour in systemd-notify, where parent pid trick
is only used when --no-block is passed, and with enough privileges ofcourse.

Also, fix a small error in systemd(1).
This commit is contained in:
Kumar Kartikeya Dwivedi 2020-04-28 19:09:53 +05:30
parent 4f07ddfa9b
commit 5ec7a9947e
No known key found for this signature in database
GPG Key ID: 4CE0C88648BF11CA
3 changed files with 32 additions and 10 deletions

View File

@ -54,15 +54,19 @@
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.</para>
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><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> described above.</para>
</refsect1>
<refsect1>
@ -129,6 +133,17 @@
with systemd. </para></listitem>
</varlistentry>
<varlistentry>
<term><option>--no-block</option></term>
<listitem><para>Do not synchronously wait for the requested operation to finish.
Use of this option is only recommended when <command>systemd-notify</command>
is spawned by the service manager, or when the invoking process is directly spawned
by the service manager and has enough privileges to allow <command>systemd-notify
</command> to send the notification on its behalf. Sending notifications with
this option set is prone to race conditions in all other cases.</para></listitem>
</varlistentry>
<xi:include href="standard-options.xml" xpointer="help" />
<xi:include href="standard-options.xml" xpointer="version" />
</variablelist>

View File

@ -959,7 +959,14 @@
<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.</para></listitem>
<varname>NotifyAccess=</varname><option>all</option> is set for it.</para>
<para>Hence, to eliminate all race conditions involving lookup of the client's unit and attribution of notifications
to units correctly, <function>sd_notify_barrier()</function> may be used. This call acts as a synchronization point
and ensures all notifications sent before this call have been picked up by the service manager when it returns
successfully. Use of <function>sd_notify_barrier()</function> is needed for clients which are not invoked by the
service manager, otherwise this synchronization mechanism is unnecessary for attribution of notifications to the
unit.</para></listitem>
</varlistentry>
<varlistentry>

View File

@ -257,7 +257,7 @@
execution compared to the target unit's state and is marked successful and
complete when both satisfy. However, this job also pulls in other
dependencies due to the defined relationships and thus leads to, in our
our example, start jobs for any of those inactive units getting queued as
example, start jobs for any of those inactive units getting queued as
well.</para>
<para>systemd contains native implementations of various tasks