summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/systemd.unit.xml13
-rw-r--r--src/core/load-fragment-gperf.gperf.m41
-rw-r--r--src/shared/install.c148
-rw-r--r--src/shared/install.h2
-rw-r--r--units/getty@.service.m41
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