Merge pull request #1854 from poettering/unit-deps

Dependency engine improvements
This commit is contained in:
Tom Gundersen 2015-11-11 23:14:12 +01:00
commit fb5c8184a9
31 changed files with 555 additions and 207 deletions

View File

@ -85,10 +85,24 @@
<para>Automount units may be used to implement on-demand mounting
as well as parallelized mounting of file systems.</para>
</refsect1>
<refsect1>
<title>Automatic Dependencies</title>
<para>If an automount unit is beneath another mount unit in the
file system hierarchy, both a requirement and an ordering
dependency between both units are created automatically.</para>
<para>An implicit <varname>Before=</varname> dependency is created
between an automount unit and the mount unit it activates.</para>
<para>Automount units acquire automatic <varname>Before=</varname>
and <varname>Conflicts=</varname> on
<filename>umount.target</filename> in order to be stopped during
shutdown, unless <varname>DefaultDependencies=no</varname> is
set.</para>
<para>If an automount point is beneath another mount point in the
file system hierarchy, a dependency between both units is created
automatically.</para>
</refsect1>
<refsect1>

View File

@ -83,7 +83,18 @@
the escaping logic used to convert a file system path to a unit
name see
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
</refsect1>
<refsect1>
<title>Automatic Dependencies</title>
<para>Many unit types automatically acquire dependencies on device
units of devices they require. For example,
<filename>.socket</filename> unit acquire dependencies on the
device units of the network interface specified in
<varname>BindToDevice=</varname>. Similar, swap and mount units
acquire dependencies on the units encapsulating their backing
block devices.</para>
</refsect1>
<refsect1>

View File

@ -76,6 +76,31 @@
unit type.</para>
</refsect1>
<refsect1>
<title>Automatic Dependencies</title>
<para>A few execution parameters result in additional, automatic
dependencies to be added.</para>
<para>Units with <varname>WorkingDirectory=</varname> or
<varname>RootDirectory=</varname> set automatically gain
dependencies of type <varname>Requires=</varname> and
<varname>After=</varname> on all mount units required to access
the specified paths. This is equivalent to having them listed
explicitly in <varname>RequiresMountsFor=</varname>.</para>
<para>Similar, units with <varname>PrivateTmp=</varname> enabled
automatically get mount unit dependencies for all mounts
required to access <filename>/tmp</filename> and
<filename>/var/tmp</filename>.</para>
<para>Units whose output standard output or error output is
connected to any other sink but <option>null</option>,
<option>tty</option> and <option>socket</option> automatically
acquire dependencies of type <varname>After=</varname> on
<filename>journald.socket</filename>.</para>
</refsect1>
<refsect1>
<title>Options</title>
@ -93,7 +118,9 @@
and the respective user's home directory if run as user. If
the setting is prefixed with the <literal>-</literal>
character, a missing working directory is not considered
fatal.</para></listitem>
fatal. Note that setting this parameter might result in
additional dependencies to be added to the unit (see
above).</para></listitem>
</varlistentry>
<varlistentry>
@ -104,7 +131,9 @@
project='man-pages'><refentrytitle>chroot</refentrytitle><manvolnum>2</manvolnum></citerefentry>
system call. If this is used, it must be ensured that the
process binary and all its auxiliary files are available in
the <function>chroot()</function> jail.</para></listitem>
the <function>chroot()</function> jail. Note that setting this
parameter might result in additional dependencies to be added
to the unit (see above).</para></listitem>
</varlistentry>
<varlistentry>
@ -378,6 +407,7 @@
<para>This setting defaults to
<option>null</option>.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>StandardOutput=</varname></term>
<listitem><para>Controls where file descriptor 1 (STDOUT) of
@ -443,8 +473,11 @@
<para>This setting defaults to the value set with
<option>DefaultStandardOutput=</option> in
<citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
which defaults to <option>journal</option>.</para></listitem>
which defaults to <option>journal</option>. Note that setting
this parameter might result in additional dependencies to be
added to the unit (see above).</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>StandardError=</varname></term>
<listitem><para>Controls where file descriptor 2 (STDERR) of
@ -455,8 +488,11 @@
standard error. This setting defaults to the value set with
<option>DefaultStandardError=</option> in
<citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
which defaults to <option>inherit</option>.</para></listitem>
which defaults to <option>inherit</option>. Note that setting
this parameter might result in additional dependencies to be
added to the unit (see above).</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>TTYPath=</varname></term>
<listitem><para>Sets the terminal device node to use if

View File

@ -94,10 +94,6 @@
unit, to allow on-demand or parallelized mounting. See
<citerefentry><refentrytitle>systemd.automount</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
<para>If a mount point is beneath another mount point in the file
system hierarchy, a dependency between both units is created
automatically.</para>
<para>Mount points created at runtime (independently of unit files
or <filename>/etc/fstab</filename>) will be monitored by systemd
and appear like any other mount unit in systemd. See
@ -113,6 +109,52 @@
File Systems</ulink>.</para>
</refsect1>
<refsect1>
<title>Automatic Dependencies</title>
<para>If a mount unit is beneath another mount unit in the file
system hierarchy, both a requirement dependency and an ordering
dependency between both units are created automatically.</para>
<para>Block device backed file systems automatically gain
<varname>BindsTo=</varname> and <varname>After=</varname> type
dependencies on the device unit encapsulating the block
device (see below).</para>
<para>If traditional file system quota is enabled for a mount
unit, automatic <varname>Wants=</varname> and
<varname>Before=</varname> dependencies on
<filename>systemd-quotacheck.service</filename> and
<filename>quotaon.service</filename> are added.</para>
<para>For mount units with
<varname>DefaultDependencies=yes</varname> (the default) a couple
additional dependencies are added. Mount units referring to local
file systems automatically gain an <varname>After=</varname>
dependency on <filename>local-fs-pre.target</filename>. Network
mount units automatically acquire <varname>After=</varname>
dependencies on <filename>remote-fs-pre.target</filename>,
<filename>network.target</filename> and
<filename>network-online.target</filename>. Towards the latter a
<varname>Wants=</varname> unit is added as well. Mount units
referring to local and network file systems are distinguished by
their file system type specification. In some cases this is not
sufficient (for example network block device based mounts, such as
iSCSI), in which case <option>_netdev</option> may be added to the
mount option string of the unit, which forces systemd to consider the
mount unit a network mount. Mount units (regardless if local or
network) also acquire automatic <varname>Before=</varname> and
<varname>Conflicts=</varname> on
<filename>umount.target</filename> in order to be stopped
during shutdown.</para>
<para>Additional implicit dependencies may be added as result of
execution and resource control parameters as documented in
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
</refsect1>
<refsect1>
<title><filename>fstab</filename></title>
@ -130,7 +172,7 @@
<para>When reading <filename>/etc/fstab</filename> a few special
mount options are understood by systemd which influence how
dependencies are created for mount points. systemd will create a
dependency of type <option>Wants</option> or
dependency of type <varname>Wants=</varname> or
<option>Requires</option> (see option <option>nofail</option>
below), from either <filename>local-fs.target</filename> or
<filename>remote-fs.target</filename>, depending whether the file

View File

@ -79,13 +79,24 @@
limitations as inotify, and for example cannot be used to monitor
files or directories changed by other machines on remote NFS file
systems.</para>
</refsect1>
<para>If a path unit is beneath another mount point in the file
system hierarchy, a dependency between both units is created
automatically.</para>
<refsect1>
<title>Automatic Dependencies</title>
<para>If a path unit is beneath another mount unit in the file
system hierarchy, both a requirement and an ordering dependency
between both units are created automatically.</para>
<para>An implicit <varname>Before=</varname> dependency is added
between a path unit and the unit it is supposed to activate.</para>
<para>Unless <varname>DefaultDependencies=false</varname> is used,
path units will implicitly have dependencies of type
<varname>Before=</varname> on <filename>paths.target</filename>,
dependencies of type <varname>After=</varname> and
<varname>Requires=</varname> on
<filename>sysinit.target</filename>, and have dependencies of type
<varname>Conflicts=</varname> and <varname>Before=</varname> on
<filename>shutdown.target</filename>. These ensure that path units
are terminated cleanly prior to system shutdown. Only path units

View File

@ -89,6 +89,15 @@
use of resource control APIs from programs.</para>
</refsect1>
<refsect1>
<title>Automatic Dependencies</title>
<para>Units with the <varname>Slice=</varname> setting set get
automatic <varname>Requires=</varname> and
<varname>After=</varname> dependencies on the specified slice
unit.</para>
</refsect1>
<refsect1>
<title>Options</title>

View File

@ -72,6 +72,10 @@
url="http://www.freedesktop.org/wiki/Software/systemd/ControlGroupInterface/">New
Control Group Interfaces</ulink> for an introduction on how to make
use of scope units from programs.</para>
</refsect1>
<refsect1>
<title>Automatic Dependencies</title>
<para>Unless <varname>DefaultDependencies=false</varname>
is used, scope units will implicitly have dependencies of
@ -82,6 +86,11 @@
shutdown. Only scope units involved with early boot or
late system shutdown should disable this option.
</para>
<para>Additional implicit dependencies may be added as result of
resource control parameters as documented in
<citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
</refsect1>
<refsect1>

View File

@ -1,4 +1,4 @@
<?xml version='1.0'?> <!--*-nxml-*-->
<?xml version='1.0'?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
@ -77,18 +77,6 @@
which configure resource control settings for the processes of the
service.</para>
<para>Unless <varname>DefaultDependencies=</varname> is set to
<option>false</option>, service units will implicitly have
dependencies of type <varname>Requires=</varname> and
<varname>After=</varname> on <filename>basic.target</filename> as
well as dependencies of type <varname>Conflicts=</varname> and
<varname>Before=</varname> on
<filename>shutdown.target</filename>. These ensure that normal
service units pull in basic system initialization, and are
terminated cleanly prior to system shutdown. Only services
involved with early boot or late system shutdown should disable
this option.</para>
<para>If a service is requested under a certain name but no unit
configuration file is found, systemd looks for a SysV init script
by the same name (with the <filename>.service</filename> suffix
@ -97,8 +85,39 @@
compatibility is quite comprehensive but not 100%. For details
about the incompatibilities, see the <ulink
url="http://www.freedesktop.org/wiki/Software/systemd/Incompatibilities">Incompatibilities
with SysV</ulink> document.
</para>
with SysV</ulink> document.</para>
</refsect1>
<refsect1>
<title>Automatic Dependencies</title>
<para>Services with <varname>Type=dbus</varname> set automatically
acquire dependencies of type <varname>Requires=</varname> and
<varname>After=</varname> on
<filename>dbus.socket</filename>.</para>
<para>Socket activated service are automatically ordered after
their activated <filename>.socket</filename> units via an
automatic <varname>After=</varname> dependency.</para>
<para>Unless <varname>DefaultDependencies=</varname> is set to
<option>false</option>, service units will implicitly have
dependencies of type <varname>Requires=</varname> and
<varname>After=</varname> on <filename>sysinit.target</filename>,
a dependency of type <varname>After=</varname> on
<filename>basic.target</filename> as well as dependencies of
type <varname>Conflicts=</varname> and <varname>Before=</varname>
on <filename>shutdown.target</filename>. These ensure that normal
service units pull in basic system initialization, and are
terminated cleanly prior to system shutdown. Only services
involved with early boot or late system shutdown should disable
this option.</para>
<para>Additional implicit dependencies may be added as result of
execution and resource control parameters as documented in
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
</refsect1>
<refsect1>

View File

@ -97,6 +97,14 @@
url="http://www.freedesktop.org/wiki/Software/systemd/ControlGroupInterface/">New
Control Group Interfaces</ulink> for an introduction on how to make
use of slice units from programs.</para>
</refsect1>
<refsect1>
<title>Automatic Dependencies</title>
<para>Slice units automatically gain dependencies of type
<varname>After=</varname> and <varname>Requires=</varname> on
their immediate parent slice unit.</para>
<para>Unless <varname>DefaultDependencies=false</varname>
is used, slice units will implicitly have dependencies of

View File

@ -133,6 +133,40 @@
service file).</para>
</refsect1>
<refsect1>
<title>Automatic Dependencies</title>
<para>Socket units automatically gain a <varname>Before=</varname>
dependency on the service units they activate.</para>
<para>Socket units referring to file system paths (such as AF_UNIX
sockets or FIFOs) implicitly gain <varname>Requires=</varname> and
<varname>After=</varname> dependencies on all mount units
necessary to access those paths.</para>
<para>Socket units using the <varname>BindToDevice=</varname>
setting automatically gain a <varname>BindsTo=</varname> and
<varname>After=</varname> dependency on the device unit
encapsulating the specified network interface.</para>
<para>If <varname>DefaultDependencies=yes</varname> is set (the
default), socket units automatically gain a
<varname>Before=</varname> dependency on
<filename>sockets.target</filename>. They also gain a pair of
<varname>After=</varname> and <varname>Requires=</varname>
dependency on <filename>sysinit.target</filename>, and a pair of
<varname>Before=</varname> and <varname>Conflicts=</varname>
dependencies on <filename>shutdown.target</filename>. These
dependencies ensure that the socket unit is started before normal
services at boot, and is stopped on shutdown.</para>
<para>Additional implicit dependencies may be added as result of
execution and resource control parameters as documented in
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
</refsect1>
<refsect1>
<title>Options</title>
@ -309,12 +343,14 @@
<listitem><para>Specifies a network interface name to bind
this socket to. If set, traffic will only be accepted from the
specified network interfaces. This controls the
SO_BINDTODEVICE socket option (see
<citerefentry project='man-pages'><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry>
SO_BINDTODEVICE socket option (see <citerefentry
project='man-pages'><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry>
for details). If this option is used, an automatic dependency
from this socket unit on the network interface device unit
(<citerefentry><refentrytitle>systemd.device</refentrytitle><manvolnum>5</manvolnum></citerefentry>
is created.</para></listitem>
is created. Note that setting this parameter might result in
additional dependencies to be added to the unit (see
above).</para></listitem>
</varlistentry>
<varlistentry>
@ -719,7 +755,9 @@
with <varname>Accept=no</varname>. It defaults to the service
that bears the same name as the socket (with the suffix
replaced). In most cases, it should not be necessary to use
this option.</para></listitem>
this option. Note that setting this parameter might result in
additional dependencies to be added to the unit (see
above).</para></listitem>
</varlistentry>
<varlistentry>

View File

@ -68,14 +68,15 @@
<para>Additional options are listed in
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
which define the execution environment the
<citerefentry project='man-pages'><refentrytitle>swapon</refentrytitle><manvolnum>8</manvolnum></citerefentry>
binary is executed in, and in
which define the execution environment the <citerefentry
project='man-pages'><refentrytitle>swapon</refentrytitle><manvolnum>8</manvolnum></citerefentry>
binary is executed in, in
<citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
which define the way the processes are terminated, and in
which define the way the these processes are
terminated, and in
<citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
which configure resource control settings for the processes of the
service.</para>
which configure resource control settings for these processes of the
unit.</para>
<para>Swap units must be named after the devices
or files they control. Example: the swap device
@ -84,15 +85,28 @@
the escaping logic used to convert a file system path to a unit
name, see
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
</refsect1>
<para>All swap units automatically get the appropriate
dependencies on the devices or on the mount points of the files
<refsect1>
<title>Automatic Dependencies</title>
<para>All swap units automatically get the
<varname>BindsTo=</varname> and <varname>After=</varname>
dependencies on the device units or the mount units of the files
they are activated from.</para>
<para>Swap units with <varname>DefaultDependencies=</varname>
enabled implicitly acquire a conflicting dependency to
enabled implicitly acquire a <varname>Conflicts=</varname> and an
<varname>After=</varname> dependency on
<filename>umount.target</filename> so that they are deactivated at
shutdown.</para>
shutdown, unless <varname>DefaultDependencies=no</varname> is
specified.</para>
<para>Additional implicit dependencies may be added as result of
execution and resource control parameters as documented in
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
</refsect1>
<refsect1>

View File

@ -77,15 +77,20 @@
See
<citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>
for details).</para>
</refsect1>
<refsect1>
<title>Automatic Dependencies</title>
<para>Unless <varname>DefaultDependencies=</varname> is set to
<option>false</option>, target units will implicitly complement
all configured dependencies of type <varname>Wants=</varname>,
<option>no</option>, target units will implicitly complement all
configured dependencies of type <varname>Wants=</varname>,
<varname>Requires=</varname>,
<varname>RequiresOverridable=</varname> with dependencies of type
<varname>After=</varname> if the units in question also have
<varname>DefaultDependencies=true</varname>.
</para>
<varname>After=</varname>, unless an ordering dependency of any
kind between the target and the respective other unit is already
in place. Note that this behaviour is disabled if either unit has
<varname>DefaultDependencies=no</varname>.</para>
</refsect1>
<refsect1>

View File

@ -1,4 +1,4 @@
<?xml version='1.0'?> <!--*-nxml-*-->
<?xml version='1.0'?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
@ -73,19 +73,29 @@
<filename>foo.timer</filename> activates a matching service
<filename>foo.service</filename>. The unit to activate may be
controlled by <varname>Unit=</varname> (see below).</para>
</refsect1>
<refsect1>
<title>Automatic Dependencies</title>
<para>Timer units automatically gain a <varname>Before=</varname>
dependency on the service they are supposed to activate.</para>
<para>Unless <varname>DefaultDependencies=</varname> is set to
<option>false</option>, all timer units will implicitly have
dependencies of type <varname>Conflicts=</varname> and
<varname>Before=</varname> on <filename>shutdown.target</filename>
to ensure that they are stopped cleanly prior to system shutdown.
Timer units with at least one <varname>OnCalendar=</varname>
directive will have an additional <varname>After=</varname>
dependency on <filename>timer-sync.target</filename> to avoid
being started before the system clock has been correctly set. Only
timer units involved with early boot or late system shutdown
should disable the <varname>DefaultDependencies=</varname>
option.</para>
dependencies of type <varname>Requires=</varname> and
<varname>After=</varname> on <filename>sysinit.target</filename>,
a dependency of type <varname>Before=</varname> on
<filename>timers.target</filename>, as well as
<varname>Conflicts=</varname> and <varname>Before=</varname> on
<filename>shutdown.target</filename> to ensure that they are
stopped cleanly prior to system shutdown. Timer units with at
least one <varname>OnCalendar=</varname> directive will have an
additional <varname>After=</varname> dependency on
<filename>timer-sync.target</filename> to avoid being started
before the system clock has been correctly set. Only timer units
involved with early boot or late system shutdown should disable
the <varname>DefaultDependencies=</varname> option.</para>
</refsect1>
<refsect1>

View File

@ -1,4 +1,4 @@
<?xml version='1.0'?> <!--*-nxml-*-->
<?xml version='1.0'?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
<!ENTITY % entities SYSTEM "custom-entities.ent" >
@ -195,12 +195,6 @@
consider it mostly obsolete, and want people to
use .d/ drop-ins instead. -->
<para>Note that while systemd offers a flexible dependency system
between units it is recommended to use this functionality only
sparingly and instead rely on techniques such as bus-based or
socket-based activation which make dependencies implicit,
resulting in a both simpler and more flexible system.</para>
<para>Some unit names reflect paths existing in the file system
namespace. Example: a device unit
<filename>dev-sda.device</filename> refers to a device with the
@ -253,6 +247,31 @@
</refsect1>
<refsect1>
<title>Automatic Dependencies</title>
<para>Note that while systemd offers a flexible dependency system
between units it is recommended to use this functionality only
sparingly and instead rely on techniques such as bus-based or
socket-based activation which make dependencies implicit,
resulting in a both simpler and more flexible system.</para>
<para>A number of unit dependencies are automatically established,
depending on unit configuration. On top of that, for units with
<varname>DefaultDependencies=yes</varname> (the default) a couple
of additional dependencies are added. The precise effect of
<varname>DefaultDependencies=yes</varname> depends on the unit
type (see below).</para>
<para>If <varname>DefaultDependencies=yes</varname> is set, units
that are referenced by other units of type
<filename>.target</filename> via a <varname>Wants=</varname> or
<varname>Requires=</varname> dependency might automatically gain
an <varname>Before=</varname> dependency too. See
<citerefentry><refentrytitle>systemd.target</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details.</para>
</refsect1>
<refsect1>
<title>Unit File Load Path</title>

View File

@ -128,7 +128,7 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
} else if (c == quote) { /* found the end quote */
quote = 0;
break;
} else if (c == '\\') {
} else if (c == '\\' && !(flags & EXTRACT_RETAIN_ESCAPE)) {
backslash = true;
break;
} else {
@ -146,7 +146,7 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
else if ((c == '\'' || c == '"') && (flags & EXTRACT_QUOTES)) {
quote = c;
break;
} else if (c == '\\') {
} else if (c == '\\' && !(flags & EXTRACT_RETAIN_ESCAPE)) {
backslash = true;
break;
} else if (strchr(separators, c)) {

View File

@ -24,11 +24,12 @@
#include "macro.h"
typedef enum ExtractFlags {
EXTRACT_RELAX = 1,
EXTRACT_CUNESCAPE = 2,
EXTRACT_CUNESCAPE_RELAX = 4,
EXTRACT_QUOTES = 8,
EXTRACT_RELAX = 1,
EXTRACT_CUNESCAPE = 2,
EXTRACT_CUNESCAPE_RELAX = 4,
EXTRACT_QUOTES = 8,
EXTRACT_DONT_COALESCE_SEPARATORS = 16,
EXTRACT_RETAIN_ESCAPE = 32,
} ExtractFlags;
int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags);

View File

@ -311,7 +311,7 @@ int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gi
if (fd < 0)
return -errno;
if (mode > 0) {
if (mode != MODE_INVALID) {
r = fchmod(fd, mode);
if (r < 0)
return -errno;
@ -338,7 +338,7 @@ int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gi
}
int touch(const char *path) {
return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, 0);
return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, MODE_INVALID);
}
int symlink_idempotent(const char *from, const char *to) {

View File

@ -148,6 +148,9 @@ static int automount_add_default_dependencies(Automount *a) {
assert(a);
if (!UNIT(a)->default_dependencies)
return 0;
if (UNIT(a)->manager->running_as != MANAGER_SYSTEM)
return 0;
@ -219,11 +222,9 @@ static int automount_load(Unit *u) {
if (r < 0)
return r;
if (UNIT(a)->default_dependencies) {
r = automount_add_default_dependencies(a);
if (r < 0)
return r;
}
r = automount_add_default_dependencies(a);
if (r < 0)
return r;
}
return automount_verify(a);

View File

@ -122,7 +122,7 @@ int config_parse_unit_deps(const char *unit,
_cleanup_free_ char *word = NULL, *k = NULL;
int r;
r = extract_first_word(&p, &word, NULL, 0);
r = extract_first_word(&p, &word, NULL, EXTRACT_RETAIN_ESCAPE);
if (r == 0)
break;
if (r == -ENOMEM)

View File

@ -387,12 +387,15 @@ static bool should_umount(Mount *m) {
}
static int mount_add_default_dependencies(Mount *m) {
const char *after, *after2, *online;
MountParameters *p;
const char *after;
int r;
assert(m);
if (!UNIT(m)->default_dependencies)
return 0;
if (UNIT(m)->manager->running_as != MANAGER_SYSTEM)
return 0;
@ -413,31 +416,35 @@ static int mount_add_default_dependencies(Mount *m) {
return 0;
if (mount_is_network(p)) {
/* We order ourselves after network.target. This is
* primarily useful at shutdown: services that take
* down the network should order themselves before
* network.target, so that they are shut down only
* after this mount unit is stopped. */
r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, SPECIAL_NETWORK_TARGET, NULL, true);
if (r < 0)
return r;
/* We pull in network-online.target, and order
* ourselves after it. This is useful at start-up to
* actively pull in tools that want to be started
* before we start mounting network file systems, and
* whose purpose it is to delay this until the network
* is "up". */
r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, SPECIAL_NETWORK_ONLINE_TARGET, NULL, true);
if (r < 0)
return r;
after = SPECIAL_REMOTE_FS_PRE_TARGET;
after2 = SPECIAL_NETWORK_TARGET;
online = SPECIAL_NETWORK_ONLINE_TARGET;
} else {
} else
after = SPECIAL_LOCAL_FS_PRE_TARGET;
after2 = NULL;
online = NULL;
}
r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, NULL, true);
if (r < 0)
return r;
if (after2) {
r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after2, NULL, true);
if (r < 0)
return r;
}
if (online) {
r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, online, NULL, true);
if (r < 0)
return r;
}
if (should_umount(m)) {
r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
if (r < 0)
@ -533,11 +540,9 @@ static int mount_add_extras(Mount *m) {
if (r < 0)
return r;
if (u->default_dependencies) {
r = mount_add_default_dependencies(m);
if (r < 0)
return r;
}
r = mount_add_default_dependencies(m);
if (r < 0)
return r;
return 0;
}

View File

@ -315,20 +315,20 @@ static int path_add_default_dependencies(Path *p) {
assert(p);
r = unit_add_dependency_by_name(UNIT(p), UNIT_BEFORE,
SPECIAL_PATHS_TARGET, NULL, true);
if (!UNIT(p)->default_dependencies)
return 0;
r = unit_add_dependency_by_name(UNIT(p), UNIT_BEFORE, SPECIAL_PATHS_TARGET, NULL, true);
if (r < 0)
return r;
if (UNIT(p)->manager->running_as == MANAGER_SYSTEM) {
r = unit_add_two_dependencies_by_name(UNIT(p), UNIT_AFTER, UNIT_REQUIRES,
SPECIAL_SYSINIT_TARGET, NULL, true);
r = unit_add_two_dependencies_by_name(UNIT(p), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
if (r < 0)
return r;
}
return unit_add_two_dependencies_by_name(UNIT(p), UNIT_BEFORE, UNIT_CONFLICTS,
SPECIAL_SHUTDOWN_TARGET, NULL, true);
return unit_add_two_dependencies_by_name(UNIT(p), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
}
static int path_load(Unit *u) {
@ -360,11 +360,9 @@ static int path_load(Unit *u) {
if (r < 0)
return r;
if (UNIT(p)->default_dependencies) {
r = path_add_default_dependencies(p);
if (r < 0)
return r;
}
r = path_add_default_dependencies(p);
if (r < 0)
return r;
}
return path_verify(p);

View File

@ -122,6 +122,9 @@ static int scope_add_default_dependencies(Scope *s) {
assert(s);
if (!UNIT(s)->default_dependencies)
return 0;
/* Make sure scopes are unloaded on shutdown */
r = unit_add_two_dependencies_by_name(
UNIT(s),
@ -173,11 +176,9 @@ static int scope_load(Unit *u) {
if (r < 0)
return r;
if (u->default_dependencies) {
r = scope_add_default_dependencies(s);
if (r < 0)
return r;
}
r = scope_add_default_dependencies(s);
if (r < 0)
return r;
return scope_verify(s);
}

View File

@ -515,15 +515,38 @@ static int service_add_default_dependencies(Service *s) {
assert(s);
if (!UNIT(s)->default_dependencies)
return 0;
/* Add a number of automatic dependencies useful for the
* majority of services. */
/* First, pull in base system */
r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_BASIC_TARGET, NULL, true);
if (UNIT(s)->manager->running_as == MANAGER_SYSTEM) {
/* First, pull in the really early boot stuff, and
* require it, so that we fail if we can't acquire
* it. */
r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
if (r < 0)
return r;
} else {
/* In the --user instance there's no sysinit.target,
* in that case require basic.target instead. */
r = unit_add_dependency_by_name(UNIT(s), UNIT_REQUIRES, SPECIAL_BASIC_TARGET, NULL, true);
if (r < 0)
return r;
}
/* Second, if the rest of the base system is in the same
* transaction, order us after it, but do not pull it in or
* even require it. */
r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_BASIC_TARGET, NULL, true);
if (r < 0)
return r;
/* Second, activate normal shutdown */
/* Third, add us in for normal shutdown. */
return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
}
@ -545,6 +568,43 @@ static void service_fix_output(Service *s) {
s->exec_context.std_output = UNIT(s)->manager->default_std_output;
}
static int service_setup_bus_name(Service *s) {
int r;
assert(s);
if (!s->bus_name)
return 0;
if (is_kdbus_available()) {
const char *n;
n = strjoina(s->bus_name, ".busname");
r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, n, NULL, true);
if (r < 0)
return log_unit_error_errno(UNIT(s), r, "Failed to add dependency to .busname unit: %m");
} else {
/* If kdbus is not available, we know the dbus socket is required, hence pull it in, and require it */
r = unit_add_dependency_by_name(UNIT(s), UNIT_REQUIRES, SPECIAL_DBUS_SOCKET, NULL, true);
if (r < 0)
return log_unit_error_errno(UNIT(s), r, "Failed to add dependency on " SPECIAL_DBUS_SOCKET ": %m");
}
/* Regardless if kdbus is used or not, we always want to be ordered against dbus.socket if both are in the transaction. */
r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_DBUS_SOCKET, NULL, true);
if (r < 0)
return log_unit_error_errno(UNIT(s), r, "Failed to add depdendency on " SPECIAL_DBUS_SOCKET ": %m");
r = unit_watch_bus_name(UNIT(s), s->bus_name);
if (r == -EEXIST)
return log_unit_error_errno(UNIT(s), r, "Two services allocated for the same bus name %s, refusing operation.", s->bus_name);
if (r < 0)
return log_unit_error_errno(UNIT(s), r, "Cannot watch bus name %s: %m", s->bus_name);
return 0;
}
static int service_add_extras(Service *s) {
int r;
@ -584,26 +644,13 @@ static int service_add_extras(Service *s) {
if (s->watchdog_usec > 0 && s->notify_access == NOTIFY_NONE)
s->notify_access = NOTIFY_MAIN;
if (s->bus_name) {
const char *n;
r = service_add_default_dependencies(s);
if (r < 0)
return r;
n = strjoina(s->bus_name, ".busname");
r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, n, NULL, true);
if (r < 0)
return r;
r = unit_watch_bus_name(UNIT(s), s->bus_name);
if (r == -EEXIST)
return log_unit_error_errno(UNIT(s), r, "Two services allocated for the same bus name %s, refusing operation.", s->bus_name);
if (r < 0)
return log_unit_error_errno(UNIT(s), r, "Cannot watch bus name %s: %m", s->bus_name);
}
if (UNIT(s)->default_dependencies) {
r = service_add_default_dependencies(s);
if (r < 0)
return r;
}
r = service_setup_bus_name(s);
if (r < 0)
return r;
return 0;
}

View File

@ -85,6 +85,9 @@ static int slice_add_default_dependencies(Slice *s) {
assert(s);
if (!UNIT(s)->default_dependencies)
return 0;
/* Make sure slices are unloaded on shutdown */
r = unit_add_two_dependencies_by_name(
UNIT(s),
@ -96,7 +99,6 @@ static int slice_add_default_dependencies(Slice *s) {
return 0;
}
static int slice_verify(Slice *s) {
_cleanup_free_ char *parent = NULL;
int r;
@ -144,11 +146,9 @@ static int slice_load(Unit *u) {
if (r < 0)
return r;
if (u->default_dependencies) {
r = slice_add_default_dependencies(s);
if (r < 0)
return r;
}
r = slice_add_default_dependencies(s);
if (r < 0)
return r;
}
return slice_verify(s);

View File

@ -296,6 +296,9 @@ static int socket_add_default_dependencies(Socket *s) {
int r;
assert(s);
if (!UNIT(s)->default_dependencies)
return 0;
r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_SOCKETS_TARGET, NULL, true);
if (r < 0)
return r;
@ -365,11 +368,9 @@ static int socket_add_extras(Socket *s) {
return r;
}
if (u->default_dependencies) {
r = socket_add_default_dependencies(s);
if (r < 0)
return r;
}
r = socket_add_default_dependencies(s);
if (r < 0)
return r;
return 0;
}

View File

@ -213,6 +213,9 @@ static int swap_add_device_links(Swap *s) {
static int swap_add_default_dependencies(Swap *s) {
assert(s);
if (!UNIT(s)->default_dependencies)
return 0;
if (UNIT(s)->manager->running_as != MANAGER_SYSTEM)
return 0;
@ -331,11 +334,9 @@ static int swap_load(Unit *u) {
if (r < 0)
return r;
if (UNIT(s)->default_dependencies) {
r = swap_add_default_dependencies(s);
if (r < 0)
return r;
}
r = swap_add_default_dependencies(s);
if (r < 0)
return r;
}
return swap_verify(s);

View File

@ -102,6 +102,9 @@ static int timer_add_default_dependencies(Timer *t) {
assert(t);
if (!UNIT(t)->default_dependencies)
return 0;
r = unit_add_dependency_by_name(UNIT(t), UNIT_BEFORE, SPECIAL_TIMERS_TARGET, NULL, true);
if (r < 0)
return r;
@ -192,11 +195,9 @@ static int timer_load(Unit *u) {
if (r < 0)
return r;
if (u->default_dependencies) {
r = timer_add_default_dependencies(t);
if (r < 0)
return r;
}
r = timer_add_default_dependencies(t);
if (r < 0)
return r;
}
return timer_verify(t);
@ -518,7 +519,7 @@ static void timer_enter_running(Timer *t) {
dual_timestamp_get(&t->last_trigger);
if (t->stamp_path)
touch_file(t->stamp_path, true, t->last_trigger.realtime, UID_INVALID, GID_INVALID, 0);
touch_file(t->stamp_path, true, t->last_trigger.realtime, UID_INVALID, GID_INVALID, MODE_INVALID);
timer_set_state(t, TIMER_RUNNING);
return;
@ -554,7 +555,7 @@ static int timer_start(Unit *u) {
/* The timer has never run before,
* make sure a stamp file exists.
*/
touch_file(t->stamp_path, true, USEC_INFINITY, UID_INVALID, GID_INVALID, 0);
touch_file(t->stamp_path, true, USEC_INFINITY, UID_INVALID, GID_INVALID, MODE_INVALID);
}
t->result = TIMER_SUCCESS;

View File

@ -133,9 +133,9 @@ static enum {
ACTION_UPDATE_CATALOG,
ACTION_LIST_BOOTS,
ACTION_FLUSH,
ACTION_SYNC,
ACTION_ROTATE,
ACTION_VACUUM,
ACTION_SYNC,
} arg_action = ACTION_SHOW;
typedef struct BootId {
@ -1771,6 +1771,11 @@ static int flush_to_var(void) {
_cleanup_close_ int watch_fd = -1;
int r;
if (arg_machine) {
log_error("--flush is not supported in conjunction with --machine=.");
return -EOPNOTSUPP;
}
/* Quick exit */
if (access("/run/systemd/journal/flushed", F_OK) >= 0)
return 0;
@ -1828,6 +1833,11 @@ static int send_signal_and_wait(int sig, const char *watch_path) {
usec_t start;
int r;
if (arg_machine) {
log_error("--sync and --rotate are not supported in conjunction with --machine=.");
return -EOPNOTSUPP;
}
start = now(CLOCK_REALTIME);
/* This call sends the specified signal to journald, and waits
@ -1935,35 +1945,19 @@ int main(int argc, char *argv[]) {
* be split up into many files. */
setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
if (arg_action == ACTION_NEW_ID128) {
switch (arg_action) {
case ACTION_NEW_ID128:
r = generate_new_id128();
goto finish;
}
if (arg_action == ACTION_FLUSH) {
r = flush_to_var();
goto finish;
}
if (arg_action == ACTION_SYNC) {
r = sync_journal();
goto finish;
}
if (arg_action == ACTION_ROTATE) {
r = rotate();
goto finish;
}
if (arg_action == ACTION_SETUP_KEYS) {
case ACTION_SETUP_KEYS:
r = setup_keys();
goto finish;
}
if (arg_action == ACTION_UPDATE_CATALOG ||
arg_action == ACTION_LIST_CATALOG ||
arg_action == ACTION_DUMP_CATALOG) {
case ACTION_LIST_CATALOG:
case ACTION_DUMP_CATALOG:
case ACTION_UPDATE_CATALOG: {
_cleanup_free_ char *database;
database = path_join(arg_root, CATALOG_DATABASE, NULL);
@ -1980,9 +1974,9 @@ int main(int argc, char *argv[]) {
bool oneline = arg_action == ACTION_LIST_CATALOG;
pager_open_if_enabled();
if (optind < argc)
r = catalog_list_items(stdout, database,
oneline, argv + optind);
r = catalog_list_items(stdout, database, oneline, argv + optind);
else
r = catalog_list(stdout, database, oneline);
if (r < 0)
@ -1992,6 +1986,31 @@ int main(int argc, char *argv[]) {
goto finish;
}
case ACTION_FLUSH:
r = flush_to_var();
goto finish;
case ACTION_SYNC:
r = sync_journal();
goto finish;
case ACTION_ROTATE:
r = rotate();
goto finish;
case ACTION_SHOW:
case ACTION_PRINT_HEADER:
case ACTION_VERIFY:
case ACTION_DISK_USAGE:
case ACTION_LIST_BOOTS:
case ACTION_VACUUM:
/* These ones require access to the journal files, continue below. */
break;
default:
assert_not_reached("Unknown action");
}
if (arg_directory)
r = sd_journal_open_directory(&j, arg_directory, arg_journal_type);
else if (arg_file)
@ -2001,8 +2020,7 @@ int main(int argc, char *argv[]) {
else
r = sd_journal_open(&j, !arg_merge*SD_JOURNAL_LOCAL_ONLY + arg_journal_type);
if (r < 0) {
log_error_errno(r, "Failed to open %s: %m",
arg_directory ? arg_directory : arg_file ? "files" : "journal");
log_error_errno(r, "Failed to open %s: %m", arg_directory ?: arg_file ? "files" : "journal");
goto finish;
}
@ -2010,18 +2028,28 @@ int main(int argc, char *argv[]) {
if (r < 0)
goto finish;
if (arg_action == ACTION_VERIFY) {
r = verify(j);
goto finish;
}
switch (arg_action) {
if (arg_action == ACTION_PRINT_HEADER) {
case ACTION_NEW_ID128:
case ACTION_SETUP_KEYS:
case ACTION_LIST_CATALOG:
case ACTION_DUMP_CATALOG:
case ACTION_UPDATE_CATALOG:
case ACTION_FLUSH:
case ACTION_SYNC:
case ACTION_ROTATE:
assert_not_reached("Unexpected action.");
case ACTION_PRINT_HEADER:
journal_print_header(j);
r = 0;
goto finish;
}
if (arg_action == ACTION_DISK_USAGE) {
case ACTION_VERIFY:
r = verify(j);
goto finish;
case ACTION_DISK_USAGE: {
uint64_t bytes = 0;
char sbytes[FORMAT_BYTES_MAX];
@ -2034,7 +2062,11 @@ int main(int argc, char *argv[]) {
goto finish;
}
if (arg_action == ACTION_VACUUM) {
case ACTION_LIST_BOOTS:
r = list_boots(j);
goto finish;
case ACTION_VACUUM: {
Directory *d;
Iterator i;
@ -2054,9 +2086,11 @@ int main(int argc, char *argv[]) {
goto finish;
}
if (arg_action == ACTION_LIST_BOOTS) {
r = list_boots(j);
goto finish;
case ACTION_SHOW:
break;
default:
assert_not_reached("Unknown action");
}
/* add_boot() must be called first!

View File

@ -26,6 +26,7 @@
#include "conf-files.h"
#include "fs-util.h"
#include "macro.h"
#include "parse-util.h"
#include "rm-rf.h"
#include "string-util.h"
#include "strv.h"
@ -40,7 +41,7 @@ static void setup_test_dir(char *tmp_dir, const char *files, ...) {
va_start(ap, files);
while (files != NULL) {
_cleanup_free_ char *path = strappend(tmp_dir, files);
assert_se(touch_file(path, true, USEC_INFINITY, UID_INVALID, GID_INVALID, 0) == 0);
assert_se(touch_file(path, true, USEC_INFINITY, UID_INVALID, GID_INVALID, MODE_INVALID) == 0);
files = va_arg(ap, const char *);
}
va_end(ap);

View File

@ -325,6 +325,18 @@ static void test_extract_first_word(void) {
assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 0);
assert_se(!t);
assert_se(!p);
p = "foo\\xbar";
assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
assert_se(streq(t, "fooxbar"));
free(t);
assert_se(p == NULL);
p = "foo\\xbar";
assert_se(extract_first_word(&p, &t, NULL, EXTRACT_RETAIN_ESCAPE) > 0);
assert_se(streq(t, "foo\\xbar"));
free(t);
assert_se(p == NULL);
}
static void test_extract_first_word_and_warn(void) {

View File

@ -10,5 +10,5 @@ Description=System Slice
Documentation=man:systemd.special(7)
DefaultDependencies=no
Before=slices.target
Wants=-.slice
Requires=-.slice
After=-.slice