diff options
author | Anita Zhang <the.anitazha@gmail.com> | 2019-10-04 17:39:34 -0700 |
---|---|---|
committer | Anita Zhang <the.anitazha@gmail.com> | 2019-10-15 11:14:54 -0700 |
commit | d272467882c9c3c3d4faca5fd7a1f44c5ef2f064 (patch) | |
tree | 7d35f1ccd84002012461a566b31b786dcb9db64b | |
parent | f18f809c07ec082a3006666c7c7e20f7045c4d87 (diff) | |
download | systemd-d272467882c9c3c3d4faca5fd7a1f44c5ef2f064.tar.gz systemd-d272467882c9c3c3d4faca5fd7a1f44c5ef2f064.tar.bz2 systemd-d272467882c9c3c3d4faca5fd7a1f44c5ef2f064.zip |
shared/dropin: support -.service.d/ top level drop-in for service units
Closes #12830
-rw-r--r-- | man/systemd.service.xml | 13 | ||||
-rw-r--r-- | man/systemd.special.xml | 9 | ||||
-rw-r--r-- | man/systemd.unit.xml | 4 | ||||
-rw-r--r-- | src/basic/unit-name.c | 9 | ||||
-rw-r--r-- | src/core/service.c | 2 | ||||
-rw-r--r-- | src/shared/dropin.c | 23 | ||||
-rwxr-xr-x | test/TEST-15-DROPIN/test-dropin.sh | 13 |
7 files changed, 70 insertions, 3 deletions
diff --git a/man/systemd.service.xml b/man/systemd.service.xml index af14eedfcc..7d120c3243 100644 --- a/man/systemd.service.xml +++ b/man/systemd.service.xml @@ -63,6 +63,19 @@ <para>The <citerefentry><refentrytitle>systemd-run</refentrytitle><manvolnum>1</manvolnum></citerefentry> command allows creating <filename>.service</filename> and <filename>.scope</filename> units dynamically and transiently from the command line.</para> + + <para>In addition to the various drop-in behaviors described in + <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>, + services also support a top-level drop-in with <filename>-.service.d/</filename> that allows + altering or adding to the settings of all services on the system. + The formatting and precedence of applying drop-in configurations follow what is defined in + <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>. + However, configurations in <filename>-.service.d/</filename> have the lowest precedence compared to settings + in the service specific override directories. For example, for <filename>foo-bar-baz.service</filename>, + drop-ins in <filename>foo-bar-baz.service.d/</filename> override the ones in + <filename>foo-bar-.service.d/</filename>, which override the ones <filename>foo-.service.d/</filename>, + which override the ones in <filename>-.service.d/</filename>. + </para> </refsect1> <refsect1> diff --git a/man/systemd.special.xml b/man/systemd.special.xml index 248fb924db..afd14b977c 100644 --- a/man/systemd.special.xml +++ b/man/systemd.special.xml @@ -120,6 +120,15 @@ </varlistentry> <varlistentry> + <term><filename>-.service</filename></term> + <listitem> + <para>This is a reserved unit name used to support top-level drop-ins for services. See + <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry> + for details.</para> + </listitem> + </varlistentry> + + <varlistentry> <term><filename>basic.target</filename></term> <listitem> <para>A special target unit covering basic boot-up.</para> diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index d812108d3c..f6e9d2a17c 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -192,6 +192,10 @@ over unit files wherever located. Multiple drop-in files with different names are applied in lexicographic order, regardless of which of the directories they reside in.</para> + <para>Service units also support a top-level drop-in directory for modifying the settings of all service units. See + <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry> + for details.</para> + <!-- Note that we do not document .include here, as we consider it mostly obsolete, and want people to use .d/ drop-ins instead. --> diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c index ecbf5ae7f5..bcd01f8515 100644 --- a/src/basic/unit-name.c +++ b/src/basic/unit-name.c @@ -678,8 +678,13 @@ bool service_unit_name_is_valid(const char *name) { /* If it's a template or instance, get the prefix as a service name. */ if (unit_name_is_valid(name, UNIT_NAME_INSTANCE|UNIT_NAME_TEMPLATE)) { - assert_se(unit_name_to_prefix(name, &prefix) == 0); - assert_se(s = strjoin(prefix, ".service")); + if (unit_name_to_prefix(name, &prefix) < 0) + return false; + + s = strjoin(prefix, ".service"); + if (!s) + return false; + service_name = s; } diff --git a/src/core/service.c b/src/core/service.c index 6880b24535..24ad1e77fa 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -554,7 +554,7 @@ static int service_verify(Service *s) { if (!service_unit_name_is_valid(UNIT(s)->id)) { log_unit_error(UNIT(s), "Service name is invalid or reserved. Refusing."); - return -ENOEXEC; + return -EINVAL; } if (!s->exec_command[SERVICE_EXEC_START] && !s->exec_command[SERVICE_EXEC_STOP] diff --git a/src/shared/dropin.c b/src/shared/dropin.c index 4a29bd09c5..2f67a44bf0 100644 --- a/src/shared/dropin.c +++ b/src/shared/dropin.c @@ -19,6 +19,7 @@ #include "mkdir.h" #include "path-util.h" #include "set.h" +#include "special.h" #include "string-util.h" #include "strv.h" #include "unit-name.h" @@ -226,12 +227,34 @@ int unit_file_find_dropin_paths( char ***ret) { _cleanup_strv_free_ char **dirs = NULL; + UnitType type = _UNIT_TYPE_INVALID; char *name, **p; Iterator i; int r; assert(ret); + /* All the names in the unit are of the same type so just grab one. */ + name = (char*) set_first(names); + if (name) { + type = unit_name_to_type(name); + if (type < 0) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "Failed to to derive unit type from unit name: %s", + name); + } + + /* Special drop in for -.service. Add this first as it's the most generic + * and should be able to be overridden by more specific drop-ins. */ + if (type == UNIT_SERVICE) + STRV_FOREACH(p, lookup_path) + (void) unit_file_find_dirs(original_root, + unit_path_cache, + *p, + SPECIAL_ROOT_SERVICE, + dir_suffix, + &dirs); + SET_FOREACH(name, names, i) STRV_FOREACH(p, lookup_path) (void) unit_file_find_dirs(original_root, unit_path_cache, *p, name, dir_suffix, &dirs); diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh index 2cef5a3c5b..75c36df2b8 100755 --- a/test/TEST-15-DROPIN/test-dropin.sh +++ b/test/TEST-15-DROPIN/test-dropin.sh @@ -101,6 +101,19 @@ test_basic_dropins () { check_ok b Wants c.service systemctl stop a c + echo "*** test -.service.d/ top level drop-in" + create_services a b + check_ko a ExecCondition "/bin/echo a" + check_ko b ExecCondition "/bin/echo b" + mkdir -p /usr/lib/systemd/system/-.service.d + cat >/usr/lib/systemd/system/-.service.d/override.conf <<EOF +[Service] +ExecCondition=/bin/echo %n +EOF + check_ok a ExecCondition "/bin/echo a" + check_ok b ExecCondition "/bin/echo b" + rm -rf /usr/lib/systemd/system/-.service.d + clear_services a b c } |