Merge pull request #5239 from poettering/notify-access-all

man: document that sd_notify() is racy in some cases
This commit is contained in:
Evgeny Vereshchagin 2017-02-06 23:59:33 +03:00 committed by GitHub
commit 1fb8579749
4 changed files with 51 additions and 23 deletions

5
TODO
View File

@ -24,6 +24,11 @@ Janitorial Clean-ups:
Features: Features:
* maybe add call sd_journal_set_block_timeout() or so to set SO_SNDTIMEO for
the sd-journal logging socket, and, if the timeout is set to 0, sets
O_NONBLOCK on it. That way people can control if and when to block for
logging.
* journald: when we recv a log datagram via the native or syslog transports, * journald: when we recv a log datagram via the native or syslog transports,
search for the PID in the active stream connections, and let's make sure to search for the PID in the active stream connections, and let's make sure to
always process the datagrams before the streams. Then, cache client metadata always process the datagrams before the streams. Then, cache client metadata

View File

@ -268,6 +268,15 @@
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry> <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details.</para> 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.</para>
<para><function>sd_notifyf()</function> is similar to <para><function>sd_notifyf()</function> is similar to
<function>sd_notify()</function> but takes a <function>sd_notify()</function> but takes a
<function>printf()</function>-like format string plus <function>printf()</function>-like format string plus

View File

@ -72,10 +72,24 @@
<para>The command line may carry a list of environment variables <para>The command line may carry a list of environment variables
to send as part of the status update.</para> to send as part of the status update.</para>
<para>Note that systemd will refuse reception of status updates <para>Note that systemd will refuse reception of status updates from this command unless
from this command unless <varname>NotifyAccess=all</varname> is <varname>NotifyAccess=</varname> is set for the service unit this command is called from.</para>
set for the service unit this command is called from.</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.</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>
<refsect1> <refsect1>

View File

@ -792,26 +792,26 @@
<varlistentry> <varlistentry>
<term><varname>NotifyAccess=</varname></term> <term><varname>NotifyAccess=</varname></term>
<listitem><para>Controls access to the service status <listitem><para>Controls access to the service status notification socket, as accessible via the
notification socket, as accessible via the <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry> call. Takes one
<citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry> of <option>none</option> (the default), <option>main</option>, <option>exec</option> or
call. Takes one of <option>none</option> (the default), <option>all</option>. If <option>none</option>, no daemon status updates are accepted from the service
<option>main</option>, <option>exec</option> or processes, all status update messages are ignored. If <option>main</option>, only service updates sent from the
<option>all</option>. If <option>none</option>, no daemon status main process of the service are accepted. If <option>exec</option>, only service updates sent from any of the
updates are accepted from the service processes, all status main or control processes originating from one of the <varname>Exec*=</varname> commands are accepted. If
update messages are ignored. If <option>main</option>, only <option>all</option>, all services updates from all members of the service's control group are accepted. This
service updates sent from the main process of the service are option should be set to open access to the notification socket when using <varname>Type=notify</varname> or
accepted. If <option>exec</option>, only service updates sent <varname>WatchdogSec=</varname> (see above). If those options are used but <varname>NotifyAccess=</varname> is
from any of the control processes originating from one of the not configured, it will be implicitly set to <option>main</option>.</para>
<varname>Exec*=</varname> commands are accepted. If
<option>all</option>, all services updates from all members of <para>Note that <function>sd_notify()</function> notifications may be attributed to units correctly only if
the service's control group are accepted. This option should either the sending process is still around at the time PID 1 processes the message, or if the sending process
be set to open access to the notification socket when using is explicitly runtime-tracked by the service manager. The latter is the case if the service manager originally
<varname>Type=notify</varname> or forked off the process, i.e. on all processes that match <option>main</option> or
<varname>WatchdogSec=</varname> (see above). If those options <option>exec</option>. Conversely, if an auxiliary process of the unit sends an
are used but <varname>NotifyAccess=</varname> is not <function>sd_notify()</function> message and immediately exits, the service manager might not be able to
configured, it will be implicitly set to properly attribute the message to the unit, and thus will ignore it, even if
<option>main</option>.</para></listitem> <varname>NotifyAccess=</varname><option>all</option> is set for it.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>