prefork.c revision 20e0c71be778348516719e1e58a9f55c8e78c570
842ae4bd224140319ae7feec1872b93dfd491143fielding/* Licensed to the Apache Software Foundation (ASF) under one or more
842ae4bd224140319ae7feec1872b93dfd491143fielding * contributor license agreements. See the NOTICE file distributed with
842ae4bd224140319ae7feec1872b93dfd491143fielding * this work for additional information regarding copyright ownership.
842ae4bd224140319ae7feec1872b93dfd491143fielding * The ASF licenses this file to You under the Apache License, Version 2.0
842ae4bd224140319ae7feec1872b93dfd491143fielding * (the "License"); you may not use this file except in compliance with
842ae4bd224140319ae7feec1872b93dfd491143fielding * the License. You may obtain a copy of the License at
04891cf70e0bfc38bfb027541dc821f04c754ff7nd * Unless required by applicable law or agreed to in writing, software
04891cf70e0bfc38bfb027541dc821f04c754ff7nd * distributed under the License is distributed on an "AS IS" BASIS,
04891cf70e0bfc38bfb027541dc821f04c754ff7nd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
04891cf70e0bfc38bfb027541dc821f04c754ff7nd * See the License for the specific language governing permissions and
04891cf70e0bfc38bfb027541dc821f04c754ff7nd * limitations under the License.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* Limit on the total --- clients will be locked out if more servers than
3568de757bac0b47256647504c186d17ca272f85rbb * this are needed. It is intended solely to keep the server from crashing
cd8f8c995d415473f3bfb0b329b2450f2a722c3atrawick * when things get out of hand.
3568de757bac0b47256647504c186d17ca272f85rbb * We keep a hard maximum number of servers, for two reasons --- first off,
3568de757bac0b47256647504c186d17ca272f85rbb * in case something goes seriously wrong, we want to stop the fork bomb
3568de757bac0b47256647504c186d17ca272f85rbb * short of actually crashing the machine we're running on by filling some
98fb535f829e2a95aabd82420931f476661fa8e3jorton * kernel table. Secondly, it keeps the size of the scoreboard file small
db12cd62083041bf90945eeb90cc40fbd2340797trawick * enough that we can read the whole thing without worrying too much about
db12cd62083041bf90945eeb90cc40fbd2340797trawick * the overhead.
3568de757bac0b47256647504c186d17ca272f85rbb/* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT. We want
3568de757bac0b47256647504c186d17ca272f85rbb * some sort of compile-time limit to help catch typos.
3568de757bac0b47256647504c186d17ca272f85rbb/* config globals */
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantzstatic int server_limit = 0;
8f3ec4772d2aeb347cf40e87c77627bb784dd018rbb/* data retained by prefork across load/unload of the module
8f3ec4772d2aeb347cf40e87c77627bb784dd018rbb * allocated on first call to pre-config hook; located on
3d96ee83babeec32482c9082c9426340cee8c44dwrowe * subsequent calls to pre-config hook
b6e310e482c42cc323a28fa6fec653e11e0552e5jortontypedef struct prefork_retained_data {
98fb535f829e2a95aabd82420931f476661fa8e3jorton * The max child slot ever assigned, preserved across restarts. Necessary
7cd5419264796cfeaf8215383cf0f89130a81fectrawick * to deal with MaxClients changes across AP_SIG_GRACEFUL restarts. We
7cd5419264796cfeaf8215383cf0f89130a81fectrawick * use this value to optimize routines that have to scan the entire scoreboard.
7cd5419264796cfeaf8215383cf0f89130a81fectrawick * idle_spawn_rate is the number of children that will be spawned on the
7cd5419264796cfeaf8215383cf0f89130a81fectrawick * next maintenance cycle if there aren't enough idle servers. It is
7cd5419264796cfeaf8215383cf0f89130a81fectrawick * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by
3568de757bac0b47256647504c186d17ca272f85rbb * without the need to spawn.
3568de757bac0b47256647504c186d17ca272f85rbb#define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid)
3568de757bac0b47256647504c186d17ca272f85rbb/* one_process --- debugging mode variable; can be set from the command line
3568de757bac0b47256647504c186d17ca272f85rbb * with the -X flag. If set, this gets you the child_main loop running
936a4025e45887d9f366bf54360c51937b6bcacejim * in the process which originally started up (no detach, no make_child),
936a4025e45887d9f366bf54360c51937b6bcacejim * which is a pretty nice debugging environment. (You'll get a SIGHUP
936a4025e45887d9f366bf54360c51937b6bcacejim * early in standalone_main; just continue through. This is the server
936a4025e45887d9f366bf54360c51937b6bcacejim * trying to kill off any child processes which it might have lying
936a4025e45887d9f366bf54360c51937b6bcacejim * around --- Apache doesn't keep track of their pids, it just sends
936a4025e45887d9f366bf54360c51937b6bcacejim * SIGHUP to the process group, ignoring it in the root process.
936a4025e45887d9f366bf54360c51937b6bcacejim * Continue through and you'll be fine.).
936a4025e45887d9f366bf54360c51937b6bcacejimstatic int one_process = 0;
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic apr_pool_t *pchild; /* Pool for httpd child stuff */
3568de757bac0b47256647504c186d17ca272f85rbbstatic pid_t ap_my_pid; /* it seems silly to call getpid all the time */
3568de757bac0b47256647504c186d17ca272f85rbb * change directory for gprof to plop the gmon.out file
3568de757bac0b47256647504c186d17ca272f85rbb * configure in httpd.conf:
41634f717c623556a16b27b25d7d909a66fe20f8wrowe * GprofDir $RuntimeDir/ -> $ServerRoot/$RuntimeDir/gmon.out
3568de757bac0b47256647504c186d17ca272f85rbb * GprofDir $RuntimeDir/% -> $ServerRoot/$RuntimeDir/gprof.$pid/gmon.out
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantzstatic void chdir_for_gprof(void)
3568de757bac0b47256647504c186d17ca272f85rbb ap_get_module_config(ap_server_conf->module_config, &core_module);
3568de757bac0b47256647504c186d17ca272f85rbb const char *use_dir;
3568de757bac0b47256647504c186d17ca272f85rbb use_dir = ap_server_root_relative(pconf, buf ? buf : dir);
fc1efab92032301e317f07e1b3a00082d9d71f3frbb ap_log_error(APLOG_MARK, APLOG_ERR, res, ap_server_conf,
3568de757bac0b47256647504c186d17ca272f85rbb use_dir = ap_server_root_relative(pconf, DEFAULT_REL_RUNTIMEDIR);
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz/* a clean exit from a child with proper cleanup */
3568de757bac0b47256647504c186d17ca272f85rbbstatic void clean_child_exit(int code) __attribute__ ((noreturn));
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantzstatic void accept_mutex_on(void)
3568de757bac0b47256647504c186d17ca272f85rbb ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, ap_server_conf, "%s", msg);
3568de757bac0b47256647504c186d17ca272f85rbb ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, "%s", msg);
3568de757bac0b47256647504c186d17ca272f85rbbstatic void accept_mutex_off(void)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_status_t rv = apr_proc_mutex_unlock(accept_mutex);
239f998fbee5ac5b114b965bb76e217cce0003edstoddard const char *msg = "couldn't release the accept mutex";
6653a33e820463abd4f81915b7a1eba0f602e200brianp ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, ap_server_conf, "%s", msg);
6653a33e820463abd4f81915b7a1eba0f602e200brianp /* don't exit here... we have a connection to
41634f717c623556a16b27b25d7d909a66fe20f8wrowe * process, after which point we'll see that the
41634f717c623556a16b27b25d7d909a66fe20f8wrowe * generation changed and we'll exit cleanly
6653a33e820463abd4f81915b7a1eba0f602e200brianp ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, "%s", msg);
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm/* On some architectures it's safe to do unserialized accept()s in the single
cd8f8c995d415473f3bfb0b329b2450f2a722c3atrawick * Listen case. But it's never safe to do it in the case where there's
36c8049de63c446926139936c3d195330a0539cetrawick * multiple Listen statements. Define SINGLE_LISTEN_UNSERIALIZED_ACCEPT
3568de757bac0b47256647504c186d17ca272f85rbb * when it's safe in the single Listen case.
e8f95a682820a599fe41b22977010636be5c2717jim#define SAFE_ACCEPT(stmt) do {if (ap_listeners->next) {stmt;}} while(0)
6653a33e820463abd4f81915b7a1eba0f602e200brianpstatic int prefork_query(int query_code, int *result, apr_status_t *rv)
9f979f5c8061f6f6f560d1824e0e378ff5b91931rpluemstatic apr_status_t prefork_note_child_killed(int childnum)
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddardstatic const char *prefork_get_name(void)
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard return "prefork";
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard/*****************************************************************
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz * Connection structures and accounting...
7cd5419264796cfeaf8215383cf0f89130a81fectrawick/* volatile because they're updated from a signal handler */
7cd5419264796cfeaf8215383cf0f89130a81fectrawickstatic int volatile shutdown_pending;
e8f95a682820a599fe41b22977010636be5c2717jimstatic int volatile restart_pending;
98cd3186185bb28ae6c95a3f159899fcf56a663ftrawickstatic int volatile die_now = 0;
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz /* For a graceful stop, we want the child to exit when done */
3cbd177a6c885562f9ad0cf11695f044489c881dgregames /* Um, is this _probably_ not an error, if the user has
3cbd177a6c885562f9ad0cf11695f044489c881dgregames * tried to do a shutdown twice quickly, so we won't
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard * worry about reporting it.
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard retained->is_graceful = (sig == AP_SIG_GRACEFUL_STOP);
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz/* restart() is the signal handler for SIGHUP and AP_SIG_GRACEFUL
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard * in the parent process, unless running in ONE_PROCESS mode
7cd5419264796cfeaf8215383cf0f89130a81fectrawick /* Probably not an error - don't bother reporting it */
7cd5419264796cfeaf8215383cf0f89130a81fectrawickstatic void set_signals(void)
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGTERM)");
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard if (sigaction(AP_SIG_GRACEFUL_STOP, &sa, NULL) < 0)
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
7cd5419264796cfeaf8215383cf0f89130a81fectrawick ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGINT)");
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXCPU)");
74fd6d9aeadb9022086259c5c1ae00bc0dda9c9astoddard /* For systems following the LFS standard, ignoring SIGXFSZ allows
72b6f1cf3e616473e1c26464b3193b13c2c09e87brianp * a write() beyond the 2GB limit to fail gracefully with E2BIG
72b6f1cf3e616473e1c26464b3193b13c2c09e87brianp * rather than terminate the process. */
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXFSZ)");
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGPIPE)");
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard * processing one
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGHUP)");
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(" AP_SIG_GRACEFUL_STRING ")");
3568de757bac0b47256647504c186d17ca272f85rbb#endif /* SIGXCPU */
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard#endif /* SIGXFSZ */
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz#endif /* SIGHUP */
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz#endif /* AP_SIG_GRACEFUL */
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard#endif /* AP_SIG_GRACEFUL */
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard#endif /* SIGPIPE */
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard/*****************************************************************
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard * Child process main loop.
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard * The following vars are static to avoid getting clobbered by longjmp();
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard * they are really private to child_main.
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddardstatic int num_listensocks = 0;
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard const char *lockfile;
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this
3568de757bac0b47256647504c186d17ca272f85rbb * child initializes
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz /* Get a sub context for global allocations in this child, so that
3568de757bac0b47256647504c186d17ca272f85rbb * we can have cleanups occur when the child exits.
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz apr_allocator_max_free_set(allocator, ap_max_mem_free);
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard /* needs to be done before we switch UIDs so we have permissions */
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz lockfile = apr_proc_mutex_lockfile(accept_mutex);
3568de757bac0b47256647504c186d17ca272f85rbb ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf,
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard "Couldn't initialize cross-process lock in child "
3568de757bac0b47256647504c186d17ca272f85rbb "(%s) (%s)",
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard if (ap_run_drop_privileges(pchild, ap_server_conf)) {
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard (void) ap_update_child_status(sbh, SERVER_READY, (request_rec *) NULL);
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard /* Set up the pollfd array */
8e9734d1a4af74c141e2a0f880bb51bb061fa03atrawick status = apr_pollset_create(&pollset, num_listensocks, pchild, 0);
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf,
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard "Couldn't create pollset in child; check system or user limits");
cd8f8c995d415473f3bfb0b329b2450f2a722c3atrawick clean_child_exit(APEXIT_CHILDSICK); /* assume temporary resource issue */
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard for (lr = ap_listeners, i = num_listensocks; i--; lr = lr->next) {
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf,
3568de757bac0b47256647504c186d17ca272f85rbb "Couldn't add listener to pollset; check system or user limits");
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* die_now is set when AP_SIG_GRACEFUL is received in the child;
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * shutdown_pending is set when SIGTERM is received when running
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * in single process mode. */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * (Re)initialize this child to a pre-connection state.
a72ba68ecbbc61e4b513e50d6000245c33f753dcwrowe && requests_this_child++ >= ap_max_requests_per_child)) {
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm (void) ap_update_child_status(sbh, SERVER_READY, (request_rec *) NULL);
2e7f1d7da527c09e717251e186deffe55e6fbd0ftrawick * Wait for an acceptable connection to arrive.
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm /* Lock around "accept", if necessary */
e8f95a682820a599fe41b22977010636be5c2717jim /* There is only one listener record, so refer to that one. */
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz /* multiple listening sockets - need to poll */
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm /* check for termination first so we don't sleep for a while in
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm * poll if already signalled
36c8049de63c446926139936c3d195330a0539cetrawick /* timeout == 10 seconds to avoid a hang at graceful restart/stop
e8f95a682820a599fe41b22977010636be5c2717jim * caused by the closing of sockets by the signal handler
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm status = apr_pollset_poll(pollset, apr_time_from_sec(10),
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* Single Unix documents select as returning errnos
cb97ae2ff6969c2789b8e03f1bc4187fa73b6bafwrowe * EBADF, EINTR, and EINVAL... and in none of those
36c8049de63c446926139936c3d195330a0539cetrawick * cases does it make sense to continue. In fact
36c8049de63c446926139936c3d195330a0539cetrawick * on Linux 2.0.x we seem to end up with EFAULT
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * occasionally, and we'd loop forever due to it.
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* We can always use pdesc[0], but sockets at position N
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * could end up completely starved of attention in a very
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * busy server. Therefore, we round-robin across the
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * returned set of descriptors. While it is possible that
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * the returned set of descriptors might flip around and
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * continue to starve some sockets, we happen to know the
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * internal pollset implementation retains ordering
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * stability of the sockets. Thus, the round-robin should
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * ensure that a socket will eventually be serviced.
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* Grab a listener record from the client_data of the poll
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * descriptor, and advance our saved index to round-robin
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * the next fetch.
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * ### hmm... this descriptor might have POLLERR rather
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * ### than POLLIN
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* if we accept() something we don't want to die, so we have to
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * defer the exit
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick SAFE_ACCEPT(accept_mutex_off()); /* unlock after "accept" */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* resource shortage or should-not-occur occured */
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm * We now have a connection, so set it up with the appropriate
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm * socket options, file descriptors, and read/write buffers.
72b6f1cf3e616473e1c26464b3193b13c2c09e87brianp current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, my_child_num, sbh, bucket_alloc);
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* Check the pod and the generation number after processing a
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * connection so that we'll go away if a graceful restart occurred
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * while we were processing the connection or we are the lucky
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm * idle server process that gets to die.
f2e009134c7e279f99dfca5bd421f721bf1f7840jorton if (ap_mpm_pod_check(pod) == APR_SUCCESS) { /* selected as idle? */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick ap_scoreboard_image->global->running_generation) { /* restart? */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* yeah, this could be non-graceful restart, in which case the
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm * parent will kill us soon enough, but why bother checking?
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick apr_pool_clear(ptrans); /* kludge to avoid crash in APR reslist cleanup code */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* Don't catch AP_SIG_GRACEFUL in ONE_PROCESS mode :) */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* NOTREACHED */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick (void) ap_update_child_status_from_indexes(slot, 0, SERVER_STARTING,
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* BS2000 requires a "special" version of fork() before a setuid() call */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick if ((pid = os_fork(ap_unixd_config.user_name)) == -1) {
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, "fork: Unable to fork new process");
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* fork didn't succeed. Fix the scoreboard or else
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * it will say SERVER_STARTING forever and ever
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick (void) ap_update_child_status_from_indexes(slot, 0, SERVER_DEAD,
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* In case system resources are maxxed out, we don't want
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * Apache running away with the CPU trying to fork over and
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * over and over again.
f886987cd0bd4220c14043c4d9be77ec22902e73trawick /* by default AIX binds to a single processor
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm * this bit unbinds children which will then bind to another cpu
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm int status = bindprocessor(BINDPROCESS, (int)getpid(),
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* Disable the parent's signal handlers and set up proper handling in
e8f95a682820a599fe41b22977010636be5c2717jim * the child.
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* The child process just closes listeners on AP_SIG_GRACEFUL.
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * The pod is used for signalling the graceful restart.
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz/* start up a bunch of children */
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe for (i = 0; number_to_start && i < ap_daemons_limit; ++i) {
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) {
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowestatic void perform_idle_server_maintenance(apr_pool_t *p)
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz /* initialize the free_list */
e8f95a682820a599fe41b22977010636be5c2717jim for (i = 0; i < ap_daemons_limit; ++i) {
98fb535f829e2a95aabd82420931f476661fa8e3jorton if (i >= retained->max_daemons_limit && free_length == retained->idle_spawn_rate)
3568de757bac0b47256647504c186d17ca272f85rbb /* try to keep children numbers as low as possible */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* We consider a starting server as idle because we started it
3568de757bac0b47256647504c186d17ca272f85rbb * at least a cycle ago, and if it still hasn't finished starting
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz * then we're just going to swamp things worse by forking more.
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz * So we hopefully won't need to fork more if we count it.
3568de757bac0b47256647504c186d17ca272f85rbb * This depends on the ordering of SERVER_READY and SERVER_STARTING.
cd8f8c995d415473f3bfb0b329b2450f2a722c3atrawick /* kill off one child... we use the pod because that'll cause it to
cd8f8c995d415473f3bfb0b329b2450f2a722c3atrawick * shut down gracefully, in case it happened to pick up a request
9d0665da83d1e22c0ea0e5f6f940f70f75bf5237ianh * while we were counting
7cd5419264796cfeaf8215383cf0f89130a81fectrawick /* terminate the free list */
7cd5419264796cfeaf8215383cf0f89130a81fectrawick /* only report this condition once */
73e8b26287de5c06fa470d36162e103dbac9c7e5wrowe ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding "server reached MaxClients setting, consider"
b980ad7fdc218b4855cde9f75a747527f50c554dwrowe " raising the MaxClients setting");
3d96ee83babeec32482c9082c9426340cee8c44dwrowe ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding "server seems busy, (you may need "
302dc1f7b3feee23a91ad8f3cf3cb2edd95a557bmanoj "to increase StartServers, or Min/MaxSpareServers), "
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz "spawning %d children, there are %d idle, and "
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz for (i = 0; i < free_length; ++i) {
3568de757bac0b47256647504c186d17ca272f85rbb /* the next time around we want to spawn twice as many if this
int index;
s, _pconf, 0);
return DONE;
return DONE;
set_signals();
if (one_process) {
int child_slot;
return DONE;
if (child_slot >= 0) {
else if (remaining_children_to_start
0, ap_server_conf,
else if (remaining_children_to_start) {
return DONE;
} else if (shutdown_pending) {
int active_children;
active_children = 0;
if (ap_graceful_shutdown_timeout) {
shutdown_pending = 0;
active_children = 0;
return DONE;
if (one_process) {
return DONE;
return OK;
int startup = 0;
int level_flags = 0;
pconf = p;
return DONE;
return DONE;
return OK;
if (debug) {
no_detach = 0;
if (!retained) {
return HTTP_INTERNAL_SERVER_ERROR;
ap_extended_status = 0;
return OK;
int startup = 0;
if (startup) {
if (startup) {
if (startup) {
if (startup) {
if (ap_daemons_to_start < 0) {
if (startup) {
if (startup) {
return OK;
return err;
return NULL;
return err;
return NULL;
return err;
return NULL;
return err;
return NULL;
return err;
return NULL;
{ NULL }