mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-11 05:17:44 +03:00
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:
parent
f928d3263d
commit
e10c9985bb
@ -1376,6 +1376,14 @@ static int service_load_pid_file(Service *s, bool may_warn) {
|
||||
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 (pid == s->main_pid)
|
||||
return 0;
|
||||
|
@ -513,6 +513,31 @@ char *truncate_nl(char *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) {
|
||||
const char *p;
|
||||
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);
|
||||
|
||||
char get_process_state(pid_t pid);
|
||||
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_exe(pid_t pid, char **name);
|
||||
|
Loading…
Reference in New Issue
Block a user