diff options
Diffstat (limited to 'pkgs/os-specific/linux/systemd/0021-core-handle-lookup-paths-being-symlinks.patch')
-rw-r--r-- | pkgs/os-specific/linux/systemd/0021-core-handle-lookup-paths-being-symlinks.patch | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/pkgs/os-specific/linux/systemd/0021-core-handle-lookup-paths-being-symlinks.patch b/pkgs/os-specific/linux/systemd/0021-core-handle-lookup-paths-being-symlinks.patch new file mode 100644 index 00000000000..4366999bee4 --- /dev/null +++ b/pkgs/os-specific/linux/systemd/0021-core-handle-lookup-paths-being-symlinks.patch @@ -0,0 +1,80 @@ +From 3e0e304959719958dee4d88ccbb9647ffb5797ef Mon Sep 17 00:00:00 2001 +From: Andreas Rammhold <andreas@rammhold.de> +Date: Wed, 18 Aug 2021 19:10:08 +0200 +Subject: [PATCH 21/22] 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. +--- + 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 884a0674a9..3ae2a115d0 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); +-- +2.33.0 + |