[systemd-commits] src/service.c
Michal Schmidt
michich at kemper.freedesktop.org
Tue Sep 20 15:58:34 PDT 2011
src/service.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
New commits:
commit db01f8b3f870611a013b913636bb7fefaab34018
Author: Michal Schmidt <mschmidt at redhat.com>
Date: Tue Sep 20 21:43:30 2011 +0200
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.
diff --git a/src/service.c b/src/service.c
index 6f1a85e..8f827aa 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);
More information about the systemd-commits
mailing list