diff --git a/src/basic/unit-file.c b/src/basic/unit-file.c index 2474648cebc..7c1ae515e10 100644 --- a/src/basic/unit-file.c +++ b/src/basic/unit-file.c @@ -282,7 +282,9 @@ int unit_file_resolve_symlink( * * If resolve_destination_target is true, an absolute path will be returned. * If not, an absolute path is returned for linked unit files, and a relative - * path otherwise. */ + * path otherwise. + * + * Returns an error, false if this is an alias, true if it's a linked unit file. */ assert(filename); assert(ret_destination); @@ -364,7 +366,7 @@ int unit_file_resolve_symlink( } *ret_destination = TAKE_PTR(dst); - return 0; + return !tail; /* true if linked unit file */ } int unit_file_build_name_map( diff --git a/src/shared/install.c b/src/shared/install.c index d5e19792802..6aacdcf967c 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -93,8 +93,9 @@ void unit_file_presets_freep(UnitFilePresets *p) { static const char *const unit_file_type_table[_UNIT_FILE_TYPE_MAX] = { [UNIT_FILE_TYPE_REGULAR] = "regular", - [UNIT_FILE_TYPE_SYMLINK] = "symlink", - [UNIT_FILE_TYPE_MASKED] = "masked", + [UNIT_FILE_TYPE_LINKED] = "linked", + [UNIT_FILE_TYPE_ALIAS] = "alias", + [UNIT_FILE_TYPE_MASKED] = "masked", }; DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(unit_file_type, UnitFileType); @@ -1402,14 +1403,17 @@ static int unit_file_load_or_readlink( true, &info->symlink_target); if (r < 0) return r; + bool outside_search_path = r > 0; r = null_or_empty_path_with_root(info->symlink_target, lp->root_dir); if (r < 0 && r != -ENOENT) return log_debug_errno(r, "Failed to stat %s: %m", info->symlink_target); if (r > 0) info->type = UNIT_FILE_TYPE_MASKED; + else if (outside_search_path) + info->type = UNIT_FILE_TYPE_LINKED; else - info->type = UNIT_FILE_TYPE_SYMLINK; + info->type = UNIT_FILE_TYPE_ALIAS; return 0; } @@ -1548,7 +1552,7 @@ static int install_info_follow( assert(ctx); assert(info); - if (info->type != UNIT_FILE_TYPE_SYMLINK) + if (!IN_SET(info->type, UNIT_FILE_TYPE_ALIAS, UNIT_FILE_TYPE_LINKED)) return -EINVAL; if (!info->symlink_target) return -EINVAL; @@ -1588,7 +1592,7 @@ static int install_info_traverse( return r; i = start; - while (i->type == UNIT_FILE_TYPE_SYMLINK) { + while (IN_SET(i->type, UNIT_FILE_TYPE_ALIAS, UNIT_FILE_TYPE_LINKED)) { /* Follow the symlink */ if (++k > UNIT_FILE_FOLLOW_SYMLINK_MAX) diff --git a/src/shared/install.h b/src/shared/install.h index dba6987406c..95427537f2e 100644 --- a/src/shared/install.h +++ b/src/shared/install.h @@ -70,7 +70,8 @@ struct UnitFileList { enum UnitFileType { UNIT_FILE_TYPE_REGULAR, - UNIT_FILE_TYPE_SYMLINK, + UNIT_FILE_TYPE_LINKED, + UNIT_FILE_TYPE_ALIAS, UNIT_FILE_TYPE_MASKED, _UNIT_FILE_TYPE_MAX, _UNIT_FILE_TYPE_INVALID = -EINVAL,