1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements.  See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License.  You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "apr.h"
18#include "apr_portable.h"
19#include "apr_strings.h"
20#include "apr_thread_proc.h"
21#include "apr_signal.h"
22
23#define APR_WANT_STDIO
24#define APR_WANT_STRFUNC
25#include "apr_want.h"
26
27#if APR_HAVE_UNISTD_H
28#include <unistd.h>
29#endif
30#if APR_HAVE_SYS_TYPES_H
31#include <sys/types.h>
32#endif
33
34#define CORE_PRIVATE
35
36#include "ap_config.h"
37#include "httpd.h"
38#include "mpm_default.h"
39#include "http_main.h"
40#include "http_log.h"
41#include "http_config.h"
42#include "http_core.h"          /* for get_remote_host */
43#include "http_connection.h"
44#include "scoreboard.h"
45#include "ap_mpm.h"
46#include "unixd.h"
47#include "mpm_common.h"
48#include "ap_listen.h"
49#include "ap_mmn.h"
50#include "apr_poll.h"
51
52#ifdef HAVE_BSTRING_H
53#include <bstring.h>            /* for IRIX, FD_SET calls bzero() */
54#endif
55#ifdef HAVE_TIME_H
56#include <time.h>
57#endif
58#ifdef HAVE_SYS_PROCESSOR_H
59#include <sys/processor.h> /* for bindprocessor() */
60#endif
61
62#include <signal.h>
63#include <sys/times.h>
64
65/* Limit on the total --- clients will be locked out if more servers than
66 * this are needed.  It is intended solely to keep the server from crashing
67 * when things get out of hand.
68 *
69 * We keep a hard maximum number of servers, for two reasons --- first off,
70 * in case something goes seriously wrong, we want to stop the fork bomb
71 * short of actually crashing the machine we're running on by filling some
72 * kernel table.  Secondly, it keeps the size of the scoreboard file small
73 * enough that we can read the whole thing without worrying too much about
74 * the overhead.
75 */
76#ifndef DEFAULT_SERVER_LIMIT
77#define DEFAULT_SERVER_LIMIT 256
78#endif
79
80/* Admin can't tune ServerLimit beyond MAX_SERVER_LIMIT.  We want
81 * some sort of compile-time limit to help catch typos.
82 */
83#ifndef MAX_SERVER_LIMIT
84#define MAX_SERVER_LIMIT 200000
85#endif
86
87#ifndef HARD_THREAD_LIMIT
88#define HARD_THREAD_LIMIT 1
89#endif
90
91/* config globals */
92
93int ap_threads_per_child=0;         /* Worker threads per child */
94static apr_proc_mutex_t *accept_mutex;
95static int ap_daemons_to_start=0;
96static int ap_daemons_min_free=0;
97static int ap_daemons_max_free=0;
98static int ap_daemons_limit=0;      /* MaxClients */
99static int server_limit = DEFAULT_SERVER_LIMIT;
100static int first_server_limit = 0;
101static int changed_limit_at_restart;
102static int mpm_state = AP_MPMQ_STARTING;
103static ap_pod_t *pod;
104
105/*
106 * The max child slot ever assigned, preserved across restarts.  Necessary
107 * to deal with MaxClients changes across AP_SIG_GRACEFUL restarts.  We
108 * use this value to optimize routines that have to scan the entire scoreboard.
109 */
110int ap_max_daemons_limit = -1;
111server_rec *ap_server_conf;
112
113/* one_process --- debugging mode variable; can be set from the command line
114 * with the -X flag.  If set, this gets you the child_main loop running
115 * in the process which originally started up (no detach, no make_child),
116 * which is a pretty nice debugging environment.  (You'll get a SIGHUP
117 * early in standalone_main; just continue through.  This is the server
118 * trying to kill off any child processes which it might have lying
119 * around --- Apache doesn't keep track of their pids, it just sends
120 * SIGHUP to the process group, ignoring it in the root process.
121 * Continue through and you'll be fine.).
122 */
123
124static int one_process = 0;
125
126static apr_pool_t *pconf;               /* Pool for config stuff */
127static apr_pool_t *pchild;              /* Pool for httpd child stuff */
128
129static pid_t ap_my_pid; /* it seems silly to call getpid all the time */
130static pid_t parent_pid;
131#ifndef MULTITHREAD
132static int my_child_num;
133#endif
134ap_generation_t volatile ap_my_generation=0;
135
136#ifdef TPF
137int tpf_child = 0;
138char tpf_server_name[INETD_SERVNAME_LENGTH+1];
139#endif /* TPF */
140
141static volatile int die_now = 0;
142
143#ifdef GPROF
144/*
145 * change directory for gprof to plop the gmon.out file
146 * configure in httpd.conf:
147 * GprofDir $RuntimeDir/   -> $ServerRoot/$RuntimeDir/gmon.out
148 * GprofDir $RuntimeDir/%  -> $ServerRoot/$RuntimeDir/gprof.$pid/gmon.out
149 */
150static void chdir_for_gprof(void)
151{
152    core_server_config *sconf =
153        ap_get_module_config(ap_server_conf->module_config, &core_module);
154    char *dir = sconf->gprof_dir;
155    const char *use_dir;
156
157    if(dir) {
158        apr_status_t res;
159        char *buf = NULL ;
160        int len = strlen(sconf->gprof_dir) - 1;
161        if(*(dir + len) == '%') {
162            dir[len] = '\0';
163            buf = ap_append_pid(pconf, dir, "gprof.");
164        }
165        use_dir = ap_server_root_relative(pconf, buf ? buf : dir);
166        res = apr_dir_make(use_dir,
167                           APR_UREAD | APR_UWRITE | APR_UEXECUTE |
168                           APR_GREAD | APR_GEXECUTE |
169                           APR_WREAD | APR_WEXECUTE, pconf);
170        if(res != APR_SUCCESS && !APR_STATUS_IS_EEXIST(res)) {
171            ap_log_error(APLOG_MARK, APLOG_ERR, res, ap_server_conf,
172                         "gprof: error creating directory %s", dir);
173        }
174    }
175    else {
176        use_dir = ap_server_root_relative(pconf, DEFAULT_REL_RUNTIMEDIR);
177    }
178
179    chdir(use_dir);
180}
181#else
182#define chdir_for_gprof()
183#endif
184
185/* XXX - I don't know if TPF will ever use this module or not, so leave
186 * the ap_check_signals calls in but disable them - manoj */
187#define ap_check_signals()
188
189/* a clean exit from a child with proper cleanup */
190static void clean_child_exit(int code) __attribute__ ((noreturn));
191static void clean_child_exit(int code)
192{
193    mpm_state = AP_MPMQ_STOPPING;
194
195    if (pchild) {
196        apr_pool_destroy(pchild);
197    }
198    ap_mpm_pod_close(pod);
199    chdir_for_gprof();
200    exit(code);
201}
202
203static void accept_mutex_on(void)
204{
205    apr_status_t rv = apr_proc_mutex_lock(accept_mutex);
206    if (rv != APR_SUCCESS) {
207        const char *msg = "couldn't grab the accept mutex";
208
209        if (ap_my_generation !=
210            ap_scoreboard_image->global->running_generation) {
211            ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, NULL, "%s", msg);
212            clean_child_exit(0);
213        }
214        else {
215            ap_log_error(APLOG_MARK, APLOG_EMERG, rv, NULL, "%s", msg);
216            exit(APEXIT_CHILDFATAL);
217        }
218    }
219}
220
221static void accept_mutex_off(void)
222{
223    apr_status_t rv = apr_proc_mutex_unlock(accept_mutex);
224    if (rv != APR_SUCCESS) {
225        const char *msg = "couldn't release the accept mutex";
226
227        if (ap_my_generation !=
228            ap_scoreboard_image->global->running_generation) {
229            ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, NULL, "%s", msg);
230            /* don't exit here... we have a connection to
231             * process, after which point we'll see that the
232             * generation changed and we'll exit cleanly
233             */
234        }
235        else {
236            ap_log_error(APLOG_MARK, APLOG_EMERG, rv, NULL, "%s", msg);
237            exit(APEXIT_CHILDFATAL);
238        }
239    }
240}
241
242/* On some architectures it's safe to do unserialized accept()s in the single
243 * Listen case.  But it's never safe to do it in the case where there's
244 * multiple Listen statements.  Define SINGLE_LISTEN_UNSERIALIZED_ACCEPT
245 * when it's safe in the single Listen case.
246 */
247#ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT
248#define SAFE_ACCEPT(stmt) do {if (ap_listeners->next) {stmt;}} while(0)
249#else
250#define SAFE_ACCEPT(stmt) do {stmt;} while(0)
251#endif
252
253AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
254{
255    switch(query_code){
256    case AP_MPMQ_MAX_DAEMON_USED:
257        *result = ap_daemons_limit;
258        return APR_SUCCESS;
259    case AP_MPMQ_IS_THREADED:
260        *result = AP_MPMQ_NOT_SUPPORTED;
261        return APR_SUCCESS;
262    case AP_MPMQ_IS_FORKED:
263        *result = AP_MPMQ_DYNAMIC;
264        return APR_SUCCESS;
265    case AP_MPMQ_HARD_LIMIT_DAEMONS:
266        *result = server_limit;
267        return APR_SUCCESS;
268    case AP_MPMQ_HARD_LIMIT_THREADS:
269        *result = HARD_THREAD_LIMIT;
270        return APR_SUCCESS;
271    case AP_MPMQ_MAX_THREADS:
272        *result = 0;
273        return APR_SUCCESS;
274    case AP_MPMQ_MIN_SPARE_DAEMONS:
275        *result = ap_daemons_min_free;
276        return APR_SUCCESS;
277    case AP_MPMQ_MIN_SPARE_THREADS:
278        *result = 0;
279        return APR_SUCCESS;
280    case AP_MPMQ_MAX_SPARE_DAEMONS:
281        *result = ap_daemons_max_free;
282        return APR_SUCCESS;
283    case AP_MPMQ_MAX_SPARE_THREADS:
284        *result = 0;
285        return APR_SUCCESS;
286    case AP_MPMQ_MAX_REQUESTS_DAEMON:
287        *result = ap_max_requests_per_child;
288        return APR_SUCCESS;
289    case AP_MPMQ_MAX_DAEMONS:
290        *result = server_limit;
291        return APR_SUCCESS;
292    case AP_MPMQ_MPM_STATE:
293        *result = mpm_state;
294        return APR_SUCCESS;
295    }
296    return APR_ENOTIMPL;
297}
298
299#if defined(NEED_WAITPID)
300/*
301   Systems without a real waitpid sometimes lose a child's exit while waiting
302   for another.  Search through the scoreboard for missing children.
303 */
304int reap_children(int *exitcode, apr_exit_why_e *status)
305{
306    int n, pid;
307
308    for (n = 0; n < ap_max_daemons_limit; ++n) {
309        if (ap_scoreboard_image->servers[n][0].status != SERVER_DEAD &&
310                kill((pid = ap_scoreboard_image->parent[n].pid), 0) == -1) {
311            ap_update_child_status_from_indexes(n, 0, SERVER_DEAD, NULL);
312            /* just mark it as having a successful exit status */
313            *status = APR_PROC_EXIT;
314            *exitcode = 0;
315            return(pid);
316        }
317    }
318    return 0;
319}
320#endif
321
322/*****************************************************************
323 * Connection structures and accounting...
324 */
325
326static void just_die(int sig)
327{
328    clean_child_exit(0);
329}
330
331static void stop_listening(int sig)
332{
333    mpm_state = AP_MPMQ_STOPPING;
334    ap_close_listeners();
335
336    /* For a graceful stop, we want the child to exit when done */
337    die_now = 1;
338}
339
340/* volatile just in case */
341static int volatile shutdown_pending;
342static int volatile restart_pending;
343static int volatile is_graceful;
344
345static void sig_term(int sig)
346{
347    if (shutdown_pending == 1) {
348        /* Um, is this _probably_ not an error, if the user has
349         * tried to do a shutdown twice quickly, so we won't
350         * worry about reporting it.
351         */
352        return;
353    }
354    mpm_state = AP_MPMQ_STOPPING;
355    shutdown_pending = 1;
356    is_graceful = (sig == AP_SIG_GRACEFUL_STOP);
357}
358
359/* restart() is the signal handler for SIGHUP and AP_SIG_GRACEFUL
360 * in the parent process, unless running in ONE_PROCESS mode
361 */
362static void restart(int sig)
363{
364    if (restart_pending == 1) {
365        /* Probably not an error - don't bother reporting it */
366        return;
367    }
368    mpm_state = AP_MPMQ_STOPPING;
369    restart_pending = 1;
370    is_graceful = (sig == AP_SIG_GRACEFUL);
371}
372
373static void set_signals(void)
374{
375#ifndef NO_USE_SIGACTION
376    struct sigaction sa;
377#endif
378
379    if (!one_process) {
380        ap_fatal_signal_setup(ap_server_conf, pconf);
381    }
382
383#ifndef NO_USE_SIGACTION
384    sigemptyset(&sa.sa_mask);
385    sa.sa_flags = 0;
386
387    sa.sa_handler = sig_term;
388    if (sigaction(SIGTERM, &sa, NULL) < 0)
389        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGTERM)");
390#ifdef AP_SIG_GRACEFUL_STOP
391    if (sigaction(AP_SIG_GRACEFUL_STOP, &sa, NULL) < 0)
392        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
393                     "sigaction(" AP_SIG_GRACEFUL_STOP_STRING ")");
394#endif
395#ifdef SIGINT
396    if (sigaction(SIGINT, &sa, NULL) < 0)
397        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGINT)");
398#endif
399#ifdef SIGXCPU
400    sa.sa_handler = SIG_DFL;
401    if (sigaction(SIGXCPU, &sa, NULL) < 0)
402        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXCPU)");
403#endif
404#ifdef SIGXFSZ
405    sa.sa_handler = SIG_DFL;
406    if (sigaction(SIGXFSZ, &sa, NULL) < 0)
407        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXFSZ)");
408#endif
409#ifdef SIGPIPE
410    sa.sa_handler = SIG_IGN;
411    if (sigaction(SIGPIPE, &sa, NULL) < 0)
412        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGPIPE)");
413#endif
414
415    /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy
416     * processing one
417     */
418    sigaddset(&sa.sa_mask, SIGHUP);
419    sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL);
420    sa.sa_handler = restart;
421    if (sigaction(SIGHUP, &sa, NULL) < 0)
422        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGHUP)");
423    if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0)
424        ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(" AP_SIG_GRACEFUL_STRING ")");
425#else
426    if (!one_process) {
427#ifdef SIGXCPU
428        apr_signal(SIGXCPU, SIG_DFL);
429#endif /* SIGXCPU */
430#ifdef SIGXFSZ
431        apr_signal(SIGXFSZ, SIG_DFL);
432#endif /* SIGXFSZ */
433    }
434
435    apr_signal(SIGTERM, sig_term);
436#ifdef SIGHUP
437    apr_signal(SIGHUP, restart);
438#endif /* SIGHUP */
439#ifdef AP_SIG_GRACEFUL
440    apr_signal(AP_SIG_GRACEFUL, restart);
441#endif /* AP_SIG_GRACEFUL */
442#ifdef AP_SIG_GRACEFUL_STOP
443    apr_signal(AP_SIG_GRACEFUL_STOP, sig_term);
444#endif /* AP_SIG_GRACEFUL */
445#ifdef SIGPIPE
446    apr_signal(SIGPIPE, SIG_IGN);
447#endif /* SIGPIPE */
448
449#endif
450}
451
452/*****************************************************************
453 * Child process main loop.
454 * The following vars are static to avoid getting clobbered by longjmp();
455 * they are really private to child_main.
456 */
457
458static int requests_this_child;
459static int num_listensocks = 0;
460
461
462int ap_graceful_stop_signalled(void)
463{
464    /* Return true if the server is stopping for whatever reason; the
465     * function is used to initiate a fast exit from the connection
466     * processing loop. */
467    return mpm_state == AP_MPMQ_STOPPING;
468}
469
470
471static void child_main(int child_num_arg)
472{
473    apr_pool_t *ptrans;
474    apr_allocator_t *allocator;
475    apr_status_t status;
476    int i;
477    ap_listen_rec *lr;
478    apr_pollset_t *pollset;
479    ap_sb_handle_t *sbh;
480    apr_bucket_alloc_t *bucket_alloc;
481    int last_poll_idx = 0;
482
483    mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this
484                                   * child initializes
485                                   */
486
487    my_child_num = child_num_arg;
488    ap_my_pid = getpid();
489    requests_this_child = 0;
490
491    ap_fatal_signal_child_setup(ap_server_conf);
492
493    /* Get a sub context for global allocations in this child, so that
494     * we can have cleanups occur when the child exits.
495     */
496    apr_allocator_create(&allocator);
497    apr_allocator_max_free_set(allocator, ap_max_mem_free);
498    apr_pool_create_ex(&pchild, pconf, NULL, allocator);
499    apr_allocator_owner_set(allocator, pchild);
500
501    apr_pool_create(&ptrans, pchild);
502    apr_pool_tag(ptrans, "transaction");
503
504    /* needs to be done before we switch UIDs so we have permissions */
505    ap_reopen_scoreboard(pchild, NULL, 0);
506    status = apr_proc_mutex_child_init(&accept_mutex, ap_lock_fname, pchild);
507    if (status != APR_SUCCESS) {
508        ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf,
509                     "Couldn't initialize cross-process lock in child "
510                     "(%s) (%d)", ap_lock_fname, ap_accept_lock_mech);
511        clean_child_exit(APEXIT_CHILDFATAL);
512    }
513
514    if (unixd_setup_child()) {
515        clean_child_exit(APEXIT_CHILDFATAL);
516    }
517
518    ap_run_child_init(pchild, ap_server_conf);
519
520    ap_create_sb_handle(&sbh, pchild, my_child_num, 0);
521
522    (void) ap_update_child_status(sbh, SERVER_READY, (request_rec *) NULL);
523
524    /* Set up the pollfd array */
525    status = apr_pollset_create(&pollset, num_listensocks, pchild, 0);
526    if (status != APR_SUCCESS) {
527        ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf,
528                     "Couldn't create pollset in child; check system or user limits");
529        clean_child_exit(APEXIT_CHILDSICK); /* assume temporary resource issue */
530    }
531
532    for (lr = ap_listeners, i = num_listensocks; i--; lr = lr->next) {
533        apr_pollfd_t pfd = { 0 };
534
535        pfd.desc_type = APR_POLL_SOCKET;
536        pfd.desc.s = lr->sd;
537        pfd.reqevents = APR_POLLIN;
538        pfd.client_data = lr;
539
540        /* ### check the status */
541        (void) apr_pollset_add(pollset, &pfd);
542    }
543
544    mpm_state = AP_MPMQ_RUNNING;
545
546    bucket_alloc = apr_bucket_alloc_create(pchild);
547
548    /* die_now is set when AP_SIG_GRACEFUL is received in the child;
549     * shutdown_pending is set when SIGTERM is received when running
550     * in single process mode.  */
551    while (!die_now && !shutdown_pending) {
552        conn_rec *current_conn;
553        void *csd;
554
555        /*
556         * (Re)initialize this child to a pre-connection state.
557         */
558
559        apr_pool_clear(ptrans);
560
561        if ((ap_max_requests_per_child > 0
562             && requests_this_child++ >= ap_max_requests_per_child)) {
563            clean_child_exit(0);
564        }
565
566        (void) ap_update_child_status(sbh, SERVER_READY, (request_rec *) NULL);
567
568        /*
569         * Wait for an acceptable connection to arrive.
570         */
571
572        /* Lock around "accept", if necessary */
573        SAFE_ACCEPT(accept_mutex_on());
574
575        if (num_listensocks == 1) {
576            /* There is only one listener record, so refer to that one. */
577            lr = ap_listeners;
578        }
579        else {
580            /* multiple listening sockets - need to poll */
581            for (;;) {
582                apr_int32_t numdesc;
583                const apr_pollfd_t *pdesc;
584
585                /* check for termination first so we don't sleep for a while in
586                 * poll if already signalled
587                 */
588                if (one_process && shutdown_pending) {
589                    SAFE_ACCEPT(accept_mutex_off());
590                    return;
591                }
592                else if (die_now) {
593                    /* In graceful stop/restart; drop the mutex
594                     * and terminate the child. */
595                    SAFE_ACCEPT(accept_mutex_off());
596                    clean_child_exit(0);
597                }
598                /* timeout == 10 seconds to avoid a hang at graceful restart/stop
599                 * caused by the closing of sockets by the signal handler
600                 */
601                status = apr_pollset_poll(pollset, apr_time_from_sec(10),
602                                          &numdesc, &pdesc);
603                if (status != APR_SUCCESS) {
604                    if (APR_STATUS_IS_TIMEUP(status) ||
605                        APR_STATUS_IS_EINTR(status)) {
606                        continue;
607                    }
608                    /* Single Unix documents select as returning errnos
609                     * EBADF, EINTR, and EINVAL... and in none of those
610                     * cases does it make sense to continue.  In fact
611                     * on Linux 2.0.x we seem to end up with EFAULT
612                     * occasionally, and we'd loop forever due to it.
613                     */
614                    ap_log_error(APLOG_MARK, APLOG_ERR, status,
615                                 ap_server_conf, "apr_pollset_poll: (listen)");
616                    SAFE_ACCEPT(accept_mutex_off());
617                    clean_child_exit(APEXIT_CHILDSICK);
618                }
619
620                /* We can always use pdesc[0], but sockets at position N
621                 * could end up completely starved of attention in a very
622                 * busy server. Therefore, we round-robin across the
623                 * returned set of descriptors. While it is possible that
624                 * the returned set of descriptors might flip around and
625                 * continue to starve some sockets, we happen to know the
626                 * internal pollset implementation retains ordering
627                 * stability of the sockets. Thus, the round-robin should
628                 * ensure that a socket will eventually be serviced.
629                 */
630                if (last_poll_idx >= numdesc)
631                    last_poll_idx = 0;
632
633                /* Grab a listener record from the client_data of the poll
634                 * descriptor, and advance our saved index to round-robin
635                 * the next fetch.
636                 *
637                 * ### hmm... this descriptor might have POLLERR rather
638                 * ### than POLLIN
639                 */
640                lr = pdesc[last_poll_idx++].client_data;
641                goto got_fd;
642            }
643        }
644    got_fd:
645        /* if we accept() something we don't want to die, so we have to
646         * defer the exit
647         */
648        status = lr->accept_func(&csd, lr, ptrans);
649
650        SAFE_ACCEPT(accept_mutex_off());      /* unlock after "accept" */
651
652        if (status == APR_EGENERAL) {
653            /* resource shortage or should-not-occur occured */
654            clean_child_exit(APEXIT_CHILDSICK);
655        }
656        else if (status != APR_SUCCESS) {
657            continue;
658        }
659
660        /*
661         * We now have a connection, so set it up with the appropriate
662         * socket options, file descriptors, and read/write buffers.
663         */
664
665        current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, my_child_num, sbh, bucket_alloc);
666        if (current_conn) {
667            ap_process_connection(current_conn, csd);
668            ap_lingering_close(current_conn);
669        }
670
671        /* Check the pod and the generation number after processing a
672         * connection so that we'll go away if a graceful restart occurred
673         * while we were processing the connection or we are the lucky
674         * idle server process that gets to die.
675         */
676        if (ap_mpm_pod_check(pod) == APR_SUCCESS) { /* selected as idle? */
677            die_now = 1;
678        }
679        else if (ap_my_generation !=
680                 ap_scoreboard_image->global->running_generation) { /* restart? */
681            /* yeah, this could be non-graceful restart, in which case the
682             * parent will kill us soon enough, but why bother checking?
683             */
684            die_now = 1;
685        }
686    }
687    /* This apr_pool_clear call is redundant, should be redundant, but compensates
688     * a flaw in the apr reslist code.  This should be removed once that flaw has
689     * been addressed.
690     */
691    apr_pool_clear(ptrans);
692    clean_child_exit(0);
693}
694
695
696static int make_child(server_rec *s, int slot)
697{
698    int pid;
699
700    if (slot + 1 > ap_max_daemons_limit) {
701        ap_max_daemons_limit = slot + 1;
702    }
703
704    if (one_process) {
705        apr_signal(SIGHUP, sig_term);
706        /* Don't catch AP_SIG_GRACEFUL in ONE_PROCESS mode :) */
707        apr_signal(SIGINT, sig_term);
708#ifdef SIGQUIT
709        apr_signal(SIGQUIT, SIG_DFL);
710#endif
711        apr_signal(SIGTERM, sig_term);
712        child_main(slot);
713        return 0;
714    }
715
716    (void) ap_update_child_status_from_indexes(slot, 0, SERVER_STARTING,
717                                               (request_rec *) NULL);
718
719
720#ifdef _OSD_POSIX
721    /* BS2000 requires a "special" version of fork() before a setuid() call */
722    if ((pid = os_fork(unixd_config.user_name)) == -1) {
723#elif defined(TPF)
724    if ((pid = os_fork(s, slot)) == -1) {
725#else
726    if ((pid = fork()) == -1) {
727#endif
728        ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, "fork: Unable to fork new process");
729
730        /* fork didn't succeed. Fix the scoreboard or else
731         * it will say SERVER_STARTING forever and ever
732         */
733        (void) ap_update_child_status_from_indexes(slot, 0, SERVER_DEAD,
734                                                   (request_rec *) NULL);
735
736        /* In case system resources are maxxed out, we don't want
737         * Apache running away with the CPU trying to fork over and
738         * over and over again.
739         */
740        sleep(10);
741
742        return -1;
743    }
744
745    if (!pid) {
746#ifdef HAVE_BINDPROCESSOR
747        /* by default AIX binds to a single processor
748         * this bit unbinds children which will then bind to another cpu
749         */
750        int status = bindprocessor(BINDPROCESS, (int)getpid(),
751                                   PROCESSOR_CLASS_ANY);
752        if (status != OK) {
753            ap_log_error(APLOG_MARK, APLOG_WARNING, errno,
754                         ap_server_conf, "processor unbind failed %d", status);
755        }
756#endif
757        RAISE_SIGSTOP(MAKE_CHILD);
758        AP_MONCONTROL(1);
759        /* Disable the parent's signal handlers and set up proper handling in
760         * the child.
761         */
762        apr_signal(SIGHUP, just_die);
763        apr_signal(SIGTERM, just_die);
764        /* The child process just closes listeners on AP_SIG_GRACEFUL.
765         * The pod is used for signalling the graceful restart.
766         */
767        apr_signal(AP_SIG_GRACEFUL, stop_listening);
768        child_main(slot);
769    }
770
771    ap_scoreboard_image->parent[slot].pid = pid;
772
773    return 0;
774}
775
776
777/* start up a bunch of children */
778static void startup_children(int number_to_start)
779{
780    int i;
781
782    for (i = 0; number_to_start && i < ap_daemons_limit; ++i) {
783        if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) {
784            continue;
785        }
786        if (make_child(ap_server_conf, i) < 0) {
787            break;
788        }
789        --number_to_start;
790    }
791}
792
793
794/*
795 * idle_spawn_rate is the number of children that will be spawned on the
796 * next maintenance cycle if there aren't enough idle servers.  It is
797 * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by
798 * without the need to spawn.
799 */
800static int idle_spawn_rate = 1;
801#ifndef MAX_SPAWN_RATE
802#define MAX_SPAWN_RATE  (32)
803#endif
804static int hold_off_on_exponential_spawning;
805
806static void perform_idle_server_maintenance(apr_pool_t *p)
807{
808    int i;
809    int to_kill;
810    int idle_count;
811    worker_score *ws;
812    int free_length;
813    int free_slots[MAX_SPAWN_RATE];
814    int last_non_dead;
815    int total_non_dead;
816
817    /* initialize the free_list */
818    free_length = 0;
819
820    to_kill = -1;
821    idle_count = 0;
822    last_non_dead = -1;
823    total_non_dead = 0;
824
825    for (i = 0; i < ap_daemons_limit; ++i) {
826        int status;
827
828        if (i >= ap_max_daemons_limit && free_length == idle_spawn_rate)
829            break;
830        ws = &ap_scoreboard_image->servers[i][0];
831        status = ws->status;
832        if (status == SERVER_DEAD) {
833            /* try to keep children numbers as low as possible */
834            if (free_length < idle_spawn_rate) {
835                free_slots[free_length] = i;
836                ++free_length;
837            }
838        }
839        else {
840            /* We consider a starting server as idle because we started it
841             * at least a cycle ago, and if it still hasn't finished starting
842             * then we're just going to swamp things worse by forking more.
843             * So we hopefully won't need to fork more if we count it.
844             * This depends on the ordering of SERVER_READY and SERVER_STARTING.
845             */
846            if (status <= SERVER_READY) {
847                ++ idle_count;
848                /* always kill the highest numbered child if we have to...
849                 * no really well thought out reason ... other than observing
850                 * the server behaviour under linux where lower numbered children
851                 * tend to service more hits (and hence are more likely to have
852                 * their data in cpu caches).
853                 */
854                to_kill = i;
855            }
856
857            ++total_non_dead;
858            last_non_dead = i;
859        }
860    }
861    ap_max_daemons_limit = last_non_dead + 1;
862    if (idle_count > ap_daemons_max_free) {
863        /* kill off one child... we use the pod because that'll cause it to
864         * shut down gracefully, in case it happened to pick up a request
865         * while we were counting
866         */
867        ap_mpm_pod_signal(pod);
868        idle_spawn_rate = 1;
869    }
870    else if (idle_count < ap_daemons_min_free) {
871        /* terminate the free list */
872        if (free_length == 0) {
873            /* only report this condition once */
874            static int reported = 0;
875
876            if (!reported) {
877                ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
878                            "server reached MaxClients setting, consider"
879                            " raising the MaxClients setting");
880                reported = 1;
881            }
882            idle_spawn_rate = 1;
883        }
884        else {
885            if (idle_spawn_rate >= 8) {
886                ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,
887                    "server seems busy, (you may need "
888                    "to increase StartServers, or Min/MaxSpareServers), "
889                    "spawning %d children, there are %d idle, and "
890                    "%d total children", idle_spawn_rate,
891                    idle_count, total_non_dead);
892            }
893            for (i = 0; i < free_length; ++i) {
894#ifdef TPF
895                if (make_child(ap_server_conf, free_slots[i]) == -1) {
896                    if(free_length == 1) {
897                        shutdown_pending = 1;
898                        ap_log_error(APLOG_MARK, APLOG_EMERG, 0, ap_server_conf,
899                                    "No active child processes: shutting down");
900                    }
901                }
902#else
903                make_child(ap_server_conf, free_slots[i]);
904#endif /* TPF */
905            }
906            /* the next time around we want to spawn twice as many if this
907             * wasn't good enough, but not if we've just done a graceful
908             */
909            if (hold_off_on_exponential_spawning) {
910                --hold_off_on_exponential_spawning;
911            }
912            else if (idle_spawn_rate < MAX_SPAWN_RATE) {
913                idle_spawn_rate *= 2;
914            }
915        }
916    }
917    else {
918        idle_spawn_rate = 1;
919    }
920}
921
922/*****************************************************************
923 * Executive routines.
924 */
925
926int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
927{
928    int index;
929    int remaining_children_to_start;
930    apr_status_t rv;
931
932    ap_log_pid(pconf, ap_pid_fname);
933
934    first_server_limit = server_limit;
935    if (changed_limit_at_restart) {
936        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
937                     "WARNING: Attempt to change ServerLimit "
938                     "ignored during restart");
939        changed_limit_at_restart = 0;
940    }
941
942    /* Initialize cross-process accept lock */
943    ap_lock_fname = apr_psprintf(_pconf, "%s.%" APR_PID_T_FMT,
944                                 ap_server_root_relative(_pconf, ap_lock_fname),
945                                 ap_my_pid);
946
947    rv = apr_proc_mutex_create(&accept_mutex, ap_lock_fname,
948                               ap_accept_lock_mech, _pconf);
949    if (rv != APR_SUCCESS) {
950        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
951                     "Couldn't create accept lock (%s) (%d)",
952                     ap_lock_fname, ap_accept_lock_mech);
953        mpm_state = AP_MPMQ_STOPPING;
954        return 1;
955    }
956
957#if APR_USE_SYSVSEM_SERIALIZE
958    if (ap_accept_lock_mech == APR_LOCK_DEFAULT ||
959        ap_accept_lock_mech == APR_LOCK_SYSVSEM) {
960#else
961    if (ap_accept_lock_mech == APR_LOCK_SYSVSEM) {
962#endif
963        rv = unixd_set_proc_mutex_perms(accept_mutex);
964        if (rv != APR_SUCCESS) {
965            ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
966                         "Couldn't set permissions on cross-process lock; "
967                         "check User and Group directives");
968            mpm_state = AP_MPMQ_STOPPING;
969            return 1;
970        }
971    }
972
973    if (!is_graceful) {
974        if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
975            mpm_state = AP_MPMQ_STOPPING;
976            return 1;
977        }
978        /* fix the generation number in the global score; we just got a new,
979         * cleared scoreboard
980         */
981        ap_scoreboard_image->global->running_generation = ap_my_generation;
982    }
983
984    set_signals();
985
986    if (one_process) {
987        AP_MONCONTROL(1);
988        make_child(ap_server_conf, 0);
989    }
990    else {
991    if (ap_daemons_max_free < ap_daemons_min_free + 1)  /* Don't thrash... */
992        ap_daemons_max_free = ap_daemons_min_free + 1;
993
994    /* If we're doing a graceful_restart then we're going to see a lot
995     * of children exiting immediately when we get into the main loop
996     * below (because we just sent them AP_SIG_GRACEFUL).  This happens pretty
997     * rapidly... and for each one that exits we'll start a new one until
998     * we reach at least daemons_min_free.  But we may be permitted to
999     * start more than that, so we'll just keep track of how many we're
1000     * supposed to start up without the 1 second penalty between each fork.
1001     */
1002    remaining_children_to_start = ap_daemons_to_start;
1003    if (remaining_children_to_start > ap_daemons_limit) {
1004        remaining_children_to_start = ap_daemons_limit;
1005    }
1006    if (!is_graceful) {
1007        startup_children(remaining_children_to_start);
1008        remaining_children_to_start = 0;
1009    }
1010    else {
1011        /* give the system some time to recover before kicking into
1012         * exponential mode
1013         */
1014        hold_off_on_exponential_spawning = 10;
1015    }
1016
1017    ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
1018                "%s configured -- resuming normal operations",
1019                ap_get_server_description());
1020    ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,
1021                "Server built: %s", ap_get_server_built());
1022#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH
1023    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
1024                "AcceptMutex: %s (default: %s)",
1025                apr_proc_mutex_name(accept_mutex),
1026                apr_proc_mutex_defname());
1027#endif
1028    restart_pending = shutdown_pending = 0;
1029
1030    mpm_state = AP_MPMQ_RUNNING;
1031
1032    while (!restart_pending && !shutdown_pending) {
1033        int child_slot;
1034        apr_exit_why_e exitwhy;
1035        int status, processed_status;
1036        /* this is a memory leak, but I'll fix it later. */
1037        apr_proc_t pid;
1038
1039        ap_wait_or_timeout(&exitwhy, &status, &pid, pconf);
1040
1041        /* XXX: if it takes longer than 1 second for all our children
1042         * to start up and get into IDLE state then we may spawn an
1043         * extra child
1044         */
1045        if (pid.pid != -1) {
1046            processed_status = ap_process_child_status(&pid, exitwhy, status);
1047            if (processed_status == APEXIT_CHILDFATAL) {
1048                mpm_state = AP_MPMQ_STOPPING;
1049                return 1;
1050            }
1051
1052            /* non-fatal death... note that it's gone in the scoreboard. */
1053            child_slot = find_child_by_pid(&pid);
1054            if (child_slot >= 0) {
1055                (void) ap_update_child_status_from_indexes(child_slot, 0, SERVER_DEAD,
1056                                                           (request_rec *) NULL);
1057                if (processed_status == APEXIT_CHILDSICK) {
1058                    /* child detected a resource shortage (E[NM]FILE, ENOBUFS, etc)
1059                     * cut the fork rate to the minimum
1060                     */
1061                    idle_spawn_rate = 1;
1062                }
1063                else if (remaining_children_to_start
1064                    && child_slot < ap_daemons_limit) {
1065                    /* we're still doing a 1-for-1 replacement of dead
1066                     * children with new children
1067                     */
1068                    make_child(ap_server_conf, child_slot);
1069                    --remaining_children_to_start;
1070                }
1071#if APR_HAS_OTHER_CHILD
1072            }
1073            else if (apr_proc_other_child_alert(&pid, APR_OC_REASON_DEATH, status) == APR_SUCCESS) {
1074                /* handled */
1075#endif
1076            }
1077            else if (is_graceful) {
1078                /* Great, we've probably just lost a slot in the
1079                 * scoreboard.  Somehow we don't know about this
1080                 * child.
1081                 */
1082                ap_log_error(APLOG_MARK, APLOG_WARNING,
1083                            0, ap_server_conf,
1084                            "long lost child came home! (pid %ld)", (long)pid.pid);
1085            }
1086            /* Don't perform idle maintenance when a child dies,
1087             * only do it when there's a timeout.  Remember only a
1088             * finite number of children can die, and it's pretty
1089             * pathological for a lot to die suddenly.
1090             */
1091            continue;
1092        }
1093        else if (remaining_children_to_start) {
1094            /* we hit a 1 second timeout in which none of the previous
1095             * generation of children needed to be reaped... so assume
1096             * they're all done, and pick up the slack if any is left.
1097             */
1098            startup_children(remaining_children_to_start);
1099            remaining_children_to_start = 0;
1100            /* In any event we really shouldn't do the code below because
1101             * few of the servers we just started are in the IDLE state
1102             * yet, so we'd mistakenly create an extra server.
1103             */
1104            continue;
1105        }
1106
1107        perform_idle_server_maintenance(pconf);
1108#ifdef TPF
1109        shutdown_pending = os_check_server(tpf_server_name);
1110        ap_check_signals();
1111        sleep(1);
1112#endif /*TPF */
1113    }
1114    } /* one_process */
1115
1116    mpm_state = AP_MPMQ_STOPPING;
1117
1118    if (shutdown_pending && !is_graceful) {
1119        /* Time to shut down:
1120         * Kill child processes, tell them to call child_exit, etc...
1121         */
1122        if (unixd_killpg(getpgrp(), SIGTERM) < 0) {
1123            ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "killpg SIGTERM");
1124        }
1125        ap_reclaim_child_processes(1);          /* Start with SIGTERM */
1126
1127        /* cleanup pid file on normal shutdown */
1128        {
1129            const char *pidfile = NULL;
1130            pidfile = ap_server_root_relative (pconf, ap_pid_fname);
1131            if ( pidfile != NULL && unlink(pidfile) == 0)
1132                ap_log_error(APLOG_MARK, APLOG_INFO,
1133                                0, ap_server_conf,
1134                                "removed PID file %s (pid=%ld)",
1135                                pidfile, (long)getpid());
1136        }
1137
1138        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
1139                    "caught SIGTERM, shutting down");
1140
1141        return 1;
1142    } else if (shutdown_pending) {
1143        /* Time to perform a graceful shut down:
1144         * Reap the inactive children, and ask the active ones
1145         * to close their listeners, then wait until they are
1146         * all done to exit.
1147         */
1148        int active_children;
1149        apr_time_t cutoff = 0;
1150
1151        /* Stop listening */
1152        ap_close_listeners();
1153
1154        /* kill off the idle ones */
1155        ap_mpm_pod_killpg(pod, ap_max_daemons_limit);
1156
1157        /* Send SIGUSR1 to the active children */
1158        active_children = 0;
1159        for (index = 0; index < ap_daemons_limit; ++index) {
1160            if (ap_scoreboard_image->servers[index][0].status != SERVER_DEAD) {
1161                /* Ask each child to close its listeners. */
1162                ap_mpm_safe_kill(MPM_CHILD_PID(index), AP_SIG_GRACEFUL);
1163                active_children++;
1164            }
1165        }
1166
1167        /* Allow each child which actually finished to exit */
1168        ap_relieve_child_processes();
1169
1170        /* cleanup pid file */
1171        {
1172            const char *pidfile = NULL;
1173            pidfile = ap_server_root_relative (pconf, ap_pid_fname);
1174            if ( pidfile != NULL && unlink(pidfile) == 0)
1175                ap_log_error(APLOG_MARK, APLOG_INFO,
1176                                0, ap_server_conf,
1177                                "removed PID file %s (pid=%ld)",
1178                                pidfile, (long)getpid());
1179        }
1180
1181        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
1182           "caught " AP_SIG_GRACEFUL_STOP_STRING ", shutting down gracefully");
1183
1184        if (ap_graceful_shutdown_timeout) {
1185            cutoff = apr_time_now() +
1186                     apr_time_from_sec(ap_graceful_shutdown_timeout);
1187        }
1188
1189        /* Don't really exit until each child has finished */
1190        shutdown_pending = 0;
1191        do {
1192            /* Pause for a second */
1193            sleep(1);
1194
1195            /* Relieve any children which have now exited */
1196            ap_relieve_child_processes();
1197
1198            active_children = 0;
1199            for (index = 0; index < ap_daemons_limit; ++index) {
1200                if (ap_mpm_safe_kill(MPM_CHILD_PID(index), 0) == APR_SUCCESS) {
1201                    active_children = 1;
1202                    /* Having just one child is enough to stay around */
1203                    break;
1204                }
1205            }
1206        } while (!shutdown_pending && active_children &&
1207                 (!ap_graceful_shutdown_timeout || apr_time_now() < cutoff));
1208
1209        /* We might be here because we received SIGTERM, either
1210         * way, try and make sure that all of our processes are
1211         * really dead.
1212         */
1213        unixd_killpg(getpgrp(), SIGTERM);
1214
1215        return 1;
1216    }
1217
1218    /* we've been told to restart */
1219    apr_signal(SIGHUP, SIG_IGN);
1220    apr_signal(AP_SIG_GRACEFUL, SIG_IGN);
1221    if (one_process) {
1222        /* not worth thinking about */
1223        return 1;
1224    }
1225
1226    /* advance to the next generation */
1227    /* XXX: we really need to make sure this new generation number isn't in
1228     * use by any of the children.
1229     */
1230    ++ap_my_generation;
1231    ap_scoreboard_image->global->running_generation = ap_my_generation;
1232
1233    if (is_graceful) {
1234        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
1235                    "Graceful restart requested, doing restart");
1236
1237        /* kill off the idle ones */
1238        ap_mpm_pod_killpg(pod, ap_max_daemons_limit);
1239
1240        /* This is mostly for debugging... so that we know what is still
1241         * gracefully dealing with existing request.  This will break
1242         * in a very nasty way if we ever have the scoreboard totally
1243         * file-based (no shared memory)
1244         */
1245        for (index = 0; index < ap_daemons_limit; ++index) {
1246            if (ap_scoreboard_image->servers[index][0].status != SERVER_DEAD) {
1247                ap_scoreboard_image->servers[index][0].status = SERVER_GRACEFUL;
1248                /* Ask each child to close its listeners.
1249                 *
1250                 * NOTE: we use the scoreboard, because if we send SIGUSR1
1251                 * to every process in the group, this may include CGI's,
1252                 * piped loggers, etc. They almost certainly won't handle
1253                 * it gracefully.
1254                 */
1255                ap_mpm_safe_kill(ap_scoreboard_image->parent[index].pid, AP_SIG_GRACEFUL);
1256            }
1257        }
1258    }
1259    else {
1260        /* Kill 'em off */
1261        if (unixd_killpg(getpgrp(), SIGHUP) < 0) {
1262            ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "killpg SIGHUP");
1263        }
1264        ap_reclaim_child_processes(0);          /* Not when just starting up */
1265        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
1266                    "SIGHUP received.  Attempting to restart");
1267    }
1268
1269    return 0;
1270}
1271
1272/* This really should be a post_config hook, but the error log is already
1273 * redirected by that point, so we need to do this in the open_logs phase.
1274 */
1275static int prefork_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
1276{
1277    apr_status_t rv;
1278
1279    pconf = p;
1280    ap_server_conf = s;
1281
1282    if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) {
1283        ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_STARTUP, 0,
1284                     NULL, "no listening sockets available, shutting down");
1285        return DONE;
1286    }
1287
1288    if ((rv = ap_mpm_pod_open(pconf, &pod))) {
1289        ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_STARTUP, rv, NULL,
1290                "Could not open pipe-of-death.");
1291        return DONE;
1292    }
1293    return OK;
1294}
1295
1296static int prefork_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp)
1297{
1298    static int restart_num = 0;
1299    int no_detach, debug, foreground;
1300    apr_status_t rv;
1301
1302    mpm_state = AP_MPMQ_STARTING;
1303
1304    debug = ap_exists_config_define("DEBUG");
1305
1306    if (debug) {
1307        foreground = one_process = 1;
1308        no_detach = 0;
1309    }
1310    else
1311    {
1312        no_detach = ap_exists_config_define("NO_DETACH");
1313        one_process = ap_exists_config_define("ONE_PROCESS");
1314        foreground = ap_exists_config_define("FOREGROUND");
1315    }
1316
1317    /* sigh, want this only the second time around */
1318    if (restart_num++ == 1) {
1319        is_graceful = 0;
1320
1321        if (!one_process && !foreground) {
1322            rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND
1323                                           : APR_PROC_DETACH_DAEMONIZE);
1324            if (rv != APR_SUCCESS) {
1325                ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL,
1326                             "apr_proc_detach failed");
1327                return HTTP_INTERNAL_SERVER_ERROR;
1328            }
1329        }
1330
1331        parent_pid = ap_my_pid = getpid();
1332    }
1333
1334    unixd_pre_config(ptemp);
1335    ap_listen_pre_config();
1336    ap_daemons_to_start = DEFAULT_START_DAEMON;
1337    ap_daemons_min_free = DEFAULT_MIN_FREE_DAEMON;
1338    ap_daemons_max_free = DEFAULT_MAX_FREE_DAEMON;
1339    ap_daemons_limit = server_limit;
1340    ap_pid_fname = DEFAULT_PIDLOG;
1341    ap_lock_fname = DEFAULT_LOCKFILE;
1342    ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD;
1343    ap_extended_status = 0;
1344#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE
1345    ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED;
1346#endif
1347
1348    apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir));
1349
1350    return OK;
1351}
1352
1353static void prefork_hooks(apr_pool_t *p)
1354{
1355    /* The prefork open_logs phase must run before the core's, or stderr
1356     * will be redirected to a file, and the messages won't print to the
1357     * console.
1358     */
1359    static const char *const aszSucc[] = {"core.c", NULL};
1360
1361#ifdef AUX3
1362    (void) set42sig();
1363#endif
1364
1365    ap_hook_open_logs(prefork_open_logs, NULL, aszSucc, APR_HOOK_MIDDLE);
1366    /* we need to set the MPM state before other pre-config hooks use MPM query
1367     * to retrieve it, so register as REALLY_FIRST
1368     */
1369    ap_hook_pre_config(prefork_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
1370}
1371
1372static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy, const char *arg)
1373{
1374    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1375    if (err != NULL) {
1376        return err;
1377    }
1378
1379    ap_daemons_to_start = atoi(arg);
1380    return NULL;
1381}
1382
1383static const char *set_min_free_servers(cmd_parms *cmd, void *dummy, const char *arg)
1384{
1385    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1386    if (err != NULL) {
1387        return err;
1388    }
1389
1390    ap_daemons_min_free = atoi(arg);
1391    if (ap_daemons_min_free <= 0) {
1392       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
1393                    "WARNING: detected MinSpareServers set to non-positive.");
1394       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
1395                    "Resetting to 1 to avoid almost certain Apache failure.");
1396       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
1397                    "Please read the documentation.");
1398       ap_daemons_min_free = 1;
1399    }
1400
1401    return NULL;
1402}
1403
1404static const char *set_max_free_servers(cmd_parms *cmd, void *dummy, const char *arg)
1405{
1406    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1407    if (err != NULL) {
1408        return err;
1409    }
1410
1411    ap_daemons_max_free = atoi(arg);
1412    return NULL;
1413}
1414
1415#include <sys/resource.h>
1416static int getproclimit(void)
1417{
1418    struct rlimit rl;
1419    memset(&rl, 0, sizeof rl);
1420    return getrlimit(RLIMIT_NPROC, &rl) == 0 ? rl.rlim_cur : 0;
1421}
1422
1423static const char *set_max_clients (cmd_parms *cmd, void *dummy, const char *arg)
1424{
1425    int tmp_daemons_limit;
1426
1427    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1428    if (err != NULL) {
1429        return err;
1430    }
1431
1432    tmp_daemons_limit = atoi(arg);
1433    if (strlen(arg) > 0 && arg[strlen(arg) - 1] == '%') {
1434	int proclimit = getproclimit();
1435	if (proclimit <= 0) {
1436	    ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
1437			 "WARNING: MaxClients %d%% ignored because "
1438			 "RLIMIT_NPROC is unknown", tmp_daemons_limit);
1439	    return NULL;
1440	}
1441	if (tmp_daemons_limit < 1 || tmp_daemons_limit > 100) {
1442	    ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
1443			 "WARNING: MaxClients %d%% ignored because "
1444			 "percentage is out of range 1-100%%",
1445			 tmp_daemons_limit);
1446	    return NULL;
1447	}
1448	tmp_daemons_limit = proclimit * tmp_daemons_limit / 100.0 + 0.5;
1449    }
1450    ap_daemons_limit = tmp_daemons_limit;
1451    if (ap_daemons_limit > server_limit) {
1452       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
1453                    "WARNING: MaxClients of %d exceeds ServerLimit value "
1454                    "of %d servers,", ap_daemons_limit, server_limit);
1455       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
1456                    " lowering MaxClients to %d.  To increase, please "
1457                    "see the ServerLimit", server_limit);
1458       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
1459                    " directive.");
1460       ap_daemons_limit = server_limit;
1461    }
1462    else if (ap_daemons_limit < 1) {
1463        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
1464                     "WARNING: Require MaxClients > 0, setting to 1");
1465        ap_daemons_limit = 1;
1466    }
1467    return NULL;
1468}
1469
1470static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg)
1471{
1472    int tmp_server_limit;
1473
1474    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1475    if (err != NULL) {
1476        return err;
1477    }
1478
1479    tmp_server_limit = atoi(arg);
1480    if (strlen(arg) > 0 && arg[strlen(arg) - 1] == '%') {
1481	int proclimit = getproclimit();
1482	if (proclimit <= 0) {
1483	    ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
1484			 "WARNING: ServerLimit %d%% ignored because "
1485			 "RLIMIT_NPROC is unknown", tmp_server_limit);
1486	    return NULL;
1487	}
1488	if (tmp_server_limit < 1 || tmp_server_limit > 100) {
1489	    ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
1490			 "WARNING: ServerLimit %d%% ignored because "
1491			 "percentage is out of range 1-100%%",
1492			 tmp_server_limit);
1493	    return NULL;
1494	}
1495	tmp_server_limit = proclimit * tmp_server_limit / 100.0 + 0.5;
1496    }
1497    /* you cannot change ServerLimit across a restart; ignore
1498     * any such attempts
1499     */
1500    if (first_server_limit &&
1501        tmp_server_limit != server_limit) {
1502        /* how do we log a message?  the error log is a bit bucket at this
1503         * point; we'll just have to set a flag so that ap_mpm_run()
1504         * logs a warning later
1505         */
1506        changed_limit_at_restart = 1;
1507        return NULL;
1508    }
1509    server_limit = tmp_server_limit;
1510
1511    if (server_limit > MAX_SERVER_LIMIT) {
1512       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
1513                    "WARNING: ServerLimit of %d exceeds compile time limit "
1514                    "of %d servers,", server_limit, MAX_SERVER_LIMIT);
1515       ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
1516                    " lowering ServerLimit to %d.", MAX_SERVER_LIMIT);
1517       server_limit = MAX_SERVER_LIMIT;
1518    }
1519    else if (server_limit < 1) {
1520        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
1521                     "WARNING: Require ServerLimit > 0, setting to 1");
1522        server_limit = 1;
1523    }
1524    return NULL;
1525}
1526
1527static const command_rec prefork_cmds[] = {
1528UNIX_DAEMON_COMMANDS,
1529LISTEN_COMMANDS,
1530AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF,
1531              "Number of child processes launched at server startup"),
1532AP_INIT_TAKE1("MinSpareServers", set_min_free_servers, NULL, RSRC_CONF,
1533              "Minimum number of idle children, to handle request spikes"),
1534AP_INIT_TAKE1("MaxSpareServers", set_max_free_servers, NULL, RSRC_CONF,
1535              "Maximum number of idle children"),
1536AP_INIT_TAKE1("MaxClients", set_max_clients, NULL, RSRC_CONF,
1537              "Maximum number of children alive at the same time"),
1538AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF,
1539              "Maximum value of MaxClients for this run of Apache"),
1540AP_GRACEFUL_SHUTDOWN_TIMEOUT_COMMAND,
1541{ NULL }
1542};
1543
1544module AP_MODULE_DECLARE_DATA mpm_prefork_module = {
1545    MPM20_MODULE_STUFF,
1546    ap_mpm_rewrite_args,        /* hook to run before apache parses args */
1547    NULL,                       /* create per-directory config structure */
1548    NULL,                       /* merge per-directory config structures */
1549    NULL,                       /* create per-server config structure */
1550    NULL,                       /* merge per-server config structures */
1551    prefork_cmds,               /* command apr_table_t */
1552    prefork_hooks,              /* register hooks */
1553};
1554