ryantimwilson / rpms / systemd

Forked from rpms/systemd a month ago
Clone
8d419f
From e2d699c92944c6251f9de161c9e3ae93d915c4e0 Mon Sep 17 00:00:00 2001
8d419f
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
8d419f
Date: Thu, 17 Mar 2022 15:50:16 +0100
8d419f
Subject: [PATCH] shared/install: split UNIT_FILE_SYMLINK into two states
8d419f
8d419f
The two states are distinguished, but are treated everywhere identically,
8d419f
so there is no difference in behaviour except for slighlty different log
8d419f
output.
8d419f
8d419f
(cherry picked from commit 48ed75adabef3427767038fa155e55b3b0d48f35)
8d419f
8d419f
Related: #2082131
8d419f
---
8d419f
 src/basic/unit-file.c |  6 ++++--
8d419f
 src/shared/install.c  | 14 +++++++++-----
8d419f
 src/shared/install.h  |  3 ++-
8d419f
 3 files changed, 15 insertions(+), 8 deletions(-)
8d419f
8d419f
diff --git a/src/basic/unit-file.c b/src/basic/unit-file.c
8d419f
index 2474648ceb..7c1ae515e1 100644
8d419f
--- a/src/basic/unit-file.c
8d419f
+++ b/src/basic/unit-file.c
8d419f
@@ -282,7 +282,9 @@ int unit_file_resolve_symlink(
8d419f
          *
8d419f
          * If resolve_destination_target is true, an absolute path will be returned.
8d419f
          * If not, an absolute path is returned for linked unit files, and a relative
8d419f
-         * path otherwise. */
8d419f
+         * path otherwise.
8d419f
+         *
8d419f
+         * Returns an error, false if this is an alias, true if it's a linked unit file. */
8d419f
 
8d419f
         assert(filename);
8d419f
         assert(ret_destination);
8d419f
@@ -364,7 +366,7 @@ int unit_file_resolve_symlink(
8d419f
         }
8d419f
 
8d419f
         *ret_destination = TAKE_PTR(dst);
8d419f
-        return 0;
8d419f
+        return !tail;  /* true if linked unit file */
8d419f
 }
8d419f
 
8d419f
 int unit_file_build_name_map(
8d419f
diff --git a/src/shared/install.c b/src/shared/install.c
8d419f
index f911d527df..b33f7d4bc1 100644
8d419f
--- a/src/shared/install.c
8d419f
+++ b/src/shared/install.c
8d419f
@@ -93,8 +93,9 @@ void unit_file_presets_freep(UnitFilePresets *p) {
8d419f
 
8d419f
 static const char *const unit_file_type_table[_UNIT_FILE_TYPE_MAX] = {
8d419f
         [UNIT_FILE_TYPE_REGULAR] = "regular",
8d419f
-        [UNIT_FILE_TYPE_SYMLINK] = "symlink",
8d419f
-        [UNIT_FILE_TYPE_MASKED] = "masked",
8d419f
+        [UNIT_FILE_TYPE_LINKED]  = "linked",
8d419f
+        [UNIT_FILE_TYPE_ALIAS]   = "alias",
8d419f
+        [UNIT_FILE_TYPE_MASKED]  = "masked",
8d419f
 };
8d419f
 
8d419f
 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(unit_file_type, UnitFileType);
8d419f
@@ -1404,14 +1405,17 @@ static int unit_file_load_or_readlink(
8d419f
                                       true, &info->symlink_target);
8d419f
         if (r < 0)
8d419f
                 return r;
8d419f
+        bool outside_search_path = r > 0;
8d419f
 
8d419f
         r = null_or_empty_path_with_root(info->symlink_target, lp->root_dir);
8d419f
         if (r < 0 && r != -ENOENT)
8d419f
                 return log_debug_errno(r, "Failed to stat %s: %m", info->symlink_target);
8d419f
         if (r > 0)
8d419f
                 info->type = UNIT_FILE_TYPE_MASKED;
8d419f
+        else if (outside_search_path)
8d419f
+                info->type = UNIT_FILE_TYPE_LINKED;
8d419f
         else
8d419f
-                info->type = UNIT_FILE_TYPE_SYMLINK;
8d419f
+                info->type = UNIT_FILE_TYPE_ALIAS;
8d419f
 
8d419f
         return 0;
8d419f
 }
8d419f
@@ -1550,7 +1554,7 @@ static int install_info_follow(
8d419f
         assert(ctx);
8d419f
         assert(info);
8d419f
 
8d419f
-        if (info->type != UNIT_FILE_TYPE_SYMLINK)
8d419f
+        if (!IN_SET(info->type, UNIT_FILE_TYPE_ALIAS, UNIT_FILE_TYPE_LINKED))
8d419f
                 return -EINVAL;
8d419f
         if (!info->symlink_target)
8d419f
                 return -EINVAL;
8d419f
@@ -1591,7 +1595,7 @@ static int install_info_traverse(
8d419f
                 return r;
8d419f
 
8d419f
         i = start;
8d419f
-        while (i->type == UNIT_FILE_TYPE_SYMLINK) {
8d419f
+        while (IN_SET(i->type, UNIT_FILE_TYPE_ALIAS, UNIT_FILE_TYPE_LINKED)) {
8d419f
                 /* Follow the symlink */
8d419f
 
8d419f
                 if (++k > UNIT_FILE_FOLLOW_SYMLINK_MAX)
8d419f
diff --git a/src/shared/install.h b/src/shared/install.h
8d419f
index dba6987406..95427537f2 100644
8d419f
--- a/src/shared/install.h
8d419f
+++ b/src/shared/install.h
8d419f
@@ -70,7 +70,8 @@ struct UnitFileList {
8d419f
 
8d419f
 enum UnitFileType {
8d419f
         UNIT_FILE_TYPE_REGULAR,
8d419f
-        UNIT_FILE_TYPE_SYMLINK,
8d419f
+        UNIT_FILE_TYPE_LINKED,
8d419f
+        UNIT_FILE_TYPE_ALIAS,
8d419f
         UNIT_FILE_TYPE_MASKED,
8d419f
         _UNIT_FILE_TYPE_MAX,
8d419f
         _UNIT_FILE_TYPE_INVALID = -EINVAL,