1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-10 16:58:28 +03:00

core: port unit/process kill logic to pidref

This commit is contained in:
Lennart Poettering 2023-10-17 10:34:00 +02:00
parent a7a877697f
commit 4d1b2df199
5 changed files with 44 additions and 33 deletions

View File

@ -291,7 +291,6 @@ static int cg_kill_items(
_cleanup_set_free_ Set *allocated_set = NULL;
bool done = false;
int r, ret = 0, ret_log_kill = 0;
pid_t my_pid;
assert(sig >= 0);
@ -310,8 +309,6 @@ static int cg_kill_items(
return -ENOMEM;
}
my_pid = getpid_cached();
do {
_cleanup_fclose_ FILE *f = NULL;
pid_t pid = 0;
@ -325,25 +322,32 @@ static int cg_kill_items(
return ret;
}
while ((r = cg_read_pid(f, &pid)) > 0) {
for (;;) {
_cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
if ((flags & CGROUP_IGNORE_SELF) && pid == my_pid)
r = cg_read_pidref(f, &pidref);
if (r < 0)
return r;
if (r == 0)
break;
if ((flags & CGROUP_IGNORE_SELF) && pidref_is_self(&pidref))
continue;
if (set_get(s, PID_TO_PTR(pid)) == PID_TO_PTR(pid))
if (set_get(s, PID_TO_PTR(pidref.pid)) == PID_TO_PTR(pidref.pid))
continue;
if (log_kill)
ret_log_kill = log_kill(pid, sig, userdata);
ret_log_kill = log_kill(&pidref, sig, userdata);
/* If we haven't killed this process yet, kill
* it */
if (kill(pid, sig) < 0) {
if (ret >= 0 && errno != ESRCH)
ret = -errno;
/* If we haven't killed this process yet, kill it */
r = pidref_kill(&pidref, sig);
if (r < 0) {
if (ret >= 0 && r != -ESRCH)
ret = r;
} else {
if (flags & CGROUP_SIGCONT)
(void) kill(pid, SIGCONT);
(void) pidref_kill(&pidref, SIGCONT);
if (ret == 0) {
if (log_kill)

View File

@ -191,7 +191,7 @@ typedef enum CGroupFlags {
CGROUP_REMOVE = 1 << 2,
} CGroupFlags;
typedef int (*cg_kill_log_func_t)(pid_t pid, int sig, void *userdata);
typedef int (*cg_kill_log_func_t)(const PidRef *pid, int sig, void *userdata);
int cg_kill(const char *path, int sig, CGroupFlags flags, Set *s, cg_kill_log_func_t kill_log, void *userdata);
int cg_kill_kernel_sigkill(const char *path);

View File

@ -4006,13 +4006,14 @@ static Set *unit_pid_set(pid_t main_pid, pid_t control_pid) {
return TAKE_PTR(pid_set);
}
static int kill_common_log(pid_t pid, int signo, void *userdata) {
static int kill_common_log(const PidRef *pid, int signo, void *userdata) {
_cleanup_free_ char *comm = NULL;
Unit *u = ASSERT_PTR(userdata);
(void) pid_get_comm(pid, &comm);
(void) pidref_get_comm(pid, &comm);
log_unit_info(u, "Sending signal SIG%s to process " PID_FMT " (%s) on client request.",
signal_to_string(signo), pid, strna(comm));
signal_to_string(signo), pid->pid, strna(comm));
return 1;
}
@ -4105,7 +4106,6 @@ int unit_kill(
if (pidref_is_set(main_pid) &&
IN_SET(who, KILL_MAIN, KILL_MAIN_FAIL, KILL_ALL, KILL_ALL_FAIL)) {
_cleanup_free_ char *comm = NULL;
(void) pidref_get_comm(main_pid, &comm);
@ -4729,10 +4729,12 @@ int unit_make_transient(Unit *u) {
return 0;
}
static int log_kill(pid_t pid, int sig, void *userdata) {
static int log_kill(const PidRef *pid, int sig, void *userdata) {
_cleanup_free_ char *comm = NULL;
(void) pid_get_comm(pid, &comm);
assert(pidref_is_set(pid));
(void) pidref_get_comm(pid, &comm);
/* Don't log about processes marked with brackets, under the assumption that these are temporary processes
only, like for example systemd's own PAM stub process. */
@ -4743,7 +4745,7 @@ static int log_kill(pid_t pid, int sig, void *userdata) {
log_unit_notice(userdata,
"Killing process " PID_FMT " (%s) with signal SIG%s.",
pid,
pid->pid,
strna(comm),
signal_to_string(sig));
@ -4815,7 +4817,7 @@ int unit_kill_context(
if (pidref_is_set(main_pid)) {
if (log_func)
log_func(main_pid->pid, sig, u);
log_func(main_pid, sig, u);
r = pidref_kill_and_sigcont(main_pid, sig);
if (r < 0 && r != -ESRCH) {
@ -4834,7 +4836,7 @@ int unit_kill_context(
if (pidref_is_set(control_pid)) {
if (log_func)
log_func(control_pid->pid, sig, u);
log_func(control_pid, sig, u);
r = pidref_kill_and_sigcont(control_pid, sig);
if (r < 0 && r != -ESRCH) {
@ -5862,10 +5864,12 @@ static bool ignore_leftover_process(const char *comm) {
return comm && comm[0] == '('; /* Most likely our own helper process (PAM?), ignore */
}
int unit_log_leftover_process_start(pid_t pid, int sig, void *userdata) {
int unit_log_leftover_process_start(const PidRef *pid, int sig, void *userdata) {
_cleanup_free_ char *comm = NULL;
(void) pid_get_comm(pid, &comm);
assert(pidref_is_set(pid));
(void) pidref_get_comm(pid, &comm);
if (ignore_leftover_process(comm))
return 0;
@ -5875,15 +5879,17 @@ int unit_log_leftover_process_start(pid_t pid, int sig, void *userdata) {
log_unit_warning(userdata,
"Found left-over process " PID_FMT " (%s) in control group while starting unit. Ignoring.\n"
"This usually indicates unclean termination of a previous run, or service implementation deficiencies.",
pid, strna(comm));
pid->pid, strna(comm));
return 1;
}
int unit_log_leftover_process_stop(pid_t pid, int sig, void *userdata) {
int unit_log_leftover_process_stop(const PidRef *pid, int sig, void *userdata) {
_cleanup_free_ char *comm = NULL;
(void) pid_get_comm(pid, &comm);
assert(pidref_is_set(pid));
(void) pidref_get_comm(pid, &comm);
if (ignore_leftover_process(comm))
return 0;
@ -5892,7 +5898,7 @@ int unit_log_leftover_process_stop(pid_t pid, int sig, void *userdata) {
log_unit_info(userdata,
"Unit process " PID_FMT " (%s) remains running after unit stopped.",
pid, strna(comm));
pid->pid, strna(comm));
return 1;
}

View File

@ -1036,8 +1036,9 @@ void unit_unlink_state_files(Unit *u);
int unit_prepare_exec(Unit *u);
int unit_log_leftover_process_start(pid_t pid, int sig, void *userdata);
int unit_log_leftover_process_stop(pid_t pid, int sig, void *userdata);
int unit_log_leftover_process_start(const PidRef* pid, int sig, void *userdata);
int unit_log_leftover_process_stop(const PidRef* pid, int sig, void *userdata);
int unit_warn_leftover_processes(Unit *u, cg_kill_log_func_t log_func);
bool unit_needs_console(Unit *u);

View File

@ -26,8 +26,8 @@ DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
OomdCGroupContext,
oomd_cgroup_context_free);
static int log_kill(pid_t pid, int sig, void *userdata) {
log_debug("oomd attempting to kill " PID_FMT " with %s", pid, signal_to_string(sig));
static int log_kill(const PidRef *pid, int sig, void *userdata) {
log_debug("oomd attempting to kill " PID_FMT " with %s", pid->pid, signal_to_string(sig));
return 0;
}