diff --git a/src/basic/unit-file.c b/src/basic/unit-file.c index 0e9a556268..6cf66b45cf 100644 --- a/src/basic/unit-file.c +++ b/src/basic/unit-file.c @@ -82,7 +82,8 @@ int unit_validate_alias_symlink_or_warn(int log_level, const char *filename, con * * -EINVAL is returned if the something is wrong with the source filename or the source unit type is * not allowed to symlink, - * -EXDEV if the target filename is not a valid unit name or doesn't match the source. + * -EXDEV if the target filename is not a valid unit name or doesn't match the source, + * -ELOOP for an alias to self. */ src = basename(filename); @@ -111,6 +112,11 @@ int unit_validate_alias_symlink_or_warn(int log_level, const char *filename, con /* dst checks */ + if (streq(src, dst)) + return log_debug_errno(SYNTHETIC_ERRNO(ELOOP), + "%s: unit self-alias: %s → %s, ignoring.", + filename, src, dst); + dst_name_type = unit_name_to_instance(dst, &dst_instance); if (dst_name_type < 0) return log_full_errno(log_level, dst_name_type == -EINVAL ? SYNTHETIC_ERRNO(EXDEV) : dst_name_type, @@ -347,24 +353,12 @@ int unit_file_resolve_symlink( if (r < 0) return r; - bool self_alias = streq(target_name, filename); - - if (is_path(tail)) - log_full(self_alias ? LOG_DEBUG : LOG_WARNING, - "Suspicious symlink %s/%s→%s, treating as alias.", - dir, filename, simplified); - r = unit_validate_alias_symlink_or_warn(LOG_NOTICE, filename, simplified); if (r < 0) return r; - - if (self_alias && !resolve_destination_target) - /* A self-alias that has no effect when loading, let's just ignore it. */ - return log_debug_errno(SYNTHETIC_ERRNO(ELOOP), - "Unit file self-alias: %s/%s → %s, ignoring.", - dir, filename, target_name); - - log_debug("Unit file alias: %s/%s → %s", dir, filename, target_name); + if (is_path(tail)) + log_warning("Suspicious symlink %s/%s→%s, treating as alias.", + dir, filename, simplified); dst = resolve_destination_target ? TAKE_PTR(simplified) : TAKE_PTR(target_name); } diff --git a/src/shared/install.c b/src/shared/install.c index cfada13442..bc15b0e9d2 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -1695,6 +1695,11 @@ int unit_file_verify_alias( * ret_dst is set in cases where "instance propagation" happens, i.e. when the instance part is * inserted into dst. It is not normally set, even on success, so that the caller can easily * distinguish the case where instance propagation occurred. + * + * Returns: + * -EXDEV when the alias doesn't match the unit, + * -EUCLEAN when the name is invalid, + * -ELOOP when the alias it to the unit itself. */ const char *path_alias = strrchr(dst, '/'); @@ -1760,6 +1765,8 @@ int unit_file_verify_alias( } r = unit_validate_alias_symlink_or_warn(LOG_DEBUG, dst_updated ?: dst, info->name); + if (r == -ELOOP) /* -ELOOP means self-alias, which we (quietly) ignore */ + return r; if (r < 0) { unit_file_changes_add(changes, n_changes, r == -EINVAL ? -EXDEV : r, @@ -1799,6 +1806,8 @@ static int install_info_symlink_alias( } q = unit_file_verify_alias(info, dst, &dst_updated, changes, n_changes); + if (q == -ELOOP) + continue; if (q < 0) { r = r < 0 ? r : q; continue; diff --git a/test/test-systemctl-enable.sh b/test/test-systemctl-enable.sh index 32bc6e5ef7..4117436462 100644 --- a/test/test-systemctl-enable.sh +++ b/test/test-systemctl-enable.sh @@ -328,8 +328,7 @@ test ! -h "$root/etc/systemd/system/services.target.wants/templ1@two.service" test ! -e "$root/etc/systemd/system/link4.service" cat >"$root/etc/systemd/system/link4.service" <"$root/etc/systemd/system/link5.service" <