summaryrefslogtreecommitdiffstats
path: root/server/mpm/prefork
diff options
context:
space:
mode:
authorStefan Fritsch <sf@apache.org>2011-10-10 01:10:12 +0200
committerStefan Fritsch <sf@apache.org>2011-10-10 01:10:12 +0200
commit7d0348cd7881374af07999cfcb936b2b79d4e6b2 (patch)
treecccb4a1f2e3134b051559130427b5a945e7d951b /server/mpm/prefork
parentCheck the return value from ap_run_create_connection in mpm_event. (diff)
downloadapache2-7d0348cd7881374af07999cfcb936b2b79d4e6b2.tar.xz
apache2-7d0348cd7881374af07999cfcb936b2b79d4e6b2.zip
If a child is created just before graceful restart and then exits because
of a missing lock file, don't shutdown the whole server. PR: 39311 Submitted by: Shawn Michael <smichael rightnow com> git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1180742 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'server/mpm/prefork')
-rw-r--r--server/mpm/prefork/prefork.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c
index 93dd65a8e1..5c382c92c8 100644
--- a/server/mpm/prefork/prefork.c
+++ b/server/mpm/prefork/prefork.c
@@ -1004,13 +1004,28 @@ static int prefork_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
*/
if (pid.pid != -1) {
processed_status = ap_process_child_status(&pid, exitwhy, status);
+ child_slot = ap_find_child_by_pid(&pid);
if (processed_status == APEXIT_CHILDFATAL) {
- mpm_state = AP_MPMQ_STOPPING;
- return DONE;
+ /* fix race condition found in PR 39311
+ * A child created at the same time as a graceful happens
+ * can find the lock missing and create a fatal error.
+ * It is not fatal for the last generation to be in this state.
+ */
+ if (child_slot < 0
+ || ap_get_scoreboard_process(child_slot)->generation
+ == retained->my_generation) {
+ mpm_state = AP_MPMQ_STOPPING;
+ return DONE;
+ }
+ else {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ap_server_conf,
+ "Ignoring fatal error in child of previous "
+ "generation (pid %ld).",
+ (long)pid.pid);
+ }
}
/* non-fatal death... note that it's gone in the scoreboard. */
- child_slot = ap_find_child_by_pid(&pid);
if (child_slot >= 0) {
(void) ap_update_child_status_from_indexes(child_slot, 0, SERVER_DEAD,
(request_rec *) NULL);