]> granicus.if.org Git - apache/blob - server/mpm/prefork/prefork.c
7e24fcf488c3382a289d3ddfab5d2b1b69cdf56c
[apache] / server / mpm / prefork / prefork.c
1 /* ====================================================================
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 2000 The Apache Software Foundation.  All rights
5  * reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  *
19  * 3. The end-user documentation included with the redistribution,
20  *    if any, must include the following acknowledgment:
21  *       "This product includes software developed by the
22  *        Apache Software Foundation (http://www.apache.org/)."
23  *    Alternately, this acknowledgment may appear in the software itself,
24  *    if and wherever such third-party acknowledgments normally appear.
25  *
26  * 4. The names "Apache" and "Apache Software Foundation" must
27  *    not be used to endorse or promote products derived from this
28  *    software without prior written permission. For written
29  *    permission, please contact apache@apache.org.
30  *
31  * 5. Products derived from this software may not be called "Apache",
32  *    nor may "Apache" appear in their name, without prior written
33  *    permission of the Apache Software Foundation.
34  *
35  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46  * SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Apache Software Foundation.  For more
51  * information on the Apache Software Foundation, please see
52  * <http://www.apache.org/>.
53  *
54  * Portions of this software are based upon public domain software
55  * originally written at the National Center for Supercomputing Applications,
56  * University of Illinois, Urbana-Champaign.
57  */
58
59 /*
60  * httpd.c: simple http daemon for answering WWW file requests
61  *
62  * 
63  * 03-21-93  Rob McCool wrote original code (up to NCSA HTTPd 1.3)
64  * 
65  * 03-06-95  blong
66  *  changed server number for child-alone processes to 0 and changed name
67  *   of processes
68  *
69  * 03-10-95  blong
70  *      Added numerous speed hacks proposed by Robert S. Thau (rst@ai.mit.edu) 
71  *      including set group before fork, and call gettime before to fork
72  *      to set up libraries.
73  *
74  * 04-14-95  rst / rh
75  *      Brandon's code snarfed from NCSA 1.4, but tinkered to work with the
76  *      Apache server, and also to have child processes do accept() directly.
77  *
78  * April-July '95 rst
79  *      Extensive rework for Apache.
80  */
81
82 /* TODO: this is a cobbled together prefork MPM example... it should mostly
83  * TODO: behave like apache-1.3... here's a short list of things I think
84  * TODO: need cleaning up still:
85  * TODO: - clean up scoreboard stuff when we figure out how to do it in 2.0
86  */
87
88 #define CORE_PRIVATE
89
90 #include "ap_config.h"
91 #include "apr_portable.h"
92 #include "apr_thread_proc.h"
93 #include "httpd.h"
94 #include "mpm_default.h"
95 #include "mpm_status.h"
96 #include "http_main.h"
97 #include "http_log.h"
98 #include "http_config.h"
99 #include "http_core.h"          /* for get_remote_host */
100 #include "http_connection.h"
101 #include "scoreboard.h"
102 #include "ap_mpm.h"
103 #include "unixd.h"
104 #include "mpm_common.h"
105 #include "iol_socket.h"
106 #include "ap_listen.h"
107 #include "ap_mmn.h"
108 #include <sys/times.h>
109 #include <sys/types.h>
110 #include <sys/wait.h>
111
112
113
114 #ifdef HAVE_BSTRING_H
115 #include <bstring.h>            /* for IRIX, FD_SET calls bzero() */
116 #endif
117 #include <signal.h>
118
119 /* config globals */
120
121 static int ap_max_requests_per_child=0;
122 static char *ap_pid_fname=NULL;
123 static char *ap_scoreboard_fname=NULL;
124 static char *ap_lock_fname;
125 static int ap_daemons_to_start=0;
126 static int ap_daemons_min_free=0;
127 static int ap_daemons_max_free=0;
128 static int ap_daemons_limit=0;
129 static time_t ap_restart_time=0;
130 static int ap_extended_status = 0;
131 static int maintain_connection_status = 1;
132
133 /*
134  * The max child slot ever assigned, preserved across restarts.  Necessary
135  * to deal with MaxClients changes across SIGUSR1 restarts.  We use this
136  * value to optimize routines that have to scan the entire scoreboard.
137  */
138 int ap_max_daemons_limit = -1;
139 server_rec *ap_server_conf;
140
141 static char ap_coredump_dir[MAX_STRING_LEN];
142
143 /* *Non*-shared http_main globals... */
144
145 static ap_socket_t *sd;
146 static fd_set listenfds;
147 static int listenmaxfd;
148
149 /* one_process --- debugging mode variable; can be set from the command line
150  * with the -X flag.  If set, this gets you the child_main loop running
151  * in the process which originally started up (no detach, no make_child),
152  * which is a pretty nice debugging environment.  (You'll get a SIGHUP
153  * early in standalone_main; just continue through.  This is the server
154  * trying to kill off any child processes which it might have lying
155  * around --- Apache doesn't keep track of their pids, it just sends
156  * SIGHUP to the process group, ignoring it in the root process.
157  * Continue through and you'll be fine.).
158  */
159
160 static int one_process = 0;
161
162 static ap_pool_t *pconf;                /* Pool for config stuff */
163 static ap_pool_t *pchild;               /* Pool for httpd child stuff */
164
165 int ap_my_pid;  /* it seems silly to call getpid all the time */
166 #ifndef MULTITHREAD
167 static int my_child_num;
168 #endif
169
170 #ifdef TPF
171 int tpf_child = 0;
172 char tpf_server_name[INETD_SERVNAME_LENGTH+1];
173 #endif /* TPF */
174
175 API_VAR_EXPORT scoreboard *ap_scoreboard_image = NULL;
176 static new_scoreboard *ap_new_scoreboard_image = NULL;
177
178 #ifdef GPROF
179 /* 
180  * change directory for gprof to plop the gmon.out file
181  * configure in httpd.conf:
182  * GprofDir logs/   -> $ServerRoot/logs/gmon.out
183  * GprofDir logs/%  -> $ServerRoot/logs/gprof.$pid/gmon.out
184  */
185 static void chdir_for_gprof(void)
186 {
187     core_server_config *sconf = 
188         ap_get_module_config(ap_server_conf->module_config, &core_module);    
189     char *dir = sconf->gprof_dir;
190
191     if(dir) {
192         char buf[512];
193         int len = strlen(sconf->gprof_dir) - 1;
194         if(*(dir + len) == '%') {
195             dir[len] = '\0';
196             ap_snprintf(buf, sizeof(buf), "%sgprof.%d", dir, (int)getpid());
197         } 
198         dir = ap_server_root_relative(pconf, buf[0] ? buf : dir);
199         if(mkdir(dir, 0755) < 0 && errno != EEXIST) {
200             ap_log_error(APLOG_MARK, APLOG_ERR, errno, ap_server_conf,
201                          "gprof: error creating directory %s", dir);
202         }
203     }
204     else {
205         dir = ap_server_root_relative(pconf, "logs");
206     }
207
208     chdir(dir);
209 }
210 #else
211 #define chdir_for_gprof()
212 #endif
213
214 /* XXX - I don't know if TPF will ever use this module or not, so leave
215  * the ap_check_signals calls in but disable them - manoj */
216 #define ap_check_signals() 
217
218 /* a clean exit from a child with proper cleanup */
219 static void clean_child_exit(int code) __attribute__ ((noreturn));
220 static void clean_child_exit(int code)
221 {
222     if (pchild) {
223         ap_destroy_pool(pchild);
224     }
225     chdir_for_gprof();
226     exit(code);
227 }
228
229 #if defined(USE_FCNTL_SERIALIZED_ACCEPT) || defined(USE_FLOCK_SERIALIZED_ACCEPT)
230 static void expand_lock_fname(ap_pool_t *p)
231 {
232     /* XXXX possibly bogus cast */
233     ap_lock_fname = ap_psprintf(p, "%s.%lu",
234         ap_server_root_relative(p, ap_lock_fname), (unsigned long)getpid());
235 }
236 #endif
237
238 #if defined (USE_USLOCK_SERIALIZED_ACCEPT)
239
240 #include <ulocks.h>
241
242 static ulock_t uslock = NULL;
243
244 #define accept_mutex_child_init(x)
245
246 static void accept_mutex_init(ap_pool_t *p)
247 {
248     ptrdiff_t old;
249     usptr_t *us;
250
251
252     /* default is 8, allocate enough for all the children plus the parent */
253     if ((old = usconfig(CONF_INITUSERS, HARD_SERVER_LIMIT + 1)) == -1) {
254         perror("usconfig(CONF_INITUSERS)");
255         exit(-1);
256     }
257
258     if ((old = usconfig(CONF_LOCKTYPE, US_NODEBUG)) == -1) {
259         perror("usconfig(CONF_LOCKTYPE)");
260         exit(-1);
261     }
262     if ((old = usconfig(CONF_ARENATYPE, US_SHAREDONLY)) == -1) {
263         perror("usconfig(CONF_ARENATYPE)");
264         exit(-1);
265     }
266     if ((us = usinit("/dev/zero")) == NULL) {
267         perror("usinit");
268         exit(-1);
269     }
270
271     if ((uslock = usnewlock(us)) == NULL) {
272         perror("usnewlock");
273         exit(-1);
274     }
275 }
276
277 static void accept_mutex_on(void)
278 {
279     switch (ussetlock(uslock)) {
280     case 1:
281         /* got lock */
282         break;
283     case 0:
284         ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
285                      "didn't get lock");
286         clean_child_exit(APEXIT_CHILDFATAL);
287     case -1:
288         perror("ussetlock");
289         clean_child_exit(APEXIT_CHILDFATAL);
290     }
291 }
292
293 static void accept_mutex_off(void)
294 {
295     if (usunsetlock(uslock) == -1) {
296         perror("usunsetlock");
297         clean_child_exit(APEXIT_CHILDFATAL);
298     }
299 }
300
301 #elif defined (USE_PTHREAD_SERIALIZED_ACCEPT)
302
303 /* This code probably only works on Solaris ... but it works really fast
304  * on Solaris.  Note that pthread mutexes are *NOT* released when a task
305  * dies ... the task has to free it itself.  So we block signals and
306  * try to be nice about releasing the mutex.
307  */
308
309 #include <pthread.h>
310
311 static pthread_mutex_t *accept_mutex = (void *)(caddr_t) -1;
312 static int have_accept_mutex;
313 static sigset_t accept_block_mask;
314 static sigset_t accept_previous_mask;
315
316 static void accept_mutex_child_cleanup(void *foo)
317 {
318     if (accept_mutex != (void *)(caddr_t)-1
319         && have_accept_mutex) {
320         pthread_mutex_unlock(accept_mutex);
321     }
322 }
323
324 static void accept_mutex_child_init(ap_pool_t *p)
325 {
326     ap_register_cleanup(p, NULL, accept_mutex_child_cleanup, ap_null_cleanup);
327 }
328
329 static void accept_mutex_cleanup(void *foo)
330 {
331     if (accept_mutex != (void *)(caddr_t)-1
332         && munmap((caddr_t) accept_mutex, sizeof(*accept_mutex))) {
333         perror("munmap");
334     }
335     accept_mutex = (void *)(caddr_t)-1;
336 }
337
338 static void accept_mutex_init(ap_pool_t *p)
339 {
340     pthread_mutexattr_t mattr;
341     int fd;
342
343     fd = open("/dev/zero", O_RDWR);
344     if (fd == -1) {
345         perror("open(/dev/zero)");
346         exit(APEXIT_INIT);
347     }
348     accept_mutex = (pthread_mutex_t *) mmap((caddr_t) 0, sizeof(*accept_mutex),
349                                  PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
350     if (accept_mutex == (void *) (caddr_t) - 1) {
351         perror("mmap");
352         exit(APEXIT_INIT);
353     }
354     close(fd);
355     if ((errno = pthread_mutexattr_init(&mattr))) {
356         perror("pthread_mutexattr_init");
357         exit(APEXIT_INIT);
358     }
359     if ((errno = pthread_mutexattr_setpshared(&mattr,
360                                                 PTHREAD_PROCESS_SHARED))) {
361         perror("pthread_mutexattr_setpshared");
362         exit(APEXIT_INIT);
363     }
364     if ((errno = pthread_mutex_init(accept_mutex, &mattr))) {
365         perror("pthread_mutex_init");
366         exit(APEXIT_INIT);
367     }
368     sigfillset(&accept_block_mask);
369     sigdelset(&accept_block_mask, SIGHUP);
370     sigdelset(&accept_block_mask, SIGTERM);
371     sigdelset(&accept_block_mask, SIGUSR1);
372     ap_register_cleanup(p, NULL, accept_mutex_cleanup, ap_null_cleanup);
373 }
374
375 static void accept_mutex_on(void)
376 {
377     int err;
378
379     if (sigprocmask(SIG_BLOCK, &accept_block_mask, &accept_previous_mask)) {
380         perror("sigprocmask(SIG_BLOCK)");
381         clean_child_exit(APEXIT_CHILDFATAL);
382     }
383     if ((err = pthread_mutex_lock(accept_mutex))) {
384         errno = err;
385         perror("pthread_mutex_lock");
386         clean_child_exit(APEXIT_CHILDFATAL);
387     }
388     have_accept_mutex = 1;
389 }
390
391 static void accept_mutex_off(void)
392 {
393     int err;
394
395     if ((err = pthread_mutex_unlock(accept_mutex))) {
396         errno = err;
397         perror("pthread_mutex_unlock");
398         clean_child_exit(APEXIT_CHILDFATAL);
399     }
400     /* There is a slight race condition right here... if we were to die right
401      * now, we'd do another pthread_mutex_unlock.  Now, doing that would let
402      * another process into the mutex.  pthread mutexes are designed to be
403      * fast, as such they don't have protection for things like testing if the
404      * thread owning a mutex is actually unlocking it (or even any way of
405      * testing who owns the mutex).
406      *
407      * If we were to unset have_accept_mutex prior to releasing the mutex
408      * then the race could result in the server unable to serve hits.  Doing
409      * it this way means that the server can continue, but an additional
410      * child might be in the critical section ... at least it's still serving
411      * hits.
412      */
413     have_accept_mutex = 0;
414     if (sigprocmask(SIG_SETMASK, &accept_previous_mask, NULL)) {
415         perror("sigprocmask(SIG_SETMASK)");
416         clean_child_exit(1);
417     }
418 }
419
420 #elif defined (USE_SYSVSEM_SERIALIZED_ACCEPT)
421
422 #include <sys/types.h>
423 #include <sys/ipc.h>
424 #include <sys/sem.h>
425
426 #ifdef NEED_UNION_SEMUN
427 /* it makes no sense, but this isn't defined on solaris */
428 union semun {
429     long val;
430     struct semid_ds *buf;
431     ushort *array;
432 };
433
434 #endif
435
436 static int sem_id = -1;
437 static struct sembuf op_on;
438 static struct sembuf op_off;
439
440 /* We get a random semaphore ... the lame sysv semaphore interface
441  * means we have to be sure to clean this up or else we'll leak
442  * semaphores.
443  */
444 static void accept_mutex_cleanup(void *foo)
445 {
446     union semun ick;
447
448     if (sem_id < 0)
449         return;
450     /* this is ignored anyhow */
451     ick.val = 0;
452     semctl(sem_id, 0, IPC_RMID, ick);
453 }
454
455 #define accept_mutex_child_init(x)
456
457 static void accept_mutex_init(ap_pool_t *p)
458 {
459     union semun ick;
460     struct semid_ds buf;
461
462     /* acquire the semaphore */
463     sem_id = semget(IPC_PRIVATE, 1, IPC_CREAT | 0600);
464     if (sem_id < 0) {
465         perror("semget");
466         exit(APEXIT_INIT);
467     }
468     ick.val = 1;
469     if (semctl(sem_id, 0, SETVAL, ick) < 0) {
470         perror("semctl(SETVAL)");
471         exit(APEXIT_INIT);
472     }
473     if (!getuid()) {
474         /* restrict it to use only by the appropriate user_id ... not that this
475          * stops CGIs from acquiring it and dinking around with it.
476          */
477         buf.sem_perm.uid = unixd_config.user_id;
478         buf.sem_perm.gid = unixd_config.group_id;
479         buf.sem_perm.mode = 0600;
480         ick.buf = &buf;
481         if (semctl(sem_id, 0, IPC_SET, ick) < 0) {
482             perror("semctl(IPC_SET)");
483             exit(APEXIT_INIT);
484         }
485     }
486     ap_register_cleanup(p, NULL, accept_mutex_cleanup, ap_null_cleanup);
487
488     /* preinitialize these */
489     op_on.sem_num = 0;
490     op_on.sem_op = -1;
491     op_on.sem_flg = SEM_UNDO;
492     op_off.sem_num = 0;
493     op_off.sem_op = 1;
494     op_off.sem_flg = SEM_UNDO;
495 }
496
497 static void accept_mutex_on(void)
498 {
499     while (semop(sem_id, &op_on, 1) < 0) {
500         if (errno != EINTR) {
501             perror("accept_mutex_on");
502             clean_child_exit(APEXIT_CHILDFATAL);
503         }
504     }
505 }
506
507 static void accept_mutex_off(void)
508 {
509     while (semop(sem_id, &op_off, 1) < 0) {
510         if (errno != EINTR) {
511             perror("accept_mutex_off");
512             clean_child_exit(APEXIT_CHILDFATAL);
513         }
514     }
515 }
516
517 #elif defined(USE_FCNTL_SERIALIZED_ACCEPT)
518 static struct flock lock_it;
519 static struct flock unlock_it;
520
521 static int lock_fd = -1;
522
523 #define accept_mutex_child_init(x)
524
525 /*
526  * Initialize mutex lock.
527  * Must be safe to call this on a restart.
528  */
529 static void accept_mutex_init(ap_pool_t *p)
530 {
531     ap_file_t *tempfile = NULL;
532     lock_it.l_whence = SEEK_SET;        /* from current point */
533     lock_it.l_start = 0;                /* -"- */
534     lock_it.l_len = 0;                  /* until end of file */
535     lock_it.l_type = F_WRLCK;           /* set exclusive/write lock */
536     lock_it.l_pid = 0;                  /* pid not actually interesting */
537     unlock_it.l_whence = SEEK_SET;      /* from current point */
538     unlock_it.l_start = 0;              /* -"- */
539     unlock_it.l_len = 0;                /* until end of file */
540     unlock_it.l_type = F_UNLCK;         /* set exclusive/write lock */
541     unlock_it.l_pid = 0;                /* pid not actually interesting */
542
543     expand_lock_fname(p);
544     ap_open(&tempfile, ap_lock_fname, APR_CREATE | APR_WRITE | APR_EXCL,
545             APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD, p);
546     ap_get_os_file(&lock_fd, tempfile);
547     if (lock_fd == -1) {
548         perror("open");
549         ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
550                      "Cannot open lock file: %s", ap_lock_fname);
551         exit(APEXIT_INIT);
552     }
553     unlink(ap_lock_fname);
554 }
555
556 static void accept_mutex_on(void)
557 {
558     int ret;
559
560     while ((ret = fcntl(lock_fd, F_SETLKW, &lock_it)) < 0 && errno == EINTR) {
561         /* nop */
562     }
563
564     if (ret < 0) {
565         ap_log_error(APLOG_MARK, APLOG_EMERG, errno, ap_server_conf,
566                     "fcntl: F_SETLKW: Error getting accept lock, exiting!  "
567                     "Perhaps you need to use the LockFile directive to place "
568                     "your lock file on a local disk!");
569         clean_child_exit(APEXIT_CHILDFATAL);
570     }
571 }
572
573 static void accept_mutex_off(void)
574 {
575     int ret;
576
577     while ((ret = fcntl(lock_fd, F_SETLKW, &unlock_it)) < 0 && errno == EINTR) {
578         /* nop */
579     }
580     if (ret < 0) {
581         ap_log_error(APLOG_MARK, APLOG_EMERG, errno, ap_server_conf,
582                     "fcntl: F_SETLKW: Error freeing accept lock, exiting!  "
583                     "Perhaps you need to use the LockFile directive to place "
584                     "your lock file on a local disk!");
585         clean_child_exit(APEXIT_CHILDFATAL);
586     }
587 }
588
589 #elif defined(USE_FLOCK_SERIALIZED_ACCEPT)
590
591 static int lock_fd = -1;
592
593 static ap_status_t accept_mutex_cleanup(void *foo)
594 {
595     unlink(ap_lock_fname);
596
597     return APR_SUCCESS;
598 }
599
600 /*
601  * Initialize mutex lock.
602  * Done by each child at it's birth
603  */
604 static void accept_mutex_child_init(ap_pool_t *p)
605 {
606     ap_file_t *tempfile = NULL;
607     ap_status_t ret;
608
609     ret=ap_open(&tempfile, ap_lock_fname, APR_WRITE, APR_UREAD|APR_UWRITE, p);
610     if (ret != APR_SUCCESS) {
611         ap_log_error(APLOG_MARK, APLOG_EMERG, ret, ap_server_conf,
612                     "Child cannot open lock file: %s", ap_lock_fname);
613         clean_child_exit(APEXIT_CHILDINIT);
614     }
615     ap_get_os_file(&lock_fd, tempfile);
616 }
617
618 /*
619  * Initialize mutex lock.
620  * Must be safe to call this on a restart.
621  */
622 static void accept_mutex_init(ap_pool_t *p)
623 {
624     ap_file_t *tempfile = NULL;
625     ap_status_t ret;
626
627     expand_lock_fname(p);
628     unlink(ap_lock_fname);
629     ret=ap_open(&tempfile, ap_lock_fname, APR_CREATE|APR_WRITE|APR_EXCL,
630             APR_UREAD|APR_UWRITE, p);
631     if (ret != APR_SUCCESS) {
632         ap_log_error(APLOG_MARK, APLOG_EMERG, ret, ap_server_conf,
633                     "Parent cannot open lock file: %s", ap_lock_fname);
634         exit(APEXIT_INIT);
635     }
636     ap_get_os_file(&lock_fd, tempfile);
637     ap_register_cleanup(p, NULL, accept_mutex_cleanup, ap_null_cleanup);
638 }
639
640 static void accept_mutex_on(void)
641 {
642     int ret;
643
644     while ((ret = flock(lock_fd, LOCK_EX)) < 0 && errno == EINTR)
645         continue;
646
647     if (ret < 0) {
648         ap_log_error(APLOG_MARK, APLOG_EMERG, errno, ap_ap_server_conf,
649                     "flock: LOCK_EX: Error getting accept lock. Exiting!");
650         clean_child_exit(APEXIT_CHILDFATAL);
651     }
652 }
653
654 static void accept_mutex_off(void)
655 {
656     if (flock(lock_fd, LOCK_UN) < 0) {
657         ap_log_error(APLOG_MARK, APLOG_EMERG, errno, ap_server_conf,
658                     "flock: LOCK_UN: Error freeing accept lock. Exiting!");
659         clean_child_exit(APEXIT_CHILDFATAL);
660     }
661 }
662
663 #elif defined(USE_OS2SEM_SERIALIZED_ACCEPT)
664
665 static HMTX lock_sem = -1;
666
667 static void accept_mutex_cleanup(void *foo)
668 {
669     DosReleaseMutexSem(lock_sem);
670     DosCloseMutexSem(lock_sem);
671 }
672
673 /*
674  * Initialize mutex lock.
675  * Done by each child at it's birth
676  */
677 static void accept_mutex_child_init(ap_pool_t *p)
678 {
679     int rc = DosOpenMutexSem(NULL, &lock_sem);
680
681     if (rc != 0) {
682         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_EMERG, ap_server_conf,
683                     "Child cannot open lock semaphore, rc=%d", rc);
684         clean_child_exit(APEXIT_CHILDINIT);
685     } else {
686         ap_register_cleanup(p, NULL, accept_mutex_cleanup, ap_null_cleanup);
687     }
688 }
689
690 /*
691  * Initialize mutex lock.
692  * Must be safe to call this on a restart.
693  */
694 static void accept_mutex_init(ap_pool_t *p)
695 {
696     int rc = DosCreateMutexSem(NULL, &lock_sem, DC_SEM_SHARED, FALSE);
697
698     if (rc != 0) {
699         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_EMERG, ap_server_conf,
700                     "Parent cannot create lock semaphore, rc=%d", rc);
701         exit(APEXIT_INIT);
702     }
703
704     ap_register_cleanup(p, NULL, accept_mutex_cleanup, ap_null_cleanup);
705 }
706
707 static void accept_mutex_on(void)
708 {
709     int rc = DosRequestMutexSem(lock_sem, SEM_INDEFINITE_WAIT);
710
711     if (rc != 0) {
712         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_EMERG, ap_server_conf,
713                     "OS2SEM: Error %d getting accept lock. Exiting!", rc);
714         clean_child_exit(APEXIT_CHILDFATAL);
715     }
716 }
717
718 static void accept_mutex_off(void)
719 {
720     int rc = DosReleaseMutexSem(lock_sem);
721     
722     if (rc != 0) {
723         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_EMERG, ap_server_conf,
724                     "OS2SEM: Error %d freeing accept lock. Exiting!", rc);
725         clean_child_exit(APEXIT_CHILDFATAL);
726     }
727 }
728
729 #elif defined(USE_TPF_CORE_SERIALIZED_ACCEPT)
730
731 static int tpf_core_held;
732
733 static void accept_mutex_cleanup(void *foo)
734 {
735     if(tpf_core_held)
736         coruc(RESOURCE_KEY);
737 }
738
739 #define accept_mutex_init(x)
740
741 static void accept_mutex_child_init(ap_pool_t *p)
742 {
743     ap_register_cleanup(p, NULL, accept_mutex_cleanup, ap_null_cleanup);
744     tpf_core_held = 0;
745 }
746
747 static void accept_mutex_on(void)
748 {
749     corhc(RESOURCE_KEY);
750     tpf_core_held = 1;
751     ap_check_signals();
752 }
753
754 static void accept_mutex_off(void)
755 {
756     coruc(RESOURCE_KEY);
757     tpf_core_held = 0;
758     ap_check_signals();
759 }
760
761 #else
762 /* Default --- no serialization.  Other methods *could* go here,
763  * as #elifs...
764  */
765 #if !defined(MULTITHREAD)
766 /* Multithreaded systems don't complete between processes for
767  * the sockets. */
768 #define NO_SERIALIZED_ACCEPT
769 #define accept_mutex_child_init(x)
770 #define accept_mutex_init(x)
771 #define accept_mutex_on()
772 #define accept_mutex_off()
773 #endif
774 #endif
775
776 /* On some architectures it's safe to do unserialized accept()s in the single
777  * Listen case.  But it's never safe to do it in the case where there's
778  * multiple Listen statements.  Define SINGLE_LISTEN_UNSERIALIZED_ACCEPT
779  * when it's safe in the single Listen case.
780  */
781 #ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT
782 #define SAFE_ACCEPT(stmt) do {if (ap_listeners->next) {stmt;}} while(0)
783 #else
784 #define SAFE_ACCEPT(stmt) do {stmt;} while(0)
785 #endif
786
787 #if APR_HAS_SHARED_MEMORY
788 #include "apr_shmem.h"
789
790 static ap_shmem_t *scoreboard_shm = NULL;
791
792 static ap_status_t cleanup_shared_mem(void *d)
793 {
794     ap_shm_free(scoreboard_shm, ap_scoreboard_image);
795     ap_scoreboard_image = NULL;
796     ap_shm_destroy(scoreboard_shm);
797     return APR_SUCCESS;
798 }
799
800 static void setup_shared_mem(ap_pool_t *p)
801 {
802     char buf[512];
803     const char *fname;
804
805     fname = ap_server_root_relative(p, ap_scoreboard_fname);
806     if (ap_shm_init(&scoreboard_shm, SCOREBOARD_SIZE + NEW_SCOREBOARD_SIZE + 40, fname, p) != APR_SUCCESS) {
807         ap_snprintf(buf, sizeof(buf), "%s: could not open(create) scoreboard",
808                     ap_server_argv0);
809         perror(buf);
810         exit(APEXIT_INIT);
811     }
812     ap_scoreboard_image = ap_shm_malloc(scoreboard_shm, SCOREBOARD_SIZE); 
813     ap_new_scoreboard_image = ap_shm_malloc(scoreboard_shm, NEW_SCOREBOARD_SIZE); 
814     if (ap_scoreboard_image == NULL) {
815         ap_snprintf(buf, sizeof(buf), "%s: cannot allocate scoreboard",
816                     ap_server_argv0);
817         perror(buf);
818         ap_shm_destroy(scoreboard_shm);
819         exit(APEXIT_INIT);
820     }
821     ap_register_cleanup(p, NULL, cleanup_shared_mem, ap_null_cleanup);
822     ap_scoreboard_image->global.running_generation = 0;
823 }
824
825 static void reopen_scoreboard(ap_pool_t *p)
826 {
827 }
828 #endif
829
830 /* Called by parent process */
831 static void reinit_scoreboard(ap_pool_t *p)
832 {
833     int running_gen = 0;
834     if (ap_scoreboard_image)
835         running_gen = ap_scoreboard_image->global.running_generation;
836
837     if (ap_scoreboard_image == NULL) {
838         setup_shared_mem(p);
839     }
840     memset(ap_scoreboard_image, 0, SCOREBOARD_SIZE);
841     ap_scoreboard_image->global.running_generation = running_gen;
842 }
843
844
845 /* Routines called to deal with the scoreboard image
846  * --- note that we do *not* need write locks, since update_child_status
847  * only updates a *single* record in place, and only one process writes to
848  * a given scoreboard slot at a time (either the child process owning that
849  * slot, or the parent, noting that the child has died).
850  *
851  * As a final note --- setting the score entry to getpid() is always safe,
852  * since when the parent is writing an entry, it's only noting SERVER_DEAD
853  * anyway.
854  */
855 ap_inline void ap_sync_scoreboard_image(void)
856 {
857 #ifdef SCOREBOARD_FILE
858     lseek(scoreboard_fd, 0L, 0);
859     force_read(scoreboard_fd, ap_scoreboard_image, sizeof(*ap_scoreboard_image))
860 ;
861 #endif
862 }
863
864 API_EXPORT(int) ap_exists_scoreboard_image(void)
865 {
866     return (ap_scoreboard_image ? 1 : 0);
867 }
868
869 static ap_inline void put_scoreboard_info(int child_num,
870                                        short_score *new_score_rec)
871 {
872 #ifdef SCOREBOARD_FILE
873     lseek(scoreboard_fd, (long) child_num * sizeof(short_score), 0);
874     force_write(scoreboard_fd, new_score_rec, sizeof(short_score));
875 #endif
876 }
877
878 int ap_update_child_status(int child_num, int status, request_rec *r)
879 {
880     int old_status;
881     short_score *ss;
882
883     if (child_num < 0)
884         return -1;
885
886     ap_check_signals();
887
888     ss = &ap_scoreboard_image->servers[child_num];
889     old_status = ss->status;
890     ss->status = status;
891
892     if (ap_extended_status) {
893         if (status == SERVER_READY || status == SERVER_DEAD) {
894             /*
895              * Reset individual counters
896              */
897             if (status == SERVER_DEAD) {
898                 ss->my_access_count = 0L;
899                 ss->my_bytes_served = 0L;
900             }
901             ss->conn_count = (unsigned short) 0;
902             ss->conn_bytes = (unsigned long) 0;
903         }
904         if (r) {
905             conn_rec *c = r->connection;
906             ap_cpystrn(ss->client, ap_get_remote_host(c, r->per_dir_config,
907                                   REMOTE_NOLOOKUP), sizeof(ss->client));
908             if (r->the_request == NULL) {
909                     ap_cpystrn(ss->request, "NULL", sizeof(ss->request));
910             } else if (r->parsed_uri.password == NULL) {
911                     ap_cpystrn(ss->request, r->the_request, sizeof(ss->request));
912             } else {
913                 /* Don't reveal the password in the server-status view */
914                     ap_cpystrn(ss->request, ap_pstrcat(r->pool, r->method, " ",
915                                                ap_unparse_uri_components(r->pool, &r->parsed_uri, UNP_OMITPASSWORD),
916                                                r->assbackwards ? NULL : " ", r->protocol, NULL),
917                                        sizeof(ss->request));
918             }
919             ss->vhostrec =  r->server;
920         }
921     }
922     if (status == SERVER_STARTING && r == NULL) {
923         /* clean up the slot's vhostrec pointer (maybe re-used)
924          * and mark the slot as belonging to a new generation.
925          */
926         ss->vhostrec = NULL;
927         ap_scoreboard_image->parent[child_num].generation = ap_my_generation;
928 #ifdef SCOREBOARD_FILE
929         lseek(scoreboard_fd, XtOffsetOf(scoreboard, parent[child_num]), 0);
930         force_write(scoreboard_fd, &ap_scoreboard_image->parent[child_num],
931             sizeof(parent_score));
932 #endif
933     }
934     put_scoreboard_info(child_num, ss);
935
936     return old_status;
937 }
938
939 static void update_scoreboard_global(void)
940 {
941 #ifdef SCOREBOARD_FILE
942     lseek(scoreboard_fd,
943           (char *) &ap_scoreboard_image->global -(char *) ap_scoreboard_image, 0);
944     force_write(scoreboard_fd, &ap_scoreboard_image->global,
945                 sizeof ap_scoreboard_image->global);
946 #endif
947 }
948
949 void ap_time_process_request(int child_num, int status)
950 {
951     short_score *ss;
952 #if !defined(HAVE_GETTIMEOFDAY) && defined(HAVE_TIMES)
953     struct tms tms_blk;
954 #endif
955
956     if (child_num < 0)
957         return;
958
959     ap_sync_scoreboard_image();
960     ss = &ap_scoreboard_image->servers[child_num];
961
962     if (status == START_PREQUEST) {
963 #if !defined(HAVE_GETTIMEOFDAY)
964 #ifdef HAVE_TIMES
965         if ((ss->start_time = times(&tms_blk)) == -1)
966 #endif /* HAVE_TIMES */
967             ss->start_time = (clock_t) 0;
968 #else
969         if (gettimeofday(&ss->start_time, (struct timezone *) 0) < 0)
970             ss->start_time.tv_sec =
971                 ss->start_time.tv_usec = 0L;
972 #endif
973     }
974     else if (status == STOP_PREQUEST) {
975 #if !defined(HAVE_GETTIMEOFDAY)
976 #ifdef HAVE_TIMES
977         if ((ss->stop_time = times(&tms_blk)) == -1)
978 #endif
979             ss->stop_time = ss->start_time = (clock_t) 0;
980 #else
981         if (gettimeofday(&ss->stop_time, (struct timezone *) 0) < 0)
982             ss->stop_time.tv_sec =
983                 ss->stop_time.tv_usec =
984                 ss->start_time.tv_sec =
985                 ss->start_time.tv_usec = 0L;
986 #endif
987
988     }
989
990     put_scoreboard_info(child_num, ss);
991 }
992
993 /*
994 static void increment_counts(int child_num, request_rec *r)
995 {
996     long int bs = 0;
997     short_score *ss;
998
999     ap_sync_scoreboard_image();
1000     ss = &ap_scoreboard_image->servers[child_num];
1001
1002     if (r->sent_bodyct)
1003         ap_bgetopt(r->connection->client, BO_BYTECT, &bs);
1004
1005 #ifdef HAVE_TIMES
1006     times(&ss->times);
1007 #endif
1008     ss->access_count++;
1009     ss->my_access_count++;
1010     ss->conn_count++;
1011     ss->bytes_served += (unsigned long) bs;
1012     ss->my_bytes_served += (unsigned long) bs;
1013     ss->conn_bytes += (unsigned long) bs;
1014
1015     put_scoreboard_info(child_num, ss);
1016 }
1017 */
1018
1019 static int find_child_by_pid(ap_proc_t *pid)
1020 {
1021     int i;
1022
1023     for (i = 0; i < ap_max_daemons_limit; ++i)
1024         if (ap_scoreboard_image->parent[i].pid == pid->pid)
1025             return i;
1026
1027     return -1;
1028 }
1029
1030 #if defined(NEED_WAITPID)
1031 /*
1032    Systems without a real waitpid sometimes lose a child's exit while waiting
1033    for another.  Search through the scoreboard for missing children.
1034  */
1035 int reap_children(ap_wait_t *status)
1036 {
1037     int n, pid;
1038
1039     for (n = 0; n < ap_max_daemons_limit; ++n) {
1040         ap_sync_scoreboard_image();
1041         if (ap_scoreboard_image->servers[n].status != SERVER_DEAD &&
1042                 kill((pid = ap_scoreboard_image->parent[n].pid), 0) == -1) {
1043             ap_update_child_status(n, SERVER_DEAD, NULL);
1044             /* just mark it as having a successful exit status */
1045             bzero((char *) status, sizeof(ap_wait_t));
1046             return(pid);
1047         }
1048     }
1049     return 0;
1050 }
1051 #endif
1052
1053 /* handle all varieties of core dumping signals */
1054 static void sig_coredump(int sig)
1055 {
1056     chdir(ap_coredump_dir);
1057     ap_signal(sig, SIG_DFL);
1058     kill(getpid(), sig);
1059     /* At this point we've got sig blocked, because we're still inside
1060      * the signal handler.  When we leave the signal handler it will
1061      * be unblocked, and we'll take the signal... and coredump or whatever
1062      * is appropriate for this particular Unix.  In addition the parent
1063      * will see the real signal we received -- whereas if we called
1064      * abort() here, the parent would only see SIGABRT.
1065      */
1066 }
1067
1068 /*****************************************************************
1069  * Connection structures and accounting...
1070  */
1071
1072 static void just_die(int sig)
1073 {
1074     clean_child_exit(0);
1075 }
1076
1077 static int volatile deferred_die;
1078 static int volatile usr1_just_die;
1079
1080 static void usr1_handler(int sig)
1081 {
1082     if (usr1_just_die) {
1083         just_die(sig);
1084     }
1085     deferred_die = 1;
1086 }
1087
1088 /* volatile just in case */
1089 static int volatile shutdown_pending;
1090 static int volatile restart_pending;
1091 static int volatile is_graceful;
1092 ap_generation_t volatile ap_my_generation=0;
1093
1094 static void sig_term(int sig)
1095 {
1096     if (shutdown_pending == 1) {
1097         /* Um, is this _probably_ not an error, if the user has
1098          * tried to do a shutdown twice quickly, so we won't
1099          * worry about reporting it.
1100          */
1101         return;
1102     }
1103     shutdown_pending = 1;
1104 }
1105
1106 static void restart(int sig)
1107 {
1108     if (restart_pending == 1) {
1109         /* Probably not an error - don't bother reporting it */
1110         return;
1111     }
1112     restart_pending = 1;
1113     if ((is_graceful = (sig == SIGUSR1))) {
1114         ap_kill_cleanup(pconf, NULL, cleanup_shared_mem);
1115     }
1116 }
1117
1118 static void set_signals(void)
1119 {
1120 #ifndef NO_USE_SIGACTION
1121     struct sigaction sa;
1122
1123     sigemptyset(&sa.sa_mask);
1124     sa.sa_flags = 0;
1125
1126     if (!one_process) {
1127         sa.sa_handler = sig_coredump;
1128 #if defined(SA_ONESHOT)
1129         sa.sa_flags = SA_ONESHOT;
1130 #elif defined(SA_RESETHAND)
1131         sa.sa_flags = SA_RESETHAND;
1132 #endif
1133         if (sigaction(SIGSEGV, &sa, NULL) < 0)
1134             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGSEGV)");
1135 #ifdef SIGBUS
1136         if (sigaction(SIGBUS, &sa, NULL) < 0)
1137             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGBUS)");
1138 #endif
1139 #ifdef SIGABORT
1140         if (sigaction(SIGABORT, &sa, NULL) < 0)
1141             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGABORT)");
1142 #endif
1143 #ifdef SIGABRT
1144         if (sigaction(SIGABRT, &sa, NULL) < 0)
1145             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGABRT)");
1146 #endif
1147 #ifdef SIGILL
1148         if (sigaction(SIGILL, &sa, NULL) < 0)
1149             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGILL)");
1150 #endif
1151         sa.sa_flags = 0;
1152     }
1153     sa.sa_handler = sig_term;
1154     if (sigaction(SIGTERM, &sa, NULL) < 0)
1155         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGTERM)");
1156 #ifdef SIGINT
1157     if (sigaction(SIGINT, &sa, NULL) < 0)
1158         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGINT)");
1159 #endif
1160 #ifdef SIGXCPU
1161     sa.sa_handler = SIG_DFL;
1162     if (sigaction(SIGXCPU, &sa, NULL) < 0)
1163         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXCPU)");
1164 #endif
1165 #ifdef SIGXFSZ
1166     sa.sa_handler = SIG_DFL;
1167     if (sigaction(SIGXFSZ, &sa, NULL) < 0)
1168         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXFSZ)");
1169 #endif
1170 #ifdef SIGPIPE
1171     sa.sa_handler = SIG_IGN;
1172     if (sigaction(SIGPIPE, &sa, NULL) < 0)
1173         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGPIPE)");
1174 #endif
1175
1176     /* we want to ignore HUPs and USR1 while we're busy processing one */
1177     sigaddset(&sa.sa_mask, SIGHUP);
1178     sigaddset(&sa.sa_mask, SIGUSR1);
1179     sa.sa_handler = restart;
1180     if (sigaction(SIGHUP, &sa, NULL) < 0)
1181         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGHUP)");
1182     if (sigaction(SIGUSR1, &sa, NULL) < 0)
1183         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGUSR1)");
1184 #else
1185     if (!one_process) {
1186         ap_signal(SIGSEGV, sig_coredump);
1187 #ifdef SIGBUS
1188         ap_signal(SIGBUS, sig_coredump);
1189 #endif /* SIGBUS */
1190 #ifdef SIGABORT
1191         ap_signal(SIGABORT, sig_coredump);
1192 #endif /* SIGABORT */
1193 #ifdef SIGABRT
1194         ap_signal(SIGABRT, sig_coredump);
1195 #endif /* SIGABRT */
1196 #ifdef SIGILL
1197         ap_signal(SIGILL, sig_coredump);
1198 #endif /* SIGILL */
1199 #ifdef SIGXCPU
1200         ap_signal(SIGXCPU, SIG_DFL);
1201 #endif /* SIGXCPU */
1202 #ifdef SIGXFSZ
1203         ap_signal(SIGXFSZ, SIG_DFL);
1204 #endif /* SIGXFSZ */
1205     }
1206
1207     ap_signal(SIGTERM, sig_term);
1208 #ifdef SIGHUP
1209     ap_signal(SIGHUP, restart);
1210 #endif /* SIGHUP */
1211 #ifdef SIGUSR1
1212     ap_signal(SIGUSR1, restart);
1213 #endif /* SIGUSR1 */
1214 #ifdef SIGPIPE
1215     ap_signal(SIGPIPE, SIG_IGN);
1216 #endif /* SIGPIPE */
1217
1218 #endif
1219 }
1220
1221 #if defined(TCP_NODELAY) && !defined(MPE) && !defined(TPF)
1222 static void sock_disable_nagle(int s)
1223 {
1224     /* The Nagle algorithm says that we should delay sending partial
1225      * packets in hopes of getting more data.  We don't want to do
1226      * this; we are not telnet.  There are bad interactions between
1227      * persistent connections and Nagle's algorithm that have very severe
1228      * performance penalties.  (Failing to disable Nagle is not much of a
1229      * problem with simple HTTP.)
1230      *
1231      * In spite of these problems, failure here is not a shooting offense.
1232      */
1233     int just_say_no = 1;
1234
1235     if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *) &just_say_no,
1236                    sizeof(int)) < 0) {
1237         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
1238                     "setsockopt: (TCP_NODELAY)");
1239     }
1240 }
1241
1242 #else
1243 #define sock_disable_nagle(s)   /* NOOP */
1244 #endif
1245
1246
1247 /*****************************************************************
1248  * Child process main loop.
1249  * The following vars are static to avoid getting clobbered by longjmp();
1250  * they are really private to child_main.
1251  */
1252
1253 static int srv;
1254 static ap_socket_t *csd;
1255 static int requests_this_child;
1256 static fd_set main_fds;
1257
1258 int ap_graceful_stop_signalled(void)
1259 {
1260     ap_sync_scoreboard_image();
1261     if (deferred_die ||
1262         ap_scoreboard_image->global.running_generation != ap_my_generation) {
1263         return 1;
1264     }
1265     return 0;
1266 }
1267
1268 static void child_main(int child_num_arg)
1269 {
1270     ap_listen_rec *lr;
1271     ap_listen_rec *last_lr;
1272     ap_listen_rec *first_lr;
1273     ap_pool_t *ptrans;
1274     conn_rec *current_conn;
1275     ap_iol *iol;
1276     ap_status_t stat;
1277     int sockdes;
1278
1279     ap_my_pid = getpid();
1280     csd = NULL;
1281     my_child_num = child_num_arg;
1282     requests_this_child = 0;
1283     last_lr = NULL;
1284
1285     /* Get a sub context for global allocations in this child, so that
1286      * we can have cleanups occur when the child exits.
1287      */
1288     ap_create_pool(&pchild, pconf);
1289
1290     ap_create_pool(&ptrans, pchild);
1291
1292     /* needs to be done before we switch UIDs so we have permissions */
1293     reopen_scoreboard(pchild);
1294     SAFE_ACCEPT(accept_mutex_child_init(pchild));
1295
1296     if (unixd_setup_child()) {
1297         clean_child_exit(APEXIT_CHILDFATAL);
1298     }
1299
1300     ap_child_init_hook(pchild, ap_server_conf);
1301
1302     (void) ap_update_child_status(my_child_num, SERVER_READY, (request_rec *) NULL);
1303
1304     ap_signal(SIGHUP, just_die);
1305     ap_signal(SIGTERM, just_die);
1306
1307 #ifdef OS2
1308 /* Stop Ctrl-C/Ctrl-Break signals going to child processes */
1309     {
1310         unsigned long ulTimes;
1311         DosSetSignalExceptionFocus(0, &ulTimes);
1312     }
1313 #endif
1314
1315     while (!ap_graceful_stop_signalled()) {
1316         BUFF *conn_io;
1317
1318         /* Prepare to receive a SIGUSR1 due to graceful restart so that
1319          * we can exit cleanly.
1320          */
1321         usr1_just_die = 1;
1322         ap_signal(SIGUSR1, usr1_handler);
1323
1324         /*
1325          * (Re)initialize this child to a pre-connection state.
1326          */
1327
1328         current_conn = NULL;
1329
1330         ap_clear_pool(ptrans);
1331
1332         if ((ap_max_requests_per_child > 0
1333              && requests_this_child++ >= ap_max_requests_per_child)) {
1334             clean_child_exit(0);
1335         }
1336
1337         (void) ap_update_child_status(my_child_num, SERVER_READY, (request_rec *) NULL);
1338
1339         /*
1340          * Wait for an acceptable connection to arrive.
1341          */
1342
1343         /* Lock around "accept", if necessary */
1344         SAFE_ACCEPT(accept_mutex_on());
1345
1346         for (;;) {
1347             if (ap_listeners->next) {
1348                 /* more than one socket */
1349                 memcpy(&main_fds, &listenfds, sizeof(fd_set));
1350                 srv = ap_select(listenmaxfd + 1, &main_fds, NULL, NULL, NULL);
1351
1352                 if (srv < 0 && errno != EINTR) {
1353                     /* Single Unix documents select as returning errnos
1354                      * EBADF, EINTR, and EINVAL... and in none of those
1355                      * cases does it make sense to continue.  In fact
1356                      * on Linux 2.0.x we seem to end up with EFAULT
1357                      * occasionally, and we'd loop forever due to it.
1358                      */
1359                     ap_log_error(APLOG_MARK, APLOG_ERR, errno, ap_server_conf, "select: (listen)");
1360                     clean_child_exit(1);
1361                 }
1362
1363                 if (srv <= 0)
1364                     continue;
1365
1366                 /* we remember the last_lr we searched last time around so that
1367                    we don't end up starving any particular listening socket */
1368                 if (last_lr == NULL) {
1369                     lr = ap_listeners;
1370                 }
1371                 else {
1372                     lr = last_lr->next;
1373                     if (!lr)
1374                         lr = ap_listeners;
1375                 }
1376                 first_lr=lr;
1377                 do {
1378                     ap_get_os_sock(&sockdes, lr->sd);
1379                     if (FD_ISSET(sockdes, &main_fds))
1380                         goto got_listener;
1381                     lr = lr->next;
1382                     if (!lr)
1383                         lr = ap_listeners;
1384                 }
1385                 while (lr != first_lr);
1386                 /* FIXME: if we get here, something bad has happened, and we're
1387                    probably gonna spin forever.
1388                 */
1389                 continue;
1390         got_listener:
1391                 last_lr = lr;
1392                 sd = lr->sd;
1393             }
1394             else {
1395                 /* only one socket, just pretend we did the other stuff */
1396                 sd = ap_listeners->sd;
1397             }
1398
1399             /* if we accept() something we don't want to die, so we have to
1400              * defer the exit
1401              */
1402             usr1_just_die = 0;
1403             for (;;) {
1404                 if (deferred_die) {
1405                     /* we didn't get a socket, and we were told to die */
1406                     clean_child_exit(0);
1407                 }
1408                 stat = ap_accept(&csd, sd, ptrans);
1409                 if (stat == APR_SUCCESS || stat != APR_EINTR)
1410                     break;
1411             }
1412
1413             if (stat == APR_SUCCESS)
1414                 break;          /* We have a socket ready for reading */
1415             else {
1416
1417 /* TODO: this accept result handling stuff should be abstracted...
1418  * it's already out of date between the various unix mpms
1419  */
1420                 /* Our old behaviour here was to continue after accept()
1421                  * errors.  But this leads us into lots of troubles
1422                  * because most of the errors are quite fatal.  For
1423                  * example, EMFILE can be caused by slow descriptor
1424                  * leaks (say in a 3rd party module, or libc).  It's
1425                  * foolish for us to continue after an EMFILE.  We also
1426                  * seem to tickle kernel bugs on some platforms which
1427                  * lead to never-ending loops here.  So it seems best
1428                  * to just exit in most cases.
1429                  */
1430                 switch (errno) {
1431 #ifdef EPROTO
1432                     /* EPROTO on certain older kernels really means
1433                      * ECONNABORTED, so we need to ignore it for them.
1434                      * See discussion in new-httpd archives nh.9701
1435                      * search for EPROTO.
1436                      *
1437                      * Also see nh.9603, search for EPROTO:
1438                      * There is potentially a bug in Solaris 2.x x<6,
1439                      * and other boxes that implement tcp sockets in
1440                      * userland (i.e. on top of STREAMS).  On these
1441                      * systems, EPROTO can actually result in a fatal
1442                      * loop.  See PR#981 for example.  It's hard to
1443                      * handle both uses of EPROTO.
1444                      */
1445                 case EPROTO:
1446 #endif
1447 #ifdef ECONNABORTED
1448                 case ECONNABORTED:
1449 #endif
1450                     /* Linux generates the rest of these, other tcp
1451                      * stacks (i.e. bsd) tend to hide them behind
1452                      * getsockopt() interfaces.  They occur when
1453                      * the net goes sour or the client disconnects
1454                      * after the three-way handshake has been done
1455                      * in the kernel but before userland has picked
1456                      * up the socket.
1457                      */
1458 #ifdef ECONNRESET
1459                 case ECONNRESET:
1460 #endif
1461 #ifdef ETIMEDOUT
1462                 case ETIMEDOUT:
1463 #endif
1464 #ifdef EHOSTUNREACH
1465                 case EHOSTUNREACH:
1466 #endif
1467 #ifdef ENETUNREACH
1468                 case ENETUNREACH:
1469 #endif
1470                     break;
1471 #ifdef ENETDOWN
1472                 case ENETDOWN:
1473                      /*
1474                       * When the network layer has been shut down, there
1475                       * is not much use in simply exiting: the parent
1476                       * would simply re-create us (and we'd fail again).
1477                       * Use the CHILDFATAL code to tear the server down.
1478                       * @@@ Martin's idea for possible improvement:
1479                       * A different approach would be to define
1480                       * a new APEXIT_NETDOWN exit code, the reception
1481                       * of which would make the parent shutdown all
1482                       * children, then idle-loop until it detected that
1483                       * the network is up again, and restart the children.
1484                       * Ben Hyde noted that temporary ENETDOWN situations
1485                       * occur in mobile IP.
1486                       */
1487                     ap_log_error(APLOG_MARK, APLOG_EMERG, errno, ap_server_conf,
1488                         "accept: giving up.");
1489                     clean_child_exit(APEXIT_CHILDFATAL);
1490 #endif /*ENETDOWN*/
1491
1492 #ifdef TPF
1493                 case EINACT:
1494                     ap_log_error(APLOG_MARK, APLOG_EMERG, errno, ap_server_conf,
1495                         "offload device inactive");
1496                     clean_child_exit(APEXIT_CHILDFATAL);
1497                     break;
1498                 default:
1499                     ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, ap_server_conf,
1500                         "select/accept error (%u)", errno);
1501                     clean_child_exit(APEXIT_CHILDFATAL);
1502 #else
1503                 default:
1504                     ap_log_error(APLOG_MARK, APLOG_ERR, errno, ap_server_conf,
1505                                 "accept: (client socket)");
1506                     clean_child_exit(1);
1507 #endif
1508                 }
1509             }
1510
1511             if (ap_graceful_stop_signalled()) {
1512                 clean_child_exit(0);
1513             }
1514             usr1_just_die = 1;
1515         }
1516
1517         SAFE_ACCEPT(accept_mutex_off());        /* unlock after "accept" */
1518
1519 #ifdef TPF
1520         if (csd == 0)                       /* 0 is invalid socket for TPF */
1521             continue;
1522 #endif
1523
1524         /* We've got a socket, let's at least process one request off the
1525          * socket before we accept a graceful restart request.  We set
1526          * the signal to ignore because we don't want to disturb any
1527          * third party code.
1528          */
1529         ap_signal(SIGUSR1, SIG_IGN);
1530         /*
1531          * We now have a connection, so set it up with the appropriate
1532          * socket options, file descriptors, and read/write buffers.
1533          */
1534
1535         ap_get_os_sock(&sockdes, csd);
1536
1537         sock_disable_nagle(sockdes);
1538
1539         iol = unix_attach_socket(csd);
1540         if (iol == NULL) {
1541             if (errno == EBADF) {
1542                 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, NULL,
1543                     "filedescriptor (%u) larger than FD_SETSIZE (%u) "
1544                     "found, you probably need to rebuild Apache with a "
1545                     "larger FD_SETSIZE", sockdes, FD_SETSIZE);
1546             }
1547             else {
1548                 ap_log_error(APLOG_MARK, APLOG_WARNING, errno, NULL,
1549                     "error attaching to socket");
1550             }
1551             ap_close_socket(csd);
1552             continue;
1553         }
1554
1555         (void) ap_update_child_status(my_child_num, SERVER_BUSY_READ,
1556                                    (request_rec *) NULL);
1557
1558         conn_io = ap_bcreate(ptrans, B_RDWR);
1559
1560         ap_bpush_iol(conn_io, iol);
1561
1562         current_conn = ap_new_apr_connection(ptrans, ap_server_conf, conn_io, csd,
1563                                          my_child_num);
1564
1565         ap_process_connection(current_conn);
1566         ap_lingering_close(current_conn);
1567     }
1568 }
1569
1570
1571 static int make_child(server_rec *s, int slot, time_t now)
1572 {
1573     int pid;
1574
1575     if (slot + 1 > ap_max_daemons_limit) {
1576         ap_max_daemons_limit = slot + 1;
1577     }
1578
1579     if (one_process) {
1580         ap_signal(SIGHUP, just_die);
1581         ap_signal(SIGINT, just_die);
1582 #ifdef SIGQUIT
1583         ap_signal(SIGQUIT, SIG_DFL);
1584 #endif
1585         ap_signal(SIGTERM, just_die);
1586         child_main(slot);
1587     }
1588
1589     (void) ap_update_child_status(slot, SERVER_STARTING, (request_rec *) NULL);
1590
1591
1592 #ifdef _OSD_POSIX
1593     /* BS2000 requires a "special" version of fork() before a setuid() call */
1594     if ((pid = os_fork(unixd_config.user_name)) == -1) {
1595 #elif defined(TPF)
1596     if ((pid = os_fork(s, slot)) == -1) {
1597 #else
1598     if ((pid = fork()) == -1) {
1599 #endif
1600         ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, "fork: Unable to fork new process");
1601
1602         /* fork didn't succeed. Fix the scoreboard or else
1603          * it will say SERVER_STARTING forever and ever
1604          */
1605         (void) ap_update_child_status(slot, SERVER_DEAD, (request_rec *) NULL);
1606
1607         /* In case system resources are maxxed out, we don't want
1608            Apache running away with the CPU trying to fork over and
1609            over and over again. */
1610         sleep(10);
1611
1612         return -1;
1613     }
1614
1615     if (!pid) {
1616 #ifdef AIX_BIND_PROCESSOR
1617 /* by default AIX binds to a single processor
1618  * this bit unbinds children which will then bind to another cpu
1619  */
1620 #include <sys/processor.h>
1621         int status = bindprocessor(BINDPROCESS, (int)getpid(), 
1622                                    PROCESSOR_CLASS_ANY);
1623         if (status != OK) {
1624             ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, ap_server_conf,
1625                         "processor unbind failed %d", status);
1626         }
1627 #endif
1628         RAISE_SIGSTOP(MAKE_CHILD);
1629         /* Disable the restart signal handlers and enable the just_die stuff.
1630          * Note that since restart() just notes that a restart has been
1631          * requested there's no race condition here.
1632          */
1633         ap_signal(SIGHUP, just_die);
1634         ap_signal(SIGUSR1, just_die);
1635         ap_signal(SIGTERM, just_die);
1636         child_main(slot);
1637     }
1638
1639     ap_scoreboard_image->parent[slot].pid = pid;
1640 #ifdef SCOREBOARD_FILE
1641     lseek(scoreboard_fd, XtOffsetOf(scoreboard, parent[slot]), 0);
1642     force_write(scoreboard_fd, &ap_scoreboard_image->parent[slot],
1643                 sizeof(parent_score));
1644 #endif
1645
1646     return 0;
1647 }
1648
1649
1650 /* start up a bunch of children */
1651 static void startup_children(int number_to_start)
1652 {
1653     int i;
1654     time_t now = time(0);
1655
1656     for (i = 0; number_to_start && i < ap_daemons_limit; ++i) {
1657         if (ap_scoreboard_image->servers[i].status != SERVER_DEAD) {
1658             continue;
1659         }
1660         if (make_child(ap_server_conf, i, now) < 0) {
1661             break;
1662         }
1663         --number_to_start;
1664     }
1665 }
1666
1667
1668 /*
1669  * idle_spawn_rate is the number of children that will be spawned on the
1670  * next maintenance cycle if there aren't enough idle servers.  It is
1671  * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by
1672  * without the need to spawn.
1673  */
1674 static int idle_spawn_rate = 1;
1675 #ifndef MAX_SPAWN_RATE
1676 #define MAX_SPAWN_RATE  (32)
1677 #endif
1678 static int hold_off_on_exponential_spawning;
1679
1680 static void perform_idle_server_maintenance(void)
1681 {
1682     int i;
1683     int to_kill;
1684     int idle_count;
1685     short_score *ss;
1686     time_t now = time(0);
1687     int free_length;
1688     int free_slots[MAX_SPAWN_RATE];
1689     int last_non_dead;
1690     int total_non_dead;
1691
1692     /* initialize the free_list */
1693     free_length = 0;
1694
1695     to_kill = -1;
1696     idle_count = 0;
1697     last_non_dead = -1;
1698     total_non_dead = 0;
1699
1700     ap_sync_scoreboard_image();
1701     for (i = 0; i < ap_daemons_limit; ++i) {
1702         int status;
1703
1704         if (i >= ap_max_daemons_limit && free_length == idle_spawn_rate)
1705             break;
1706         ss = &ap_scoreboard_image->servers[i];
1707         status = ss->status;
1708         if (status == SERVER_DEAD) {
1709             /* try to keep children numbers as low as possible */
1710             if (free_length < idle_spawn_rate) {
1711                 free_slots[free_length] = i;
1712                 ++free_length;
1713             }
1714         }
1715         else {
1716             /* We consider a starting server as idle because we started it
1717              * at least a cycle ago, and if it still hasn't finished starting
1718              * then we're just going to swamp things worse by forking more.
1719              * So we hopefully won't need to fork more if we count it.
1720              * This depends on the ordering of SERVER_READY and SERVER_STARTING.
1721              */
1722             if (status <= SERVER_READY) {
1723                 ++ idle_count;
1724                 /* always kill the highest numbered child if we have to...
1725                  * no really well thought out reason ... other than observing
1726                  * the server behaviour under linux where lower numbered children
1727                  * tend to service more hits (and hence are more likely to have
1728                  * their data in cpu caches).
1729                  */
1730                 to_kill = i;
1731             }
1732
1733             ++total_non_dead;
1734             last_non_dead = i;
1735         }
1736     }
1737     ap_max_daemons_limit = last_non_dead + 1;
1738     if (idle_count > ap_daemons_max_free) {
1739         /* kill off one child... we use SIGUSR1 because that'll cause it to
1740          * shut down gracefully, in case it happened to pick up a request
1741          * while we were counting
1742          */
1743         kill(ap_scoreboard_image->parent[to_kill].pid, SIGUSR1);
1744         idle_spawn_rate = 1;
1745     }
1746     else if (idle_count < ap_daemons_min_free) {
1747         /* terminate the free list */
1748         if (free_length == 0) {
1749             /* only report this condition once */
1750             static int reported = 0;
1751
1752             if (!reported) {
1753                 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, ap_server_conf,
1754                             "server reached MaxClients setting, consider"
1755                             " raising the MaxClients setting");
1756                 reported = 1;
1757             }
1758             idle_spawn_rate = 1;
1759         }
1760         else {
1761             if (idle_spawn_rate >= 8) {
1762                 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0, ap_server_conf,
1763                     "server seems busy, (you may need "
1764                     "to increase StartServers, or Min/MaxSpareServers), "
1765                     "spawning %d children, there are %d idle, and "
1766                     "%d total children", idle_spawn_rate,
1767                     idle_count, total_non_dead);
1768             }
1769             for (i = 0; i < free_length; ++i) {
1770 #ifdef TPF
1771         if(make_child(ap_server_conf, free_slots[i], now) == -1) {
1772             if(free_length == 1) {
1773                 shutdown_pending = 1;
1774                 ap_log_error(APLOG_MARK, APLOG_EMERG, ap_server_conf,
1775                 "No active child processes: shutting down");
1776             }
1777         }
1778 #else
1779                 make_child(ap_server_conf, free_slots[i], now);
1780 #endif /* TPF */
1781             }
1782             /* the next time around we want to spawn twice as many if this
1783              * wasn't good enough, but not if we've just done a graceful
1784              */
1785             if (hold_off_on_exponential_spawning) {
1786                 --hold_off_on_exponential_spawning;
1787             }
1788             else if (idle_spawn_rate < MAX_SPAWN_RATE) {
1789                 idle_spawn_rate *= 2;
1790             }
1791         }
1792     }
1793     else {
1794         idle_spawn_rate = 1;
1795     }
1796 }
1797
1798
1799 static void process_child_status(ap_proc_t *pid, ap_wait_t status)
1800 {
1801     /* Child died... if it died due to a fatal error,
1802         * we should simply bail out.
1803         */
1804     if ((WIFEXITED(status)) &&
1805         WEXITSTATUS(status) == APEXIT_CHILDFATAL) {
1806         ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, 0, ap_server_conf,
1807                         "Child %d returned a Fatal error... \n"
1808                         "Apache is exiting!",
1809                         pid->pid);
1810         exit(APEXIT_CHILDFATAL);
1811     }
1812     if (WIFSIGNALED(status)) {
1813         switch (WTERMSIG(status)) {
1814         case SIGTERM:
1815         case SIGHUP:
1816         case SIGUSR1:
1817         case SIGKILL:
1818             break;
1819         default:
1820 #ifdef SYS_SIGLIST
1821 #ifdef WCOREDUMP
1822             if (WCOREDUMP(status)) {
1823                 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE,
1824                              0, ap_server_conf,
1825                              "child pid %d exit signal %s (%d), "
1826                              "possible coredump in %s",
1827                              pid->pid, (WTERMSIG(status) >= NumSIG) ? "" : 
1828                              SYS_SIGLIST[WTERMSIG(status)], WTERMSIG(status),
1829                              ap_coredump_dir);
1830             }
1831             else {
1832 #endif
1833                 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE,
1834                              0, ap_server_conf,
1835                              "child pid %d exit signal %s (%d)", pid->pid,
1836                              SYS_SIGLIST[WTERMSIG(status)], WTERMSIG(status));
1837 #ifdef WCOREDUMP
1838             }
1839 #endif
1840 #else
1841             ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE,
1842                          ap_server_conf,
1843                          "child pid %d exit signal %d",
1844                          pid->pid, WTERMSIG(status));
1845 #endif
1846         }
1847     }
1848 }
1849
1850
1851 static int setup_listeners(server_rec *s)
1852 {
1853     ap_listen_rec *lr;
1854     int sockdes;
1855
1856     if (ap_listen_open(s->process, s->port)) {
1857         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ALERT, 0, s,
1858                     "no listening sockets available, shutting down");
1859         return -1;
1860     }
1861
1862     listenmaxfd = -1;
1863     FD_ZERO(&listenfds);
1864     for (lr = ap_listeners; lr; lr = lr->next) {
1865         ap_get_os_sock(&sockdes, lr->sd);
1866         FD_SET(sockdes, &listenfds);
1867         if (sockdes > listenmaxfd) {
1868             listenmaxfd = sockdes;
1869         }
1870     }
1871     return 0;
1872 }
1873
1874 /* Useful to erase the status of children that might be from previous
1875  * generations */
1876 static void ap_prefork_force_reset_connection_status(long conn_id)
1877 {
1878     int i;
1879
1880     for (i = 0; i < STATUSES_PER_CONNECTION; i++) {
1881         ap_new_scoreboard_image->table[conn_id][i].key[0] = '\0';
1882     }                                                                           }
1883
1884 void ap_reset_connection_status(long conn_id)
1885 {
1886     if (maintain_connection_status) {
1887         ap_prefork_force_reset_connection_status(conn_id);
1888     }
1889 }
1890
1891 /*****************************************************************
1892  * Executive routines.
1893  */
1894
1895 int ap_mpm_run(ap_pool_t *_pconf, ap_pool_t *plog, server_rec *s)
1896 {
1897     int remaining_children_to_start;
1898
1899     pconf = _pconf;
1900
1901     ap_server_conf = s;
1902  
1903     ap_log_pid(pconf, ap_pid_fname);
1904
1905     if (setup_listeners(s)) {
1906         /* XXX: hey, what's the right way for the mpm to indicate a fatal error? */
1907         return 1;
1908     }
1909
1910     SAFE_ACCEPT(accept_mutex_init(pconf));
1911     if (!is_graceful) {
1912         reinit_scoreboard(pconf);
1913     }
1914 #ifdef SCOREBOARD_FILE
1915     else {
1916         ap_scoreboard_fname = ap_server_root_relative(pconf, ap_scoreboard_fname);
1917         ap_note_cleanups_for_fd(pconf, scoreboard_fd);
1918     }
1919 #endif
1920
1921     set_signals();
1922
1923     if (ap_daemons_max_free < ap_daemons_min_free + 1)  /* Don't thrash... */
1924         ap_daemons_max_free = ap_daemons_min_free + 1;
1925
1926     /* If we're doing a graceful_restart then we're going to see a lot
1927         * of children exiting immediately when we get into the main loop
1928         * below (because we just sent them SIGUSR1).  This happens pretty
1929         * rapidly... and for each one that exits we'll start a new one until
1930         * we reach at least daemons_min_free.  But we may be permitted to
1931         * start more than that, so we'll just keep track of how many we're
1932         * supposed to start up without the 1 second penalty between each fork.
1933         */
1934     remaining_children_to_start = ap_daemons_to_start;
1935     if (remaining_children_to_start > ap_daemons_limit) {
1936         remaining_children_to_start = ap_daemons_limit;
1937     }
1938     if (!is_graceful) {
1939         startup_children(remaining_children_to_start);
1940         remaining_children_to_start = 0;
1941     }
1942     else {
1943         /* give the system some time to recover before kicking into
1944             * exponential mode */
1945         hold_off_on_exponential_spawning = 10;
1946     }
1947
1948     ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, ap_server_conf,
1949                 "%s configured -- resuming normal operations",
1950                 ap_get_server_version());
1951     ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0, ap_server_conf,
1952                 "Server built: %s", ap_get_server_built());
1953     restart_pending = shutdown_pending = 0;
1954
1955     while (!restart_pending && !shutdown_pending) {
1956         int child_slot;
1957         ap_wait_t status;
1958         /* this is a memory leak, but I'll fix it later. */
1959         ap_proc_t pid;
1960
1961         ap_wait_or_timeout(&status, &pid, pconf);
1962
1963         /* XXX: if it takes longer than 1 second for all our children
1964          * to start up and get into IDLE state then we may spawn an
1965          * extra child
1966          */
1967         if (pid.pid != -1) {
1968             process_child_status(&pid, status);
1969             /* non-fatal death... note that it's gone in the scoreboard. */
1970             ap_sync_scoreboard_image();
1971             child_slot = find_child_by_pid(&pid);
1972             if (child_slot >= 0) {
1973                 ap_prefork_force_reset_connection_status(child_slot);
1974                 (void) ap_update_child_status(child_slot, SERVER_DEAD,
1975                                             (request_rec *) NULL);
1976                 if (remaining_children_to_start
1977                     && child_slot < ap_daemons_limit) {
1978                     /* we're still doing a 1-for-1 replacement of dead
1979                         * children with new children
1980                         */
1981                     make_child(ap_server_conf, child_slot, time(0));
1982                     --remaining_children_to_start;
1983                 }
1984 #ifdef APR_HAS_OTHER_CHILD
1985             }
1986             else if (ap_reap_other_child(&pid, status) == 0) {
1987                 /* handled */
1988 #endif
1989             }
1990             else if (is_graceful) {
1991                 /* Great, we've probably just lost a slot in the
1992                     * scoreboard.  Somehow we don't know about this
1993                     * child.
1994                     */
1995                 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 
1996                             0, ap_server_conf,
1997                             "long lost child came home! (pid %d)", pid.pid);
1998             }
1999             /* Don't perform idle maintenance when a child dies,
2000                 * only do it when there's a timeout.  Remember only a
2001                 * finite number of children can die, and it's pretty
2002                 * pathological for a lot to die suddenly.
2003                 */
2004             continue;
2005         }
2006         else if (remaining_children_to_start) {
2007             /* we hit a 1 second timeout in which none of the previous
2008                 * generation of children needed to be reaped... so assume
2009                 * they're all done, and pick up the slack if any is left.
2010                 */
2011             startup_children(remaining_children_to_start);
2012             remaining_children_to_start = 0;
2013             /* In any event we really shouldn't do the code below because
2014                 * few of the servers we just started are in the IDLE state
2015                 * yet, so we'd mistakenly create an extra server.
2016                 */
2017             continue;
2018         }
2019
2020         perform_idle_server_maintenance();
2021 #ifdef TPF
2022     shutdown_pending = os_check_server(tpf_server_name);
2023     ap_check_signals();
2024     sleep(1);
2025 #endif /*TPF */
2026     }
2027
2028     if (shutdown_pending) {
2029         /* Time to gracefully shut down:
2030          * Kill child processes, tell them to call child_exit, etc...
2031          */
2032         if (unixd_killpg(getpgrp(), SIGTERM) < 0) {
2033             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "killpg SIGTERM");
2034         }
2035         ap_reclaim_child_processes(1);          /* Start with SIGTERM */
2036
2037         /* cleanup pid file on normal shutdown */
2038         {
2039             const char *pidfile = NULL;
2040             pidfile = ap_server_root_relative (pconf, ap_pid_fname);
2041             if ( pidfile != NULL && unlink(pidfile) == 0)
2042                 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO,
2043                                 0, ap_server_conf,
2044                                 "removed PID file %s (pid=%ld)",
2045                                 pidfile, (long)getpid());
2046         }
2047
2048         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, ap_server_conf,
2049                     "caught SIGTERM, shutting down");
2050         return 1;
2051     }
2052
2053     /* we've been told to restart */
2054     ap_signal(SIGHUP, SIG_IGN);
2055     ap_signal(SIGUSR1, SIG_IGN);
2056     if (one_process) {
2057         /* not worth thinking about */
2058         return 1;
2059     }
2060
2061     /* advance to the next generation */
2062     /* XXX: we really need to make sure this new generation number isn't in
2063      * use by any of the children.
2064      */
2065     ++ap_my_generation;
2066     ap_scoreboard_image->global.running_generation = ap_my_generation;
2067     update_scoreboard_global();
2068
2069     if (is_graceful) {
2070 #ifndef SCOREBOARD_FILE
2071         int i;
2072 #endif
2073         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, ap_server_conf,
2074                     "SIGUSR1 received.  Doing graceful restart");
2075
2076         /* kill off the idle ones */
2077         if (unixd_killpg(getpgrp(), SIGUSR1) < 0) {
2078             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "killpg SIGUSR1");
2079         }
2080 #ifndef SCOREBOARD_FILE
2081         /* This is mostly for debugging... so that we know what is still
2082             * gracefully dealing with existing request.  But we can't really
2083             * do it if we're in a SCOREBOARD_FILE because it'll cause
2084             * corruption too easily.
2085             */
2086         ap_sync_scoreboard_image();
2087         for (i = 0; i < ap_daemons_limit; ++i) {
2088             if (ap_scoreboard_image->servers[i].status != SERVER_DEAD) {
2089                 ap_scoreboard_image->servers[i].status = SERVER_GRACEFUL;
2090             }
2091         }
2092 #endif
2093     }
2094     else {
2095         /* Kill 'em off */
2096         if (unixd_killpg(getpgrp(), SIGHUP) < 0) {
2097             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "killpg SIGHUP");
2098         }
2099         ap_reclaim_child_processes(0);          /* Not when just starting up */
2100         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, ap_server_conf,
2101                     "SIGHUP received.  Attempting to restart");
2102     }
2103
2104     if (!is_graceful) {
2105         ap_restart_time = time(NULL);
2106     }
2107
2108     return 0;
2109 }
2110
2111 static void prefork_pre_config(ap_pool_t *p, ap_pool_t *plog, ap_pool_t *ptemp)
2112 {
2113     static int restart_num = 0;
2114
2115     one_process = !!getenv("ONE_PROCESS");
2116
2117     /* sigh, want this only the second time around */
2118     if (restart_num++ == 1) {
2119         is_graceful = 0;
2120
2121         if (!one_process) {
2122             unixd_detach();
2123         }
2124
2125         ap_my_pid = getpid();
2126     }
2127
2128     unixd_pre_config();
2129     ap_listen_pre_config();
2130     ap_daemons_to_start = DEFAULT_START_DAEMON;
2131     ap_daemons_min_free = DEFAULT_MIN_FREE_DAEMON;
2132     ap_daemons_max_free = DEFAULT_MAX_FREE_DAEMON;
2133     ap_daemons_limit = HARD_SERVER_LIMIT;
2134     ap_pid_fname = DEFAULT_PIDLOG;
2135     ap_scoreboard_fname = DEFAULT_SCOREBOARD;
2136     ap_lock_fname = DEFAULT_LOCKFILE;
2137     ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD;
2138     ap_extended_status = 0;
2139
2140     ap_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir));
2141 }
2142
2143 static void prefork_hooks(void)
2144 {
2145     INIT_SIGLIST();
2146 #ifdef AUX3
2147     (void) set42sig();
2148 #endif
2149     /* TODO: set one_process properly */ one_process = 0;
2150 }
2151
2152 static const char *set_pidfile(cmd_parms *cmd, void *dummy, char *arg) 
2153 {
2154     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2155     if (err != NULL) {
2156         return err;
2157     }
2158
2159     if (cmd->server->is_virtual) {
2160         return "PidFile directive not allowed in <VirtualHost>";
2161     }
2162     ap_pid_fname = arg;
2163     return NULL;
2164 }
2165
2166 static const char *set_scoreboard(cmd_parms *cmd, void *dummy, char *arg) 
2167 {
2168     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2169     if (err != NULL) {
2170         return err;
2171     }
2172
2173     ap_scoreboard_fname = arg;
2174     return NULL;
2175 }
2176
2177 static const char *set_lockfile(cmd_parms *cmd, void *dummy, char *arg) 
2178 {
2179     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2180     if (err != NULL) {
2181         return err;
2182     }
2183
2184     ap_lock_fname = arg;
2185     return NULL;
2186 }
2187
2188 static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy, char *arg) 
2189 {
2190     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2191     if (err != NULL) {
2192         return err;
2193     }
2194
2195     ap_daemons_to_start = atoi(arg);
2196     return NULL;
2197 }
2198
2199 static const char *set_min_free_servers(cmd_parms *cmd, void *dummy, char *arg)
2200 {
2201     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2202     if (err != NULL) {
2203         return err;
2204     }
2205
2206     ap_daemons_min_free = atoi(arg);
2207     if (ap_daemons_min_free <= 0) {
2208        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
2209                     "WARNING: detected MinSpareServers set to non-positive.");
2210        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
2211                     "Resetting to 1 to avoid almost certain Apache failure.");
2212        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
2213                     "Please read the documentation.");
2214        ap_daemons_min_free = 1;
2215     }
2216        
2217     return NULL;
2218 }
2219
2220 static const char *set_max_free_servers(cmd_parms *cmd, void *dummy, char *arg)
2221 {
2222     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2223     if (err != NULL) {
2224         return err;
2225     }
2226
2227     ap_daemons_max_free = atoi(arg);
2228     return NULL;
2229 }
2230
2231 static const char *set_server_limit (cmd_parms *cmd, void *dummy, char *arg) 
2232 {
2233     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2234     if (err != NULL) {
2235         return err;
2236     }
2237
2238     ap_daemons_limit = atoi(arg);
2239     if (ap_daemons_limit > HARD_SERVER_LIMIT) {
2240        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
2241                     "WARNING: MaxClients of %d exceeds compile time limit "
2242                     "of %d servers,", ap_daemons_limit, HARD_SERVER_LIMIT);
2243        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
2244                     " lowering MaxClients to %d.  To increase, please "
2245                     "see the", HARD_SERVER_LIMIT);
2246        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
2247                     " HARD_SERVER_LIMIT define in src/include/httpd.h.");
2248        ap_daemons_limit = HARD_SERVER_LIMIT;
2249     } 
2250     else if (ap_daemons_limit < 1) {
2251         ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
2252                      "WARNING: Require MaxClients > 0, setting to 1");
2253         ap_daemons_limit = 1;
2254     }
2255     return NULL;
2256 }
2257
2258 static const char *set_max_requests(cmd_parms *cmd, void *dummy, char *arg) 
2259 {
2260     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2261     if (err != NULL) {
2262         return err;
2263     }
2264
2265     ap_max_requests_per_child = atoi(arg);
2266
2267     return NULL;
2268 }
2269
2270 static const char *set_coredumpdir (cmd_parms *cmd, void *dummy, char *arg) 
2271 {
2272     struct stat finfo;
2273     const char *fname;
2274     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
2275     if (err != NULL) {
2276         return err;
2277     }
2278
2279     fname = ap_server_root_relative(cmd->pool, arg);
2280     if ((stat(fname, &finfo) == -1) || !S_ISDIR(finfo.st_mode)) {
2281         return ap_pstrcat(cmd->pool, "CoreDumpDirectory ", fname, 
2282                           " does not exist or is not a directory", NULL);
2283     }
2284     ap_cpystrn(ap_coredump_dir, fname, sizeof(ap_coredump_dir));
2285     return NULL;
2286 }
2287
2288 /* Stub functions until this MPM supports the connection status API */
2289 /* Don't mess with the string you get back from this function */
2290 const char *ap_get_connection_status(long conn_id, const char *key)
2291 {
2292     int i = 0;
2293     status_table_entry *ss;
2294
2295     if (!maintain_connection_status) return "";
2296     while (i < STATUSES_PER_CONNECTION) {
2297         ss = &(ap_new_scoreboard_image->table[conn_id][i]);
2298         if (ss->key[0] == '\0') {
2299             break;
2300         }
2301         if (0 == strcmp(ss->key, key)) {
2302             return ss->value;
2303         }
2304     }
2305
2306     return NULL;
2307 }
2308
2309 ap_array_header_t *ap_get_connections(ap_pool_t *p)
2310 {
2311     int i;
2312     ap_array_header_t *connection_list;
2313     long *array_slot;
2314
2315     connection_list = ap_make_array(p, 0, sizeof(long));
2316     /* We assume that there is a connection iff it has an entry in the status
2317      * table. Connections without any status sound problematic to me, so this
2318      * is probably for the best. - manoj */
2319     for (i = 0; i < ap_max_daemons_limit; i++) {
2320          if (ap_new_scoreboard_image->table[i][0].key[0] != '\0') {
2321             array_slot = ap_push_array(connection_list);
2322             *array_slot = i;
2323         }
2324     }
2325     return connection_list;
2326 }
2327
2328 ap_array_header_t *ap_get_connection_keys(ap_pool_t *p, long conn_id)
2329 {
2330     int i = 0;
2331     status_table_entry *ss;
2332     ap_array_header_t *key_list;
2333     char **array_slot;
2334
2335     key_list = ap_make_array(p, 0, KEY_LENGTH * sizeof(char));
2336     while (i < STATUSES_PER_CONNECTION) {
2337         ss = &(ap_new_scoreboard_image->table[conn_id][i]);
2338         if (ss->key[0] == '\0') {
2339             break;
2340         }
2341         array_slot = ap_push_array(key_list);
2342         *array_slot = ap_pstrdup(p, ss->key);
2343         i++;
2344     }
2345     return key_list;
2346 }
2347
2348 /* Note: no effort is made here to prevent multiple threads from messing with
2349  * a single connection at the same time. ap_update_connection_status should
2350  * only be called by the thread that owns the connection */
2351
2352 void ap_update_connection_status(long conn_id, const char *key,
2353                                  const char *value)
2354 {
2355     int i = 0;
2356     status_table_entry *ss;
2357
2358     if (!maintain_connection_status) return;
2359     while (i < STATUSES_PER_CONNECTION) {
2360         ss = &(ap_new_scoreboard_image->table[conn_id][i]);
2361         if (ss->key[0] == '\0') {
2362             break;
2363         }
2364         if (0 == strcmp(ss->key, key)) {
2365             ap_cpystrn(ss->value, value, VALUE_LENGTH);
2366             return;
2367         }
2368         i++;
2369     }
2370     /* Not found. Add an entry for this value */
2371     if (i >= STATUSES_PER_CONNECTION) {
2372         /* No room. Oh well, not much anyone can do about it. */
2373         return;
2374     }
2375     ap_cpystrn(ss->key, key, KEY_LENGTH);
2376     ap_cpystrn(ss->value, value, VALUE_LENGTH);
2377     return;
2378 }
2379
2380 ap_array_header_t *ap_get_status_table(ap_pool_t *p)
2381 {
2382     int i, j;
2383     ap_array_header_t *server_status;
2384     ap_status_table_row_t *array_slot;
2385     status_table_entry *ss;
2386
2387     server_status = ap_make_array(p, 0, sizeof(ap_status_table_row_t));
2388
2389     /* Go ahead and return what's in the connection status table even if we
2390      * aren't maintaining it. We can at least look at what children from
2391      * previous generations are up to. */
2392
2393     for (i = 0; i < ap_max_daemons_limit; i++) {
2394         if (ap_new_scoreboard_image->table[i][0].key[0] == '\0')
2395             continue;
2396         array_slot = ap_push_array(server_status);
2397         array_slot->data = ap_make_table(p, 0);
2398         array_slot->conn_id = i;
2399
2400         for (j = 0; j < STATUSES_PER_CONNECTION; j++) {
2401             ss = &(ap_new_scoreboard_image->table[i][j]);
2402             if (ss->key[0] != '\0') {
2403                 ap_table_add(array_slot->data, ss->key, ss->value);
2404             }
2405             else {
2406                 break;
2407             }
2408         }
2409     }
2410     return server_status;
2411 }
2412
2413 static const command_rec prefork_cmds[] = {
2414 UNIX_DAEMON_COMMANDS
2415 LISTEN_COMMANDS
2416 { "PidFile", set_pidfile, NULL, RSRC_CONF, TAKE1,
2417     "A file for logging the server process ID"},
2418 { "ScoreBoardFile", set_scoreboard, NULL, RSRC_CONF, TAKE1,
2419     "A file for Apache to maintain runtime process management information"},
2420 { "LockFile", set_lockfile, NULL, RSRC_CONF, TAKE1,
2421     "The lockfile used when Apache needs to lock the accept() call"},
2422 { "StartServers", set_daemons_to_start, NULL, RSRC_CONF, TAKE1,
2423   "Number of child processes launched at server startup" },
2424 { "MinSpareServers", set_min_free_servers, NULL, RSRC_CONF, TAKE1,
2425   "Minimum number of idle children, to handle request spikes" },
2426 { "MaxSpareServers", set_max_free_servers, NULL, RSRC_CONF, TAKE1,
2427   "Maximum number of idle children" },
2428 { "MaxClients", set_server_limit, NULL, RSRC_CONF, TAKE1,
2429   "Maximum number of children alive at the same time" },
2430 { "MaxRequestsPerChild", set_max_requests, NULL, RSRC_CONF, TAKE1,
2431   "Maximum number of requests a particular child serves before dying." },
2432 { "CoreDumpDirectory", set_coredumpdir, NULL, RSRC_CONF, TAKE1,
2433   "The location of the directory Apache changes to before dumping core" },
2434 { NULL }
2435 };
2436
2437 module MODULE_VAR_EXPORT mpm_prefork_module = {
2438     MPM20_MODULE_STUFF,
2439     prefork_pre_config,         /* run hook before the configuration is read */
2440     NULL,                       /* create per-directory config structure */
2441     NULL,                       /* merge per-directory config structures */
2442     NULL,                       /* create per-server config structure */
2443     NULL,                       /* merge per-server config structures */
2444     prefork_cmds,               /* command ap_table_t */
2445     NULL,                       /* handlers */
2446     prefork_hooks,              /* register hooks */
2447 };