Changeset View
Changeset View
Standalone View
Standalone View
files/0001-core-handle-lookup-paths-being-symlinks.patch
- This file was added.
| From 5f17b65d30480e489e135b403a072b38535b2911 Mon Sep 17 00:00:00 2001 | |||||
| From: Andreas Rammhold <andreas@rammhold.de> | |||||
| Date: Wed, 18 Aug 2021 19:10:08 +0200 | |||||
| Subject: [PATCH] core: handle lookup paths being symlinks | |||||
| With a recent change paths leaving the statically known lookup paths | |||||
| would be treated differently then those that remained within those. That | |||||
| was done (AFAIK) to consistently handle alias names. Unfortunately that | |||||
| means that on some distributions, especially those where /etc/ consists | |||||
| mostly of symlinks, would trigger that new detection for every single | |||||
| unit in /etc/systemd/system. The reason for that is that the units | |||||
| directory itself is already a symlink. | |||||
| Solus Note: Can be removed when https://github.com/systemd/systemd/pull/20479 is merged | |||||
| --- | |||||
| src/basic/unit-file.c | 33 +++++++++++++++++++++++++++++++-- | |||||
| 1 file changed, 31 insertions(+), 2 deletions(-) | |||||
| diff --git a/src/basic/unit-file.c b/src/basic/unit-file.c | |||||
| index 884a0674a9c0..3ae2a115d047 100644 | |||||
| --- a/src/basic/unit-file.c | |||||
| +++ b/src/basic/unit-file.c | |||||
| @@ -254,6 +254,7 @@ int unit_file_build_name_map( | |||||
| _cleanup_hashmap_free_ Hashmap *ids = NULL, *names = NULL; | |||||
| _cleanup_set_free_free_ Set *paths = NULL; | |||||
| + _cleanup_strv_free_ char **expanded_search_paths = NULL; | |||||
| uint64_t timestamp_hash; | |||||
| char **dir; | |||||
| int r; | |||||
| @@ -273,6 +274,34 @@ int unit_file_build_name_map( | |||||
| return log_oom(); | |||||
| } | |||||
| + /* Go over all our search paths, chase their symlinks and store the | |||||
| + * result in the expanded_search_paths list. | |||||
| + * | |||||
| + * This is important for cases where any of the unit directories itself | |||||
| + * are symlinks into other directories and would therefore cause all of | |||||
| + * the unit files to be recognized as linked units. | |||||
| + * | |||||
| + * This is important for distributions such as NixOS where most paths | |||||
| + * in /etc/ are symlinks to some other location on the filesystem (e.g. | |||||
| + * into /nix/store/). | |||||
| + */ | |||||
| + STRV_FOREACH(dir, (char**) lp->search_path) { | |||||
| + _cleanup_free_ char *resolved_dir = NULL; | |||||
| + r = strv_extend(&expanded_search_paths, *dir); | |||||
| + if (r < 0) | |||||
| + return log_oom(); | |||||
| + | |||||
| + r = chase_symlinks(*dir, NULL, 0, &resolved_dir, NULL); | |||||
| + if (r < 0) { | |||||
| + if (r != -ENOENT) | |||||
| + log_warning_errno(r, "Failed to resolve symlink %s, ignoring: %m", *dir); | |||||
| + continue; | |||||
| + } | |||||
| + | |||||
| + if (strv_consume(&expanded_search_paths, TAKE_PTR(resolved_dir)) < 0) | |||||
| + return log_oom(); | |||||
| + } | |||||
| + | |||||
| STRV_FOREACH(dir, (char**) lp->search_path) { | |||||
| struct dirent *de; | |||||
| _cleanup_closedir_ DIR *d = NULL; | |||||
| @@ -351,11 +380,11 @@ int unit_file_build_name_map( | |||||
| continue; | |||||
| } | |||||
| - /* Check if the symlink goes outside of our search path. | |||||
| + /* Check if the symlink goes outside of our (expanded) search path. | |||||
| * If yes, it's a linked unit file or mask, and we don't care about the target name. | |||||
| * Let's just store the link source directly. | |||||
| * If not, let's verify that it's a good symlink. */ | |||||
| - char *tail = path_startswith_strv(simplified, lp->search_path); | |||||
| + char *tail = path_startswith_strv(simplified, expanded_search_paths); | |||||
| if (!tail) { | |||||
| log_debug("%s: linked unit file: %s → %s", | |||||
| __func__, filename, simplified); | |||||
Copyright © 2015-2021 Solus Project. The Solus logo is Copyright © 2016-2021 Solus Project. All Rights Reserved.