prefork.c revision 0101229a61bb9313c61fb94360f8546cfa985479
60a4b2c422dcbb08a554fb193105c08da592718bpoirier/* ====================================================================
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * The Apache Software License, Version 1.1
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * Copyright (c) 2000-2003 The Apache Software Foundation. All rights
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * reserved.
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * Redistribution and use in source and binary forms, with or without
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * modification, are permitted provided that the following conditions
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * 1. Redistributions of source code must retain the above copyright
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * notice, this list of conditions and the following disclaimer.
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * 2. Redistributions in binary form must reproduce the above copyright
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * notice, this list of conditions and the following disclaimer in
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * the documentation and/or other materials provided with the
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * distribution.
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * 3. The end-user documentation included with the redistribution,
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * if any, must include the following acknowledgment:
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * "This product includes software developed by the
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * Apache Software Foundation (http://www.apache.org/)."
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * Alternately, this acknowledgment may appear in the software itself,
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * if and wherever such third-party acknowledgments normally appear.
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * 4. The names "Apache" and "Apache Software Foundation" must
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * not be used to endorse or promote products derived from this
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * software without prior written permission. For written
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * permission, please contact apache@apache.org.
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * 5. Products derived from this software may not be called "Apache",
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * nor may "Apache" appear in their name, without prior written
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * permission of the Apache Software Foundation.
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
5cd08ee4a8f5a665e656f70048a1268a02bc0e73sf * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
5cd08ee4a8f5a665e656f70048a1268a02bc0e73sf * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * SUCH DAMAGE.
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * ====================================================================
5cd08ee4a8f5a665e656f70048a1268a02bc0e73sf * This software consists of voluntary contributions made by many
5cd08ee4a8f5a665e656f70048a1268a02bc0e73sf * individuals on behalf of the Apache Software Foundation. For more
5cd08ee4a8f5a665e656f70048a1268a02bc0e73sf * information on the Apache Software Foundation, please see
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * Portions of this software are based upon public domain software
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * originally written at the National Center for Supercomputing Applications,
5cd08ee4a8f5a665e656f70048a1268a02bc0e73sf * University of Illinois, Urbana-Champaign.
60a4b2c422dcbb08a554fb193105c08da592718bpoirier/* Limit on the total --- clients will be locked out if more servers than
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * this are needed. It is intended solely to keep the server from crashing
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * when things get out of hand.
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * We keep a hard maximum number of servers, for two reasons --- first off,
fe1c96d8f3b0c1f7e75eb8feb0170432bd91c951sf * in case something goes seriously wrong, we want to stop the fork bomb
fe1c96d8f3b0c1f7e75eb8feb0170432bd91c951sf * short of actually crashing the machine we're running on by filling some
bcb2c4ef861e8f8260284631b6753e1088643c8asf * kernel table. Secondly, it keeps the size of the scoreboard file small
bcb2c4ef861e8f8260284631b6753e1088643c8asf * enough that we can read the whole thing without worrying too much about
bcb2c4ef861e8f8260284631b6753e1088643c8asf * the overhead.
5cd08ee4a8f5a665e656f70048a1268a02bc0e73sf/* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT. We want
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * some sort of compile-time limit to help catch typos.
d474d8ef01ec5c2a09341cd148851ed383c3287crbowen/* config globals */
0236ede61169f34359c234625a1d792b97d7db12ndint ap_threads_per_child=0; /* Worker threads per child */
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * The max child slot ever assigned, preserved across restarts. Necessary
fed47023e9be04c612b5f6d4a5ee2b8e7c587181rbowen * to deal with MaxClients changes across AP_SIG_GRACEFUL restarts. We
fed47023e9be04c612b5f6d4a5ee2b8e7c587181rbowen * use this value to optimize routines that have to scan the entire scoreboard.
5cd08ee4a8f5a665e656f70048a1268a02bc0e73sf/* one_process --- debugging mode variable; can be set from the command line
5cd08ee4a8f5a665e656f70048a1268a02bc0e73sf * with the -X flag. If set, this gets you the child_main loop running
5cd08ee4a8f5a665e656f70048a1268a02bc0e73sf * in the process which originally started up (no detach, no make_child),
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * which is a pretty nice debugging environment. (You'll get a SIGHUP
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * early in standalone_main; just continue through. This is the server
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * trying to kill off any child processes which it might have lying
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * around --- Apache doesn't keep track of their pids, it just sends
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * SIGHUP to the process group, ignoring it in the root process.
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * Continue through and you'll be fine.).
60a4b2c422dcbb08a554fb193105c08da592718bpoirierstatic int one_process = 0;
5cd08ee4a8f5a665e656f70048a1268a02bc0e73sfstatic apr_pool_t *pchild; /* Pool for httpd child stuff */
60a4b2c422dcbb08a554fb193105c08da592718bpoirierstatic pid_t ap_my_pid; /* it seems silly to call getpid all the time */
60a4b2c422dcbb08a554fb193105c08da592718bpoirier#endif /* TPF */
60a4b2c422dcbb08a554fb193105c08da592718bpoirierstatic int die_now = 0;
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * change directory for gprof to plop the gmon.out file
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * configure in httpd.conf:
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * GprofDir $RuntimeDir/ -> $ServerRoot/$RuntimeDir/gmon.out
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * GprofDir $RuntimeDir/% -> $ServerRoot/$RuntimeDir/gprof.$pid/gmon.out
60a4b2c422dcbb08a554fb193105c08da592718bpoirierstatic void chdir_for_gprof(void)
60a4b2c422dcbb08a554fb193105c08da592718bpoirier ap_get_module_config(ap_server_conf->module_config, &core_module);
5cd08ee4a8f5a665e656f70048a1268a02bc0e73sf const char *use_dir;
b6529ec5115d80b7dedcfd0935746015b2096084minfrin apr_snprintf(buf, sizeof(buf), "%sgprof.%d", dir, (int)getpid());
b6529ec5115d80b7dedcfd0935746015b2096084minfrin use_dir = ap_server_root_relative(pconf, buf[0] ? buf : dir);
b6529ec5115d80b7dedcfd0935746015b2096084minfrin if(res != APR_SUCCESS && !APR_STATUS_IS_EEXIST(res)) {
b6529ec5115d80b7dedcfd0935746015b2096084minfrin ap_log_error(APLOG_MARK, APLOG_ERR, errno, ap_server_conf,
5cd08ee4a8f5a665e656f70048a1268a02bc0e73sf use_dir = ap_server_root_relative(pconf, DEFAULT_REL_RUNTIMEDIR);
b6529ec5115d80b7dedcfd0935746015b2096084minfrin/* XXX - I don't know if TPF will ever use this module or not, so leave
78f97ce162b66a0dbfd7af4dcd9984f162569b04minfrin * the ap_check_signals calls in but disable them - manoj */
78f97ce162b66a0dbfd7af4dcd9984f162569b04minfrin/* a clean exit from a child with proper cleanup */
78f97ce162b66a0dbfd7af4dcd9984f162569b04minfrinstatic void clean_child_exit(int code) __attribute__ ((noreturn));
60a4b2c422dcbb08a554fb193105c08da592718bpoirierstatic void accept_mutex_on(void)
60a4b2c422dcbb08a554fb193105c08da592718bpoirier apr_status_t rv = apr_proc_mutex_lock(accept_mutex);
60a4b2c422dcbb08a554fb193105c08da592718bpoirier ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, NULL, msg);
60a4b2c422dcbb08a554fb193105c08da592718bpoirier ap_log_error(APLOG_MARK, APLOG_EMERG, rv, NULL, msg);
5cd08ee4a8f5a665e656f70048a1268a02bc0e73sfstatic void accept_mutex_off(void)
60a4b2c422dcbb08a554fb193105c08da592718bpoirier apr_status_t rv = apr_proc_mutex_unlock(accept_mutex);
5cd08ee4a8f5a665e656f70048a1268a02bc0e73sf /* don't exit here... we have a connection to
5cd08ee4a8f5a665e656f70048a1268a02bc0e73sf * process, after which point we'll see that the
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * generation changed and we'll exit cleanly
60a4b2c422dcbb08a554fb193105c08da592718bpoirier/* On some architectures it's safe to do unserialized accept()s in the single
60a4b2c422dcbb08a554fb193105c08da592718bpoirier * Listen case. But it's never safe to do it in the case where there's
5cd08ee4a8f5a665e656f70048a1268a02bc0e73sf * multiple Listen statements. Define SINGLE_LISTEN_UNSERIALIZED_ACCEPT
5cd08ee4a8f5a665e656f70048a1268a02bc0e73sf * when it's safe in the single Listen case.
5cd08ee4a8f5a665e656f70048a1268a02bc0e73sf#define SAFE_ACCEPT(stmt) do {if (ap_listeners->next) {stmt;}} while(0)
5cd08ee4a8f5a665e656f70048a1268a02bc0e73sfAP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
68e7d4f7d80c3e5ed94185cb28100bc786e4304atrawick Systems without a real waitpid sometimes lose a child's exit while waiting
68e7d4f7d80c3e5ed94185cb28100bc786e4304atrawick for another. Search through the scoreboard for missing children.
68e7d4f7d80c3e5ed94185cb28100bc786e4304atrawickint reap_children(int *exitcode, apr_exit_why_e *status)
68e7d4f7d80c3e5ed94185cb28100bc786e4304atrawick for (n = 0; n < ap_max_daemons_limit; ++n) {
68e7d4f7d80c3e5ed94185cb28100bc786e4304atrawick if (ap_scoreboard_image->servers[n][0].status != SERVER_DEAD &&
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf kill((pid = ap_scoreboard_image->parent[n].pid), 0) == -1) {
68e7d4f7d80c3e5ed94185cb28100bc786e4304atrawick ap_update_child_status_from_indexes(n, 0, SERVER_DEAD, NULL);
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick /* just mark it as having a successful exit status */
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick/*****************************************************************
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick * Connection structures and accounting...
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick/* volatile just in case */
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawickstatic int volatile shutdown_pending;
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawickstatic int volatile restart_pending;
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawickstatic int volatile is_graceful;
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick /* Um, is this _probably_ not an error, if the user has
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick * tried to do a shutdown twice quickly, so we won't
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick * worry about reporting it.
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick/* restart() is the signal handler for SIGHUP and AP_SIG_GRACEFUL
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick * in the parent process, unless running in ONE_PROCESS mode
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick /* Probably not an error - don't bother reporting it */
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawickstatic void set_signals(void)
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGTERM)");
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGINT)");
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXCPU)");
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXFSZ)");
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGPIPE)");
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick * processing one */
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGHUP)");
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(" AP_SIG_GRACEFUL_STRING ")");
8cef90cad1b259d4a94f6095aa30439c60549a5drbowen#endif /* SIGXCPU */
8cef90cad1b259d4a94f6095aa30439c60549a5drbowen#endif /* SIGXFSZ */
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick#endif /* SIGHUP */
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick#endif /* AP_SIG_GRACEFUL */
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick#endif /* SIGPIPE */
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick/*****************************************************************
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick * Child process main loop.
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick * The following vars are static to avoid getting clobbered by longjmp();
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick * they are really private to child_main.
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawickstatic int num_listensocks = 0;
2d5f033e0b60accdc5c92470a71c6e9cd6c90803trawick /* not ever called anymore... */
60a4b2c422dcbb08a554fb193105c08da592718bpoirier /* Get a sub context for global allocations in this child, so that
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 }