diff options
author | Michal Schmidt <mschmidt@redhat.com> | 2011-09-20 21:43:30 +0200 |
---|---|---|
committer | Michal Schmidt <mschmidt@redhat.com> | 2011-09-21 00:57:41 +0200 |
commit | db01f8b3f870611a013b913636bb7fefaab34018 (patch) | |
tree | 9efc3b2a929ab66e84a0c1fa707334ae28fdab7a /src/service.c | |
parent | b1db68fa60d4257d5cc84b512719dd99e856d82f (diff) |
service: handle forking services that move to a new PID
When some forking daemons receive a SIGHUP, they re-execute themselves
and consequently change to a new main PID. As long as they update the
PID file in the right order (before exiting the old PID), we can detect
that and avoid killing them.
Diffstat (limited to 'src/service.c')
-rw-r--r-- | src/service.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/src/service.c b/src/service.c index 6f1a85e943..8f827aa520 100644 --- a/src/service.c +++ b/src/service.c @@ -1269,9 +1269,6 @@ static int service_load_pid_file(Service *s) { assert(s); - if (s->main_pid_known) - return 0; - if (!s->pid_file) return 0; @@ -1290,6 +1287,16 @@ static int service_load_pid_file(Service *s) { return -ESRCH; } + if (s->main_pid_known) { + if (pid == s->main_pid) + return 0; + + log_debug("Main PID changing: %lu -> %lu", + (unsigned long) s->main_pid, (unsigned long) pid); + service_unwatch_main_pid(s); + s->main_pid_known = false; + } + if ((r = service_set_main_pid(s, pid)) < 0) return r; @@ -2575,6 +2582,11 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { success = is_clean_exit(code, status); if (s->main_pid == pid) { + /* Forking services may occasionally move to a new PID. + * As long as they update the PID file before exiting the old + * PID, they're fine. */ + if (s->pid_file && service_load_pid_file(s) == 0) + return; s->main_pid = 0; exec_status_exit(&s->main_exec_status, &s->exec_context, pid, code, status); |