From 4ecc87bf1cacb4514cc9bbd6a00049d3d367fe20 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 23 Mar 2025 18:35:36 -0400 Subject: [PATCH 1/3] process-util: add pidref-based version of wait_for_terminate_and_check() --- src/basic/process-util.c | 29 +++++++++++++++++++---------- src/basic/process-util.h | 2 ++ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/basic/process-util.c b/src/basic/process-util.c index ee15f72df4..df547ccada 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -916,24 +916,29 @@ int wait_for_terminate(pid_t pid, siginfo_t *status) { * A warning is emitted if the process terminates abnormally, * and also if it returns non-zero unless check_exit_code is true. */ -int wait_for_terminate_and_check(const char *name, pid_t pid, WaitFlags flags) { +int pidref_wait_for_terminate_and_check(const char *name, PidRef *pidref, WaitFlags flags) { + int r; + + if (!pidref_is_set(pidref)) + return -ESRCH; + if (pidref_is_remote(pidref)) + return -EREMOTE; + if (pidref->pid == 1 || pidref_is_self(pidref)) + return -ECHILD; + _cleanup_free_ char *buffer = NULL; - siginfo_t status; - int r, prio; - - assert(pid > 1); - if (!name) { - r = pid_get_comm(pid, &buffer); + r = pidref_get_comm(pidref, &buffer); if (r < 0) - log_debug_errno(r, "Failed to acquire process name of " PID_FMT ", ignoring: %m", pid); + log_debug_errno(r, "Failed to acquire process name of " PID_FMT ", ignoring: %m", pidref->pid); else name = buffer; } - prio = flags & WAIT_LOG_ABNORMAL ? LOG_ERR : LOG_DEBUG; + int prio = flags & WAIT_LOG_ABNORMAL ? LOG_ERR : LOG_DEBUG; - r = wait_for_terminate(pid, &status); + siginfo_t status; + r = pidref_wait_for_terminate(pidref, &status); if (r < 0) return log_full_errno(prio, r, "Failed to wait for %s: %m", strna(name)); @@ -956,6 +961,10 @@ int wait_for_terminate_and_check(const char *name, pid_t pid, WaitFlags flags) { return -EPROTO; } +int wait_for_terminate_and_check(const char *name, pid_t pid, WaitFlags flags) { + return pidref_wait_for_terminate_and_check(name, &PIDREF_MAKE_FROM_PID(pid), flags); +} + /* * Return values: * diff --git a/src/basic/process-util.h b/src/basic/process-util.h index c3b86f064f..910fc604cd 100644 --- a/src/basic/process-util.h +++ b/src/basic/process-util.h @@ -75,7 +75,9 @@ typedef enum WaitFlags { WAIT_LOG = WAIT_LOG_ABNORMAL|WAIT_LOG_NON_ZERO_EXIT_STATUS, } WaitFlags; +int pidref_wait_for_terminate_and_check(const char *name, PidRef *pidref, WaitFlags flags); int wait_for_terminate_and_check(const char *name, pid_t pid, WaitFlags flags); + int wait_for_terminate_with_timeout(pid_t pid, usec_t timeout); void sigkill_wait(pid_t pid); From 147f1d7b2615a1707daad6f990c9bbc6585141fb Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 3 Apr 2025 00:08:07 +0900 Subject: [PATCH 2/3] process-util: make wait_for_terminate() as trivial wrapper of its PidRef version --- src/basic/process-util.c | 23 ++--------------------- src/basic/process-util.h | 2 +- 2 files changed, 3 insertions(+), 22 deletions(-) diff --git a/src/basic/process-util.c b/src/basic/process-util.c index df547ccada..d3c43c3ba4 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -879,27 +879,8 @@ int get_process_umask(pid_t pid, mode_t *ret) { return parse_mode(m, ret); } -int wait_for_terminate(pid_t pid, siginfo_t *status) { - siginfo_t dummy; - - assert(pid >= 1); - - if (!status) - status = &dummy; - - for (;;) { - zero(*status); - - if (waitid(P_PID, pid, status, WEXITED) < 0) { - - if (errno == EINTR) - continue; - - return negative_errno(); - } - - return 0; - } +int wait_for_terminate(pid_t pid, siginfo_t *ret) { + return pidref_wait_for_terminate(&PIDREF_MAKE_FROM_PID(pid), ret); } /* diff --git a/src/basic/process-util.h b/src/basic/process-util.h index 910fc604cd..fd24ee41ce 100644 --- a/src/basic/process-util.h +++ b/src/basic/process-util.h @@ -65,7 +65,7 @@ static inline bool SIGINFO_CODE_IS_DEAD(int code) { return IN_SET(code, CLD_EXITED, CLD_KILLED, CLD_DUMPED); } -int wait_for_terminate(pid_t pid, siginfo_t *status); +int wait_for_terminate(pid_t pid, siginfo_t *ret); typedef enum WaitFlags { WAIT_LOG_ABNORMAL = 1 << 0, From 7207bb026945cfafb9332d370b3aad4ec7739aae Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 2 Apr 2025 23:16:05 +0900 Subject: [PATCH 3/3] udevadm-lock: use PidRef --- src/udev/udevadm-lock.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/udev/udevadm-lock.c b/src/udev/udevadm-lock.c index 78dd43ea45..9b495fda3c 100644 --- a/src/udev/udevadm-lock.c +++ b/src/udev/udevadm-lock.c @@ -232,7 +232,6 @@ int lock_main(int argc, char *argv[], void *userdata) { _cleanup_free_ dev_t *devnos = NULL; size_t n_devnos = 0; usec_t deadline; - pid_t pid; int r; r = parse_argv(argc, argv); @@ -290,7 +289,11 @@ int lock_main(int argc, char *argv[], void *userdata) { /* Ignore SIGINT and allow the forked process to receive it */ (void) ignore_signals(SIGINT); - r = safe_fork("(lock)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid); + _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL; + r = pidref_safe_fork( + "(lock)", + FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, + &pidref); if (r < 0) return r; if (r == 0) { @@ -302,5 +305,5 @@ int lock_main(int argc, char *argv[], void *userdata) { _exit(EXIT_FAILURE); } - return wait_for_terminate_and_check(arg_cmdline[0], pid, 0); + return pidref_wait_for_terminate_and_check(arg_cmdline[0], &pidref, 0); }