prefork.c revision 776fd45d47de92104680e335bc91aecdf6d267b0
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun/* ====================================================================
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * The Apache Software License, Version 1.1
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar * Copyright (c) 2000-2002 The Apache Software Foundation. All rights
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * reserved.
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * Redistribution and use in source and binary forms, with or without
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * modification, are permitted provided that the following conditions
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * 1. Redistributions of source code must retain the above copyright
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * notice, this list of conditions and the following disclaimer.
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * 2. Redistributions in binary form must reproduce the above copyright
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * notice, this list of conditions and the following disclaimer in
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * the documentation and/or other materials provided with the
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * distribution.
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * 3. The end-user documentation included with the redistribution,
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * if any, must include the following acknowledgment:
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * "This product includes software developed by the
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * Apache Software Foundation (http://www.apache.org/)."
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * Alternately, this acknowledgment may appear in the software itself,
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * if and wherever such third-party acknowledgments normally appear.
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * 4. The names "Apache" and "Apache Software Foundation" must
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * not be used to endorse or promote products derived from this
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * software without prior written permission. For written
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * permission, please contact apache@apache.org.
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * 5. Products derived from this software may not be called "Apache",
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * nor may "Apache" appear in their name, without prior written
c1f36c839f3c21a48076fa2b7194250c53f197c5rjung * permission of the Apache Software Foundation.
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
c1f36c839f3c21a48076fa2b7194250c53f197c5rjung * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
c1f36c839f3c21a48076fa2b7194250c53f197c5rjung * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
c1f36c839f3c21a48076fa2b7194250c53f197c5rjung * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
c1f36c839f3c21a48076fa2b7194250c53f197c5rjung * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * SUCH DAMAGE.
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * ====================================================================
c1f36c839f3c21a48076fa2b7194250c53f197c5rjung * This software consists of voluntary contributions made by many
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * individuals on behalf of the Apache Software Foundation. For more
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * information on the Apache Software Foundation, please see
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * Portions of this software are based upon public domain software
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * originally written at the National Center for Supercomputing Applications,
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * University of Illinois, Urbana-Champaign.
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun#include <bstring.h> /* for IRIX, FD_SET calls bzero() */
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun/* Limit on the total --- clients will be locked out if more servers than
c1f36c839f3c21a48076fa2b7194250c53f197c5rjung * this are needed. It is intended solely to keep the server from crashing
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * when things get out of hand.
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * We keep a hard maximum number of servers, for two reasons --- first off,
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * in case something goes seriously wrong, we want to stop the fork bomb
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * short of actually crashing the machine we're running on by filling some
c1f36c839f3c21a48076fa2b7194250c53f197c5rjung * kernel table. Secondly, it keeps the size of the scoreboard file small
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * enough that we can read the whole thing without worrying too much about
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * the overhead.
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun/* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT. We want
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * some sort of compile-time limit to help catch typos.
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun/* config globals */
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgunint ap_threads_per_child=0; /* Worker threads per child */
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * The max child slot ever assigned, preserved across restarts. Necessary
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * to deal with MaxClients changes across AP_SIG_GRACEFUL restarts. We
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * use this value to optimize routines that have to scan the entire scoreboard.
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun/* one_process --- debugging mode variable; can be set from the command line
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * with the -X flag. If set, this gets you the child_main loop running
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * in the process which originally started up (no detach, no make_child),
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * which is a pretty nice debugging environment. (You'll get a SIGHUP
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * early in standalone_main; just continue through. This is the server
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * trying to kill off any child processes which it might have lying
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * around --- Apache doesn't keep track of their pids, it just sends
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * SIGHUP to the process group, ignoring it in the root process.
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * Continue through and you'll be fine.).
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgunstatic int one_process = 0;
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgunstatic apr_pool_t *pchild; /* Pool for httpd child stuff */
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgunstatic pid_t ap_my_pid; /* it seems silly to call getpid all the time */
c1f36c839f3c21a48076fa2b7194250c53f197c5rjung#endif /* TPF */
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgunstatic int die_now = 0;
c1f36c839f3c21a48076fa2b7194250c53f197c5rjung * change directory for gprof to plop the gmon.out file
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * configure in httpd.conf:
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * GprofDir $RuntimeDir/ -> $ServerRoot/$RuntimeDir/gmon.out
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * GprofDir $RuntimeDir/% -> $ServerRoot/$RuntimeDir/gprof.$pid/gmon.out
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgunstatic void chdir_for_gprof(void)
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun ap_get_module_config(ap_server_conf->module_config, &core_module);
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun const char *use_dir;
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun apr_snprintf(buf, sizeof(buf), "%sgprof.%d", dir, (int)getpid());
c1f36c839f3c21a48076fa2b7194250c53f197c5rjung use_dir = ap_server_root_relative(pconf, buf[0] ? buf : dir);
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun if(res != APR_SUCCESS && !APR_STATUS_IS_EEXIST(res)) {
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun ap_log_error(APLOG_MARK, APLOG_ERR, errno, ap_server_conf,
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun use_dir = ap_server_root_relative(pconf, DEFAULT_REL_RUNTIMEDIR);
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun/* XXX - I don't know if TPF will ever use this module or not, so leave
c1f36c839f3c21a48076fa2b7194250c53f197c5rjung * the ap_check_signals calls in but disable them - manoj */
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun/* a clean exit from a child with proper cleanup */
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgunstatic void clean_child_exit(int code) __attribute__ ((noreturn));
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgunstatic void accept_mutex_on(void)
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, NULL, msg);
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun ap_log_error(APLOG_MARK, APLOG_EMERG, rv, NULL, msg);
c1f36c839f3c21a48076fa2b7194250c53f197c5rjungstatic void accept_mutex_off(void)
c1f36c839f3c21a48076fa2b7194250c53f197c5rjung apr_status_t rv = apr_proc_mutex_unlock(accept_mutex);
c1f36c839f3c21a48076fa2b7194250c53f197c5rjung const char *msg = "couldn't release the accept mutex";
d4cd628a85e7ba869d3564684abcccd9863a3aafnilgun ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, NULL, msg);
d4cd628a85e7ba869d3564684abcccd9863a3aafnilgun /* don't exit here... we have a connection to
d4cd628a85e7ba869d3564684abcccd9863a3aafnilgun * process, after which point we'll see that the
d4cd628a85e7ba869d3564684abcccd9863a3aafnilgun * generation changed and we'll exit cleanly
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun ap_log_error(APLOG_MARK, APLOG_EMERG, rv, NULL, msg);
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun/* On some architectures it's safe to do unserialized accept()s in the single
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * Listen case. But it's never safe to do it in the case where there's
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * multiple Listen statements. Define SINGLE_LISTEN_UNSERIALIZED_ACCEPT
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun * when it's safe in the single Listen case.
ace2018fdbe2ee482163115d1544d2e2e8ce1781nilgun#define SAFE_ACCEPT(stmt) do {if (ap_listeners->next) {stmt;}} while(0)
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgunAP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
c1f36c839f3c21a48076fa2b7194250c53f197c5rjung Systems without a real waitpid sometimes lose a child's exit while waiting
c1f36c839f3c21a48076fa2b7194250c53f197c5rjung for another. Search through the scoreboard for missing children.
c1f36c839f3c21a48076fa2b7194250c53f197c5rjungint reap_children(int *exitcode, apr_exit_why_e *status)
c1f36c839f3c21a48076fa2b7194250c53f197c5rjung for (n = 0; n < ap_max_daemons_limit; ++n) {
c1f36c839f3c21a48076fa2b7194250c53f197c5rjung if (ap_scoreboard_image->servers[n][0].status != SERVER_DEAD &&
c1f36c839f3c21a48076fa2b7194250c53f197c5rjung kill((pid = ap_scoreboard_image->parent[n].pid), 0) == -1) {
c1f36c839f3c21a48076fa2b7194250c53f197c5rjung ap_update_child_status_from_indexes(n, 0, SERVER_DEAD, NULL);
c1f36c839f3c21a48076fa2b7194250c53f197c5rjung /* just mark it as having a successful exit status */
34be775b7fb103ca189f3a38979f46ce8a74ef68nilgun/* handle all varieties of core dumping signals */
0, ap_server_conf,
clean_child_exit(0);
static int volatile shutdown_pending;
static int volatile restart_pending;
static int volatile is_graceful;
static void set_signals(void)
#ifndef NO_USE_SIGACTION
if (!one_process) {
#if defined(SA_ONESHOT)
#ifdef SIGBUS
#ifdef SIGABORT
#ifdef SIGABRT
#ifdef SIGILL
#ifdef SIGINT
#ifdef SIGXCPU
#ifdef SIGXFSZ
#ifdef SIGPIPE
ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(" AP_SIG_GRACEFUL_STRING ")");
if (!one_process) {
#ifdef SIGBUS
#ifdef SIGABORT
#ifdef SIGABRT
#ifdef SIGILL
#ifdef SIGXCPU
#ifdef SIGXFSZ
#ifdef SIGHUP
#ifdef AP_SIG_GRACEFUL
#ifdef SIGPIPE
static int requests_this_child;
static int num_listensocks = 0;
int ap_graceful_stop_signalled(void)
int offset;
void *csd;
requests_this_child = 0;
if (unixd_setup_child()) {
for (i = 0; i < num_listensocks; i++) {
while (!die_now) {
if ((ap_max_requests_per_child > 0
clean_child_exit(0);
offset = 0;
apr_int32_t n;
curr_pollfd++;
curr_pollfd = 0;
goto got_fd;
current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, my_child_num, sbh, bucket_alloc);
if (current_conn) {
else if (ap_my_generation !=
clean_child_exit(0);
int pid;
if (one_process) {
#ifdef SIGQUIT
#ifdef _OSD_POSIX
if (!pid) {
#ifdef HAVE_BINDPROCESSOR
#ifndef MAX_SPAWN_RATE
static int hold_off_on_exponential_spawning;
int to_kill;
int idle_count;
int free_length;
int last_non_dead;
int total_non_dead;
free_length = 0;
idle_count = 0;
total_non_dead = 0;
for (i = 0; i < ap_daemons_limit; ++i) {
int status;
++free_length;
++ idle_count;
to_kill = i;
last_non_dead = i;
if (free_length == 0) {
static int reported = 0;
if (!reported) {
"to increase StartServers, or Min/MaxSpareServers), "
for (i = 0; i < free_length; ++i) {
#ifdef TPF
int index;
if (changed_limit_at_restart) {
if (!is_graceful) {
set_signals();
if (one_process) {
if (!is_graceful) {
int child_slot;
if (child_slot >= 0) {
else if (remaining_children_to_start
else if (is_graceful) {
0, ap_server_conf,
else if (remaining_children_to_start) {
#ifdef TPF
if (shutdown_pending) {
0, ap_server_conf,
if (one_process) {
if (is_graceful) {
pconf = p;
ap_server_conf = s;
return DONE;
return DONE;
return OK;
static int restart_num = 0;
if (debug) {
no_detach = 0;
is_graceful = 0;
return HTTP_INTERNAL_SERVER_ERROR;
ap_extended_status = 0;
return OK;
#ifdef AUX3
(void) set42sig();
return err;
return NULL;
return err;
if (ap_daemons_min_free <= 0) {
return NULL;
return err;
return NULL;
return err;
return NULL;
int tmp_server_limit;
return err;
if (first_server_limit &&
return NULL;
return NULL;
{ NULL }