prefork.c revision c3e233736c4a453cbb2166a041f779e86230630a
3a666413480ef97101461705e1f47cbab0266301Brendan Mmiller/* Licensed to the Apache Software Foundation (ASF) under one or more
088fa5d9eaa83bf4b3d59a64c0519f42a143aaa9Alin Brici * contributor license agreements. See the NOTICE file distributed with
3a666413480ef97101461705e1f47cbab0266301Brendan Mmiller * this work for additional information regarding copyright ownership.
3a666413480ef97101461705e1f47cbab0266301Brendan Mmiller * The ASF licenses this file to You under the Apache License, Version 2.0
3a666413480ef97101461705e1f47cbab0266301Brendan Mmiller * (the "License"); you may not use this file except in compliance with
3a666413480ef97101461705e1f47cbab0266301Brendan Mmiller * the License. You may obtain a copy of the License at
3a666413480ef97101461705e1f47cbab0266301Brendan Mmiller * http://www.apache.org/licenses/LICENSE-2.0
3a666413480ef97101461705e1f47cbab0266301Brendan Mmiller * Unless required by applicable law or agreed to in writing, software
3a666413480ef97101461705e1f47cbab0266301Brendan Mmiller * distributed under the License is distributed on an "AS IS" BASIS,
3a666413480ef97101461705e1f47cbab0266301Brendan Mmiller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3a666413480ef97101461705e1f47cbab0266301Brendan Mmiller * See the License for the specific language governing permissions and
3a666413480ef97101461705e1f47cbab0266301Brendan Mmiller * limitations under the License.
3a666413480ef97101461705e1f47cbab0266301Brendan Mmiller#include "http_core.h" /* for get_remote_host */
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller#include <sys/processor.h> /* for bindprocessor() */
a20f25a11beaf0445cc53f4d56537cef3d26281eBrendan Mmiller/* Limit on the total --- clients will be locked out if more servers than
a20f25a11beaf0445cc53f4d56537cef3d26281eBrendan Mmiller * this are needed. It is intended solely to keep the server from crashing
a20f25a11beaf0445cc53f4d56537cef3d26281eBrendan Mmiller * when things get out of hand.
3a666413480ef97101461705e1f47cbab0266301Brendan Mmiller * We keep a hard maximum number of servers, for two reasons --- first off,
3a666413480ef97101461705e1f47cbab0266301Brendan Mmiller * in case something goes seriously wrong, we want to stop the fork bomb
3a666413480ef97101461705e1f47cbab0266301Brendan Mmiller * short of actually crashing the machine we're running on by filling some
3a666413480ef97101461705e1f47cbab0266301Brendan Mmiller * kernel table. Secondly, it keeps the size of the scoreboard file small
3a666413480ef97101461705e1f47cbab0266301Brendan Mmiller * enough that we can read the whole thing without worrying too much about
80a21b2f138c5017c1d929d4879bfc686d6841ebBrendan Miller * the overhead.
3a666413480ef97101461705e1f47cbab0266301Brendan Mmiller/* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT. We want
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller * some sort of compile-time limit to help catch typos.
bfd9faff49961e9db7b92f310d59923fd6234372Brendan Mmiller/* config globals */
1865547d14d52f49a59e81d183910420f25dcecaBrendan Mmillerstatic int ap_daemons_limit=0; /* MaxClients */
typedef struct prefork_retained_data {
int first_server_limit;
int module_loads;
static int one_process = 0;
static int my_child_num;
static volatile int die_now = 0;
#ifdef GPROF
* configure in httpd.conf:
* GprofDir $RuntimeDir/ -> $ServerRoot/$RuntimeDir/gmon.out
* GprofDir $RuntimeDir/% -> $ServerRoot/$RuntimeDir/gprof.$pid/gmon.out
static void chdir_for_gprof(void)
const char *use_dir;
if(dir) {
#define chdir_for_gprof()
if (pchild) {
static void accept_mutex_on(void)
if (my_generation !=
clean_child_exit(0);
static void accept_mutex_off(void)
if (my_generation !=
switch(query_code){
case AP_MPMQ_MAX_DAEMON_USED:
case AP_MPMQ_IS_THREADED:
case AP_MPMQ_IS_FORKED:
case AP_MPMQ_MAX_THREADS:
*result = 0;
*result = 0;
*result = 0;
case AP_MPMQ_MAX_DAEMONS:
case AP_MPMQ_MPM_STATE:
case AP_MPMQ_GENERATION:
return OK;
return APR_SUCCESS;
static const char *prefork_get_name(void)
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) {
#ifndef NO_USE_SIGACTION
#ifdef AP_SIG_GRACEFUL_STOP
#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 SIGXCPU
#ifdef SIGXFSZ
#ifdef SIGHUP
#ifdef AP_SIG_GRACEFUL
#ifdef AP_SIG_GRACEFUL_STOP
#ifdef SIGPIPE
static int requests_this_child;
static int num_listensocks = 0;
#if APR_HAS_THREADS
int last_poll_idx = 0;
const char *lockfile;
requests_this_child = 0;
#if APR_HAS_THREADS
pchild);
void *csd;
if ((ap_max_requests_per_child > 0
clean_child_exit(0);
else if (die_now) {
clean_child_exit(0);
last_poll_idx = 0;
goto got_fd;
current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, my_child_num, sbh, bucket_alloc);
if (current_conn) {
#if APR_HAS_THREADS
else if (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 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;
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) {
int index;
s, _pconf, 0);
return DONE;
if (!is_graceful) {
return DONE;
set_signals();
if (one_process) {
if (!is_graceful) {
int child_slot;
return DONE;
if (child_slot >= 0) {
else if (remaining_children_to_start
else if (is_graceful) {
0, ap_server_conf,
else if (remaining_children_to_start) {
0, ap_server_conf,
return DONE;
} else if (shutdown_pending) {
int active_children;
active_children = 0;
0, ap_server_conf,
if (ap_graceful_shutdown_timeout) {
shutdown_pending = 0;
active_children = 0;
return DONE;
if (one_process) {
return DONE;
if (is_graceful) {
return OK;
int startup = 0;
int level_flags = 0;
pconf = p;
return DONE;
return DONE;
return OK;
if (debug) {
no_detach = 0;
if (!retained) {
is_graceful = 0;
return HTTP_INTERNAL_SERVER_ERROR;
ap_extended_status = 0;
return OK;
int startup = 0;
if (startup) {
if (startup) {
if (startup) {
if (startup) {
if (ap_daemons_to_start < 0) {
if (startup) {
if (startup) {
return OK;
return err;
return NULL;
return err;
return NULL;
return err;
return NULL;
return err;
return NULL;
return err;
return NULL;
{ NULL }