[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