diff --git a/man/systemd.automount.xml b/man/systemd.automount.xml
index 26a0f291dd..1b0ae832da 100644
--- a/man/systemd.automount.xml
+++ b/man/systemd.automount.xml
@@ -85,10 +85,24 @@
Automount units may be used to implement on-demand mounting
as well as parallelized mounting of file systems.
+
+
+
+ Automatic Dependencies
+
+ 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.
+
+ An implicit Before= dependency is created
+ between an automount unit and the mount unit it activates.
+
+ Automount units acquire automatic Before=
+ and Conflicts= on
+ umount.target in order to be stopped during
+ shutdown, unless DefaultDependencies=no is
+ set.
- If an automount point is beneath another mount point in the
- file system hierarchy, a dependency between both units is created
- automatically.
diff --git a/man/systemd.device.xml b/man/systemd.device.xml
index ac6deafb18..effed098dd 100644
--- a/man/systemd.device.xml
+++ b/man/systemd.device.xml
@@ -83,7 +83,18 @@
the escaping logic used to convert a file system path to a unit
name see
systemd.unit5.
+
+
+ Automatic Dependencies
+
+ Many unit types automatically acquire dependencies on device
+ units of devices they require. For example,
+ .socket unit acquire dependencies on the
+ device units of the network interface specified in
+ BindToDevice=. Similar, swap and mount units
+ acquire dependencies on the units encapsulating their backing
+ block devices.
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
index 5bb97bd98e..6dda6c5e69 100644
--- a/man/systemd.exec.xml
+++ b/man/systemd.exec.xml
@@ -76,6 +76,31 @@
unit type.
+
+ Automatic Dependencies
+
+ A few execution parameters result in additional, automatic
+ dependencies to be added.
+
+ Units with WorkingDirectory= or
+ RootDirectory= set automatically gain
+ dependencies of type Requires= and
+ After= on all mount units required to access
+ the specified paths. This is equivalent to having them listed
+ explicitly in RequiresMountsFor=.
+
+ Similar, units with PrivateTmp= enabled
+ automatically get mount unit dependencies for all mounts
+ required to access /tmp and
+ /var/tmp.
+
+ Units whose output standard output or error output is
+ connected to any other sink but ,
+ and automatically
+ acquire dependencies of type After= on
+ journald.socket.
+
+
Options
@@ -93,7 +118,9 @@
and the respective user's home directory if run as user. If
the setting is prefixed with the -
character, a missing working directory is not considered
- fatal.
+ fatal. Note that setting this parameter might result in
+ additional dependencies to be added to the unit (see
+ above).
@@ -104,7 +131,9 @@
project='man-pages'>chroot2
system call. If this is used, it must be ensured that the
process binary and all its auxiliary files are available in
- the chroot() jail.
+ the chroot() jail. Note that setting this
+ parameter might result in additional dependencies to be added
+ to the unit (see above).
@@ -378,6 +407,7 @@
This setting defaults to
.
+
StandardOutput=Controls where file descriptor 1 (STDOUT) of
@@ -443,8 +473,11 @@
This setting defaults to the value set with
in
systemd-system.conf5,
- which defaults to .
+ which defaults to . Note that setting
+ this parameter might result in additional dependencies to be
+ added to the unit (see above).
+
StandardError=Controls where file descriptor 2 (STDERR) of
@@ -455,8 +488,11 @@
standard error. This setting defaults to the value set with
in
systemd-system.conf5,
- which defaults to .
+ which defaults to . Note that setting
+ this parameter might result in additional dependencies to be
+ added to the unit (see above).
+
TTYPath=Sets the terminal device node to use if
diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml
index dd6b7a51a8..67e96dc157 100644
--- a/man/systemd.mount.xml
+++ b/man/systemd.mount.xml
@@ -94,10 +94,6 @@
unit, to allow on-demand or parallelized mounting. See
systemd.automount5.
- If a mount point is beneath another mount point in the file
- system hierarchy, a dependency between both units is created
- automatically.
-
Mount points created at runtime (independently of unit files
or /etc/fstab) will be monitored by systemd
and appear like any other mount unit in systemd. See
@@ -113,6 +109,52 @@
File Systems.
+
+ Automatic Dependencies
+
+ 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.
+
+ Block device backed file systems automatically gain
+ BindsTo= and After= type
+ dependencies on the device unit encapsulating the block
+ device (see below).
+
+ If traditional file system quota is enabled for a mount
+ unit, automatic Wants= and
+ Before= dependencies on
+ systemd-quotacheck.service and
+ quotaon.service are added.
+
+ For mount units with
+ DefaultDependencies=yes (the default) a couple
+ additional dependencies are added. Mount units referring to local
+ file systems automatically gain an After=
+ dependency on local-fs-pre.target. Network
+ mount units automatically acquire After=
+ dependencies on remote-fs-pre.target,
+ network.target and
+ network-online.target. Towards the latter a
+ Wants= 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 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 Before= and
+ Conflicts= on
+ umount.target in order to be stopped
+ during shutdown.
+
+ Additional implicit dependencies may be added as result of
+ execution and resource control parameters as documented in
+ systemd.exec5
+ and
+ systemd.resource-control5.
+
+
fstab
@@ -130,7 +172,7 @@
When reading /etc/fstab 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 or
+ dependency of type Wants= or
(see option
below), from either local-fs.target or
remote-fs.target, depending whether the file
diff --git a/man/systemd.path.xml b/man/systemd.path.xml
index d02bc92ae6..1bd65ce86d 100644
--- a/man/systemd.path.xml
+++ b/man/systemd.path.xml
@@ -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.
+
- If a path unit is beneath another mount point in the file
- system hierarchy, a dependency between both units is created
- automatically.
+
+ Automatic Dependencies
+
+ 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.
+
+ An implicit Before= dependency is added
+ between a path unit and the unit it is supposed to activate.Unless DefaultDependencies=false is used,
path units will implicitly have dependencies of type
+ Before= on paths.target,
+ dependencies of type After= and
+ Requires= on
+ sysinit.target, and have dependencies of type
Conflicts= and Before= on
shutdown.target. These ensure that path units
are terminated cleanly prior to system shutdown. Only path units
diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml
index 164adb938a..0497f60546 100644
--- a/man/systemd.resource-control.xml
+++ b/man/systemd.resource-control.xml
@@ -89,6 +89,15 @@
use of resource control APIs from programs.
+
+ Automatic Dependencies
+
+ Units with the Slice= setting set get
+ automatic Requires= and
+ After= dependencies on the specified slice
+ unit.
+
+
Options
diff --git a/man/systemd.scope.xml b/man/systemd.scope.xml
index fd65a851e2..f69b2ef635 100644
--- a/man/systemd.scope.xml
+++ b/man/systemd.scope.xml
@@ -72,6 +72,10 @@
url="http://www.freedesktop.org/wiki/Software/systemd/ControlGroupInterface/">New
Control Group Interfaces for an introduction on how to make
use of scope units from programs.
+
+
+
+ Automatic DependenciesUnless DefaultDependencies=false
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.
+
+ Additional implicit dependencies may be added as result of
+ resource control parameters as documented in
+ systemd.resource-control5.
+
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index 4e5098f0e1..c6ed75d158 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -1,4 +1,4 @@
-
+
@@ -77,18 +77,6 @@
which configure resource control settings for the processes of the
service.
- Unless DefaultDependencies= is set to
- , service units will implicitly have
- dependencies of type Requires= and
- After= on basic.target as
- well as dependencies of type Conflicts= and
- Before= on
- shutdown.target. 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.
-
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 .service suffix
@@ -97,8 +85,39 @@
compatibility is quite comprehensive but not 100%. For details
about the incompatibilities, see the Incompatibilities
- with SysV document.
-
+ with SysV document.
+
+
+
+ Automatic Dependencies
+
+ Services with Type=dbus set automatically
+ acquire dependencies of type Requires= and
+ After= on
+ dbus.socket.
+
+ Socket activated service are automatically ordered after
+ their activated .socket units via an
+ automatic After= dependency.
+
+ Unless DefaultDependencies= is set to
+ , service units will implicitly have
+ dependencies of type Requires= and
+ After= on sysinit.target,
+ a dependency of type After= on
+ basic.target as well as dependencies of
+ type Conflicts= and Before=
+ on shutdown.target. 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.
+
+ Additional implicit dependencies may be added as result of
+ execution and resource control parameters as documented in
+ systemd.exec5
+ and
+ systemd.resource-control5.
diff --git a/man/systemd.slice.xml b/man/systemd.slice.xml
index 87c2a3bce3..5c87bf0260 100644
--- a/man/systemd.slice.xml
+++ b/man/systemd.slice.xml
@@ -97,6 +97,14 @@
url="http://www.freedesktop.org/wiki/Software/systemd/ControlGroupInterface/">New
Control Group Interfaces for an introduction on how to make
use of slice units from programs.
+
+
+
+ Automatic Dependencies
+
+ Slice units automatically gain dependencies of type
+ After= and Requires= on
+ their immediate parent slice unit.Unless DefaultDependencies=false
is used, slice units will implicitly have dependencies of
diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml
index 410886f841..beac053bf0 100644
--- a/man/systemd.socket.xml
+++ b/man/systemd.socket.xml
@@ -133,6 +133,40 @@
service file).
+
+ Automatic Dependencies
+
+ Socket units automatically gain a Before=
+ dependency on the service units they activate.
+
+ Socket units referring to file system paths (such as AF_UNIX
+ sockets or FIFOs) implicitly gain Requires= and
+ After= dependencies on all mount units
+ necessary to access those paths.
+
+ Socket units using the BindToDevice=
+ setting automatically gain a BindsTo= and
+ After= dependency on the device unit
+ encapsulating the specified network interface.
+
+ If DefaultDependencies=yes is set (the
+ default), socket units automatically gain a
+ Before= dependency on
+ sockets.target. They also gain a pair of
+ After= and Requires=
+ dependency on sysinit.target, and a pair of
+ Before= and Conflicts=
+ dependencies on shutdown.target. These
+ dependencies ensure that the socket unit is started before normal
+ services at boot, and is stopped on shutdown.
+
+ Additional implicit dependencies may be added as result of
+ execution and resource control parameters as documented in
+ systemd.exec5
+ and
+ systemd.resource-control5.
+
+
Options
@@ -309,12 +343,14 @@
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
- socket7
+ SO_BINDTODEVICE socket option (see socket7
for details). If this option is used, an automatic dependency
from this socket unit on the network interface device unit
(systemd.device5
- is created.
+ is created. Note that setting this parameter might result in
+ additional dependencies to be added to the unit (see
+ above).
@@ -719,7 +755,9 @@
with Accept=no. 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.
+ this option. Note that setting this parameter might result in
+ additional dependencies to be added to the unit (see
+ above).
diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml
index bc9ef826e1..c600405c87 100644
--- a/man/systemd.swap.xml
+++ b/man/systemd.swap.xml
@@ -68,14 +68,15 @@
Additional options are listed in
systemd.exec5,
- which define the execution environment the
- swapon8
- binary is executed in, and in
+ which define the execution environment the swapon8
+ binary is executed in, in
systemd.kill5,
- which define the way the processes are terminated, and in
+ which define the way the these processes are
+ terminated, and in
systemd.resource-control5,
- which configure resource control settings for the processes of the
- service.
+ which configure resource control settings for these processes of the
+ unit.
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
systemd.unit5.
+
- All swap units automatically get the appropriate
- dependencies on the devices or on the mount points of the files
+
+ Automatic Dependencies
+
+ All swap units automatically get the
+ BindsTo= and After=
+ dependencies on the device units or the mount units of the files
they are activated from.Swap units with DefaultDependencies=
- enabled implicitly acquire a conflicting dependency to
+ enabled implicitly acquire a Conflicts= and an
+ After= dependency on
umount.target so that they are deactivated at
- shutdown.
+ shutdown, unless DefaultDependencies=no is
+ specified.
+
+ Additional implicit dependencies may be added as result of
+ execution and resource control parameters as documented in
+ systemd.exec5
+ and
+ systemd.resource-control5.
diff --git a/man/systemd.target.xml b/man/systemd.target.xml
index e790e9b77a..54a5f5035c 100644
--- a/man/systemd.target.xml
+++ b/man/systemd.target.xml
@@ -77,15 +77,20 @@
See
systemd.special7
for details).
+
+
+
+ Automatic DependenciesUnless DefaultDependencies= is set to
- , target units will implicitly complement
- all configured dependencies of type Wants=,
+ , target units will implicitly complement all
+ configured dependencies of type Wants=,
Requires=,
RequiresOverridable= with dependencies of type
- After= if the units in question also have
- DefaultDependencies=true.
-
+ After=, 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
+ DefaultDependencies=no.
diff --git a/man/systemd.timer.xml b/man/systemd.timer.xml
index c98258a0d7..8cf6c4683b 100644
--- a/man/systemd.timer.xml
+++ b/man/systemd.timer.xml
@@ -1,4 +1,4 @@
-
+
@@ -73,19 +73,29 @@
foo.timer activates a matching service
foo.service. The unit to activate may be
controlled by Unit= (see below).
+
+
+
+ Automatic Dependencies
+
+ Timer units automatically gain a Before=
+ dependency on the service they are supposed to activate.Unless DefaultDependencies= is set to
, all timer units will implicitly have
- dependencies of type Conflicts= and
- Before= on shutdown.target
- to ensure that they are stopped cleanly prior to system shutdown.
- Timer units with at least one OnCalendar=
- directive will have an additional After=
- dependency on timer-sync.target 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 DefaultDependencies=
- option.
+ dependencies of type Requires= and
+ After= on sysinit.target,
+ a dependency of type Before= on
+ timers.target, as well as
+ Conflicts= and Before= on
+ shutdown.target to ensure that they are
+ stopped cleanly prior to system shutdown. Timer units with at
+ least one OnCalendar= directive will have an
+ additional After= dependency on
+ timer-sync.target 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 DefaultDependencies= option.
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index caba7ea69d..b4044f43ef 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -1,4 +1,4 @@
-
+
@@ -195,12 +195,6 @@
consider it mostly obsolete, and want people to
use .d/ drop-ins instead. -->
- 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.
-
Some unit names reflect paths existing in the file system
namespace. Example: a device unit
dev-sda.device refers to a device with the
@@ -253,6 +247,31 @@
+
+ Automatic Dependencies
+
+ 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.
+
+ A number of unit dependencies are automatically established,
+ depending on unit configuration. On top of that, for units with
+ DefaultDependencies=yes (the default) a couple
+ of additional dependencies are added. The precise effect of
+ DefaultDependencies=yes depends on the unit
+ type (see below).
+
+ If DefaultDependencies=yes is set, units
+ that are referenced by other units of type
+ .target via a Wants= or
+ Requires= dependency might automatically gain
+ an Before= dependency too. See
+ systemd.target5
+ for details.
+
+
Unit File Load Path
diff --git a/src/basic/extract-word.c b/src/basic/extract-word.c
index ff6d211ef4..fd495692fa 100644
--- a/src/basic/extract-word.c
+++ b/src/basic/extract-word.c
@@ -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)) {
diff --git a/src/basic/extract-word.h b/src/basic/extract-word.h
index ddc1c4f463..9606ab64b3 100644
--- a/src/basic/extract-word.h
+++ b/src/basic/extract-word.h
@@ -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);
diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c
index 7aee404bfc..cddd4232fc 100644
--- a/src/basic/fs-util.c
+++ b/src/basic/fs-util.c
@@ -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) {
diff --git a/src/core/automount.c b/src/core/automount.c
index 4c229247c5..41ead117c8 100644
--- a/src/core/automount.c
+++ b/src/core/automount.c
@@ -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);
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index 53d96dee14..18cbbf0dcc 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -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)
diff --git a/src/core/mount.c b/src/core/mount.c
index d3766ba934..e86bcf3830 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -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;
}
diff --git a/src/core/path.c b/src/core/path.c
index 35e1753583..c0992b4fcc 100644
--- a/src/core/path.c
+++ b/src/core/path.c
@@ -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);
diff --git a/src/core/scope.c b/src/core/scope.c
index 8d6149aab0..5f6527c155 100644
--- a/src/core/scope.c
+++ b/src/core/scope.c
@@ -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);
}
diff --git a/src/core/service.c b/src/core/service.c
index 74bbadd3ff..e9d259b84f 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -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;
}
diff --git a/src/core/slice.c b/src/core/slice.c
index 2aa3fbf8be..39dabae055 100644
--- a/src/core/slice.c
+++ b/src/core/slice.c
@@ -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);
diff --git a/src/core/socket.c b/src/core/socket.c
index c73ee78b13..43d4ec5dca 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -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;
}
diff --git a/src/core/swap.c b/src/core/swap.c
index e44cffc2e8..ee0838e676 100644
--- a/src/core/swap.c
+++ b/src/core/swap.c
@@ -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);
diff --git a/src/core/timer.c b/src/core/timer.c
index c9dc97d4fb..06a6035315 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -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;
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 521360b11b..ac0751c547 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -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!
diff --git a/src/test/test-conf-files.c b/src/test/test-conf-files.c
index a69698d4ea..86ac513d4f 100644
--- a/src/test/test-conf-files.c
+++ b/src/test/test-conf-files.c
@@ -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);
diff --git a/src/test/test-extract-word.c b/src/test/test-extract-word.c
index 09698c07c7..65d3a0a96e 100644
--- a/src/test/test-extract-word.c
+++ b/src/test/test-extract-word.c
@@ -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) {
diff --git a/units/system.slice b/units/system.slice
index c0e3df9d0f..841f049b58 100644
--- a/units/system.slice
+++ b/units/system.slice
@@ -10,5 +10,5 @@ Description=System Slice
Documentation=man:systemd.special(7)
DefaultDependencies=no
Before=slices.target
-Wants=-.slice
+Requires=-.slice
After=-.slice