diff --git a/man/systemd.automount.xml b/man/systemd.automount.xml
index 93bae2a6dc..a43dc981bd 100644
--- a/man/systemd.automount.xml
+++ b/man/systemd.automount.xml
@@ -66,14 +66,13 @@
[Install] sections. The automount specific configuration options
are configured in the [Automount] section.
- Automount units must be named after the automount
- directories they control. Example: the automount point
- /home/lennart must be
- configured in a unit file
- home-lennart.automount. For details about the
- escaping logic used to convert a file system path to a unit name
- see
- systemd.unit5.
+ Automount units must be named after the automount directories they control. Example: the automount point
+ /home/lennart must be configured in a unit file
+ home-lennart.automount. For details about the escaping logic used to convert a file system
+ path to a unit name see
+ systemd.unit5. Note that
+ automount units cannot be templated, nor is it possible to add multiple names to an automount unit by creating
+ additional symlinks to its unit file.
For each automount unit file a matching mount unit file (see
systemd.mount5
diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml
index f116782b40..bf56a49e58 100644
--- a/man/systemd.mount.xml
+++ b/man/systemd.mount.xml
@@ -82,14 +82,12 @@
will refuse options that are not listed in
/etc/fstab if it is not run as UID 0.
- Mount units must be named after the mount point directories
- they control. Example: the mount point
- /home/lennart must be
- configured in a unit file home-lennart.mount.
- For details about the escaping logic used to convert a file system
- path to a unit name, see
- systemd.unit5.
- Note that mount units cannot be templated.
+ Mount units must be named after the mount point directories they control. Example: the mount point /home/lennart must be configured in a unit file home-lennart.mount.
+ For details about the escaping logic used to convert a file system path to a unit name, see
+ systemd.unit5. Note that mount
+ units cannot be templated, nor is possible to add multiple names to a mount unit by creating additional symlinks to
+ it.
Optionally, a mount unit may be accompanied by an automount
unit, to allow on-demand or parallelized mounting. See
diff --git a/man/systemd.slice.xml b/man/systemd.slice.xml
index 16247628af..eee98d99ee 100644
--- a/man/systemd.slice.xml
+++ b/man/systemd.slice.xml
@@ -71,6 +71,9 @@
the root slice -.slice.
+ Note that slice units cannot be templated, nor is possible to add multiple names to a slice unit by creating
+ additional symlinks to it.
+
By default, service and scope units are placed in
system.slice, virtual machines and containers
registered with
diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml
index 6fc4c7bf13..cf4e1ba839 100644
--- a/man/systemd.swap.xml
+++ b/man/systemd.swap.xml
@@ -78,13 +78,12 @@
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
- /dev/sda5 must be configured in a
- unit file dev-sda5.swap. For details about
- the escaping logic used to convert a file system path to a unit
- name, see
- systemd.unit5.
+ Swap units must be named after the devices or files they control. Example: the swap device /dev/sda5 must be configured in a unit file dev-sda5.swap. For
+ details about the escaping logic used to convert a file system path to a unit name, see
+ systemd.unit5. Note that swap
+ units cannot be templated, nor is possible to add multiple names to a swap unit by creating additional symlinks to
+ it.
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index f4b13a7a77..abd47bd237 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -1103,13 +1103,12 @@
Alias=
- A space-separated list of additional names
- this unit shall be installed under. The names listed here must
- have the same suffix (i.e. type) as the unit file name. This
- option may be specified more than once, in which case all
- listed names are used. At installation time,
- systemctl enable will create symlinks from
- these names to the unit filename.
+ A space-separated list of additional names this unit shall be installed under. The names listed
+ here must have the same suffix (i.e. type) as the unit file name. This option may be specified more than once,
+ in which case all listed names are used. At installation time, systemctl enable will create
+ symlinks from these names to the unit filename. Note that not all unit types support such alias names, and this
+ setting is not supported for them. Specifically, mount, slice, swap, and automount units do not support
+ aliasing.
diff --git a/src/basic/hashmap.c b/src/basic/hashmap.c
index 85b8d812b3..49a0479592 100644
--- a/src/basic/hashmap.c
+++ b/src/basic/hashmap.c
@@ -1773,20 +1773,18 @@ int set_consume(Set *s, void *value) {
int set_put_strdup(Set *s, const char *p) {
char *c;
- int r;
assert(s);
assert(p);
+ if (set_contains(s, (char*) p))
+ return 0;
+
c = strdup(p);
if (!c)
return -ENOMEM;
- r = set_consume(s, c);
- if (r == -EEXIST)
- return 0;
-
- return r;
+ return set_consume(s, c);
}
int set_put_strdupv(Set *s, char **l) {
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index c4566f7709..31b995aa6a 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -3427,10 +3427,10 @@ int config_parse_protect_system(
#define FOLLOW_MAX 8
static int open_follow(char **filename, FILE **_f, Set *names, char **_final) {
+ char *id = NULL;
unsigned c = 0;
int fd, r;
FILE *f;
- char *id = NULL;
assert(filename);
assert(*filename);
@@ -3452,7 +3452,6 @@ static int open_follow(char **filename, FILE **_f, Set *names, char **_final) {
* the names of this unit, but only if it is a valid
* unit name. */
name = basename(*filename);
-
if (unit_name_is_valid(name, UNIT_NAME_ANY)) {
id = set_get(names, name);
@@ -3492,6 +3491,7 @@ static int open_follow(char **filename, FILE **_f, Set *names, char **_final) {
*_f = f;
*_final = id;
+
return 0;
}
@@ -3552,13 +3552,13 @@ static int merge_by_names(Unit **u, Set *names, const char *id) {
}
static int load_from_path(Unit *u, const char *path) {
- int r;
_cleanup_set_free_free_ Set *symlink_names = NULL;
_cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *filename = NULL;
char *id = NULL;
Unit *merged;
struct stat st;
+ int r;
assert(u);
assert(path);
@@ -3597,18 +3597,14 @@ static int load_from_path(Unit *u, const char *path) {
r = -ENOENT;
else
r = open_follow(&filename, &f, symlink_names, &id);
+ if (r >= 0)
+ break;
+ filename = mfree(filename);
+ if (r != -ENOENT)
+ return r;
- if (r < 0) {
- filename = mfree(filename);
- if (r != -ENOENT)
- return r;
-
- /* Empty the symlink names for the next run */
- set_clear_free(symlink_names);
- continue;
- }
-
- break;
+ /* Empty the symlink names for the next run */
+ set_clear_free(symlink_names);
}
}
@@ -3616,6 +3612,11 @@ static int load_from_path(Unit *u, const char *path) {
/* Hmm, no suitable file found? */
return 0;
+ if (UNIT_VTABLE(u)->no_alias && set_size(symlink_names) > 1) {
+ log_unit_warning(u, "Unit type of %s does not support alias names, refusing loading via symlink.", u->id);
+ return -ELOOP;
+ }
+
merged = u;
r = merge_by_names(&merged, symlink_names, id);
if (r < 0)
diff --git a/src/core/unit.c b/src/core/unit.c
index 81cd7ee2b8..64466e4fb4 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -720,6 +720,9 @@ int unit_merge(Unit *u, Unit *other) {
if (!u->instance != !other->instance)
return -EINVAL;
+ if (UNIT_VTABLE(u)->no_alias) /* Merging only applies to unit names that support aliases */
+ return -EEXIST;
+
if (other->load_state != UNIT_STUB &&
other->load_state != UNIT_NOT_FOUND)
return -EEXIST;
@@ -776,9 +779,9 @@ int unit_merge(Unit *u, Unit *other) {
}
int unit_merge_by_name(Unit *u, const char *name) {
+ _cleanup_free_ char *s = NULL;
Unit *other;
int r;
- _cleanup_free_ char *s = NULL;
assert(u);
assert(name);