]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
ssh-generator: follow symlink when searching for sshd@.service
authorMike Yuan <me@yhndnzj.com>
Mon, 2 Feb 2026 15:24:00 +0000 (16:24 +0100)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 2 Feb 2026 23:17:34 +0000 (08:17 +0900)
unit_file_exists() currently does not follow symlinks, as it is
mainly used to test whether the unit (of any install state)
has been seen under search dirs. However, in ssh-generator
we should search for and honor whatever the distro ships,
which might be an alias or linked externally.

src/shared/install.c
src/shared/install.h
src/ssh-generator/ssh-generator.c

index dc27d53f0984ec51fa4e7bf96a5b0747a19985a6..4c68821562c74450f76bd5293bebf5388ce654df 100644 (file)
@@ -3239,7 +3239,13 @@ int unit_file_get_state(
         return unit_file_lookup_state(scope, &lp, name, ret);
 }
 
-int unit_file_exists_full(RuntimeScope scope, const LookupPaths *lp, const char *name, char **ret_path) {
+int unit_file_exists_full(
+                RuntimeScope scope,
+                const LookupPaths *lp,
+                bool follow,
+                const char *name,
+                char **ret_path) {
+
         _cleanup_(install_context_done) InstallContext c = {
                 .scope = scope,
         };
@@ -3256,7 +3262,7 @@ int unit_file_exists_full(RuntimeScope scope, const LookupPaths *lp, const char
                         &c,
                         lp,
                         name,
-                        /* flags= */ 0,
+                        follow ? SEARCH_FOLLOW_CONFIG_SYMLINKS : 0,
                         ret_path ? &info : NULL,
                         /* changes= */ NULL,
                         /* n_changes= */ NULL);
index c4592fed358ea9b661ded2caa65b6ddaafdabff3..98d5a41d3e5101ac58452c73d3badab74e0fb988 100644 (file)
@@ -181,9 +181,15 @@ int unit_file_lookup_state(
 
 int unit_file_get_state(RuntimeScope scope, const char *root_dir, const char *filename, UnitFileState *ret);
 
-int unit_file_exists_full(RuntimeScope scope, const LookupPaths *lp, const char *name, char **ret_path);
+int unit_file_exists_full(
+                RuntimeScope scope,
+                const LookupPaths *lp,
+                bool follow,
+                const char *name,
+                char **ret_path);
+
 static inline int unit_file_exists(RuntimeScope scope, const LookupPaths *lp, const char *name) {
-        return unit_file_exists_full(scope, lp, name, NULL);
+        return unit_file_exists_full(scope, lp, false, name, NULL);
 }
 
 int unit_file_get_list(RuntimeScope scope, const char *root_dir, char * const *states, char * const *patterns, Hashmap **ret);
index 2364f86e256aa603d0cddcf6c0c34f93307e3a15..5cb4c98b8a1d97b36c231986d881667e97da4699 100644 (file)
@@ -475,7 +475,10 @@ static int run(const char *dest, const char *dest_early, const char *dest_late)
                 return r;
 
         _cleanup_free_ char *found_sshd_template_unit = NULL;
-        r = unit_file_exists_full(RUNTIME_SCOPE_SYSTEM, &lp, "sshd@.service", &found_sshd_template_unit);
+        r = unit_file_exists_full(RUNTIME_SCOPE_SYSTEM, &lp,
+                                  /* follow = */ true,
+                                  "sshd@.service",
+                                  &found_sshd_template_unit);
         if (r < 0)
                 return log_error_errno(r, "Unable to detect if sshd@.service exists: %m");