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. + + <filename>fstab</filename> @@ -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 Dependencies Unless 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 Dependencies Unless 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