1
1
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:
Yuxuan Shui 2014-02-15 02:38:50 +08:00 committed by Zbigniew Jędrzejewski-Szmek
parent f928d3263d
commit e10c9985bb
3 changed files with 34 additions and 0 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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);