summary refs log tree commit diff
path: root/pkgs/os-specific/linux/systemd/0021-core-handle-lookup-paths-being-symlinks.patch
diff options
context:
space:
mode:
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.patch80
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
+