install: introduce new DefaultInstance= field for [Install] sections
The DefaultInstance= name is used when enabling template units when only specifying the template name, but no instance. Add DefaultInstance=tty1 to getty@.service, so that when the template itself is enabled an instance for tty1 is created. This is useful so that we "systemctl preset-all" can work properly, because we can operate on getty@.service after finding it, and the right instance is created.
This commit is contained in:
parent
e50bd77516
commit
d54c499369
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,17 +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) {
|
||||
if (unit_name_is_template(i->name) && i->default_instance) {
|
||||
buf = unit_name_replace_instance(i->name, i->default_instance);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
n = buf;
|
||||
} else
|
||||
n = i->name;
|
||||
|
||||
STRV_FOREACH(s, list) {
|
||||
_cleanup_free_ char *path = NULL, *dst = NULL;
|
||||
|
||||
q = install_full_printf(i, *s, &dst);
|
||||
|
@ -1233,48 +1282,11 @@ static int install_info_symlink_wants(
|
|||
continue;
|
||||
}
|
||||
|
||||
if (asprintf(&path, "%s/%s.wants/%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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
STRV_FOREACH(s, i->required_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.requires/%s", config_path, dst, i->name) < 0)
|
||||
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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -46,3 +46,4 @@ Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETA
|
|||
|
||||
[Install]
|
||||
WantedBy=getty.target
|
||||
DefaultInstance=tty1
|
||||
|
|
Loading…
Reference in New Issue