mirror of
https://github.com/systemd/systemd.git
synced 2025-01-11 09:18:07 +03:00
man/systemd.service: advise Type=exec instead of Type=simple
The descriptions of various options are reworked: first say what protocol actually is, i.e. describe what type of notification the manager waits for. Only after that describe various steps and things the service should do. Also, apply some paragraph breaks. Instead of recommending Type=simple, recommend Type=exec. Say explicitly that Type=simple, Type=forking are not recommended. Type=simple ignores failure in a way that doesn't make any sense except as a historical accident. We introduced 'exec' instead of changing 'simple' to keep backwards-compatiblity, but 'simple' is not very useful. 'forking' works, but is inefficient: correctly programming the interface requires a lot of work, and at runtime, the additional one or two forks are just a waste of CPU resources. Furthermore, we now understand that because of COW traps, they may also increase memory requirements. There is really no reason to use 'forking', except if it's already implemented and the code cannot be changed to use 'notify'. Also, remove the recommendations to use Type=simple to avoid delaying boot. In most cases, if the service can support notifications about startup, those should be done. Overall, for new services, "notify", "notify-reload", and "dbus" are the types that make sense.
This commit is contained in:
parent
ffe7ddb9bc
commit
377d3a31e6
@ -155,41 +155,52 @@
|
||||
<term><varname>Type=</varname></term>
|
||||
|
||||
<listitem>
|
||||
<para>Configures the process start-up type for this service unit. One of <option>simple</option>,
|
||||
<option>exec</option>, <option>forking</option>, <option>oneshot</option>, <option>dbus</option>,
|
||||
<option>notify</option>, <option>notify-reload</option> or <option>idle</option>:</para>
|
||||
<para>Configures the mechanism via which the service notifies the manager that the service start-up
|
||||
has finished. One of <option>simple</option>, <option>exec</option>, <option>forking</option>,
|
||||
<option>oneshot</option>, <option>dbus</option>, <option>notify</option>,
|
||||
<option>notify-reload</option>, or <option>idle</option>:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para>If set to <option>simple</option> (the default if <varname>ExecStart=</varname> is
|
||||
specified but neither <varname>Type=</varname> nor <varname>BusName=</varname> are), the service manager
|
||||
will consider the unit started immediately after the main service process has been forked off. It is
|
||||
expected that the process configured with <varname>ExecStart=</varname> is the main process of the
|
||||
service. In this mode, if the process offers functionality to other processes on the system, its
|
||||
communication channels should be installed before the service is started up (e.g. sockets set up by
|
||||
systemd, via socket activation), as the service manager will immediately proceed starting follow-up units,
|
||||
right after creating the main service process, and before executing the service's binary. Note that this
|
||||
means <command>systemctl start</command> command lines for <option>simple</option> services will report
|
||||
success even if the service's binary cannot be invoked successfully (for example because the selected
|
||||
<varname>User=</varname> doesn't exist, or the service binary is missing).</para></listitem>
|
||||
will consider the unit started immediately after the main service process has been forked off.
|
||||
<emphasis>The use of this type is discouraged, use <option>exec</option> instead.
|
||||
</emphasis></para>
|
||||
|
||||
<listitem><para>The <option>exec</option> type is similar to <option>simple</option>, but the service
|
||||
manager will consider the unit started immediately after the main service binary has been executed. The service
|
||||
manager will delay starting of follow-up units until that point. (Or in other words:
|
||||
<option>simple</option> proceeds with further jobs right after <function>fork()</function> returns, while
|
||||
<option>exec</option> will not proceed before both <function>fork()</function> and
|
||||
<function>execve()</function> in the service process succeeded.) Note that this means <command>systemctl
|
||||
start</command> command lines for <option>exec</option> services will report failure when the service's
|
||||
binary cannot be invoked successfully (for example because the selected <varname>User=</varname> doesn't
|
||||
<para>It is expected that the process configured with <varname>ExecStart=</varname> is the main
|
||||
process of the service. In this mode, if the process offers functionality to other processes on
|
||||
the system, its communication channels should be installed before the service is started up
|
||||
(e.g. sockets set up by systemd, via socket activation), as the service manager will immediately
|
||||
proceed starting follow-up units, right after creating the main service process, and before
|
||||
executing the service's binary. Note that this means <command>systemctl start</command> command
|
||||
lines for <option>simple</option> services will report success even if the service's binary
|
||||
cannot be invoked successfully (for example because the selected <varname>User=</varname> doesn't
|
||||
exist, or the service binary is missing).</para></listitem>
|
||||
|
||||
<listitem><para>If set to <option>forking</option>, it is expected that the process configured with
|
||||
<varname>ExecStart=</varname> will call <function>fork()</function> as part of its start-up. The parent
|
||||
process is expected to exit when start-up is complete and all communication channels are set up. The child
|
||||
continues to run as the main service process, and the service manager will consider the unit started when
|
||||
the parent process exits. This is the behavior of traditional UNIX services. If this setting is used, it is
|
||||
recommended to also use the <varname>PIDFile=</varname> option, so that systemd can reliably identify the
|
||||
main process of the service. systemd will proceed with starting follow-up units as soon as the parent
|
||||
process exits.</para></listitem>
|
||||
<listitem><para>The <option>exec</option> type is similar to <option>simple</option>, but the
|
||||
service manager will consider the unit started immediately after the main service binary has been
|
||||
executed. The service manager will delay starting of follow-up units until that point. (Or in
|
||||
other words: <option>simple</option> proceeds with further jobs right after
|
||||
<function>fork()</function> returns, while <option>exec</option> will not proceed before both
|
||||
<function>fork()</function> and <function>execve()</function> in the service process succeeded.)
|
||||
Note that this means <command>systemctl start</command> command lines for <option>exec</option>
|
||||
services will report failure when the service's binary cannot be invoked successfully (for
|
||||
example because the selected <varname>User=</varname> doesn't exist, or the service binary is
|
||||
missing).</para></listitem>
|
||||
|
||||
<listitem><para>If set to <option>forking</option>, the manager will consider the unit started
|
||||
immediately after the binary that forked off by the manager exits. <emphasis>The use of this type
|
||||
is discouraged, use <option>notify</option>, <option>notify-reload</option>, or
|
||||
<option>dbus</option> instead.</emphasis></para>
|
||||
|
||||
<para>It is expected that the process configured with <varname>ExecStart=</varname> will call
|
||||
<function>fork()</function> as part of its start-up. The parent process is expected to exit when
|
||||
start-up is complete and all communication channels are set up. The child continues to run as the
|
||||
main service process, and the service manager will consider the unit started when the parent
|
||||
process exits. This is the behavior of traditional UNIX services. If this setting is used, it is
|
||||
recommended to also use the <varname>PIDFile=</varname> option, so that systemd can reliably
|
||||
identify the main process of the service. The manager will proceed with starting follow-up units
|
||||
after the parent process exits.</para></listitem>
|
||||
|
||||
<listitem><para>Behavior of <option>oneshot</option> is similar to <option>simple</option>;
|
||||
however, the service manager will consider the unit up after the main process exits. It will then
|
||||
@ -197,18 +208,19 @@
|
||||
of service. <varname>Type=</varname><option>oneshot</option> is the implied default if neither
|
||||
<varname>Type=</varname> nor <varname>ExecStart=</varname> are specified. Note that if this
|
||||
option is used without <varname>RemainAfterExit=</varname> the service will never enter
|
||||
<literal>active</literal> unit state, but directly transition from <literal>activating</literal>
|
||||
to <literal>deactivating</literal> or <literal>dead</literal> since no process is configured that
|
||||
shall run continuously. In particular this means that after a service of this type ran (and which
|
||||
has <varname>RemainAfterExit=</varname> not set) it will not show up as started afterwards, but
|
||||
as dead.</para></listitem>
|
||||
<literal>active</literal> unit state, but will directly transition from
|
||||
<literal>activating</literal> to <literal>deactivating</literal> or <literal>dead</literal>,
|
||||
since no process is configured that shall run continuously. In particular this means that after a
|
||||
service of this type ran (and which has <varname>RemainAfterExit=</varname> not set) it will not
|
||||
show up as started afterwards, but as dead.</para></listitem>
|
||||
|
||||
<listitem><para>Behavior of <option>dbus</option> is similar to <option>simple</option>; however,
|
||||
it is expected that the service acquires a name on the D-Bus bus, as configured by
|
||||
<varname>BusName=</varname>. systemd will proceed with starting follow-up units after the D-Bus
|
||||
bus name has been acquired. Service units with this option configured implicitly gain
|
||||
dependencies on the <filename>dbus.socket</filename> unit. This type is the default if
|
||||
<varname>BusName=</varname> is specified. A service unit of this type is considered to be in the
|
||||
units of this type must have the <varname>BusName=</varname> specified and the service manager
|
||||
will consider the unit up when the specified bus name has been acquired. This type is the default
|
||||
if <varname>BusName=</varname> is specified.</para>
|
||||
|
||||
<para>Service units with this option configured implicitly gain dependencies on the
|
||||
<filename>dbus.socket</filename> unit. A service unit of this type is considered to be in the
|
||||
activating state until the specified bus name is acquired. It is considered activated while the
|
||||
bus name is taken. Once the bus name is released the service is considered being no longer
|
||||
functional which has the effect that the service manager attempts to terminate any remaining
|
||||
@ -223,15 +235,19 @@
|
||||
units after this notification message has been sent. If this option is used,
|
||||
<varname>NotifyAccess=</varname> (see below) should be set to open access to the notification
|
||||
socket provided by systemd. If <varname>NotifyAccess=</varname> is missing or set to
|
||||
<option>none</option>, it will be forcibly set to <option>main</option>.</para></listitem>
|
||||
<option>none</option>, it will be forcibly set to <option>main</option>.</para>
|
||||
|
||||
<listitem><para>Behavior of <option>notify-reload</option> is identical to
|
||||
<option>notify</option>. However, it extends the logic in one way: the
|
||||
<constant>SIGHUP</constant> UNIX process signal is sent to the service's main process when the
|
||||
service is asked to reload. (The signal to send can be tweaked via
|
||||
<varname>ReloadSignal=</varname>, see below.) When
|
||||
initiating the reload process the service is then expected to reply with a notification message
|
||||
via <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||
<para>If the service supports reloading, and uses the a signal to start the reload, using
|
||||
<option>notify-reload</option> instead is recommended.</para></listitem>
|
||||
|
||||
<listitem><para>Behavior of <option>notify-reload</option> is similar to <option>notify</option>,
|
||||
with one difference: the <constant>SIGHUP</constant> UNIX process signal is sent to the service's
|
||||
main process when the service is asked to reload and the manager will wait for a notification
|
||||
about the reload being finished.</para>
|
||||
|
||||
<para>When initiating the reload process the service is expected to reply with a notification
|
||||
message via
|
||||
<citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||
that contains the <literal>RELOADING=1</literal> field in combination with
|
||||
<literal>MONOTONIC_USEC=</literal> set to the current monotonic time
|
||||
(i.e. <constant>CLOCK_MONOTONIC</constant> in
|
||||
@ -239,7 +255,10 @@
|
||||
in μs, formatted as decimal string. Once reloading is complete another notification message must
|
||||
be sent, containing <literal>READY=1</literal>. Using this service type and implementing this
|
||||
reload protocol is an efficient alternative to providing an <varname>ExecReload=</varname>
|
||||
command for reloading of the service's configuration.</para></listitem>
|
||||
command for reloading of the service's configuration.</para>
|
||||
|
||||
<para>The signal to send can be tweaked via <varname>ReloadSignal=</varname>, see below.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem><para>Behavior of <option>idle</option> is very similar to <option>simple</option>; however,
|
||||
actual execution of the service program is delayed until all active jobs are dispatched. This may be used
|
||||
@ -249,27 +268,25 @@
|
||||
anyway.</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>It is generally recommended to use <varname>Type=</varname><option>simple</option> for
|
||||
<para>It is generally recommended to use <varname>Type=</varname><option>exec</option> for
|
||||
long-running services whenever possible, as it is the simplest and fastest option. However, as this
|
||||
service type won't propagate service start-up failures and doesn't allow ordering of other units
|
||||
against completion of initialization of the service (which for example is useful if clients need to
|
||||
connect to the service through some form of IPC, and the IPC channel is only established by the
|
||||
service itself — in contrast to doing this ahead of time through socket or bus activation or
|
||||
similar), it might not be sufficient for many cases. If so, <option>notify</option>,
|
||||
<option>notify-reload</option> or <option>dbus</option> (the latter only in case the service
|
||||
<option>notify-reload</option>, or <option>dbus</option> (the latter only in case the service
|
||||
provides a D-Bus interface) are the preferred options as they allow service program code to
|
||||
precisely schedule when to consider the service started up successfully and when to proceed with
|
||||
follow-up units. The <option>notify</option>/<option>notify-reload</option> service types require
|
||||
explicit support in the service codebase (as <function>sd_notify()</function> or an equivalent API
|
||||
needs to be invoked by the service at the appropriate time) — if it's not supported, then
|
||||
<option>forking</option> is an alternative: it supports the traditional UNIX service start-up
|
||||
protocol. Finally, <option>exec</option> might be an option for cases where it is enough to ensure
|
||||
the service binary is invoked, and where the service binary itself executes no or little
|
||||
initialization on its own (and its initialization is unlikely to fail). Note that using any type
|
||||
other than <option>simple</option> possibly delays the boot process, as the service manager needs
|
||||
to wait for service initialization to complete. It is hence recommended not to needlessly use any
|
||||
types other than <option>simple</option>. (Also note it is generally not recommended to use
|
||||
<option>idle</option> or <option>oneshot</option> for long-running services.)</para>
|
||||
<option>forking</option> is an alternative: it supports the traditional heavy-weight UNIX service
|
||||
start-up protocol. Note that using any type other than
|
||||
<option>simple</option>/<option>exec</option> possibly delays the boot process, as the service
|
||||
manager needs to wait for service initialization to complete. (Also note it is generally not
|
||||
recommended to use <option>idle</option> or <option>oneshot</option> for long-running services.)
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user