mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 08:25:20 +09:00
udev-spawn: search executed command in build directory (#36985)
This makes pin_callout_binary() optionally provides the path of the pinned
binary, and makes it used in udev-spawn.c, to allow easy debugging of
program invocations requested by RUN{program} and friends.
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include "build-path.h"
|
||||
#include "errno-list.h"
|
||||
#include "errno-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "macro.h"
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
@@ -245,12 +246,39 @@ int invoke_callout_binary(const char *path, char *const argv[]) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
int pin_callout_binary(const char *path) {
|
||||
static int open_executable(const char *path, char **ret_path) {
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
|
||||
/* Similar to invoke_callout_binary(), but pins (i.e. O_PATH opens) the binary instead of executing it. */
|
||||
_cleanup_close_ int fd = RET_NERRNO(open(path, O_CLOEXEC|O_PATH));
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
r = fd_verify_regular(fd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = access_fd(fd, X_OK);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (ret_path) {
|
||||
r = fd_get_path(fd, ret_path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return TAKE_FD(fd);
|
||||
}
|
||||
|
||||
int pin_callout_binary(const char *path, char **ret_path) {
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
|
||||
/* Similar to invoke_callout_binary(), but pins (i.e. O_PATH opens) the binary instead of executing
|
||||
* it, also optionally provides the path to the binary. */
|
||||
|
||||
_cleanup_free_ char *fn = NULL;
|
||||
r = path_extract_filename(path, &fn);
|
||||
@@ -261,14 +289,14 @@ int pin_callout_binary(const char *path) {
|
||||
|
||||
const char *e;
|
||||
if (find_environment_binary(fn, &e) >= 0)
|
||||
return RET_NERRNO(open(e, O_CLOEXEC|O_PATH));
|
||||
return open_executable(e, ret_path);
|
||||
|
||||
_cleanup_free_ char *np = NULL;
|
||||
if (find_build_dir_binary(fn, &np) >= 0) {
|
||||
r = RET_NERRNO(open(np, O_CLOEXEC|O_PATH));
|
||||
r = open_executable(np, ret_path);
|
||||
if (r >= 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return RET_NERRNO(open(path, O_CLOEXEC|O_PATH));
|
||||
return open_executable(path, ret_path);
|
||||
}
|
||||
|
||||
@@ -5,4 +5,4 @@ int get_build_exec_dir(char **ret);
|
||||
|
||||
int invoke_callout_binary(const char *path, char *const argv[]);
|
||||
|
||||
int pin_callout_binary(const char *path);
|
||||
int pin_callout_binary(const char *path, char **ret_path);
|
||||
|
||||
@@ -1048,7 +1048,7 @@ int manager_new(RuntimeScope runtime_scope, ManagerTestRunFlags test_run_flags,
|
||||
}
|
||||
|
||||
if (!FLAGS_SET(test_run_flags, MANAGER_TEST_DONT_OPEN_EXECUTOR)) {
|
||||
m->executor_fd = pin_callout_binary(SYSTEMD_EXECUTOR_BINARY_PATH);
|
||||
m->executor_fd = pin_callout_binary(SYSTEMD_EXECUTOR_BINARY_PATH, /* ret_path = */ NULL);
|
||||
if (m->executor_fd < 0)
|
||||
return log_debug_errno(m->executor_fd, "Failed to pin executor binary: %m");
|
||||
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
#include "sd-event.h"
|
||||
|
||||
#include "build-path.h"
|
||||
#include "device-private.h"
|
||||
#include "device-util.h"
|
||||
#include "event-util.h"
|
||||
#include "exec-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
@@ -279,6 +281,14 @@ int udev_event_spawn(
|
||||
free_and_replace(argv[0], program);
|
||||
}
|
||||
|
||||
char *found;
|
||||
_cleanup_close_ int fd_executable = r = pin_callout_binary(argv[0], &found);
|
||||
if (r < 0)
|
||||
return log_device_error_errno(event->dev, r, "Failed to find and pin callout binary \"%s\": %m", argv[0]);
|
||||
|
||||
log_device_debug(event->dev, "Found callout binary: \"%s\".", found);
|
||||
free_and_replace(argv[0], found);
|
||||
|
||||
char **envp;
|
||||
r = device_get_properties_strv(event->dev, &envp);
|
||||
if (r < 0)
|
||||
@@ -290,7 +300,7 @@ int udev_event_spawn(
|
||||
r = pidref_safe_fork_full(
|
||||
"(spawn)",
|
||||
(int[]) { -EBADF, outpipe[WRITE_END], errpipe[WRITE_END] },
|
||||
NULL, 0,
|
||||
&fd_executable, 1,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
|
||||
&pidref);
|
||||
if (r < 0)
|
||||
@@ -298,7 +308,7 @@ int udev_event_spawn(
|
||||
"Failed to fork() to execute command '%s': %m", cmd);
|
||||
if (r == 0) {
|
||||
DEVICE_TRACE_POINT(spawn_exec, event->dev, cmd);
|
||||
execve(argv[0], argv, envp);
|
||||
(void) fexecve_or_execve(fd_executable, argv[0], argv, envp);
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user