]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
pid1: port executor binary pinning to new build path logic
authorLennart Poettering <lennart@poettering.net>
Tue, 20 Feb 2024 11:47:10 +0000 (12:47 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 21 Feb 2024 08:25:46 +0000 (09:25 +0100)
src/basic/build-path.c
src/basic/build-path.h
src/core/manager.c

index 0c43afaefdf502723c62b348bef03a8a714a19e2..8ddef7b2dd5e3cf97b61684a2e6a86981b85be78 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "build-path.h"
 #include "errno-list.h"
+#include "errno-util.h"
 #include "macro.h"
 #include "path-util.h"
 #include "process-util.h"
@@ -236,3 +237,31 @@ int invoke_callout_binary(const char *path, char *const argv[]) {
         execv(path, argv);
         return -errno;
 }
+
+int pin_callout_binary(const char *path) {
+        int r;
+
+        assert(path);
+
+        /* Similar to invoke_callout_binary(), but pins (i.e. O_PATH opens) the binary instead of executing it. */
+
+        _cleanup_free_ char *fn = NULL;
+        r = path_extract_filename(path, &fn);
+        if (r < 0)
+                return r;
+        if (r == O_DIRECTORY) /* Uh? */
+                return -EISDIR;
+
+        const char *e;
+        if (find_environment_binary(fn, &e) >= 0)
+                return RET_NERRNO(open(e, O_CLOEXEC|O_PATH));
+
+        _cleanup_free_ char *np = NULL;
+        if (find_build_dir_binary(fn, &np) >= 0) {
+                r = RET_NERRNO(open(np, O_CLOEXEC|O_PATH));
+                if (r >= 0)
+                        return r;
+        }
+
+        return RET_NERRNO(open(path, O_CLOEXEC|O_PATH));
+}
index bf42783f1b0e157084dfed2a2ae87dffa479aeb3..6c38a4a3bb50b864d01abccc37d06b440fd8e55f 100644 (file)
@@ -4,3 +4,5 @@
 int get_build_exec_dir(char **ret);
 
 int invoke_callout_binary(const char *path, char *const argv[]);
+
+int pin_callout_binary(const char *path);
index e8c747d96d9e5fe89ddf9b70d733ac5dd6b603b5..7a7669f315f6fed37a3ae2b268a0ab1e1845e590 100644 (file)
@@ -25,6 +25,7 @@
 #include "alloc-util.h"
 #include "audit-fd.h"
 #include "boot-timestamps.h"
+#include "build-path.h"
 #include "bus-common-errors.h"
 #include "bus-error.h"
 #include "bus-kernel.h"
@@ -1024,42 +1025,19 @@ int manager_new(RuntimeScope runtime_scope, ManagerTestRunFlags test_run_flags,
 
                 if (r < 0 && r != -EEXIST)
                         return r;
+        }
 
-                m->executor_fd = open(SYSTEMD_EXECUTOR_BINARY_PATH, O_CLOEXEC|O_PATH);
-                if (m->executor_fd < 0)
-                        return log_emergency_errno(errno,
-                                                   "Failed to open executor binary '%s': %m",
-                                                   SYSTEMD_EXECUTOR_BINARY_PATH);
-        } else if (!FLAGS_SET(test_run_flags, MANAGER_TEST_DONT_OPEN_EXECUTOR)) {
-                _cleanup_free_ char *self_exe = NULL, *executor_path = NULL;
-                _cleanup_close_ int self_dir_fd = -EBADF;
-                int level = LOG_DEBUG;
-
-                /* Prefer sd-executor from the same directory as the test, e.g.: when running unit tests from the
-                * build directory. Fallback to working directory and then the installation path. */
-                r = readlink_and_make_absolute("/proc/self/exe", &self_exe);
-                if (r < 0)
-                        return r;
-
-                self_dir_fd = open_parent(self_exe, O_CLOEXEC|O_PATH|O_DIRECTORY, 0);
-                if (self_dir_fd < 0)
-                        return self_dir_fd;
-
-                m->executor_fd = RET_NERRNO(openat(self_dir_fd, "systemd-executor", O_CLOEXEC|O_PATH));
-                if (m->executor_fd == -ENOENT)
-                        m->executor_fd = RET_NERRNO(openat(AT_FDCWD, "systemd-executor", O_CLOEXEC|O_PATH));
-                if (m->executor_fd == -ENOENT) {
-                        m->executor_fd = RET_NERRNO(open(SYSTEMD_EXECUTOR_BINARY_PATH, O_CLOEXEC|O_PATH));
-                        level = LOG_WARNING; /* Tests should normally use local builds */
-                }
+        if (!FLAGS_SET(test_run_flags, MANAGER_TEST_DONT_OPEN_EXECUTOR)) {
+                m->executor_fd = pin_callout_binary(SYSTEMD_EXECUTOR_BINARY_PATH);
                 if (m->executor_fd < 0)
-                        return m->executor_fd;
+                        return log_debug_errno(m->executor_fd, "Failed to pin executor binary: %m");
 
+                _cleanup_free_ char *executor_path = NULL;
                 r = fd_get_path(m->executor_fd, &executor_path);
                 if (r < 0)
                         return r;
 
-                log_full(level, "Using systemd-executor binary from '%s'.", executor_path);
+                log_debug("Using systemd-executor binary from '%s'.", executor_path);
         }
 
         /* Note that we do not set up the notify fd here. We do that after deserialization,