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
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:
* 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
* 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)
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;
/*
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) {
/* 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)
/* 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;
}
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;
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;
"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)
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;
}
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;
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;
"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)
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;
}
* 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);
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)
{
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) {
}
}
- /* 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;
}
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) {
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;
/*
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) {
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)
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;
}
#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)) {