diff --git a/TODO b/TODO index 8b00c10344..2ad44ce70a 100644 --- a/TODO +++ b/TODO @@ -209,7 +209,6 @@ Features: - pid_is_alive() → pidref_is_alive() - is_kernel_thread() → pidref_is_kernel_thread() - pid_is_my_child() → pidref_is_my_child() - - cg_pid_get_path() → cg_pidref_get_path() - get_process_uid() → pidref_get_uid() - actually wait for POLLIN on pidref's pidfd in service logic - exec_spawn() diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index fdbb749b4e..db803084ae 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -809,6 +809,28 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **ret_path) { } } +int cg_pidref_get_path(const char *controller, PidRef *pidref, char **ret_path) { + _cleanup_free_ char *path = NULL; + int r; + + assert(ret_path); + + if (!pidref_is_set(pidref)) + return -ESRCH; + + r = cg_pid_get_path(controller, pidref->pid, &path); + if (r < 0) + return r; + + /* Before we return the path, make sure the procfs entry for this pid still matches the pidref */ + r = pidref_verify(pidref); + if (r < 0) + return r; + + *ret_path = TAKE_PTR(path); + return 0; +} + int cg_install_release_agent(const char *controller, const char *agent) { _cleanup_free_ char *fs = NULL, *contents = NULL; const char *sc; diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h index f98d222b84..625816d9cf 100644 --- a/src/basic/cgroup-util.h +++ b/src/basic/cgroup-util.h @@ -204,6 +204,7 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **fs); int cg_pid_get_path(const char *controller, pid_t pid, char **path); +int cg_pidref_get_path(const char *controller, PidRef *pidref, char **path); int cg_rmdir(const char *controller, const char *path); diff --git a/src/core/cgroup.c b/src/core/cgroup.c index a88078c570..29905b08ad 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -3784,10 +3784,7 @@ Unit *manager_get_unit_by_pidref_cgroup(Manager *m, PidRef *pid) { assert(m); - if (!pidref_is_set(pid)) - return NULL; - - if (cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid->pid, &cgroup) < 0) + if (cg_pidref_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &cgroup) < 0) return NULL; return manager_get_unit_by_cgroup(m, cgroup);