]> granicus.if.org Git - apache/commitdiff
Get mod_cgid killed when a MPM exits due to a fatal error.
authorJeff Trawick <trawick@apache.org>
Sat, 17 Nov 2001 14:02:26 +0000 (14:02 +0000)
committerJeff Trawick <trawick@apache.org>
Sat, 17 Nov 2001 14:02:26 +0000 (14:02 +0000)
Presumably other such processes are affected to.  Now we
give main() a chance to clean up.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@92019 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
STATUS
include/mpm_common.h
server/mpm/beos/beos.c
server/mpm/experimental/perchild/perchild.c
server/mpm/perchild/perchild.c
server/mpm/prefork/prefork.c
server/mpm/spmt_os2/spmt_os2.c
server/mpm/threaded/threaded.c
server/mpm/worker/worker.c
server/mpm_common.c

diff --git a/CHANGES b/CHANGES
index 7785f1509c3a67bf9d34765be6c333273b4a79e2..5bddc8837a140f6242730a7cb713aa9862cb444f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,8 @@
 Changes with Apache 2.0.29-dev
 
+  *) Get mod_cgid killed when a MPM exits due to a fatal error.
+     [Jeff Trawick]
+
   *) Fix a file descriptor leak in mod_include.  When we include a
      file, we use a sub-request, but we didn't destroy the sub-request
      immediately, instead we waited until the original request was
diff --git a/STATUS b/STATUS
index 6013e849939e449e70c4e9c2c28268d27f023685..a9670ff402bc3de3a706cf405545be6c04f94cf6 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -1,5 +1,5 @@
 APACHE 2.0 STATUS:                                             -*-text-*-
-Last modified at [$Date: 2001/11/17 02:31:23 $]
+Last modified at [$Date: 2001/11/17 14:02:25 $]
 
 Release:
 
@@ -297,10 +297,6 @@ RELEASE NON-SHOWSTOPPERS BUT WOULD BE REAL NICE TO WRAP THESE UP:
     * callers of ap_run_create_request() should check the return value
       for failure (Doug volunteers)
 
-    * when a Unix MPM bails out due to an initialization error in the 
-      detached process (e.g., mutex init failure, pthread_create failure), 
-      other children (cgid, at least) are left hanging around
-
     * Win32: Get Apache working on Windows 95/98. The following work
        (at least) needs to be done:
        - winnt MPM: Fix 95/98 code paths in the winnt MPM. There is some NT
index 5f7b466296288b4a21cddc3bcbba7ecd13d8d3fd..0ce0f4fc7b4d66d7297eec8efa41fe5346d18367 100644 (file)
@@ -134,9 +134,10 @@ void ap_wait_or_timeout(apr_exit_why_e *status, int *exitcode, apr_proc_t *ret,
  * parent signalling it.
  * @param pid The child that has died
  * @param status The status returned from ap_wait_or_timeout
+ * @return 0 on success, APEXIT_CHILDFATAL if MPM should terminate
  */
 #ifdef AP_MPM_WANT_PROCESS_CHILD_STATUS
-void ap_process_child_status(apr_proc_t *pid, apr_exit_why_e why, int status);
+int ap_process_child_status(apr_proc_t *pid, apr_exit_why_e why, int status);
 #endif
 
 #if defined(TCP_NODELAY) && !defined(MPE) && !defined(TPF)
index 106d1c3ac5d7df1dbb25054d6fe47dde556829e6..f8a2be958d0dbfe36b6e3ecfab33a1dd97c0294c 100644 (file)
@@ -171,6 +171,7 @@ static void sig_coredump(int sig)
 static int volatile shutdown_pending;
 static int volatile restart_pending;
 static int volatile is_graceful;
+static int volatile child_fatal;
 ap_generation_t volatile ap_my_generation = 0;
 
 /*
@@ -610,7 +611,11 @@ static void server_main_loop(int remaining_threads_to_start)
         ap_wait_or_timeout(&exitwhy, &status, &pid, pconf);
          
         if (pid.pid >= 0) {
-            ap_process_child_status(&pid, exitwhy, status);
+            if (ap_process_child_status(&pid, exitwhy, status) == APEXIT_CHILDFATAL) {
+                shutdown_pending = 1;
+                child_fatal = 1;
+                return;
+            }
             /* non-fatal death... note that it's gone in the scoreboard. */
             child_slot = -1;
             for (i = 0; i < ap_max_child_assigned; ++i) {
@@ -887,7 +892,7 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
     /* close the UDP socket we've been using... */
     apr_socket_close(listening_sockets[0]);
 
-    if (one_process || shutdown_pending) {
+    if ((one_process || shutdown_pending) && !child_fatal) {
         const char *pidfile = NULL;
         pidfile = ap_server_root_relative (pconf, ap_pid_fname);
         if ( pidfile != NULL && unlink(pidfile) == 0)
@@ -914,9 +919,11 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
         /* use ap_reclaim_child_processes starting with SIGTERM */
         ap_reclaim_child_processes(1);
 
-        /* record the shutdown in the log */
-        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, ap_server_conf,
-            "caught SIGTERM, shutting down");
+        if (!child_fatal) {         /* already recorded */
+            /* record the shutdown in the log */
+            ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, ap_server_conf,
+                         "caught SIGTERM, shutting down");
+        }
     
         return 1;
     }
index 909567770a9bbf096f95e3de9c668d35d7279be7..385dbdae14d23dc216f5b0923aaee0a94fa9207f 100644 (file)
@@ -295,6 +295,7 @@ static void just_die(int sig)
 static int volatile shutdown_pending;
 static int volatile restart_pending;
 static int volatile is_graceful;
+static int volatile child_fatal;
 /* we don't currently track ap_my_generation, but mod_status 
  * references it so it must be defined */
 ap_generation_t volatile ap_my_generation=0;
@@ -1100,7 +1101,11 @@ static void server_main_loop(int remaining_children_to_start)
         ap_wait_or_timeout(&exitwhy, &status, &pid, pconf);
         
         if (pid.pid != -1) {
-            ap_process_child_status(&pid, exitwhy, status);
+            if (ap_process_child_status(&pid, exitwhy, status) == APEXIT_CHILDFATAL) {
+                shutdown_pending = 1;
+                child_fatal = 1;
+                return;
+            }
             /* non-fatal death... note that it's gone in the child table and
              * clean out the status table. */
             child_slot = -1;
@@ -1257,9 +1262,9 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
                          "killpg SIGTERM");
         }
         ap_reclaim_child_processes(1);         /* Start with SIGTERM */
-    
-        /* cleanup pid file on normal shutdown */
-        {
+
+        if (!child_fatal) {
+            /* cleanup pid file on normal shutdown */
             const char *pidfile = NULL;
             pidfile = ap_server_root_relative (pconf, ap_pid_fname);
             if ( pidfile != NULL && unlink(pidfile) == 0)
@@ -1267,11 +1272,10 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
                         ap_server_conf,
                         "removed PID file %s (pid=%ld)",
                         pidfile, (long)getpid());
-        }
-    
-        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0,
-                     ap_server_conf, "caught SIGTERM, shutting down");
     
+            ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0,
+                         ap_server_conf, "caught SIGTERM, shutting down");
+        }
        return 1;
     }
 
index 909567770a9bbf096f95e3de9c668d35d7279be7..385dbdae14d23dc216f5b0923aaee0a94fa9207f 100644 (file)
@@ -295,6 +295,7 @@ static void just_die(int sig)
 static int volatile shutdown_pending;
 static int volatile restart_pending;
 static int volatile is_graceful;
+static int volatile child_fatal;
 /* we don't currently track ap_my_generation, but mod_status 
  * references it so it must be defined */
 ap_generation_t volatile ap_my_generation=0;
@@ -1100,7 +1101,11 @@ static void server_main_loop(int remaining_children_to_start)
         ap_wait_or_timeout(&exitwhy, &status, &pid, pconf);
         
         if (pid.pid != -1) {
-            ap_process_child_status(&pid, exitwhy, status);
+            if (ap_process_child_status(&pid, exitwhy, status) == APEXIT_CHILDFATAL) {
+                shutdown_pending = 1;
+                child_fatal = 1;
+                return;
+            }
             /* non-fatal death... note that it's gone in the child table and
              * clean out the status table. */
             child_slot = -1;
@@ -1257,9 +1262,9 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
                          "killpg SIGTERM");
         }
         ap_reclaim_child_processes(1);         /* Start with SIGTERM */
-    
-        /* cleanup pid file on normal shutdown */
-        {
+
+        if (!child_fatal) {
+            /* cleanup pid file on normal shutdown */
             const char *pidfile = NULL;
             pidfile = ap_server_root_relative (pconf, ap_pid_fname);
             if ( pidfile != NULL && unlink(pidfile) == 0)
@@ -1267,11 +1272,10 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
                         ap_server_conf,
                         "removed PID file %s (pid=%ld)",
                         pidfile, (long)getpid());
-        }
-    
-        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0,
-                     ap_server_conf, "caught SIGTERM, shutting down");
     
+            ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0,
+                         ap_server_conf, "caught SIGTERM, shutting down");
+        }
        return 1;
     }
 
index 0d7832404bdbba92288358b57e725039a01e112e..641b613be883f653c64f87f89cd729268e367208 100644 (file)
@@ -1016,7 +1016,10 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
         * extra child
         */
        if (pid.pid != -1) {
-           ap_process_child_status(&pid, exitwhy, status);
+            if (ap_process_child_status(&pid, exitwhy, status) == APEXIT_CHILDFATAL) {
+                return 1;
+            }
+
            /* non-fatal death... note that it's gone in the scoreboard. */
            ap_sync_scoreboard_image();
            child_slot = find_child_by_pid(&pid);
index f4ad1db88174975c2e9e69f4151bd0c7bb26d703..350d852415ce12ed9fe6a936e6f4c2d806849de2 100644 (file)
@@ -297,6 +297,7 @@ static void usr1_handler(int sig)
 static int volatile shutdown_pending;
 static int volatile restart_pending;
 static int volatile is_graceful;
+static int volatile child_fatal;
 
 static void sig_term(int sig)
 {
@@ -998,7 +999,11 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
        if (tid >= 0) {
             apr_proc_t dummyproc;
             dummyproc.pid = tid;
-            ap_process_child_status(&dummyproc, status);
+            if (ap_process_child_status(&dummyproc, status) == APEXIT_CHILDFATAL) {
+                shutdown_pending = 1;
+                child_fatal = 1;
+                break;
+            }
            /* non-fatal death... note that it's gone in the scoreboard. */
            thread_slot = find_thread_by_tid(tid);
            if (thread_slot >= 0) {
@@ -1086,16 +1091,18 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
             }
         }
 
-        /* cleanup pid file on normal shutdown */
-        pidfile = ap_server_root_relative (pconf, ap_pid_fname);
-        if ( pidfile != NULL && unlink(pidfile) == 0)
-            ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0,
-                            ap_server_conf,
-                            "removed PID file %s (pid=%ld)",
-                            pidfile, (long)getpid());
-
-       ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, ap_server_conf,
-                   "caught SIGTERM, shutting down");
+        if (!child_fatal) {
+            /* cleanup pid file on normal shutdown */
+            pidfile = ap_server_root_relative (pconf, ap_pid_fname);
+            if ( pidfile != NULL && unlink(pidfile) == 0)
+                ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0,
+                             ap_server_conf,
+                             "removed PID file %s (pid=%ld)",
+                             pidfile, (long)getpid());
+            
+            ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, ap_server_conf,
+                         "caught SIGTERM, shutting down");
+        }
        return 1;
     }
 
index ad2274d650389b325a88255ca80550e9bff0f59e..4a1498f6ed42f37ec030a5459bede370b8394f42 100644 (file)
@@ -1129,7 +1129,11 @@ static void server_main_loop(int remaining_children_to_start)
         ap_wait_or_timeout(&exitwhy, &status, &pid, pconf);
         
         if (pid.pid != -1) {
-            ap_process_child_status(&pid, exitwhy, status);
+            if (ap_process_child_status(&pid, exitwhy, status) != 0) {
+                /* if we keep this MPM, somebody fix handling of APEXIT_CHILDFATAL */
+                exit(1);
+            }
+            
             /* non-fatal death... note that it's gone in the scoreboard. */
             child_slot = find_child_by_pid(&pid);
             if (child_slot >= 0) {
index 3d0c590c7d66436a64d1bb51007b8a23bb7691ea..d29e22881ca7ac62405b7e05dbb42f8b9b4a56b9 100644 (file)
@@ -300,6 +300,7 @@ static void just_die(int sig)
 static int volatile shutdown_pending;
 static int volatile restart_pending;
 static int volatile is_graceful;
+static volatile int child_fatal;
 ap_generation_t volatile ap_my_generation;
 
 /*
@@ -1178,7 +1179,11 @@ static void server_main_loop(int remaining_children_to_start)
         ap_wait_or_timeout(&exitwhy, &status, &pid, pconf);
         
         if (pid.pid != -1) {
-            ap_process_child_status(&pid, exitwhy, status);
+            if (ap_process_child_status(&pid, exitwhy, status) == APEXIT_CHILDFATAL) {
+                shutdown_pending = 1;
+                child_fatal = 1;
+                return;
+            }
             /* non-fatal death... note that it's gone in the scoreboard. */
             child_slot = find_child_by_pid(&pid);
             if (child_slot >= 0) {
@@ -1361,9 +1366,9 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "killpg SIGTERM");
         }
         ap_reclaim_child_processes(1);         /* Start with SIGTERM */
-    
-        /* cleanup pid file on normal shutdown */
-        {
+
+        if (!child_fatal) {
+            /* cleanup pid file on normal shutdown */
             const char *pidfile = NULL;
             pidfile = ap_server_root_relative (pconf, ap_pid_fname);
             if ( pidfile != NULL && unlink(pidfile) == 0)
@@ -1371,11 +1376,10 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
                         ap_server_conf,
                         "removed PID file %s (pid=%ld)",
                         pidfile, (long)getpid());
-        }
-    
-        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, ap_server_conf,
-            "caught SIGTERM, shutting down");
     
+            ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0,
+                         ap_server_conf, "caught SIGTERM, shutting down");
+        }
        return 1;
     }
 
index f066549639442051fc8c0eecbf80ff83fb6de557..e353f1c321ef8694d87e63aa23d246661cb8c2b2 100644 (file)
@@ -225,21 +225,24 @@ void ap_wait_or_timeout(apr_exit_why_e *status, int *exitcode, apr_proc_t *ret,
 #endif /* AP_MPM_WANT_WAIT_OR_TIMEOUT */
 
 #ifdef AP_MPM_WANT_PROCESS_CHILD_STATUS
-void ap_process_child_status(apr_proc_t *pid, apr_exit_why_e why, int status)
+int ap_process_child_status(apr_proc_t *pid, apr_exit_why_e why, int status)
 {
     int signum = status;
     const char *sigdesc = apr_signal_get_description(signum);
 
     /* Child died... if it died due to a fatal error,
-        * we should simply bail out.
-        */
+     * we should simply bail out.  The caller needs to
+     * check for bad rc from us and exit, running any
+     * appropriate cleanups.
+     */
     if ((APR_PROC_CHECK_EXIT(why)) &&
         (status == APEXIT_CHILDFATAL)) {
         ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, 0, ap_server_conf,
-                        "Child %ld returned a Fatal error..." APR_EOL_STR
-                        "Apache is exiting!",
-                        (long)pid->pid);
-        exit(APEXIT_CHILDFATAL);
+                     "Child %" APR_OS_PROC_T_FMT
+                     " returned a Fatal error..." APR_EOL_STR
+                     "Apache is exiting!",
+                     pid->pid);
+        return APEXIT_CHILDFATAL;
     }
 
     if (APR_PROC_CHECK_SIGNALED(why)) {