From: Mike Yuan Date: Fri, 25 Oct 2024 23:51:18 +0000 (+0200) Subject: notify: send MAINPIDFDID= for --pid= too if available X-Git-Tag: v257-rc1~110^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e2037d07c061174ed824f83bc4fe5336b8e76ada;p=thirdparty%2Fsystemd.git notify: send MAINPIDFDID= for --pid= too if available --- diff --git a/src/notify/notify.c b/src/notify/notify.c index 32bd6e6a7ae..8937457ec99 100644 --- a/src/notify/notify.c +++ b/src/notify/notify.c @@ -28,7 +28,7 @@ static bool arg_ready = false; static bool arg_reloading = false; static bool arg_stopping = false; -static pid_t arg_pid = 0; +static PidRef arg_pid = PIDREF_NULL; static const char *arg_status = NULL; static bool arg_booted = false; static uid_t arg_uid = UID_INVALID; @@ -39,6 +39,7 @@ static char **arg_exec = NULL; static FDSet *arg_fds = NULL; static char *arg_fdname = NULL; +STATIC_DESTRUCTOR_REGISTER(arg_pid, pidref_done); STATIC_DESTRUCTOR_REGISTER(arg_env, strv_freep); STATIC_DESTRUCTOR_REGISTER(arg_exec, strv_freep); STATIC_DESTRUCTOR_REGISTER(arg_fds, fdset_freep); @@ -99,16 +100,24 @@ static pid_t manager_pid(void) { return pid; } -static pid_t pid_parent_if_possible(void) { - pid_t parent_pid = getppid(); +static int pidref_parent_if_applicable(PidRef *ret) { + _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL; + int r; + + assert(ret); + + r = pidref_set_parent(&pidref); + if (r < 0) + return log_debug_errno(r, "Failed to create reference to our parent process: %m"); /* Don't send from PID 1 or the service manager's PID (which might be distinct from 1, if we are a * --user service). That'd just be confusing for the service manager. */ - if (parent_pid <= 1 || - parent_pid == manager_pid()) - return getpid_cached(); + if (pidref.pid <= 1 || + pidref.pid == manager_pid()) + return pidref_set_self(ret); - return parent_pid; + *ret = TAKE_PIDREF(pidref); + return 0; } static int parse_argv(int argc, char *argv[]) { @@ -175,17 +184,18 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_PID: + pidref_done(&arg_pid); + if (isempty(optarg) || streq(optarg, "auto")) - arg_pid = pid_parent_if_possible(); + r = pidref_parent_if_applicable(&arg_pid); else if (streq(optarg, "parent")) - arg_pid = getppid(); + r = pidref_set_parent(&arg_pid); else if (streq(optarg, "self")) - arg_pid = getpid_cached(); - else { - r = parse_pid(optarg, &arg_pid); - if (r < 0) - return log_error_errno(r, "Failed to parse PID %s.", optarg); - } + r = pidref_set_self(&arg_pid); + else + r = pidref_set_pidstr(&arg_pid, optarg); + if (r < 0) + return log_error_errno(r, "Failed to refer to --pid='%s': %m", optarg); break; @@ -276,7 +286,7 @@ static int parse_argv(int argc, char *argv[]) { if (arg_fdname && fdset_isempty(arg_fds)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No file descriptors passed, but --fdname= set, refusing."); - bool have_env = arg_ready || arg_stopping || arg_reloading || arg_status || arg_pid > 0 || !fdset_isempty(arg_fds); + bool have_env = arg_ready || arg_stopping || arg_reloading || arg_status || pidref_is_set(&arg_pid) || !fdset_isempty(arg_fds); size_t n_arg_env; if (do_exec) { @@ -326,9 +336,10 @@ static int parse_argv(int argc, char *argv[]) { } static int run(int argc, char* argv[]) { - _cleanup_free_ char *status = NULL, *cpid = NULL, *msg = NULL, *monotonic_usec = NULL, *fdn = NULL; + _cleanup_free_ char *status = NULL, *main_pid = NULL, *main_pidfd_id = NULL, *msg = NULL, + *monotonic_usec = NULL, *fdn = NULL; _cleanup_strv_free_ char **final_env = NULL; - const char *our_env[9]; + const char *our_env[10]; size_t i = 0; int r; @@ -371,11 +382,22 @@ static int run(int argc, char* argv[]) { our_env[i++] = status; } - if (arg_pid > 0) { - if (asprintf(&cpid, "MAINPID="PID_FMT, arg_pid) < 0) + if (pidref_is_set(&arg_pid)) { + if (asprintf(&main_pid, "MAINPID="PID_FMT, arg_pid.pid) < 0) return log_oom(); - our_env[i++] = cpid; + our_env[i++] = main_pid; + + r = pidref_acquire_pidfd_id(&arg_pid); + if (r < 0) + log_debug_errno(r, "Unable to acquire pidfd id of new main pid " PID_FMT ", ignoring: %m", + arg_pid.pid); + else { + if (asprintf(&main_pidfd_id, "MAINPIDFDID=%" PRIu64, arg_pid.fd_id) < 0) + return log_oom(); + + our_env[i++] = main_pidfd_id; + } } if (!fdset_isempty(arg_fds)) { @@ -415,11 +437,11 @@ static int run(int argc, char* argv[]) { /* If --pid= is explicitly specified, use it as source pid. Otherwise, pretend the message originates * from our parent, i.e. --pid=auto */ - if (arg_pid <= 0) - arg_pid = pid_parent_if_possible(); + if (!pidref_is_set(&arg_pid)) + (void) pidref_parent_if_applicable(&arg_pid); if (fdset_isempty(arg_fds)) - r = sd_pid_notify(arg_pid, /* unset_environment= */ false, msg); + r = sd_pid_notify(arg_pid.pid, /* unset_environment= */ false, msg); else { _cleanup_free_ int *a = NULL; int k; @@ -428,7 +450,7 @@ static int run(int argc, char* argv[]) { if (k < 0) return log_error_errno(k, "Failed to convert file descriptor set to array: %m"); - r = sd_pid_notify_with_fds(arg_pid, /* unset_environment= */ false, msg, a, k); + r = sd_pid_notify_with_fds(arg_pid.pid, /* unset_environment= */ false, msg, a, k); } if (r < 0) @@ -440,7 +462,7 @@ static int run(int argc, char* argv[]) { arg_fds = fdset_free(arg_fds); /* Close before we execute anything */ if (!arg_no_block) { - r = sd_pid_notify_barrier(arg_pid, /* unset_environment= */ false, 5 * USEC_PER_SEC); + r = sd_pid_notify_barrier(arg_pid.pid, /* unset_environment= */ false, 5 * USEC_PER_SEC); if (r < 0) return log_error_errno(r, "Failed to invoke barrier: %m"); if (r == 0)