diff options
-rw-r--r-- | man/systemd.unit.xml | 13 | ||||
-rw-r--r-- | src/core/load-fragment-gperf.gperf.m4 | 1 | ||||
-rw-r--r-- | src/shared/install.c | 148 | ||||
-rw-r--r-- | src/shared/install.h | 2 | ||||
-rw-r--r-- | units/getty@.service.m4 | 1 |
5 files changed, 97 insertions, 68 deletions
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index e9031567d2..b337bb42bc 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -1286,6 +1286,19 @@ of unit names may be given.</para></listitem> </varlistentry> + + <varlistentry> + <term><varname>DefaultInstance=</varname></term> + + <listitem><para>In template unit files + this specifies for which instance the + unit shall be enabled if the template + is enabled without any explicitly set + instance. This option has no effect in + non-template unit files. The specified + string must be usable as instance + identifier.</para></listitem> + </varlistentry> </variablelist> <para>The following specifiers are interpreted in the diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 3471ccbe0a..4f3731b441 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -319,3 +319,4 @@ Install.Alias, NULL, 0, Install.WantedBy, NULL, 0, 0 Install.RequiredBy, NULL, 0, 0 Install.Also, NULL, 0, 0 +Install.DefaultInstance, NULL, 0, 0 diff --git a/src/shared/install.c b/src/shared/install.c index b300be8680..1e7863acbf 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -819,6 +819,7 @@ static void install_info_free(InstallInfo *i) { strv_free(i->aliases); strv_free(i->wanted_by); strv_free(i->required_by); + free(i->default_instance); free(i); } @@ -911,16 +912,17 @@ static int install_info_add_auto( return install_info_add(c, name_or_path, NULL); } -static int config_parse_also(const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { +static int config_parse_also( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { char *w; size_t l; @@ -947,19 +949,20 @@ static int config_parse_also(const char *unit, return 0; } -static int config_parse_user(const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { +static int config_parse_user( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { InstallInfo *i = data; - char* printed; + char *printed; int r; assert(filename); @@ -976,6 +979,39 @@ static int config_parse_user(const char *unit, return 0; } +static int config_parse_default_instance( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + InstallInfo *i = data; + char *printed; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + + r = install_full_printf(i, rvalue, &printed); + if (r < 0) + return r; + + if (!unit_instance_is_valid(printed)) + return -EINVAL; + + free(i->default_instance); + i->default_instance = printed; + + return 0; +} + static int unit_file_load( InstallContext *c, InstallInfo *info, @@ -983,12 +1019,13 @@ static int unit_file_load( bool allow_symlink) { const ConfigTableItem items[] = { - { "Install", "Alias", config_parse_strv, 0, &info->aliases }, - { "Install", "WantedBy", config_parse_strv, 0, &info->wanted_by }, - { "Install", "RequiredBy", config_parse_strv, 0, &info->required_by }, - { "Install", "Also", config_parse_also, 0, c }, - { "Exec", "User", config_parse_user, 0, info }, - { NULL, NULL, NULL, 0, NULL } + { "Install", "Alias", config_parse_strv, 0, &info->aliases }, + { "Install", "WantedBy", config_parse_strv, 0, &info->wanted_by }, + { "Install", "RequiredBy", config_parse_strv, 0, &info->required_by }, + { "Install", "DefaultInstance", config_parse_default_instance, 0, info }, + { "Install", "Also", config_parse_also, 0, c }, + { "Exec", "User", config_parse_user, 0, info }, + {} }; int fd; @@ -1009,8 +1046,7 @@ static int unit_file_load( return -ENOMEM; } - r = config_parse(NULL, path, f, NULL, - config_item_table_lookup, (void*) items, true, true, info); + r = config_parse(NULL, path, f, NULL, config_item_table_lookup, (void*) items, true, true, info); if (r < 0) return r; @@ -1211,54 +1247,30 @@ static int install_info_symlink_alias( static int install_info_symlink_wants( InstallInfo *i, const char *config_path, + char **list, + const char *suffix, bool force, UnitFileChange **changes, unsigned *n_changes) { + _cleanup_free_ char *buf = NULL; + const char *n; char **s; int r = 0, q; assert(i); assert(config_path); - STRV_FOREACH(s, i->wanted_by) { - _cleanup_free_ char *path = NULL, *dst = NULL; - - q = install_full_printf(i, *s, &dst); - if (q < 0) - return q; - - if (!unit_name_is_valid(dst, TEMPLATE_VALID)) { - r = -EINVAL; - continue; - } - - if (asprintf(&path, "%s/%s.wants/%s", config_path, dst, i->name) < 0) + if (unit_name_is_template(i->name) && i->default_instance) { + buf = unit_name_replace_instance(i->name, i->default_instance); + if (!buf) return -ENOMEM; - q = create_symlink(i->path, path, force, changes, n_changes); - - if (r == 0) - r = q; - } - - return r; -} - -static int install_info_symlink_requires( - InstallInfo *i, - const char *config_path, - bool force, - UnitFileChange **changes, - unsigned *n_changes) { - - char **s; - int r = 0, q; - - assert(i); - assert(config_path); + n = buf; + } else + n = i->name; - STRV_FOREACH(s, i->required_by) { + STRV_FOREACH(s, list) { _cleanup_free_ char *path = NULL, *dst = NULL; q = install_full_printf(i, *s, &dst); @@ -1270,11 +1282,11 @@ static int install_info_symlink_requires( continue; } - if (asprintf(&path, "%s/%s.requires/%s", config_path, dst, i->name) < 0) + path = strjoin(config_path, "/", dst, suffix, n, NULL); + if (!path) return -ENOMEM; q = create_symlink(i->path, path, force, changes, n_changes); - if (r == 0) r = q; } @@ -1325,11 +1337,11 @@ static int install_info_apply( r = install_info_symlink_alias(i, config_path, force, changes, n_changes); - q = install_info_symlink_wants(i, config_path, force, changes, n_changes); + q = install_info_symlink_wants(i, config_path, i->wanted_by, ".wants/", force, changes, n_changes); if (r == 0) r = q; - q = install_info_symlink_requires(i, config_path, force, changes, n_changes); + q = install_info_symlink_wants(i, config_path, i->required_by, ".requires/", force, changes, n_changes); if (r == 0) r = q; diff --git a/src/shared/install.h b/src/shared/install.h index d057bb052b..91ce192a4f 100644 --- a/src/shared/install.h +++ b/src/shared/install.h @@ -79,6 +79,8 @@ typedef struct { char **aliases; char **wanted_by; char **required_by; + + char *default_instance; } InstallInfo; int unit_file_enable(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes); diff --git a/units/getty@.service.m4 b/units/getty@.service.m4 index aa853b8d6d..46164ab9d8 100644 --- a/units/getty@.service.m4 +++ b/units/getty@.service.m4 @@ -46,3 +46,4 @@ Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETA [Install] WantedBy=getty.target +DefaultInstance=tty1 |