core: fix detection of dead processes
Commit 5ba6985b moves the UNIT_VTABLE(u)->sigchld_event before systemd
actually reaps the zombie. Which leads to service_load_pid_file accepting
zombie as a valid pid.
This fixes timeouts like:
[ 2746.602243] systemd[1]: chronyd.service stop-sigterm timed out. Killing.
[ 2836.852545] systemd[1]: chronyd.service still around after SIGKILL. Ignoring.
[ 2927.102187] systemd[1]: chronyd.service stop-final-sigterm timed out. Killing.
[ 3017.352560] systemd[1]: chronyd.service still around after final SIGKILL. Entering failed mode.
This commit is contained in:
committed by
Zbigniew Jędrzejewski-Szmek
parent
f928d3263d
commit
e10c9985bb
@@ -1376,6 +1376,14 @@ static int service_load_pid_file(Service *s, bool may_warn) {
|
|||||||
return -ESRCH;
|
return -ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (get_process_state(pid) == 'Z') {
|
||||||
|
if (may_warn)
|
||||||
|
log_info_unit(UNIT(s)->id,
|
||||||
|
"PID "PID_FMT" read from file %s is a zombie.",
|
||||||
|
pid, s->pid_file);
|
||||||
|
return -ESRCH;
|
||||||
|
}
|
||||||
|
|
||||||
if (s->main_pid_known) {
|
if (s->main_pid_known) {
|
||||||
if (pid == s->main_pid)
|
if (pid == s->main_pid)
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -513,6 +513,31 @@ char *truncate_nl(char *s) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int get_process_state(pid_t pid) {
|
||||||
|
const char *p;
|
||||||
|
char state;
|
||||||
|
int r;
|
||||||
|
_cleanup_free_ char *line = NULL;
|
||||||
|
|
||||||
|
assert(pid >= 0);
|
||||||
|
|
||||||
|
p = procfs_file_alloca(pid, "stat");
|
||||||
|
r = read_one_line_file(p, &line);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
p = strrchr(line, ')');
|
||||||
|
if (!p)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
p++;
|
||||||
|
|
||||||
|
if (sscanf(p, " %c", &state) != 1)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
return (unsigned char) state;
|
||||||
|
}
|
||||||
|
|
||||||
int get_process_comm(pid_t pid, char **name) {
|
int get_process_comm(pid_t pid, char **name) {
|
||||||
const char *p;
|
const char *p;
|
||||||
int r;
|
int r;
|
||||||
|
|||||||
@@ -238,6 +238,7 @@ char *file_in_same_dir(const char *path, const char *filename);
|
|||||||
|
|
||||||
int rmdir_parents(const char *path, const char *stop);
|
int rmdir_parents(const char *path, const char *stop);
|
||||||
|
|
||||||
|
char get_process_state(pid_t pid);
|
||||||
int get_process_comm(pid_t pid, char **name);
|
int get_process_comm(pid_t pid, char **name);
|
||||||
int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line);
|
int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line);
|
||||||
int get_process_exe(pid_t pid, char **name);
|
int get_process_exe(pid_t pid, char **name);
|
||||||
|
|||||||
Reference in New Issue
Block a user