prefork.c revision 05552d1205ee9de24e6a003f2b51985f2431250d
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq/* ====================================================================
78cd48acd325773619d78ac0d7263a99a8922faend * The Apache Software License, Version 1.1
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding *
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * reserved.
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd *
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * Redistribution and use in source and binary forms, with or without
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * modification, are permitted provided that the following conditions
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * are met:
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd *
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * 1. Redistributions of source code must retain the above copyright
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * notice, this list of conditions and the following disclaimer.
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd *
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * 2. Redistributions in binary form must reproduce the above copyright
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * notice, this list of conditions and the following disclaimer in
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * the documentation and/or other materials provided with the
7708bd70088b64148d7d78fd84ede43ced63c713minfrin * distribution.
7708bd70088b64148d7d78fd84ede43ced63c713minfrin *
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * 3. The end-user documentation included with the redistribution,
36a72c96fc2dda27eadbae8a108fa428cc1419c1wrowe * if any, must include the following acknowledgment:
1723d9ccdd3b647f5b7bae44cab9ab3eca7a4874dougm * "This product includes software developed by the
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe * Apache Software Foundation (http://www.apache.org/)."
2555a6b5da21d61804f47084d8fcc98eb4acbc42wrowe * Alternately, this acknowledgment may appear in the software itself,
2555a6b5da21d61804f47084d8fcc98eb4acbc42wrowe * if and wherever such third-party acknowledgments normally appear.
70535d6421eb979ac79d8f49d31cd94d75dd8b2fjorton *
2555a6b5da21d61804f47084d8fcc98eb4acbc42wrowe * 4. The names "Apache" and "Apache Software Foundation" must
2555a6b5da21d61804f47084d8fcc98eb4acbc42wrowe * not be used to endorse or promote products derived from this
2555a6b5da21d61804f47084d8fcc98eb4acbc42wrowe * software without prior written permission. For written
2555a6b5da21d61804f47084d8fcc98eb4acbc42wrowe * permission, please contact apache@apache.org.
1723d9ccdd3b647f5b7bae44cab9ab3eca7a4874dougm *
e9501b71b8a1e76384cb010b1e41e76a1e47aacctrawick * 5. Products derived from this software may not be called "Apache",
e9501b71b8a1e76384cb010b1e41e76a1e47aacctrawick * nor may "Apache" appear in their name, without prior written
e9501b71b8a1e76384cb010b1e41e76a1e47aacctrawick * permission of the Apache Software Foundation.
6335eb31f0f0ed54628a04ed32946360b8b77684minfrin *
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * SUCH DAMAGE.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * ====================================================================
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * This software consists of voluntary contributions made by many
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * individuals on behalf of the Apache Software Foundation. For more
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * information on the Apache Software Foundation, please see
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq * <http://www.apache.org/>.
a812b025d139f465a31c76fc02ed162ed5271b03nd *
a812b025d139f465a31c76fc02ed162ed5271b03nd * Portions of this software are based upon public domain software
a812b025d139f465a31c76fc02ed162ed5271b03nd * originally written at the National Center for Supercomputing Applications,
a812b025d139f465a31c76fc02ed162ed5271b03nd * University of Illinois, Urbana-Champaign.
a812b025d139f465a31c76fc02ed162ed5271b03nd */
a812b025d139f465a31c76fc02ed162ed5271b03nd
a812b025d139f465a31c76fc02ed162ed5271b03nd/*
a812b025d139f465a31c76fc02ed162ed5271b03nd * httpd.c: simple http daemon for answering WWW file requests
a812b025d139f465a31c76fc02ed162ed5271b03nd *
a812b025d139f465a31c76fc02ed162ed5271b03nd *
a812b025d139f465a31c76fc02ed162ed5271b03nd * 03-21-93 Rob McCool wrote original code (up to NCSA HTTPd 1.3)
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq *
a812b025d139f465a31c76fc02ed162ed5271b03nd * 03-06-95 blong
00211b036b78699ace57a6d800a52e6c2d57652fnd * changed server number for child-alone processes to 0 and changed name
00211b036b78699ace57a6d800a52e6c2d57652fnd * of processes
00211b036b78699ace57a6d800a52e6c2d57652fnd *
a812b025d139f465a31c76fc02ed162ed5271b03nd * 03-10-95 blong
a812b025d139f465a31c76fc02ed162ed5271b03nd * Added numerous speed hacks proposed by Robert S. Thau (rst@ai.mit.edu)
a812b025d139f465a31c76fc02ed162ed5271b03nd * including set group before fork, and call gettime before to fork
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq * to set up libraries.
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq *
a812b025d139f465a31c76fc02ed162ed5271b03nd * 04-14-95 rst / rh
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe * Brandon's code snarfed from NCSA 1.4, but tinkered to work with the
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe * Apache server, and also to have child processes do accept() directly.
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe *
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe * April-July '95 rst
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe * Extensive rework for Apache.
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe */
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe/* TODO: this is a cobbled together prefork MPM example... it should mostly
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe * TODO: behave like apache-1.3... here's a short list of things I think
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe * TODO: need cleaning up still:
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe */
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#include "apr.h"
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#include "apr_portable.h"
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#include "apr_strings.h"
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#include "apr_thread_proc.h"
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#include "apr_signal.h"
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#define APR_WANT_STDIO
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#define APR_WANT_STRFUNC
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe#include "apr_want.h"
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#if APR_HAVE_UNISTD_H
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#include <unistd.h>
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#endif
c1c0628ca9788908a5fc7502d04a89c348b75ee6wrowe#if APR_HAVE_SYS_TYPES_H
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#include <sys/types.h>
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#endif
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#define CORE_PRIVATE
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe#include "ap_config.h"
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#include "httpd.h"
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#include "mpm_default.h"
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#include "http_main.h"
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#include "http_log.h"
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#include "http_config.h"
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe#include "http_core.h" /* for get_remote_host */
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#include "http_connection.h"
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#include "scoreboard.h"
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#include "ap_mpm.h"
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#include "unixd.h"
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#include "mpm_common.h"
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe#include "ap_listen.h"
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#include "ap_mmn.h"
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#ifdef HAVE_BSTRING_H
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#include <bstring.h> /* for IRIX, FD_SET calls bzero() */
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#endif
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#ifdef HAVE_TIME_H
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe#include <time.h>
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe#endif
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe
9621e4c4056383e4a2b844b14687bae500b33a82wrowe#include <signal.h>
9621e4c4056383e4a2b844b14687bae500b33a82wrowe#include <sys/times.h>
9621e4c4056383e4a2b844b14687bae500b33a82wrowe
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe/* config globals */
9621e4c4056383e4a2b844b14687bae500b33a82wrowe
9621e4c4056383e4a2b844b14687bae500b33a82wroweint ap_threads_per_child=0; /* Worker threads per child */
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowestatic int ap_max_requests_per_child=0;
4c67ef499845a08771e81254ce6eb2324a160bc7wrowestatic const char *ap_pid_fname=NULL;
4c67ef499845a08771e81254ce6eb2324a160bc7wrowestatic apr_lock_t *accept_lock;
4c67ef499845a08771e81254ce6eb2324a160bc7wrowestatic const char *ap_lock_fname;
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowestatic int ap_daemons_to_start=0;
4c67ef499845a08771e81254ce6eb2324a160bc7wrowestatic int ap_daemons_min_free=0;
4c67ef499845a08771e81254ce6eb2324a160bc7wrowestatic int ap_daemons_max_free=0;
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowestatic int ap_daemons_limit=0;
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe/*
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe * The max child slot ever assigned, preserved across restarts. Necessary
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe * to deal with MaxClients changes across SIGWINCH restarts. We use this
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe * value to optimize routines that have to scan the entire scoreboard.
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe */
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wroweint ap_max_daemons_limit = -1;
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wroweserver_rec *ap_server_conf;
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowechar ap_coredump_dir[MAX_STRING_LEN];
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe/* *Non*-shared http_main globals... */
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe
41c38e78e8e5dc73544571cc2b749d40869e84fawrowestatic apr_socket_t *sd;
41c38e78e8e5dc73544571cc2b749d40869e84fawrowestatic fd_set listenfds;
41c38e78e8e5dc73544571cc2b749d40869e84fawrowestatic int listenmaxfd;
41c38e78e8e5dc73544571cc2b749d40869e84fawrowe
41c38e78e8e5dc73544571cc2b749d40869e84fawrowe/* one_process --- debugging mode variable; can be set from the command line
41c38e78e8e5dc73544571cc2b749d40869e84fawrowe * with the -X flag. If set, this gets you the child_main loop running
41c38e78e8e5dc73544571cc2b749d40869e84fawrowe * in the process which originally started up (no detach, no make_child),
41c38e78e8e5dc73544571cc2b749d40869e84fawrowe * which is a pretty nice debugging environment. (You'll get a SIGHUP
41c38e78e8e5dc73544571cc2b749d40869e84fawrowe * early in standalone_main; just continue through. This is the server
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe * trying to kill off any child processes which it might have lying
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe * around --- Apache doesn't keep track of their pids, it just sends
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe * SIGHUP to the process group, ignoring it in the root process.
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe * Continue through and you'll be fine.).
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe */
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe
4415d997ac73262e513c0a571bd5be4f609040bawrowestatic int one_process = 0;
4415d997ac73262e513c0a571bd5be4f609040bawrowe
4415d997ac73262e513c0a571bd5be4f609040bawrowestatic apr_pool_t *pconf; /* Pool for config stuff */
4415d997ac73262e513c0a571bd5be4f609040bawrowestatic apr_pool_t *pchild; /* Pool for httpd child stuff */
4415d997ac73262e513c0a571bd5be4f609040bawrowe
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowestatic pid_t ap_my_pid; /* it seems silly to call getpid all the time */
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe#ifndef MULTITHREAD
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowestatic int my_child_num;
4415d997ac73262e513c0a571bd5be4f609040bawrowe#endif
4415d997ac73262e513c0a571bd5be4f609040bawrowe
4415d997ac73262e513c0a571bd5be4f609040bawrowe#ifdef TPF
4415d997ac73262e513c0a571bd5be4f609040bawroweint tpf_child = 0;
4415d997ac73262e513c0a571bd5be4f609040bawrowechar tpf_server_name[INETD_SERVNAME_LENGTH+1];
4415d997ac73262e513c0a571bd5be4f609040bawrowe#endif /* TPF */
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe
4415d997ac73262e513c0a571bd5be4f609040bawrowe#ifdef GPROF
4415d997ac73262e513c0a571bd5be4f609040bawrowe/*
4415d997ac73262e513c0a571bd5be4f609040bawrowe * change directory for gprof to plop the gmon.out file
4415d997ac73262e513c0a571bd5be4f609040bawrowe * configure in httpd.conf:
4415d997ac73262e513c0a571bd5be4f609040bawrowe * GprofDir logs/ -> $ServerRoot/logs/gmon.out
4415d997ac73262e513c0a571bd5be4f609040bawrowe * GprofDir logs/% -> $ServerRoot/logs/gprof.$pid/gmon.out
4415d997ac73262e513c0a571bd5be4f609040bawrowe */
4415d997ac73262e513c0a571bd5be4f609040bawrowestatic void chdir_for_gprof(void)
4415d997ac73262e513c0a571bd5be4f609040bawrowe{
4415d997ac73262e513c0a571bd5be4f609040bawrowe core_server_config *sconf =
4415d997ac73262e513c0a571bd5be4f609040bawrowe ap_get_module_config(ap_server_conf->module_config, &core_module);
4415d997ac73262e513c0a571bd5be4f609040bawrowe char *dir = sconf->gprof_dir;
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe const char *use_dir;
4415d997ac73262e513c0a571bd5be4f609040bawrowe
4415d997ac73262e513c0a571bd5be4f609040bawrowe if(dir) {
4415d997ac73262e513c0a571bd5be4f609040bawrowe apr_status_t res;
4415d997ac73262e513c0a571bd5be4f609040bawrowe char buf[512];
4415d997ac73262e513c0a571bd5be4f609040bawrowe int len = strlen(sconf->gprof_dir) - 1;
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe if(*(dir + len) == '%') {
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe dir[len] = '\0';
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe apr_snprintf(buf, sizeof(buf), "%sgprof.%d", dir, (int)getpid());
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding use_dir = ap_server_root_relative(pconf, buf[0] ? buf : dir);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding res = apr_dir_make(use_dir, 0755, pconf);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if(res != APR_SUCCESS && !APR_STATUS_IS_EEXIST(res)) {
00211b036b78699ace57a6d800a52e6c2d57652fnd ap_log_error(APLOG_MARK, APLOG_ERR, errno, ap_server_conf,
a812b025d139f465a31c76fc02ed162ed5271b03nd "gprof: error creating directory %s", dir);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
00211b036b78699ace57a6d800a52e6c2d57652fnd }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard else {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard use_dir = ap_server_root_relative(pconf, "logs");
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard chdir(dir);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard}
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard#else
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard#define chdir_for_gprof()
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard#endif
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard/* XXX - I don't know if TPF will ever use this module or not, so leave
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard * the ap_check_signals calls in but disable them - manoj */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard#define ap_check_signals()
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard/* a clean exit from a child with proper cleanup */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddardstatic void clean_child_exit(int code) __attribute__ ((noreturn));
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddardstatic void clean_child_exit(int code)
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq{
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq if (pchild) {
a812b025d139f465a31c76fc02ed162ed5271b03nd apr_pool_destroy(pchild);
a812b025d139f465a31c76fc02ed162ed5271b03nd }
a812b025d139f465a31c76fc02ed162ed5271b03nd ap_scoreboard_image->servers[my_child_num][0].life_status = SB_WORKING;
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq chdir_for_gprof();
a812b025d139f465a31c76fc02ed162ed5271b03nd exit(code);
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq}
a812b025d139f465a31c76fc02ed162ed5271b03nd
a812b025d139f465a31c76fc02ed162ed5271b03ndstatic void expand_lock_fname(apr_pool_t *p)
a812b025d139f465a31c76fc02ed162ed5271b03nd{
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq /* XXXX possibly bogus cast */
a812b025d139f465a31c76fc02ed162ed5271b03nd ap_lock_fname = apr_psprintf(p, "%s.%lu",
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq ap_server_root_relative(p, ap_lock_fname), (unsigned long)getpid());
a812b025d139f465a31c76fc02ed162ed5271b03nd}
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq/* Initialize mutex lock.
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq * Done by each child at its birth
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard */
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic void accept_mutex_child_init(apr_pool_t *p)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
00211b036b78699ace57a6d800a52e6c2d57652fnd apr_status_t rv;
00211b036b78699ace57a6d800a52e6c2d57652fnd
00211b036b78699ace57a6d800a52e6c2d57652fnd rv = apr_lock_child_init(&accept_lock, ap_lock_fname, p);
00211b036b78699ace57a6d800a52e6c2d57652fnd if (rv) {
00211b036b78699ace57a6d800a52e6c2d57652fnd ap_log_error(APLOG_MARK, APLOG_EMERG, rv, NULL,
00211b036b78699ace57a6d800a52e6c2d57652fnd "couldn't do child init for accept mutex");
00211b036b78699ace57a6d800a52e6c2d57652fnd clean_child_exit(APEXIT_CHILDINIT);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
50b2d068ddf98cf75622a0020cd143d379d1b235jfclere}
50b2d068ddf98cf75622a0020cd143d379d1b235jfclere
50b2d068ddf98cf75622a0020cd143d379d1b235jfclere/* Initialize mutex lock.
50b2d068ddf98cf75622a0020cd143d379d1b235jfclere * Must be safe to call this on a restart.
50b2d068ddf98cf75622a0020cd143d379d1b235jfclere */
50b2d068ddf98cf75622a0020cd143d379d1b235jfclerestatic void accept_mutex_init(apr_pool_t *p)
50b2d068ddf98cf75622a0020cd143d379d1b235jfclere{
00211b036b78699ace57a6d800a52e6c2d57652fnd apr_status_t rv;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard expand_lock_fname(p);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding rv = apr_lock_create(&accept_lock, APR_MUTEX, APR_CROSS_PROCESS, ap_lock_fname, p);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (rv) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_error(APLOG_MARK, APLOG_EMERG, rv, NULL, "couldn't create accept mutex");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding exit(APEXIT_INIT);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic void accept_mutex_on(void)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_status_t rv = apr_lock_acquire(accept_lock);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (rv != APR_SUCCESS) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_error(APLOG_MARK, APLOG_EMERG, rv, NULL, "couldn't grab the accept mutex");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding exit(APEXIT_CHILDFATAL);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic void accept_mutex_off(void)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_status_t rv = apr_lock_release(accept_lock);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (rv != APR_SUCCESS) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_error(APLOG_MARK, APLOG_EMERG, rv, NULL, "couldn't release the accept mutex");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding exit(APEXIT_CHILDFATAL);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq}
a812b025d139f465a31c76fc02ed162ed5271b03nd
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq/* On some architectures it's safe to do unserialized accept()s in the single
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq * Listen case. But it's never safe to do it in the case where there's
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq * multiple Listen statements. Define SINGLE_LISTEN_UNSERIALIZED_ACCEPT
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq * when it's safe in the single Listen case.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
16d38ac65d7e54cd44eeda7b23f84ee68b35094ewrowe#ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT
16d38ac65d7e54cd44eeda7b23f84ee68b35094ewrowe#define SAFE_ACCEPT(stmt) do {if (ap_listeners->next) {stmt;}} while(0)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#else
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard#define SAFE_ACCEPT(stmt) do {stmt;} while(0)
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard#endif
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddardAP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard{
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard switch(query_code){
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard case AP_MPMQ_MAX_DAEMONS:
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard *result = ap_daemons_limit;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return APR_SUCCESS;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard case AP_MPMQ_IS_THREADED:
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *result = AP_MPMQ_NOT_SUPPORTED;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return APR_SUCCESS;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding case AP_MPMQ_IS_FORKED:
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *result = AP_MPMQ_DYNAMIC;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return APR_SUCCESS;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard case AP_MPMQ_HARD_LIMIT_DAEMONS:
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard *result = HARD_SERVER_LIMIT;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return APR_SUCCESS;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard case AP_MPMQ_HARD_LIMIT_THREADS:
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard *result = HARD_THREAD_LIMIT;
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq return APR_SUCCESS;
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq case AP_MPMQ_MAX_THREADS:
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq *result = 0;
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq return APR_SUCCESS;
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq }
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq return APR_ENOTIMPL;
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq}
a812b025d139f465a31c76fc02ed162ed5271b03nd
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq#if defined(NEED_WAITPID)
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq/*
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq Systems without a real waitpid sometimes lose a child's exit while waiting
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq for another. Search through the scoreboard for missing children.
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq */
33cb45dc8c5106018b7c2f6ae42478b109423e0eniqint reap_children(apr_wait_t *status)
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding int n, pid;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding for (n = 0; n < ap_max_daemons_limit; ++n) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_sync_scoreboard_image();
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (ap_scoreboard_image->servers[n][0].status != SERVER_DEAD &&
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding kill((pid = ap_scoreboard_image->parent[n].pid), 0) == -1) {
134330b92fbc39045b7e56654f4c252fb7c53803nd ap_update_child_status(AP_CHILD_THREAD_FROM_ID(n), SERVER_DEAD, NULL);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* just mark it as having a successful exit status */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding memset(status, 0, sizeof(apr_wait_t));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return(pid);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
134330b92fbc39045b7e56654f4c252fb7c53803nd return 0;
a812b025d139f465a31c76fc02ed162ed5271b03nd}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#endif
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard/* handle all varieties of core dumping signals */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddardstatic void sig_coredump(int sig)
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding chdir(ap_coredump_dir);
a812b025d139f465a31c76fc02ed162ed5271b03nd apr_signal(sig, SIG_DFL);
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq kill(getpid(), sig);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* At this point we've got sig blocked, because we're still inside
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * the signal handler. When we leave the signal handler it will
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * be unblocked, and we'll take the signal... and coredump or whatever
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * is appropriate for this particular Unix. In addition the parent
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * will see the real signal we received -- whereas if we called
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * abort() here, the parent would only see SIGABRT.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard}
11c3b5180e1de6776035320b012a28bb146e7b46chuck
a812b025d139f465a31c76fc02ed162ed5271b03nd/*****************************************************************
22d348febc3c258df246ac93e37945398dbf0348ianh * Connection structures and accounting...
22d348febc3c258df246ac93e37945398dbf0348ianh */
22d348febc3c258df246ac93e37945398dbf0348ianh
1ccd992d37d62c8cb2056126f2234f64ec189bfddougmstatic void just_die(int sig)
a812b025d139f465a31c76fc02ed162ed5271b03nd{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding clean_child_exit(0);
1d7f1b96b49dafbd6cb414fb709cb85de2686a72chuck}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddardstatic void please_die_gracefully(int sig)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq /* clean_child_exit(0); */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_scoreboard_image->servers[my_child_num][0].life_status = SB_IDLE_DIE;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (sig == SIGHUP) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(my_child_num),
9b3001f2097437c3c605d29e353fda5131b9952bminfrin SERVER_GRACEFUL, (request_rec *) NULL);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe else {
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(my_child_num),
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe SERVER_IDLE_KILL, (request_rec *) NULL);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe}
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe/* volatile just in case */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddardstatic int volatile shutdown_pending;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddardstatic int volatile restart_pending;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddardstatic int volatile is_graceful;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwroweap_generation_t volatile ap_my_generation=0;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowestatic void sig_term(int sig)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe{
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (shutdown_pending == 1) {
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe /* Um, is this _probably_ not an error, if the user has
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe * tried to do a shutdown twice quickly, so we won't
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe * worry about reporting it.
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe */
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe shutdown_pending = 1;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe}
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowestatic void restart(int sig)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe{
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (restart_pending == 1) {
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe /* Probably not an error - don't bother reporting it */
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe restart_pending = 1;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if ((is_graceful = (sig == SIGWINCH))) {
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe apr_pool_cleanup_kill(pconf, NULL, ap_cleanup_scoreboard);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe}
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowestatic void set_signals(void)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe{
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe#ifndef NO_USE_SIGACTION
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe struct sigaction sa;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe sigemptyset(&sa.sa_mask);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe sa.sa_flags = 0;
8632261c895a84c88ae6ade6ea4c62b27bd22b3ebrianp
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (!one_process) {
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe sa.sa_handler = sig_coredump;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe#if defined(SA_ONESHOT)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe sa.sa_flags = SA_ONESHOT;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe#elif defined(SA_RESETHAND)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe sa.sa_flags = SA_RESETHAND;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe#endif
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (sigaction(SIGSEGV, &sa, NULL) < 0)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGSEGV)");
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe#ifdef SIGBUS
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (sigaction(SIGBUS, &sa, NULL) < 0)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGBUS)");
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq#endif
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#ifdef SIGABORT
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (sigaction(SIGABORT, &sa, NULL) < 0)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGABORT)");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#endif
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#ifdef SIGABRT
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (sigaction(SIGABRT, &sa, NULL) < 0)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGABRT)");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#endif
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#ifdef SIGILL
68ce856106f153813339db8670f6cd0ab8dea484minfrin if (sigaction(SIGILL, &sa, NULL) < 0)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGILL)");
45dac0729754e413ff7c673481b219e9ab1a11f1bnicholes#endif
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard sa.sa_flags = 0;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq sa.sa_handler = sig_term;
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq if (sigaction(SIGTERM, &sa, NULL) < 0)
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGTERM)");
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq#ifdef SIGINT
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq if (sigaction(SIGINT, &sa, NULL) < 0)
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGINT)");
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq#endif
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq#ifdef SIGXCPU
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq sa.sa_handler = SIG_DFL;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (sigaction(SIGXCPU, &sa, NULL) < 0)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXCPU)");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#endif
68ce856106f153813339db8670f6cd0ab8dea484minfrin#ifdef SIGXFSZ
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin sa.sa_handler = SIG_DFL;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (sigaction(SIGXFSZ, &sa, NULL) < 0)
68ce856106f153813339db8670f6cd0ab8dea484minfrin ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXFSZ)");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#endif
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#ifdef SIGPIPE
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding sa.sa_handler = SIG_IGN;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (sigaction(SIGPIPE, &sa, NULL) < 0)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGPIPE)");
11c3b5180e1de6776035320b012a28bb146e7b46chuck#endif
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq /* we want to ignore HUPs and WINCH while we're busy processing one */
11c3b5180e1de6776035320b012a28bb146e7b46chuck sigaddset(&sa.sa_mask, SIGHUP);
11c3b5180e1de6776035320b012a28bb146e7b46chuck sigaddset(&sa.sa_mask, SIGWINCH);
11c3b5180e1de6776035320b012a28bb146e7b46chuck sa.sa_handler = restart;
11c3b5180e1de6776035320b012a28bb146e7b46chuck if (sigaction(SIGHUP, &sa, NULL) < 0)
11c3b5180e1de6776035320b012a28bb146e7b46chuck ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGHUP)");
11c3b5180e1de6776035320b012a28bb146e7b46chuck if (sigaction(SIGWINCH, &sa, NULL) < 0)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGWINCH)");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#else
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (!one_process) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_signal(SIGSEGV, sig_coredump);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#ifdef SIGBUS
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_signal(SIGBUS, sig_coredump);
d7387fcd4969206172e3a2a8bbcd25a3d7011ac5rbb#endif /* SIGBUS */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard#ifdef SIGABORT
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_signal(SIGABORT, sig_coredump);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#endif /* SIGABORT */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#ifdef SIGABRT
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_signal(SIGABRT, sig_coredump);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard#endif /* SIGABRT */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#ifdef SIGILL
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm apr_signal(SIGILL, sig_coredump);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#endif /* SIGILL */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#ifdef SIGXCPU
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_signal(SIGXCPU, SIG_DFL);
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm#endif /* SIGXCPU */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard#ifdef SIGXFSZ
b999f6ba2a266bf9a92687f31bb7e76021ac5891ianh apr_signal(SIGXFSZ, SIG_DFL);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard#endif /* SIGXFSZ */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm apr_signal(SIGTERM, sig_term);
1cde33c7e2019830f8fb3224e01649305583916etrawick#ifdef SIGHUP
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard apr_signal(SIGHUP, restart);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard#endif /* SIGHUP */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard#ifdef SIGWINCH
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard apr_signal(SIGWINCH, restart);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#endif /* SIGWINCH */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#ifdef SIGPIPE
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_signal(SIGPIPE, SIG_IGN);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#endif /* SIGPIPE */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#endif
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/*****************************************************************
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * Child process main loop.
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb * The following vars are static to avoid getting clobbered by longjmp();
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * they are really private to child_main.
5babe00918c88eda487771fa6d6d4a1a19c0ced0chuck */
5babe00918c88eda487771fa6d6d4a1a19c0ced0chuck
1ccd992d37d62c8cb2056126f2234f64ec189bfddougmstatic int srv;
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic apr_socket_t *csd;
2e41eca72bcc4167d1871b0941ee79845540d58eminfrinstatic int requests_this_child;
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic fd_set main_fds;
35c9e4d2c0a6465746a98958ef756114834461e6minfrin
35c9e4d2c0a6465746a98958ef756114834461e6minfrin#define I_AM_TO_SHUTDOWN() \
5a5a6c22260854843c973e2ea9a14bec64362ab5wrowe(ap_scoreboard_image->servers[my_child_num][0].life_status != SB_WORKING)
d75bc22ab2702fa770f6935f07107efff16a76f0wrowe
11c3b5180e1de6776035320b012a28bb146e7b46chuckint ap_graceful_stop_signalled(void)
35c9e4d2c0a6465746a98958ef756114834461e6minfrin{
45dac0729754e413ff7c673481b219e9ab1a11f1bnicholes /* not ever called anymore... */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return 0;
11c3b5180e1de6776035320b012a28bb146e7b46chuck}
35c9e4d2c0a6465746a98958ef756114834461e6minfrin
35c9e4d2c0a6465746a98958ef756114834461e6minfrin
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddardstatic void child_main(int child_num_arg)
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard{
e2b2e15108eb7cb566b1d70ce4e479276d951de5minfrin ap_listen_rec *lr;
e2b2e15108eb7cb566b1d70ce4e479276d951de5minfrin ap_listen_rec *last_lr;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard ap_listen_rec *first_lr;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard apr_pool_t *ptrans;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard conn_rec *current_conn;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard apr_status_t stat = APR_EINIT;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard int sockdes;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard my_child_num = child_num_arg;
e2b2e15108eb7cb566b1d70ce4e479276d951de5minfrin ap_my_pid = getpid();
e2b2e15108eb7cb566b1d70ce4e479276d951de5minfrin csd = NULL;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard requests_this_child = 0;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard last_lr = NULL;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /* Get a sub context for global allocations in this child, so that
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard * we can have cleanups occur when the child exits.
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard apr_pool_create(&pchild, pconf);
e2b2e15108eb7cb566b1d70ce4e479276d951de5minfrin
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard apr_pool_create(&ptrans, pchild);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /* needs to be done before we switch UIDs so we have permissions */
e2b2e15108eb7cb566b1d70ce4e479276d951de5minfrin reopen_scoreboard(pchild);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard SAFE_ACCEPT(accept_mutex_child_init(pchild));
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (unixd_setup_child()) {
35c9e4d2c0a6465746a98958ef756114834461e6minfrin clean_child_exit(APEXIT_CHILDFATAL);
35c9e4d2c0a6465746a98958ef756114834461e6minfrin }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard ap_run_child_init(pchild, ap_server_conf);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
3d350b6e1cb11fa790a6adb428856b5dd9857fecianh (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(my_child_num), SERVER_READY, (request_rec *) NULL);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_signal(SIGHUP, please_die_gracefully);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_sync_scoreboard_image();
409f0f53a83313c59f1b227ed0a340adc1081e88wrowe while (!I_AM_TO_SHUTDOWN()) {
409f0f53a83313c59f1b227ed0a340adc1081e88wrowe
409f0f53a83313c59f1b227ed0a340adc1081e88wrowe /* Prepare to receive a SIGWINCH due to graceful restart so that
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard * we can exit cleanly.
409f0f53a83313c59f1b227ed0a340adc1081e88wrowe */
5babe00918c88eda487771fa6d6d4a1a19c0ced0chuck apr_signal(SIGWINCH, please_die_gracefully);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_signal(SIGTERM, just_die);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /*
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard * (Re)initialize this child to a pre-connection state.
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding current_conn = NULL;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm apr_pool_clear(ptrans);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if ((ap_max_requests_per_child > 0
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding && requests_this_child++ >= ap_max_requests_per_child)) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding clean_child_exit(0);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(my_child_num), SERVER_READY, (request_rec *) NULL);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /*
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * Wait for an acceptable connection to arrive.
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /* Lock around "accept", if necessary */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding SAFE_ACCEPT(accept_mutex_on());
1cde33c7e2019830f8fb3224e01649305583916etrawick
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard for (;;) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (ap_listeners->next) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* more than one socket */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding memcpy(&main_fds, &listenfds, sizeof(fd_set));
002bcf949b064d7c042465d1095cafcfc6c9b701wrowe srv = select(listenmaxfd + 1, &main_fds, NULL, NULL, NULL);
d75bc22ab2702fa770f6935f07107efff16a76f0wrowe
002bcf949b064d7c042465d1095cafcfc6c9b701wrowe if (srv < 0 && errno != EINTR) {
002bcf949b064d7c042465d1095cafcfc6c9b701wrowe /* Single Unix documents select as returning errnos
d75bc22ab2702fa770f6935f07107efff16a76f0wrowe * EBADF, EINTR, and EINVAL... and in none of those
002bcf949b064d7c042465d1095cafcfc6c9b701wrowe * cases does it make sense to continue. In fact
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin * on Linux 2.0.x we seem to end up with EFAULT
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin * occasionally, and we'd loop forever due to it.
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard */
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb ap_log_error(APLOG_MARK, APLOG_ERR, errno, ap_server_conf, "select: (listen)");
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard clean_child_exit(1);
9379749d811388a7d0e3410940ddd6743a33d330jim }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (srv <= 0)
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard continue;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /* we remember the last_lr we searched last time around so that
1cde33c7e2019830f8fb3224e01649305583916etrawick we don't end up starving any particular listening socket */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (last_lr == NULL) {
446c6a9a1e1073798258f1237f8c848b5f917b66wrowe lr = ap_listeners;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard else {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard lr = last_lr->next;
c1c0628ca9788908a5fc7502d04a89c348b75ee6wrowe if (!lr)
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard lr = ap_listeners;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard first_lr=lr;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard do {
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin apr_os_sock_get(&sockdes, lr->sd);
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin if (FD_ISSET(sockdes, &main_fds))
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin goto got_listener;
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin lr = lr->next;
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin if (!lr)
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin lr = ap_listeners;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding while (lr != first_lr);
1cde33c7e2019830f8fb3224e01649305583916etrawick /* FIXME: if we get here, something bad has happened, and we're
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard probably gonna spin forever.
446c6a9a1e1073798258f1237f8c848b5f917b66wrowe */
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin continue;
1cde33c7e2019830f8fb3224e01649305583916etrawick got_listener:
6bdb2c094666367615890147775bb18761216c8dminfrin last_lr = lr;
6bdb2c094666367615890147775bb18761216c8dminfrin sd = lr->sd;
6bdb2c094666367615890147775bb18761216c8dminfrin }
6bdb2c094666367615890147775bb18761216c8dminfrin else {
c1c0628ca9788908a5fc7502d04a89c348b75ee6wrowe /* only one socket, just pretend we did the other stuff */
c1c0628ca9788908a5fc7502d04a89c348b75ee6wrowe sd = ap_listeners->sd;
9865751743e928ea0a9ad83faa04a738001932deminfrin }
c1c0628ca9788908a5fc7502d04a89c348b75ee6wrowe
c1c0628ca9788908a5fc7502d04a89c348b75ee6wrowe /* if we accept() something we don't want to die, so we have to
002bcf949b064d7c042465d1095cafcfc6c9b701wrowe * defer the exit
c1c0628ca9788908a5fc7502d04a89c348b75ee6wrowe */
c1c0628ca9788908a5fc7502d04a89c348b75ee6wrowe apr_signal(SIGTERM, please_die_gracefully);
c1c0628ca9788908a5fc7502d04a89c348b75ee6wrowe for (;;) {
002bcf949b064d7c042465d1095cafcfc6c9b701wrowe ap_sync_scoreboard_image();
002bcf949b064d7c042465d1095cafcfc6c9b701wrowe if (I_AM_TO_SHUTDOWN()) {
d75bc22ab2702fa770f6935f07107efff16a76f0wrowe /* we didn't get a socket, and we were told to die */
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin clean_child_exit(0);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding stat = apr_accept(&csd, sd, ptrans);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (stat == APR_SUCCESS || !APR_STATUS_IS_EINTR(stat))
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding break;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
11c3b5180e1de6776035320b012a28bb146e7b46chuck
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (stat == APR_SUCCESS)
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe break; /* We have a socket ready for reading */
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe else {
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe/* TODO: this accept result handling stuff should be abstracted...
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe * it's already out of date between the various unix mpms
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe */
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq /* Our old behaviour here was to continue after accept()
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq * errors. But this leads us into lots of troubles
a812b025d139f465a31c76fc02ed162ed5271b03nd * because most of the errors are quite fatal. For
a812b025d139f465a31c76fc02ed162ed5271b03nd * example, EMFILE can be caused by slow descriptor
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe * leaks (say in a 3rd party module, or libc). It's
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe * foolish for us to continue after an EMFILE. We also
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe * seem to tickle kernel bugs on some platforms which
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe * lead to never-ending loops here. So it seems best
5a5a6c22260854843c973e2ea9a14bec64362ab5wrowe * to just exit in most cases.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding switch (stat) {
af952917c05e56874069e1e5f64e6473bb478b68minfrin#ifdef EPROTO
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* EPROTO on certain older kernels really means
af952917c05e56874069e1e5f64e6473bb478b68minfrin * ECONNABORTED, so we need to ignore it for them.
af952917c05e56874069e1e5f64e6473bb478b68minfrin * See discussion in new-httpd archives nh.9701
af952917c05e56874069e1e5f64e6473bb478b68minfrin * search for EPROTO.
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin *
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin * Also see nh.9603, search for EPROTO:
35c9e4d2c0a6465746a98958ef756114834461e6minfrin * There is potentially a bug in Solaris 2.x x<6,
35c9e4d2c0a6465746a98958ef756114834461e6minfrin * and other boxes that implement tcp sockets in
4a7df15077ff65dbf3b2cf68fa3063273ac0a547minfrin * userland (i.e. on top of STREAMS). On these
dcc56911d2b95e73554ff8ced9f72fd456d73881minfrin * systems, EPROTO can actually result in a fatal
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim * loop. See PR#981 for example. It's hard to
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim * handle both uses of EPROTO.
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim */
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim case EPROTO:
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim#endif
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim#ifdef ECONNABORTED
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding case ECONNABORTED:
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#endif
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* Linux generates the rest of these, other tcp
af952917c05e56874069e1e5f64e6473bb478b68minfrin * stacks (i.e. bsd) tend to hide them behind
af952917c05e56874069e1e5f64e6473bb478b68minfrin * getsockopt() interfaces. They occur when
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe * the net goes sour or the client disconnects
af952917c05e56874069e1e5f64e6473bb478b68minfrin * after the three-way handshake has been done
af952917c05e56874069e1e5f64e6473bb478b68minfrin * in the kernel but before userland has picked
af952917c05e56874069e1e5f64e6473bb478b68minfrin * up the socket.
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe */
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe#ifdef ECONNRESET
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe case ECONNRESET:
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe#endif
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq#ifdef ETIMEDOUT
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq case ETIMEDOUT:
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq#endif
a812b025d139f465a31c76fc02ed162ed5271b03nd#ifdef EHOSTUNREACH
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq case EHOSTUNREACH:
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq#endif
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe#ifdef ENETUNREACH
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe case ENETUNREACH:
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe#endif
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe break;
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe#ifdef ENETDOWN
af952917c05e56874069e1e5f64e6473bb478b68minfrin case ENETDOWN:
af952917c05e56874069e1e5f64e6473bb478b68minfrin /*
af952917c05e56874069e1e5f64e6473bb478b68minfrin * When the network layer has been shut down, there
af952917c05e56874069e1e5f64e6473bb478b68minfrin * is not much use in simply exiting: the parent
af952917c05e56874069e1e5f64e6473bb478b68minfrin * would simply re-create us (and we'd fail again).
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin * Use the CHILDFATAL code to tear the server down.
35c9e4d2c0a6465746a98958ef756114834461e6minfrin * @@@ Martin's idea for possible improvement:
dcc56911d2b95e73554ff8ced9f72fd456d73881minfrin * A different approach would be to define
fd3fa792f04fc9c4e8f5f83dceb0fc34e71f8570ianh * a new APEXIT_NETDOWN exit code, the reception
4224d5789080ea5586d49420da1e1996f5653bb5ianh * of which would make the parent shutdown all
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim * children, then idle-loop until it detected that
af952917c05e56874069e1e5f64e6473bb478b68minfrin * the network is up again, and restart the children.
af952917c05e56874069e1e5f64e6473bb478b68minfrin * Ben Hyde noted that temporary ENETDOWN situations
af952917c05e56874069e1e5f64e6473bb478b68minfrin * occur in mobile IP.
af952917c05e56874069e1e5f64e6473bb478b68minfrin */
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_log_error(APLOG_MARK, APLOG_EMERG, stat, ap_server_conf,
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe "apr_accept: giving up.");
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe clean_child_exit(APEXIT_CHILDFATAL);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe#endif /*ENETDOWN*/
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe#ifdef TPF
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe case EINACT:
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_log_error(APLOG_MARK, APLOG_EMERG, stat, ap_server_conf,
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe "offload device inactive");
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe clean_child_exit(APEXIT_CHILDFATAL);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe break;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe default:
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, ap_server_conf,
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe "select/accept error (%u)", stat);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe clean_child_exit(APEXIT_CHILDFATAL);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe#else
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe default:
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_log_error(APLOG_MARK, APLOG_ERR, stat, ap_server_conf,
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe "apr_accept: (client socket)");
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe clean_child_exit(1);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe#endif
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
9379749d811388a7d0e3410940ddd6743a33d330jim
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_sync_scoreboard_image();
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (I_AM_TO_SHUTDOWN()) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding clean_child_exit(0);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
3c59b18ce62f97468aaa5951d4e21a5478ef36ecminfrin SAFE_ACCEPT(accept_mutex_off()); /* unlock after "accept" */
9379749d811388a7d0e3410940ddd6743a33d330jim
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* We've got a socket, let's at least process one request off the
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * socket before we accept a graceful restart request. We set
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb * the signal to ignore because we don't want to disturb any
3c59b18ce62f97468aaa5951d4e21a5478ef36ecminfrin * third party code.
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_signal(SIGWINCH, SIG_IGN);
3c59b18ce62f97468aaa5951d4e21a5478ef36ecminfrin /*
9379749d811388a7d0e3410940ddd6743a33d330jim * We now have a connection, so set it up with the appropriate
9379749d811388a7d0e3410940ddd6743a33d330jim * socket options, file descriptors, and read/write buffers.
9379749d811388a7d0e3410940ddd6743a33d330jim */
9379749d811388a7d0e3410940ddd6743a33d330jim
3c59b18ce62f97468aaa5951d4e21a5478ef36ecminfrin apr_os_sock_get(&sockdes, csd);
3c59b18ce62f97468aaa5951d4e21a5478ef36ecminfrin
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (sockdes >= FD_SETSIZE) {
3c59b18ce62f97468aaa5951d4e21a5478ef36ecminfrin ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, NULL,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding "new file descriptor %d is too large; you probably need "
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding "to rebuild Apache with a larger FD_SETSIZE "
9379749d811388a7d0e3410940ddd6743a33d330jim "(currently %d)",
9379749d811388a7d0e3410940ddd6743a33d330jim sockdes, FD_SETSIZE);
9379749d811388a7d0e3410940ddd6743a33d330jim apr_socket_close(csd);
9379749d811388a7d0e3410940ddd6743a33d330jim ap_sync_scoreboard_image();
9379749d811388a7d0e3410940ddd6743a33d330jim continue;
9379749d811388a7d0e3410940ddd6743a33d330jim }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#ifdef TPF
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (sockdes == 0) { /* 0 is invalid socket for TPF */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard ap_sync_scoreboard_image();
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding continue;
9379749d811388a7d0e3410940ddd6743a33d330jim }
9379749d811388a7d0e3410940ddd6743a33d330jim#endif
9379749d811388a7d0e3410940ddd6743a33d330jim
9379749d811388a7d0e3410940ddd6743a33d330jim ap_sock_disable_nagle(csd);
9379749d811388a7d0e3410940ddd6743a33d330jim
9379749d811388a7d0e3410940ddd6743a33d330jim current_conn = ap_new_connection(ptrans, ap_server_conf, csd,
9379749d811388a7d0e3410940ddd6743a33d330jim my_child_num);
9379749d811388a7d0e3410940ddd6743a33d330jim if (current_conn) {
11c3b5180e1de6776035320b012a28bb146e7b46chuck ap_process_connection(current_conn);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_lingering_close(current_conn);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
24efed0910118b762a4eb84830875d4714b8d315ianh
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_sync_scoreboard_image();
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
066877f1a045103acfdd376d48cdd473c33f409bdougm clean_child_exit(0);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic int make_child(server_rec *s, int slot)
9379749d811388a7d0e3410940ddd6743a33d330jim{
9379749d811388a7d0e3410940ddd6743a33d330jim int pid;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (slot + 1 > ap_max_daemons_limit) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_max_daemons_limit = slot + 1;
9379749d811388a7d0e3410940ddd6743a33d330jim }
9379749d811388a7d0e3410940ddd6743a33d330jim
9379749d811388a7d0e3410940ddd6743a33d330jim if (one_process) {
9379749d811388a7d0e3410940ddd6743a33d330jim apr_signal(SIGHUP, please_die_gracefully);
9379749d811388a7d0e3410940ddd6743a33d330jim apr_signal(SIGINT, please_die_gracefully);
9379749d811388a7d0e3410940ddd6743a33d330jim#ifdef SIGQUIT
9379749d811388a7d0e3410940ddd6743a33d330jim apr_signal(SIGQUIT, SIG_DFL);
9379749d811388a7d0e3410940ddd6743a33d330jim#endif
9379749d811388a7d0e3410940ddd6743a33d330jim apr_signal(SIGTERM, just_die);
9379749d811388a7d0e3410940ddd6743a33d330jim ap_scoreboard_image->servers[slot][0].life_status = SB_WORKING;
9379749d811388a7d0e3410940ddd6743a33d330jim child_main(slot);
9379749d811388a7d0e3410940ddd6743a33d330jim }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(slot), SERVER_STARTING, (request_rec *) NULL);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#ifdef _OSD_POSIX
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* BS2000 requires a "special" version of fork() before a setuid() call */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if ((pid = os_fork(unixd_config.user_name)) == -1) {
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe#elif defined(TPF)
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe if ((pid = os_fork(s, slot)) == -1) {
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe#else
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe if ((pid = fork()) == -1) {
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe#endif
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, "fork: Unable to fork new process");
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe /* fork didn't succeed. Fix the scoreboard or else
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe * it will say SERVER_STARTING forever and ever
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe */
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(slot), SERVER_DEAD, (request_rec *) NULL);
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe /* In case system resources are maxxed out, we don't want
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe Apache running away with the CPU trying to fork over and
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe over and over again. */
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe sleep(10);
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe return -1;
433dc2d5dae74ed067db6175010ff973d02511e9jerenkrantz }
433dc2d5dae74ed067db6175010ff973d02511e9jerenkrantz
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe if (!pid) {
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe#ifdef AIX_BIND_PROCESSOR
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe/* by default AIX binds to a single processor
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe * this bit unbinds children which will then bind to another cpu
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe */
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe#include <sys/processor.h>
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe int status = bindprocessor(BINDPROCESS, (int)getpid(),
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe PROCESSOR_CLASS_ANY);
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe if (status != OK) {
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, ap_server_conf,
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe "processor unbind failed %d", status);
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe }
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe#endif
75b0a6a06ca1f4de80e3dd2a09c9f0c7d0a56089wrowe RAISE_SIGSTOP(MAKE_CHILD);
75b0a6a06ca1f4de80e3dd2a09c9f0c7d0a56089wrowe /* Disable the restart signal handlers and enable the please_die_gracefully stuff.
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe * Note that since restart() just notes that a restart has been
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe * requested there's no race condition here.
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe */
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe apr_signal(SIGHUP, please_die_gracefully);
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe apr_signal(SIGWINCH, please_die_gracefully);
5a5a6c22260854843c973e2ea9a14bec64362ab5wrowe apr_signal(SIGTERM, just_die);
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe ap_scoreboard_image->servers[slot][0].life_status = SB_WORKING;
4415d997ac73262e513c0a571bd5be4f609040bawrowe child_main(slot);
4415d997ac73262e513c0a571bd5be4f609040bawrowe }
4415d997ac73262e513c0a571bd5be4f609040bawrowe
4415d997ac73262e513c0a571bd5be4f609040bawrowe ap_scoreboard_image->parent[slot].pid = pid;
de274dca1be855ebb66bb7857951aae26fcb54c7wrowe#ifdef SCOREBOARD_FILE
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe lseek(scoreboard_fd, XtOffsetOf(scoreboard, parent[slot]), 0);
4415d997ac73262e513c0a571bd5be4f609040bawrowe force_write(scoreboard_fd, &ap_scoreboard_image->parent[slot],
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe sizeof(parent_score));
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe#endif
4415d997ac73262e513c0a571bd5be4f609040bawrowe
de274dca1be855ebb66bb7857951aae26fcb54c7wrowe return 0;
4415d997ac73262e513c0a571bd5be4f609040bawrowe}
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe
446c6a9a1e1073798258f1237f8c848b5f917b66wrowe/* start up a bunch of children */
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowestatic void startup_children(int number_to_start)
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe{
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe int i;
de274dca1be855ebb66bb7857951aae26fcb54c7wrowe
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe for (i = 0; number_to_start && i < ap_daemons_limit; ++i) {
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) {
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe continue;
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe }
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe if (make_child(ap_server_conf, i) < 0) {
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe break;
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe }
de274dca1be855ebb66bb7857951aae26fcb54c7wrowe --number_to_start;
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe }
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe}
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/*
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * idle_spawn_rate is the number of children that will be spawned on the
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb * next maintenance cycle if there aren't enough idle servers. It is
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * without the need to spawn.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic int idle_spawn_rate = 1;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#ifndef MAX_SPAWN_RATE
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#define MAX_SPAWN_RATE (32)
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard#endif
529005244758297d4415aa912c67a67f805349bcianhstatic int hold_off_on_exponential_spawning;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddardstatic void perform_idle_server_maintenance(void)
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard{
529005244758297d4415aa912c67a67f805349bcianh int i;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard int to_kill;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard int idle_count;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard short_score *ss;
529005244758297d4415aa912c67a67f805349bcianh int free_length;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard int free_slots[MAX_SPAWN_RATE];
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard int last_non_dead;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard int total_non_dead;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
529005244758297d4415aa912c67a67f805349bcianh /* initialize the free_list */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard free_length = 0;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding to_kill = -1;
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq idle_count = 0;
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq last_non_dead = -1;
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq total_non_dead = 0;
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq ap_sync_scoreboard_image();
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq for (i = 0; i < ap_daemons_limit; ++i) {
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq int status;
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq if (i >= ap_max_daemons_limit && free_length == idle_spawn_rate)
a812b025d139f465a31c76fc02ed162ed5271b03nd break;
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq ss = &ap_scoreboard_image->servers[i][0];
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq status = ss->status;
a812b025d139f465a31c76fc02ed162ed5271b03nd if (status == SERVER_DEAD) {
a812b025d139f465a31c76fc02ed162ed5271b03nd /* try to keep children numbers as low as possible */
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq if (free_length < idle_spawn_rate) {
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq free_slots[free_length] = i;
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq ++free_length;
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq }
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq }
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq else {
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq /* We consider a starting server as idle because we started it
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq * at least a cycle ago, and if it still hasn't finished starting
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq * then we're just going to swamp things worse by forking more.
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq * So we hopefully won't need to fork more if we count it.
a812b025d139f465a31c76fc02ed162ed5271b03nd * This depends on the ordering of SERVER_READY and SERVER_STARTING.
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq */
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq if (status <= SERVER_READY) {
a812b025d139f465a31c76fc02ed162ed5271b03nd ++ idle_count;
a812b025d139f465a31c76fc02ed162ed5271b03nd /* always kill the highest numbered child if we have to...
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq * no really well thought out reason ... other than observing
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * the server behaviour under linux where lower numbered children
11c3b5180e1de6776035320b012a28bb146e7b46chuck * tend to service more hits (and hence are more likely to have
11c3b5180e1de6776035320b012a28bb146e7b46chuck * their data in cpu caches).
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding to_kill = i;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ++total_non_dead;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding last_non_dead = i;
a6314dfa8dd8a0d69db16288581e4950a2dd3955minfrin }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_max_daemons_limit = last_non_dead + 1;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (idle_count > ap_daemons_max_free) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* kill off one child... we use SIGWINCH because that'll cause it to
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * shut down gracefully, in case it happened to pick up a request
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard * while we were counting
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard kill(ap_scoreboard_image->parent[to_kill].pid, SIGWINCH);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding idle_spawn_rate = 1;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding else if (idle_count < ap_daemons_min_free) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /* terminate the free list */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (free_length == 0) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /* only report this condition once */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard static int reported = 0;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (!reported) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, ap_server_conf,
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard "server reached MaxClients setting, consider"
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding " raising the MaxClients setting");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding reported = 1;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding idle_spawn_rate = 1;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding else {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (idle_spawn_rate >= 8) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0, ap_server_conf,
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb "server seems busy, (you may need "
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding "to increase StartServers, or Min/MaxSpareServers), "
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding "spawning %d children, there are %d idle, and "
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding "%d total children", idle_spawn_rate,
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard idle_count, total_non_dead);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding for (i = 0; i < free_length; ++i) {
10a4cdd68ef1ca0e54af296fe1d08ac00150c90bwrowe#ifdef TPF
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (make_child(ap_server_conf, free_slots[i]) == -1) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if(free_length == 1) {
066877f1a045103acfdd376d48cdd473c33f409bdougm shutdown_pending = 1;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_EMERG, 0, ap_server_conf,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding "No active child processes: shutting down");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#else
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding make_child(ap_server_conf, free_slots[i]);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#endif /* TPF */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
11c3b5180e1de6776035320b012a28bb146e7b46chuck /* the next time around we want to spawn twice as many if this
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * wasn't good enough, but not if we've just done a graceful
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (hold_off_on_exponential_spawning) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding --hold_off_on_exponential_spawning;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding else if (idle_spawn_rate < MAX_SPAWN_RATE) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding idle_spawn_rate *= 2;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding else {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard idle_spawn_rate = 1;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic int setup_listeners(server_rec *s)
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard{
11c3b5180e1de6776035320b012a28bb146e7b46chuck ap_listen_rec *lr;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard int sockdes;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
11c3b5180e1de6776035320b012a28bb146e7b46chuck if (ap_setup_listeners(s) < 1 ) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ALERT, 0, s,
1cde33c7e2019830f8fb3224e01649305583916etrawick "no listening sockets available, shutting down");
407cde44becba3694e7c3d81ac99b5d86f4b03a9rbb return -1;
1cde33c7e2019830f8fb3224e01649305583916etrawick }
407cde44becba3694e7c3d81ac99b5d86f4b03a9rbb
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding listenmaxfd = -1;
11c3b5180e1de6776035320b012a28bb146e7b46chuck FD_ZERO(&listenfds);
11c3b5180e1de6776035320b012a28bb146e7b46chuck for (lr = ap_listeners; lr; lr = lr->next) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard apr_os_sock_get(&sockdes, lr->sd);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding FD_SET(sockdes, &listenfds);
1cde33c7e2019830f8fb3224e01649305583916etrawick if (sockdes > listenmaxfd) {
407cde44becba3694e7c3d81ac99b5d86f4b03a9rbb listenmaxfd = sockdes;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return 0;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
1cde33c7e2019830f8fb3224e01649305583916etrawick/*****************************************************************
407cde44becba3694e7c3d81ac99b5d86f4b03a9rbb * Executive routines.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddardint ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding int index;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard int remaining_children_to_start;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard pconf = _pconf;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_server_conf = s;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_pid(pconf, ap_pid_fname);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
11c3b5180e1de6776035320b012a28bb146e7b46chuck if (setup_listeners(s)) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* XXX: hey, what's the right way for the mpm to indicate a fatal error? */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return 1;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding SAFE_ACCEPT(accept_mutex_init(pconf));
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (!is_graceful) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_create_scoreboard(pconf, SB_SHARED);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#ifdef SCOREBOARD_FILE
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding else {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_scoreboard_fname = ap_server_root_relative(pconf, ap_scoreboard_fname);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_note_cleanups_for_fd(pconf, scoreboard_fd);
11c3b5180e1de6776035320b012a28bb146e7b46chuck }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#endif
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding set_signals();
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (ap_daemons_max_free < ap_daemons_min_free + 1) /* Don't thrash... */
af952917c05e56874069e1e5f64e6473bb478b68minfrin ap_daemons_max_free = ap_daemons_min_free + 1;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* If we're doing a graceful_restart then we're going to see a lot
ff1234e45aca1b8171d711ecb87f58b9d9100a99ianh * of children exiting immediately when we get into the main loop
4a7df15077ff65dbf3b2cf68fa3063273ac0a547minfrin * below (because we just sent them SIGWINCH). This happens pretty
ff1234e45aca1b8171d711ecb87f58b9d9100a99ianh * rapidly... and for each one that exits we'll start a new one until
ff1234e45aca1b8171d711ecb87f58b9d9100a99ianh * we reach at least daemons_min_free. But we may be permitted to
ff1234e45aca1b8171d711ecb87f58b9d9100a99ianh * start more than that, so we'll just keep track of how many we're
ff1234e45aca1b8171d711ecb87f58b9d9100a99ianh * supposed to start up without the 1 second penalty between each fork.
4a7df15077ff65dbf3b2cf68fa3063273ac0a547minfrin */
dcc56911d2b95e73554ff8ced9f72fd456d73881minfrin remaining_children_to_start = ap_daemons_to_start;
ff1234e45aca1b8171d711ecb87f58b9d9100a99ianh if (remaining_children_to_start > ap_daemons_limit) {
ff1234e45aca1b8171d711ecb87f58b9d9100a99ianh remaining_children_to_start = ap_daemons_limit;
fd3fa792f04fc9c4e8f5f83dceb0fc34e71f8570ianh }
fd3fa792f04fc9c4e8f5f83dceb0fc34e71f8570ianh if (!is_graceful) {
fd3fa792f04fc9c4e8f5f83dceb0fc34e71f8570ianh startup_children(remaining_children_to_start);
fd3fa792f04fc9c4e8f5f83dceb0fc34e71f8570ianh remaining_children_to_start = 0;
fd3fa792f04fc9c4e8f5f83dceb0fc34e71f8570ianh }
fd3fa792f04fc9c4e8f5f83dceb0fc34e71f8570ianh else {
fd3fa792f04fc9c4e8f5f83dceb0fc34e71f8570ianh /* give the system some time to recover before kicking into
fd3fa792f04fc9c4e8f5f83dceb0fc34e71f8570ianh * exponential mode */
fd3fa792f04fc9c4e8f5f83dceb0fc34e71f8570ianh hold_off_on_exponential_spawning = 10;
fd3fa792f04fc9c4e8f5f83dceb0fc34e71f8570ianh }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, ap_server_conf,
11c3b5180e1de6776035320b012a28bb146e7b46chuck "%s configured -- resuming normal operations",
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_get_server_version());
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0, ap_server_conf,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding "Server built: %s", ap_get_server_built());
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding restart_pending = shutdown_pending = 0;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard while (!restart_pending && !shutdown_pending) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding int child_slot;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_wait_t status;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* this is a memory leak, but I'll fix it later. */
af952917c05e56874069e1e5f64e6473bb478b68minfrin apr_proc_t pid;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_wait_or_timeout(&status, &pid, pconf);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin /* XXX: if it takes longer than 1 second for all our children
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin * to start up and get into IDLE state then we may spawn an
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin * extra child
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin */
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin if (pid.pid != -1) {
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin ap_process_child_status(&pid, status);
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin /* non-fatal death... note that it's gone in the scoreboard. */
10306ac2c175f420e6989568f4c8535a5dbc1349minfrin ap_sync_scoreboard_image();
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin child_slot = find_child_by_pid(&pid);
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin if (child_slot >= 0) {
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(child_slot), SERVER_DEAD,
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin (request_rec *) NULL);
35c9e4d2c0a6465746a98958ef756114834461e6minfrin if (remaining_children_to_start
35c9e4d2c0a6465746a98958ef756114834461e6minfrin && child_slot < ap_daemons_limit) {
35c9e4d2c0a6465746a98958ef756114834461e6minfrin /* we're still doing a 1-for-1 replacement of dead
35c9e4d2c0a6465746a98958ef756114834461e6minfrin * children with new children
35c9e4d2c0a6465746a98958ef756114834461e6minfrin */
35c9e4d2c0a6465746a98958ef756114834461e6minfrin make_child(ap_server_conf, child_slot);
35c9e4d2c0a6465746a98958ef756114834461e6minfrin --remaining_children_to_start;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
35c9e4d2c0a6465746a98958ef756114834461e6minfrin#if APR_HAS_OTHER_CHILD
35c9e4d2c0a6465746a98958ef756114834461e6minfrin }
35c9e4d2c0a6465746a98958ef756114834461e6minfrin else if (apr_proc_other_child_read(&pid, status) == 0) {
35c9e4d2c0a6465746a98958ef756114834461e6minfrin /* handled */
35c9e4d2c0a6465746a98958ef756114834461e6minfrin#endif
35c9e4d2c0a6465746a98958ef756114834461e6minfrin }
4224d5789080ea5586d49420da1e1996f5653bb5ianh else if (is_graceful) {
4224d5789080ea5586d49420da1e1996f5653bb5ianh /* Great, we've probably just lost a slot in the
4224d5789080ea5586d49420da1e1996f5653bb5ianh * scoreboard. Somehow we don't know about this
4224d5789080ea5586d49420da1e1996f5653bb5ianh * child.
4224d5789080ea5586d49420da1e1996f5653bb5ianh */
4224d5789080ea5586d49420da1e1996f5653bb5ianh ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING,
4224d5789080ea5586d49420da1e1996f5653bb5ianh 0, ap_server_conf,
4224d5789080ea5586d49420da1e1996f5653bb5ianh "long lost child came home! (pid %ld)", (long)pid.pid);
4224d5789080ea5586d49420da1e1996f5653bb5ianh }
4224d5789080ea5586d49420da1e1996f5653bb5ianh /* Don't perform idle maintenance when a child dies,
4224d5789080ea5586d49420da1e1996f5653bb5ianh * only do it when there's a timeout. Remember only a
4224d5789080ea5586d49420da1e1996f5653bb5ianh * finite number of children can die, and it's pretty
fa861fc5a880d2c3a5ecc0ec71fa7da556adf5c1wrowe * pathological for a lot to die suddenly.
4224d5789080ea5586d49420da1e1996f5653bb5ianh */
4224d5789080ea5586d49420da1e1996f5653bb5ianh continue;
4224d5789080ea5586d49420da1e1996f5653bb5ianh }
35c9e4d2c0a6465746a98958ef756114834461e6minfrin else if (remaining_children_to_start) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* we hit a 1 second timeout in which none of the previous
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb * generation of children needed to be reaped... so assume
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * they're all done, and pick up the slack if any is left.
11c3b5180e1de6776035320b012a28bb146e7b46chuck */
11c3b5180e1de6776035320b012a28bb146e7b46chuck startup_children(remaining_children_to_start);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding remaining_children_to_start = 0;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* In any event we really shouldn't do the code below because
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * few of the servers we just started are in the IDLE state
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * yet, so we'd mistakenly create an extra server.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding continue;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding perform_idle_server_maintenance();
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#ifdef TPF
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard shutdown_pending = os_check_server(tpf_server_name);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard ap_check_signals();
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding sleep(1);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#endif /*TPF */
af952917c05e56874069e1e5f64e6473bb478b68minfrin }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (shutdown_pending) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* Time to gracefully shut down:
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim * Kill child processes, tell them to call child_exit, etc...
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim */
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim if (unixd_killpg(getpgrp(), SIGTERM) < 0) {
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "killpg SIGTERM");
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim }
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim ap_reclaim_child_processes(1); /* Start with SIGTERM */
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim /* cleanup pid file on normal shutdown */
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim {
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim const char *pidfile = NULL;
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim pidfile = ap_server_root_relative (pconf, ap_pid_fname);
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim if ( pidfile != NULL && unlink(pidfile) == 0)
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO,
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim 0, ap_server_conf,
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim "removed PID file %s (pid=%ld)",
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim pidfile, (long)getpid());
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim }
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, ap_server_conf,
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim "caught SIGTERM, shutting down");
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim return 1;
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe }
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe /* we've been told to restart */
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe apr_signal(SIGHUP, SIG_IGN);
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe apr_signal(SIGWINCH, SIG_IGN);
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe if (one_process) {
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe /* not worth thinking about */
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe return 1;
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe }
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe /* advance to the next generation */
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe /* XXX: we really need to make sure this new generation number isn't in
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe * use by any of the children.
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe */
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe ++ap_my_generation;
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe ap_scoreboard_image->global.running_generation = ap_my_generation;
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe update_scoreboard_global();
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe for (index = 0; index < ap_daemons_limit; ++index) {
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe ap_scoreboard_image->servers[index][0].life_status = SB_IDLE_DIE;
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe }
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe if (is_graceful) {
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, ap_server_conf,
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe "SIGWINCH received. Doing graceful restart");
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe
5a5a6c22260854843c973e2ea9a14bec64362ab5wrowe /* kill off the idle ones */
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe if (unixd_killpg(getpgrp(), SIGWINCH) < 0) {
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "killpg SIGWINCH");
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe }
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe#ifndef SCOREBOARD_FILE
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe /* This is mostly for debugging... so that we know what is still
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe * gracefully dealing with existing request. But we can't really
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe * do it if we're in a SCOREBOARD_FILE because it'll cause
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe * corruption too easily.
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe */
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe ap_sync_scoreboard_image();
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe for (index = 0; index < ap_daemons_limit; ++index) {
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe if (ap_scoreboard_image->servers[index][0].status != SERVER_DEAD) {
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe ap_scoreboard_image->servers[index][0].status = SERVER_GRACEFUL;
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe }
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe }
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe#endif
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe }
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe else {
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe /* Kill 'em off */
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe if (unixd_killpg(getpgrp(), SIGHUP) < 0) {
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "killpg SIGHUP");
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe }
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe ap_reclaim_child_processes(0); /* Not when just starting up */
433dc2d5dae74ed067db6175010ff973d02511e9jerenkrantz ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, ap_server_conf,
433dc2d5dae74ed067db6175010ff973d02511e9jerenkrantz "SIGHUP received. Attempting to restart");
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe }
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe return 0;
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe}
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowestatic void prefork_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp)
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe{
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe static int restart_num = 0;
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe int no_detach = 0;
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe no_detach = !!ap_exists_config_define("NO_DETACH");
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe one_process = !!ap_exists_config_define("ONE_PROCESS");
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe /* sigh, want this only the second time around */
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe if (restart_num++ == 1) {
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe is_graceful = 0;
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe if (!one_process && !no_detach) {
de274dca1be855ebb66bb7857951aae26fcb54c7wrowe apr_proc_detach();
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe }
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe
4c67ef499845a08771e81254ce6eb2324a160bc7wrowe ap_my_pid = getpid();
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe }
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe unixd_pre_config(ptemp);
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe ap_listen_pre_config();
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe ap_daemons_to_start = DEFAULT_START_DAEMON;
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe ap_daemons_min_free = DEFAULT_MIN_FREE_DAEMON;
de274dca1be855ebb66bb7857951aae26fcb54c7wrowe ap_daemons_max_free = DEFAULT_MAX_FREE_DAEMON;
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe ap_daemons_limit = HARD_SERVER_LIMIT;
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe ap_pid_fname = DEFAULT_PIDLOG;
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe ap_scoreboard_fname = DEFAULT_SCOREBOARD;
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe ap_lock_fname = DEFAULT_LOCKFILE;
4415d997ac73262e513c0a571bd5be4f609040bawrowe ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD;
4415d997ac73262e513c0a571bd5be4f609040bawrowe ap_extended_status = 0;
4415d997ac73262e513c0a571bd5be4f609040bawrowe
4415d997ac73262e513c0a571bd5be4f609040bawrowe apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir));
de274dca1be855ebb66bb7857951aae26fcb54c7wrowe}
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowestatic void prefork_hooks(apr_pool_t *p)
4cc02d7521758b07c7cd240e8ea32fb7a20909cfwrowe{
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe#ifdef AUX3
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe (void) set42sig();
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe#endif
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe ap_hook_pre_config(prefork_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe}
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowestatic const char *set_pidfile(cmd_parms *cmd, void *dummy, const char *arg)
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe{
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
5a5a6c22260854843c973e2ea9a14bec64362ab5wrowe if (err != NULL) {
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe return err;
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe }
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe if (cmd->server->is_virtual) {
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe return "PidFile directive not allowed in <VirtualHost>";
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe }
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe ap_pid_fname = arg;
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe return NULL;
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe}
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowestatic const char *set_scoreboard(cmd_parms *cmd, void *dummy, const char *arg)
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe{
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe if (err != NULL) {
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe return err;
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe }
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe ap_scoreboard_fname = arg;
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe return NULL;
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe}
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowestatic const char *set_lockfile(cmd_parms *cmd, void *dummy, const char *arg)
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe{
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe if (err != NULL) {
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe return err;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_lock_fname = arg;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return NULL;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe}
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowestatic const char *set_daemons_to_start(cmd_parms *cmd, void *dummy, const char *arg)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe{
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (err != NULL) {
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return err;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_daemons_to_start = atoi(arg);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return NULL;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe}
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowestatic const char *set_min_free_servers(cmd_parms *cmd, void *dummy, const char *arg)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe{
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (err != NULL) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return err;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_daemons_min_free = atoi(arg);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (ap_daemons_min_free <= 0) {
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe "WARNING: detected MinSpareServers set to non-positive.");
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe "Resetting to 1 to avoid almost certain Apache failure.");
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe "Please read the documentation.");
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_daemons_min_free = 1;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return NULL;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe}
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowestatic const char *set_max_free_servers(cmd_parms *cmd, void *dummy, const char *arg)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe{
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (err != NULL) {
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return err;
52489511342e4ff3fe399e57f29d38e5c4227bc8trawick }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_daemons_max_free = atoi(arg);
52489511342e4ff3fe399e57f29d38e5c4227bc8trawick return NULL;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe}
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowestatic const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe{
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
e6c244ee56578707b20a86e0e938498299a93b6cnd if (err != NULL) {
e6c244ee56578707b20a86e0e938498299a93b6cnd return err;
e6c244ee56578707b20a86e0e938498299a93b6cnd }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_daemons_limit = atoi(arg);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (ap_daemons_limit > HARD_SERVER_LIMIT) {
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe "WARNING: MaxClients of %d exceeds compile time limit "
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe "of %d servers,", ap_daemons_limit, HARD_SERVER_LIMIT);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard " lowering MaxClients to %d. To increase, please "
e6c244ee56578707b20a86e0e938498299a93b6cnd "see the", HARD_SERVER_LIMIT);
e6c244ee56578707b20a86e0e938498299a93b6cnd ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
e6c244ee56578707b20a86e0e938498299a93b6cnd " HARD_SERVER_LIMIT define in %s.",
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe AP_MPM_HARD_LIMITS_FILE);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_daemons_limit = HARD_SERVER_LIMIT;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe else if (ap_daemons_limit < 1) {
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe "WARNING: Require MaxClients > 0, setting to 1");
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_daemons_limit = 1;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return NULL;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe}
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowestatic const char *set_max_requests(cmd_parms *cmd, void *dummy, const char *arg)
9a806b671337b22acf6418e60a83f6bbeabdf771wrowe{
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (err != NULL) {
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return err;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard ap_max_requests_per_child = atoi(arg);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return NULL;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe}
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowestatic const char *set_coredumpdir (cmd_parms *cmd, void *dummy, const char *arg)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe{
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe apr_finfo_t finfo;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe const char *fname;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (err != NULL) {
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return err;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe fname = ap_server_root_relative(cmd->pool, arg);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if ((apr_stat(&finfo, fname, APR_FINFO_TYPE, cmd->pool) != APR_SUCCESS)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe || (finfo.filetype != APR_DIR)) {
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb return apr_pstrcat(cmd->pool, "CoreDumpDirectory ", fname,
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb " does not exist or is not a directory", NULL);
9379749d811388a7d0e3410940ddd6743a33d330jim }
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb apr_cpystrn(ap_coredump_dir, fname, sizeof(ap_coredump_dir));
9379749d811388a7d0e3410940ddd6743a33d330jim return NULL;
9379749d811388a7d0e3410940ddd6743a33d330jim}
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbbstatic const command_rec prefork_cmds[] = {
93aa7afe1af831ee8b23aa0d97323c388e3fb8d3ianhUNIX_DAEMON_COMMANDS
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbbLISTEN_COMMANDS
33cb45dc8c5106018b7c2f6ae42478b109423e0eniqAP_INIT_TAKE1("PidFile", set_pidfile, NULL, RSRC_CONF,
a812b025d139f465a31c76fc02ed162ed5271b03nd "A file for logging the server process ID"),
33cb45dc8c5106018b7c2f6ae42478b109423e0eniqAP_INIT_TAKE1("ScoreBoardFile", set_scoreboard, NULL, RSRC_CONF,
a812b025d139f465a31c76fc02ed162ed5271b03nd "A file for Apache to maintain runtime process management information"),
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbbAP_INIT_TAKE1("LockFile", set_lockfile, NULL, RSRC_CONF,
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb "The lockfile used when Apache needs to lock the accept() call"),
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbbAP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF,
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb "Number of child processes launched at server startup"),
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrinAP_INIT_TAKE1("MinSpareServers", set_min_free_servers, NULL, RSRC_CONF,
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin "Minimum number of idle children, to handle request spikes"),
35c9e4d2c0a6465746a98958ef756114834461e6minfrinAP_INIT_TAKE1("MaxSpareServers", set_max_free_servers, NULL, RSRC_CONF,
35c9e4d2c0a6465746a98958ef756114834461e6minfrin "Maximum number of idle children"),
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbbAP_INIT_TAKE1("MaxClients", set_server_limit, NULL, RSRC_CONF,
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb "Maximum number of children alive at the same time"),
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbbAP_INIT_TAKE1("MaxRequestsPerChild", set_max_requests, NULL, RSRC_CONF,
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb "Maximum number of requests a particular child serves before dying."),
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbbAP_INIT_TAKE1("CoreDumpDirectory", set_coredumpdir, NULL, RSRC_CONF,
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb "The location of the directory Apache changes to before dumping core"),
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb{ NULL }
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb};
4a7df15077ff65dbf3b2cf68fa3063273ac0a547minfrin
4ecd546edd89824908c2a9ad2e07339d89368f9cmartinmodule AP_MODULE_DECLARE_DATA mpm_prefork_module = {
fd3fa792f04fc9c4e8f5f83dceb0fc34e71f8570ianh MPM20_MODULE_STUFF,
4ecd546edd89824908c2a9ad2e07339d89368f9cmartin NULL, /* hook to run before apache parses args */
4224d5789080ea5586d49420da1e1996f5653bb5ianh NULL, /* create per-directory config structure */
4224d5789080ea5586d49420da1e1996f5653bb5ianh NULL, /* merge per-directory config structures */
4224d5789080ea5586d49420da1e1996f5653bb5ianh NULL, /* create per-server config structure */
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim NULL, /* merge per-server config structures */
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim prefork_cmds, /* command apr_table_t */
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe prefork_hooks, /* register hooks */
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe};
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe