const char *root_dir,
const UnitFileInstallInfo *i,
bool match_aliases,
+ bool ignore_same_name,
int fd,
const char *path,
const char *config_path,
}
/* This will close nfd, regardless whether it succeeds or not */
- q = find_symlinks_fd(root_dir, i, match_aliases, nfd,
+ q = find_symlinks_fd(root_dir, i, match_aliases, ignore_same_name, nfd,
p, config_path, same_name_link);
if (q > 0)
return 1;
} else if (de->d_type == DT_LNK) {
_cleanup_free_ char *p = NULL, *dest = NULL;
- bool found_path, found_dest, b = false;
+ bool found_path = false, found_dest, b = false;
int q;
/* Acquire symlink name */
free_and_replace(dest, x);
}
- /* Check if the symlink itself matches what we are looking for */
assert(unit_name_is_valid(i->name, UNIT_NAME_ANY));
- found_path = streq(de->d_name, i->name);
+ if (!ignore_same_name)
+ /* Check if the symlink itself matches what we are looking for.
+ *
+ * If ignore_same_name is specified, we are in one of the directories which
+ * have lower priority than the unit file, and even if a file or symlink with
+ * this name was found, we should ignore it. */
+ found_path = streq(de->d_name, i->name);
/* Check if what the symlink points to matches what we are looking for */
found_dest = streq(basename(dest), i->name);
const char *root_dir,
const UnitFileInstallInfo *i,
bool match_name,
+ bool ignore_same_name,
const char *config_path,
bool *same_name_link) {
}
/* This takes possession of fd and closes it */
- return find_symlinks_fd(root_dir, i, match_name, fd,
+ return find_symlinks_fd(root_dir, i, match_name, ignore_same_name, fd,
config_path, config_path, same_name_link);
}
bool same_name_link_runtime = false, same_name_link_config = false;
bool enabled_in_runtime = false, enabled_at_all = false;
+ bool ignore_same_name = false;
char **p;
int r;
assert(paths);
assert(i);
+ /* As we iterate over the list of search paths in paths->search_path, we may encounter "same name"
+ * symlinks. The ones which are "below" (i.e. have lower priority) than the unit file itself are
+ * efectively masked, so we should ignore them. */
+
STRV_FOREACH(p, paths->search_path) {
bool same_name_link = false;
- r = find_symlinks(paths->root_dir, i, match_name, *p, &same_name_link);
+ r = find_symlinks(paths->root_dir, i, match_name, ignore_same_name, *p, &same_name_link);
if (r < 0)
return r;
if (r > 0) {
same_name_link_runtime = true;
}
}
+
+ /* Check if next iteration will be "below" the unit file (either a regular file
+ * or a symlink), and hence should be ignored */
+ if (!ignore_same_name && path_startswith(i->path, *p))
+ ignore_same_name = true;
}
if (enabled_in_runtime) {