]> granicus.if.org Git - apache/blob - server/mpm/perchild/perchild.c
This serves requests again, although it still doesn't forward requests off
[apache] / server / mpm / perchild / perchild.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 #define CORE_PRIVATE 
60  
61 #include "ap_config.h"
62 #include "apr_hash.h"
63 #include "apr_strings.h"
64 #include "apr_portable.h"
65 #include "apr_file_io.h"
66 #include "httpd.h" 
67 #include "http_main.h" 
68 #include "http_log.h" 
69 #include "http_config.h"        /* for read_config */ 
70 #include "http_core.h"          /* for get_remote_host */ 
71 #include "http_protocol.h"
72 #include "http_connection.h"
73 #include "ap_mpm.h"
74 #include "unixd.h"
75 #include "mpm_common.h"
76 #include "ap_iol.h"
77 #include "ap_listen.h"
78 #include "mpm_default.h"
79 #include "mpm.h"
80 #include "scoreboard.h"
81
82 #ifdef HAVE_UNISTD_H
83 #include <unistd.h>
84 #endif
85 #include <poll.h>
86 #ifdef HAVE_SYS_SOCKET_H
87 #include <sys/socket.h>
88 #endif
89 #ifdef HAVE_NETINET_TCP_H
90 #include <netinet/tcp.h>
91 #endif
92 #include <grp.h>
93 #include <pwd.h>
94 #include <pthread.h>
95 #include <sys/stat.h>
96 #include <signal.h>
97 #include <sys/un.h>
98
99 /*
100  * Actual definitions of config globals
101  */
102
103 static int threads_to_start = 0;         /* Worker threads per child */
104 static int min_spare_threads = 0;
105 static int max_spare_threads = 0;
106 static int max_threads = 0;
107 static int max_requests_per_child = 0;
108 static const char *ap_pid_fname=NULL;
109 API_VAR_EXPORT const char *ap_scoreboard_fname=NULL;
110 static int num_daemons=0;
111 static int curr_child_num=0;
112 static int socket_num=0;
113 static int workers_may_exit = 0;
114 static int requests_this_child;
115 static int num_listenfds = 0;
116 static ap_socket_t **listenfds;
117
118 struct child_info_t {
119     uid_t uid;
120     gid_t gid;
121     char *name;          /* The extention for this socket.  "uig:gid" */
122     int num;
123     int sd;
124 };
125
126 struct socket_info_t {
127     const char *sname;   /* The servername */
128     int        cnum;     /* The socket number */
129 };
130
131 typedef struct {
132     const char *sockname;
133 } perchild_server_conf;
134
135 typedef struct child_info_t child_info_t;
136 typedef struct socket_info_t socket_info_t;
137
138 /* Tables used to determine the user and group each child process should
139  * run as.  The hash table is used to correlate a server name with a child
140  * process.
141  */
142 static child_info_t child_info_table[HARD_SERVER_LIMIT];
143 static ap_hash_t    *socket_info_table = NULL;
144
145
146 struct ap_ctable    ap_child_table[HARD_SERVER_LIMIT];
147
148 /*
149  * The max child slot ever assigned, preserved across restarts.  Necessary
150  * to deal with NumServers changes across SIGWINCH restarts.  We use this
151  * value to optimize routines that have to scan the entire child table.
152  *
153  * XXX - It might not be worth keeping this code in. There aren't very
154  * many child processes in this MPM.
155  */
156 int ap_max_daemons_limit = -1;
157
158 char ap_coredump_dir[MAX_STRING_LEN];
159
160 module MODULE_VAR_EXPORT mpm_perchild_module;
161
162 static ap_file_t *pipe_of_death_in = NULL;
163 static ap_file_t *pipe_of_death_out = NULL;
164 static pthread_mutex_t pipe_of_death_mutex;
165
166 /* *Non*-shared http_main globals... */
167
168 server_rec *ap_server_conf;
169
170 /* one_process --- debugging mode variable; can be set from the command line
171  * with the -X flag.  If set, this gets you the child_main loop running
172  * in the process which originally started up (no detach, no make_child),
173  * which is a pretty nice debugging environment.  (You'll get a SIGHUP
174  * early in standalone_main; just continue through.  This is the server
175  * trying to kill off any child processes which it might have lying
176  * around --- Apache doesn't keep track of their pids, it just sends
177  * SIGHUP to the process group, ignoring it in the root process.
178  * Continue through and you'll be fine.).
179  */
180
181 static int one_process = 0;
182
183 #ifdef DEBUG_SIGSTOP
184 int raise_sigstop_flags;
185 #endif
186
187 static ap_pool_t *pconf;                /* Pool for config stuff */
188 static ap_pool_t *pchild;               /* Pool for httpd child stuff */
189 static ap_pool_t *thread_pool_parent; /* Parent of per-thread pools */
190 static pthread_mutex_t thread_pool_parent_mutex;
191
192 static int child_num;
193 static unsigned int my_pid; /* Linux getpid() doesn't work except in 
194                       main thread. Use this instead */
195 /* Keep track of the number of worker threads currently active */
196 static int worker_thread_count;
197 static pthread_mutex_t worker_thread_count_mutex;
198 static int worker_thread_free_ids[HARD_THREAD_LIMIT];
199 static pthread_attr_t worker_thread_attr;
200
201 /* Keep track of the number of idle worker threads */
202 static int idle_thread_count;
203 static pthread_mutex_t idle_thread_count_mutex;
204
205 /* Locks for accept serialization */
206 #ifdef NO_SERIALIZED_ACCEPT
207 #define SAFE_ACCEPT(stmt) APR_SUCCESS
208 #else
209 #define SAFE_ACCEPT(stmt) (stmt)
210 static ap_lock_t *process_accept_mutex;
211 #endif /* NO_SERIALIZED_ACCEPT */
212 static const char *lock_fname;
213 static pthread_mutex_t thread_accept_mutex = PTHREAD_MUTEX_INITIALIZER;
214
215 API_EXPORT(int) ap_get_max_daemons(void)
216 {
217     return ap_max_daemons_limit;
218 }
219
220 /* a clean exit from a child with proper cleanup */
221 static void clean_child_exit(int code)
222 {
223     if (pchild) {
224         ap_destroy_pool(pchild);
225     }
226     exit(code);
227 }
228
229 /* handle all varieties of core dumping signals */
230 static void sig_coredump(int sig)
231 {
232     chdir(ap_coredump_dir);
233     ap_signal(sig, SIG_DFL);
234     kill(getpid(), sig);
235     /* At this point we've got sig blocked, because we're still inside
236      * the signal handler.  When we leave the signal handler it will
237      * be unblocked, and we'll take the signal... and coredump or whatever
238      * is appropriate for this particular Unix.  In addition the parent
239      * will see the real signal we received -- whereas if we called
240      * abort() here, the parent would only see SIGABRT.
241      */
242 }
243
244 static void just_die(int sig)
245 {
246     clean_child_exit(0);
247 }
248
249 /*****************************************************************
250  * Connection structures and accounting...
251  */
252
253 /* volatile just in case */
254 static int volatile shutdown_pending;
255 static int volatile restart_pending;
256 static int volatile is_graceful;
257
258 /*
259  * ap_start_shutdown() and ap_start_restart(), below, are a first stab at
260  * functions to initiate shutdown or restart without relying on signals. 
261  * Previously this was initiated in sig_term() and restart() signal handlers, 
262  * but we want to be able to start a shutdown/restart from other sources --
263  * e.g. on Win32, from the service manager. Now the service manager can
264  * call ap_start_shutdown() or ap_start_restart() as appropiate.  Note that
265  * these functions can also be called by the child processes, since global
266  * variables are no longer used to pass on the required action to the parent.
267  *
268  * These should only be called from the parent process itself, since the
269  * parent process will use the shutdown_pending and restart_pending variables
270  * to determine whether to shutdown or restart. The child process should
271  * call signal_parent() directly to tell the parent to die -- this will
272  * cause neither of those variable to be set, which the parent will
273  * assume means something serious is wrong (which it will be, for the
274  * child to force an exit) and so do an exit anyway.
275  */
276
277 void ap_start_shutdown(void)
278 {
279     if (shutdown_pending == 1) {
280         /* Um, is this _probably_ not an error, if the user has
281          * tried to do a shutdown twice quickly, so we won't
282          * worry about reporting it.
283          */
284         return;
285     }
286     shutdown_pending = 1;
287 }
288
289 /* do a graceful restart if graceful == 1 */
290 static void ap_start_restart(int graceful)
291 {
292
293     if (restart_pending == 1) {
294         /* Probably not an error - don't bother reporting it */
295         return;
296     }
297     restart_pending = 1;
298     is_graceful = graceful;
299     if (is_graceful) {
300         ap_kill_cleanup(pconf, NULL, ap_cleanup_shared_mem);
301     }
302 }
303
304 static void sig_term(int sig)
305 {
306     ap_start_shutdown();
307 }
308
309 static void restart(int sig)
310 {
311 #ifndef WIN32
312     ap_start_restart(sig == SIGWINCH);
313 #else
314     ap_start_restart(1);
315 #endif
316 }
317
318 static void set_signals(void)
319 {
320 #ifndef NO_USE_SIGACTION
321     struct sigaction sa;
322
323     sigemptyset(&sa.sa_mask);
324     sa.sa_flags = 0;
325
326     if (!one_process) {
327         sa.sa_handler = sig_coredump;
328 #if defined(SA_ONESHOT)
329         sa.sa_flags = SA_ONESHOT;
330 #elif defined(SA_RESETHAND)
331         sa.sa_flags = SA_RESETHAND;
332 #endif
333         if (sigaction(SIGSEGV, &sa, NULL) < 0)
334             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGSEGV)");
335 #ifdef SIGBUS
336         if (sigaction(SIGBUS, &sa, NULL) < 0)
337             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGBUS)");
338 #endif
339 #ifdef SIGABORT
340         if (sigaction(SIGABORT, &sa, NULL) < 0)
341             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGABORT)");
342 #endif
343 #ifdef SIGABRT
344         if (sigaction(SIGABRT, &sa, NULL) < 0)
345             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGABRT)");
346 #endif
347 #ifdef SIGILL
348         if (sigaction(SIGILL, &sa, NULL) < 0)
349             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGILL)");
350 #endif
351         sa.sa_flags = 0;
352     }
353     sa.sa_handler = sig_term;
354     if (sigaction(SIGTERM, &sa, NULL) < 0)
355         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGTERM)");
356 #ifdef SIGINT
357     if (sigaction(SIGINT, &sa, NULL) < 0)
358         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGINT)");
359 #endif
360 #ifdef SIGXCPU
361     sa.sa_handler = SIG_DFL;
362     if (sigaction(SIGXCPU, &sa, NULL) < 0)
363         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXCPU)");
364 #endif
365 #ifdef SIGXFSZ
366     sa.sa_handler = SIG_DFL;
367     if (sigaction(SIGXFSZ, &sa, NULL) < 0)
368         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXFSZ)");
369 #endif
370 #ifdef SIGPIPE
371     sa.sa_handler = SIG_IGN;
372     if (sigaction(SIGPIPE, &sa, NULL) < 0)
373         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGPIPE)");
374 #endif
375
376     /* we want to ignore HUPs and WINCH while we're busy processing one */
377     sigaddset(&sa.sa_mask, SIGHUP);
378     sigaddset(&sa.sa_mask, SIGWINCH);
379     sa.sa_handler = restart;
380     if (sigaction(SIGHUP, &sa, NULL) < 0)
381         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGHUP)");
382     if (sigaction(SIGWINCH, &sa, NULL) < 0)
383         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGWINCH)");
384 #else
385     if (!one_process) {
386         ap_signal(SIGSEGV, sig_coredump);
387 #ifdef SIGBUS
388         ap_signal(SIGBUS, sig_coredump);
389 #endif /* SIGBUS */
390 #ifdef SIGABORT
391         ap_signal(SIGABORT, sig_coredump);
392 #endif /* SIGABORT */
393 #ifdef SIGABRT
394         ap_signal(SIGABRT, sig_coredump);
395 #endif /* SIGABRT */
396 #ifdef SIGILL
397         ap_signal(SIGILL, sig_coredump);
398 #endif /* SIGILL */
399 #ifdef SIGXCPU
400         ap_signal(SIGXCPU, SIG_DFL);
401 #endif /* SIGXCPU */
402 #ifdef SIGXFSZ
403         ap_signal(SIGXFSZ, SIG_DFL);
404 #endif /* SIGXFSZ */
405     }
406
407     ap_signal(SIGTERM, sig_term);
408 #ifdef SIGHUP
409     ap_signal(SIGHUP, restart);
410 #endif /* SIGHUP */
411 #ifdef SIGWINCH
412     ap_signal(SIGWINCH, restart);
413 #endif /* SIGWINCH */
414 #ifdef SIGPIPE
415     ap_signal(SIGPIPE, SIG_IGN);
416 #endif /* SIGPIPE */
417
418 #endif
419 }
420
421 /*****************************************************************
422  * Here follows a long bunch of generic server bookkeeping stuff...
423  */
424
425 int ap_graceful_stop_signalled(void)
426 {
427     /* XXX - Does this really work? - Manoj */
428     return is_graceful;
429 }
430
431 /*****************************************************************
432  * Child process main loop.
433  */
434
435 static void process_socket(ap_pool_t *p, ap_socket_t *sock, long conn_id)
436 {
437     BUFF *conn_io;
438     conn_rec *current_conn;
439     ap_iol *iol;
440     int csd;
441     ap_status_t rv;
442
443     if ((rv = ap_get_os_sock(&csd, sock)) != APR_SUCCESS) {
444         ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, "ap_get_os_sock");
445     }
446
447     if (csd >= FD_SETSIZE) {
448         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, NULL,
449                      "new file descriptor %d is too large; you probably need "
450                      "to rebuild Apache with a larger FD_SETSIZE "
451                      "(currently %d)", 
452                      csd, FD_SETSIZE);
453         ap_close_socket(sock);
454         return;
455     }
456
457     ap_sock_disable_nagle(csd);
458     iol = ap_iol_attach_socket(p, sock);
459     conn_io = ap_bcreate(p, B_RDWR);
460     ap_bpush_iol(conn_io, iol);
461
462     current_conn = ap_new_apr_connection(p, ap_server_conf, conn_io, sock,
463                                          conn_id);
464
465     ap_process_connection(current_conn);
466     ap_lingering_close(current_conn);
467 }
468
469 static void *worker_thread(void *);
470
471 /* Starts a thread as long as we're below max_threads */
472 static int start_thread(void)
473 {
474     pthread_t thread;
475     int rc;
476
477     pthread_mutex_lock(&worker_thread_count_mutex);
478     if (worker_thread_count < max_threads) {
479         if ((rc = pthread_create(&thread, &worker_thread_attr, worker_thread,
480           &worker_thread_free_ids[worker_thread_count]))) {
481 #ifdef PTHREAD_SETS_ERRNO
482             rc = errno;
483 #endif
484             ap_log_error(APLOG_MARK, APLOG_ALERT, rc, ap_server_conf,
485                          "pthread_create: unable to create worker thread");
486             /* In case system resources are maxxed out, we don't want
487                Apache running away with the CPU trying to fork over and
488                over and over again if we exit. */
489             sleep(10);
490             workers_may_exit = 1;
491             pthread_mutex_unlock(&worker_thread_count_mutex);
492             return 0;
493         }
494         else {
495             worker_thread_count++;
496         }
497     }
498     else {
499         static int reported = 0;
500         
501         if (!reported) {
502             ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, ap_server_conf,
503                          "server reached MaxThreadsPerChild setting, consider raising the"
504                          " MaxThreadsPerChild or NumServers settings");
505             reported = 1;
506         }
507         pthread_mutex_unlock(&worker_thread_count_mutex);
508         return 0;
509     }
510     pthread_mutex_unlock(&worker_thread_count_mutex);
511     return 1;
512
513 }
514 /* Sets workers_may_exit if we received a character on the pipe_of_death */
515 static void check_pipe_of_death(void)
516 {
517     pthread_mutex_lock(&pipe_of_death_mutex);
518     if (!workers_may_exit) {
519         int ret;
520         char pipe_read_char;
521         ap_ssize_t n = 1;
522
523         ret = ap_recv(listenfds[0], &pipe_read_char, &n);
524         if (ap_canonical_error(ret) == APR_EAGAIN) {
525             /* It lost the lottery. It must continue to suffer
526              * through a life of servitude. */
527         }
528         else {
529             /* It won the lottery (or something else is very
530              * wrong). Embrace death with open arms. */
531             workers_may_exit = 1;
532         }
533     }
534     pthread_mutex_unlock(&pipe_of_death_mutex);
535 }
536
537 /* idle_thread_count should be incremented before starting a worker_thread */
538
539 static void *worker_thread(void *arg)
540 {
541     ap_socket_t *csd = NULL;
542     ap_pool_t *tpool;           /* Pool for this thread           */
543     ap_pool_t *ptrans;          /* Pool for per-transaction stuff */
544     ap_socket_t *sd = NULL;
545     int srv;
546     int curr_pollfd, last_pollfd = 0;
547     int thread_just_started = 1;
548     int thread_num = *((int *) arg);
549     long conn_id = child_num * HARD_THREAD_LIMIT + thread_num;
550     ap_pollfd_t *pollset;
551     int n;
552     ap_status_t rv;
553
554     pthread_mutex_lock(&thread_pool_parent_mutex);
555     ap_create_pool(&tpool, thread_pool_parent);
556     pthread_mutex_unlock(&thread_pool_parent_mutex);
557     ap_create_pool(&ptrans, tpool);
558
559     ap_setup_poll(&pollset, num_listenfds+1, tpool);
560     for(n=0 ; n <= num_listenfds ; ++n) {
561         ap_add_poll_socket(pollset, listenfds[n], APR_POLLIN);
562     }
563
564     while (!workers_may_exit) {
565         workers_may_exit |= (max_requests_per_child != 0) && (requests_this_child <= 0);
566         if (workers_may_exit) break;
567         if (!thread_just_started) {
568             pthread_mutex_lock(&idle_thread_count_mutex);
569             if (idle_thread_count < max_spare_threads) {
570                 idle_thread_count++;
571                 pthread_mutex_unlock(&idle_thread_count_mutex);
572             }
573             else {
574                 pthread_mutex_unlock(&idle_thread_count_mutex);
575                 break;
576             }
577         }
578         else {
579             thread_just_started = 0;
580         }
581         pthread_mutex_lock(&thread_accept_mutex);
582         if (workers_may_exit) {
583             pthread_mutex_unlock(&thread_accept_mutex);
584             break;
585         }
586         if ((rv = SAFE_ACCEPT(ap_lock(process_accept_mutex)))
587             != APR_SUCCESS) {
588             ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
589                          "ap_lock failed. Attempting to shutdown "
590                          "process gracefully.");
591             workers_may_exit = 1;
592         }
593
594         while (!workers_may_exit) {
595             ap_int16_t event;
596             srv = ap_poll(pollset, &n, -1);
597
598             if (srv != APR_SUCCESS) {
599                 if (ap_canonical_error(srv) == APR_EINTR) {
600                     continue;
601                 }
602
603                 /* ap_poll() will only return errors in catastrophic
604                  * circumstances. Let's try exiting gracefully, for now. */
605                 ap_log_error(APLOG_MARK, APLOG_ERR, srv, (const server_rec *)
606                              ap_server_conf, "ap_poll: (listen)");
607                 workers_may_exit = 1;
608             }
609             if (workers_may_exit) break;
610
611             ap_get_revents(&event, listenfds[0], pollset);
612             if (event & APR_POLLIN) {
613                 /* A process got a signal on the shutdown pipe. Check if we're
614                  * the lucky process to die. */
615                 check_pipe_of_death();
616                 continue;
617             }
618
619             if (num_listenfds == 1) {
620                 sd = ap_listeners->sd;
621                 goto got_fd;
622             }
623             else {
624                 /* find a listener */
625                 curr_pollfd = last_pollfd;
626                 do {
627                     curr_pollfd++;
628                     if (curr_pollfd > num_listenfds) {
629                         curr_pollfd = 1;
630                     }
631                     /* XXX: Should we check for POLLERR? */
632                     ap_get_revents(&event, listenfds[curr_pollfd], pollset);
633                     if (event & APR_POLLIN) {
634                         last_pollfd = curr_pollfd;
635                         sd = listenfds[curr_pollfd];
636                         goto got_fd;
637                     }
638                 } while (curr_pollfd != last_pollfd);
639             }
640         }
641     got_fd:
642         if (!workers_may_exit) {
643             if ((rv = ap_accept(&csd, sd, ptrans)) != APR_SUCCESS) {
644                 ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, "ap_accept");
645             }
646             if ((rv = SAFE_ACCEPT(ap_unlock(process_accept_mutex)))
647                 != APR_SUCCESS) {
648                 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
649                              "ap_unlock failed. Attempting to shutdown "
650                              "process gracefully.");
651                 workers_may_exit = 1;
652             }
653             pthread_mutex_unlock(&thread_accept_mutex);
654             pthread_mutex_lock(&idle_thread_count_mutex);
655             if (idle_thread_count > min_spare_threads) {
656                 idle_thread_count--;
657             }
658             else {
659                 if (!start_thread()) {
660                     idle_thread_count--;
661                 }
662             }
663             pthread_mutex_unlock(&idle_thread_count_mutex);
664             process_socket(ptrans, csd, conn_id);
665             requests_this_child--;
666         } else {
667             if ((rv = SAFE_ACCEPT(ap_unlock(process_accept_mutex)))
668                 != APR_SUCCESS) {
669                 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
670                              "ap_unlock failed. Attempting to shutdown "
671                              "process gracefully.");
672                 workers_may_exit = 1;
673             }
674             pthread_mutex_unlock(&thread_accept_mutex);
675             pthread_mutex_lock(&idle_thread_count_mutex);
676             idle_thread_count--;
677             pthread_mutex_unlock(&idle_thread_count_mutex);
678             break;
679         }
680         ap_clear_pool(ptrans);
681     }
682
683     pthread_mutex_lock(&thread_pool_parent_mutex);
684     ap_destroy_pool(tpool);
685     pthread_mutex_unlock(&thread_pool_parent_mutex);
686     pthread_mutex_lock(&worker_thread_count_mutex);
687     worker_thread_count--;
688     worker_thread_free_ids[worker_thread_count] = thread_num;
689     if (worker_thread_count == 0) {
690         /* All the threads have exited, now finish the shutdown process
691          * by signalling the sigwait thread */
692         kill(my_pid, SIGTERM);
693     }
694     pthread_mutex_unlock(&worker_thread_count_mutex);
695
696     return NULL;
697 }
698
699 /* Set group privileges.
700  *
701  * Note that we use the username as set in the config files, rather than
702  * the lookup of to uid --- the same uid may have multiple passwd entries,
703  * with different sets of groups for each.
704  */
705
706 static int set_group_privs(uid_t uid, gid_t gid)
707 {
708     if (!geteuid()) {
709         const char *name;
710
711         /* Get username if passed as a uid */
712
713         struct passwd *ent;
714
715         if ((ent = getpwuid(uid)) == NULL) {
716             ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
717                      "getpwuid: couldn't determine user name from uid %u, "
718                      "you probably need to modify the User directive",
719                      (unsigned)uid);
720             return -1;
721         }
722
723         name = ent->pw_name;
724
725         /*
726          * Set the GID before initgroups(), since on some platforms
727          * setgid() is known to zap the group list.
728          */
729         if (setgid(gid) == -1) {
730             ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
731                         "setgid: unable to set group id to Group %u",
732                         (unsigned)gid);
733             return -1;
734         }
735
736         /* Reset `groups' attributes. */
737
738         if (initgroups(name, gid) == -1) {
739             ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
740                         "initgroups: unable to set groups for User %s "
741                         "and Group %u", name, (unsigned)gid);
742             return -1;
743         }
744     }
745     return 0;
746 }
747
748
749 static int perchild_setup_child(int childnum)
750 {
751     child_info_t *ug = &child_info_table[childnum];
752
753     if (ug->uid == -1 && ug->gid == -1) {
754         return unixd_setup_child();
755     }
756     if (set_group_privs(ug->uid, ug->gid)) {
757         return -1;
758     }
759     /* Only try to switch if we're running as root */
760     if (!geteuid() && (
761 #ifdef _OSD_POSIX
762         os_init_job_environment(server_conf, unixd_config.user_name, one_process) != 0 ||
763 #endif
764         setuid(ug->uid) == -1)) {
765         ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL,
766                     "setuid: unable to change to uid: %ld",
767                     (long) ug->uid);
768         return -1;
769     }
770     return 0;
771 }
772
773 static int create_child_socket(int child_num, ap_pool_t *p)
774 {
775     struct sockaddr_un unix_addr;
776     mode_t omask;
777     int rc;
778     int sd;
779     perchild_server_conf *sconf = (perchild_server_conf *)
780               ap_get_module_config(ap_server_conf->module_config, &mpm_perchild_module);
781     int len = strlen(sconf->sockname) + strlen(child_info_table[child_num].name) + 3;
782     char *socket_name = ap_palloc(p, len);
783
784     ap_snprintf(socket_name, len, "%s.%s", sconf->sockname, child_info_table[child_num].name);
785     if (unlink(socket_name) < 0 &&
786         errno != ENOENT) {
787         ap_log_error(APLOG_MARK, APLOG_ERR, errno, ap_server_conf,
788                      "Couldn't unlink unix domain socket %s",
789                      socket_name);
790         /* Just a warning; don't bail out */
791     }
792
793     if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
794         ap_log_error(APLOG_MARK, APLOG_ERR, errno, ap_server_conf,
795                      "Couldn't create unix domain socket");
796         return -1;
797     }
798
799     memset(&unix_addr, 0, sizeof(unix_addr));
800     unix_addr.sun_family = AF_UNIX;
801     strcpy(unix_addr.sun_path, socket_name);
802
803     omask = umask(0077); /* so that only Apache can use socket */
804     rc = bind(sd, (struct sockaddr *)&unix_addr, sizeof(unix_addr));
805     umask(omask); /* can't fail, so can't clobber errno */
806     if (rc < 0) {
807         ap_log_error(APLOG_MARK, APLOG_ERR, errno, ap_server_conf,
808                      "Couldn't bind unix domain socket %s",
809                      socket_name);
810         return -1;
811     }
812
813     if (listen(sd, DEFAULT_PERCHILD_LISTENBACKLOG) < 0) {
814         ap_log_error(APLOG_MARK, APLOG_ERR, errno, ap_server_conf,
815                      "Couldn't listen on unix domain socket");
816         return -1;
817     }
818
819     if (!geteuid()) {
820         if (chown(socket_name, unixd_config.user_id, -1) < 0) {
821             ap_log_error(APLOG_MARK, APLOG_ERR, errno, ap_server_conf,
822                          "Couldn't change owner of unix domain socket %s",
823                          socket_name);
824             return -1;
825         }
826     }
827     return sd;
828 }
829
830 static void child_main(int child_num_arg)
831 {
832     sigset_t sig_mask;
833     int signal_received;
834     int i;
835     ap_listen_rec *lr;
836     ap_status_t rv;
837
838     my_pid = getpid();
839     child_num = child_num_arg;
840     ap_create_pool(&pchild, pconf);
841
842     /*stuff to do before we switch id's, so we have permissions.*/
843
844     rv = SAFE_ACCEPT(ap_child_init_lock(&process_accept_mutex, lock_fname,
845                                         pchild));
846     if (rv != APR_SUCCESS) {
847         ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
848                      "Couldn't initialize cross-process lock in child");
849         clean_child_exit(APEXIT_CHILDFATAL);
850     }
851
852     if (perchild_setup_child(child_num)) {
853         clean_child_exit(APEXIT_CHILDFATAL);
854     }
855
856     ap_child_init_hook(pchild, ap_server_conf);
857
858     /*done with init critical section */
859
860     /* All threads should mask signals out, accoring to sigwait(2) man page */
861     sigfillset(&sig_mask);
862
863 #ifdef SIGPROCMASK_SETS_THREAD_MASK
864     if (sigprocmask(SIG_SETMASK, &sig_mask, NULL) != 0) {
865         ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf, "sigprocmask");
866     }
867 #else
868     if ((rv = pthread_sigmask(SIG_SETMASK, &sig_mask, NULL)) != 0) {
869 #ifdef PTHREAD_SETS_ERRNO
870         rv = errno;
871 #endif
872         ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
873                      "pthread_sigmask");
874     }
875 #endif
876
877     requests_this_child = max_requests_per_child;
878     
879     /* Set up the pollfd array, num_listenfds + 1 for the pipe and 1 for
880      * the child socket.
881      */
882     listenfds = ap_pcalloc(pchild, sizeof(*listenfds) * (num_listenfds + 2));
883 #if APR_FILES_AS_SOCKETS
884     ap_socket_from_file(&listenfds[0], pipe_of_death_in);
885 #endif
886
887     /* The child socket */
888     ap_put_os_sock(&listenfds[1], &child_info_table[child_num].sd, pchild);
889
890     num_listenfds++;
891     for (lr = ap_listeners, i = 2; i <= num_listenfds; lr = lr->next, ++i)
892         listenfds[i]=lr->sd;
893
894     /* Setup worker threads */
895
896     if (threads_to_start > max_threads) {
897         threads_to_start = max_threads;
898     }
899     idle_thread_count = threads_to_start;
900     worker_thread_count = 0;
901     for (i = 0; i < max_threads; i++) {
902         worker_thread_free_ids[i] = i;
903     }
904     ap_create_pool(&thread_pool_parent, pchild);
905     pthread_mutex_init(&thread_pool_parent_mutex, NULL);
906     pthread_mutex_init(&idle_thread_count_mutex, NULL);
907     pthread_mutex_init(&worker_thread_count_mutex, NULL);
908     pthread_mutex_init(&pipe_of_death_mutex, NULL);
909     pthread_attr_init(&worker_thread_attr);
910 #ifdef PTHREAD_ATTR_SETDETACHSTATE_ARG2_ADDR
911     {
912         int on = 1;
913
914         pthread_attr_setdetachstate(&worker_thread_attr, &on);
915     }
916 #else
917     pthread_attr_setdetachstate(&worker_thread_attr, PTHREAD_CREATE_DETACHED);
918 #endif
919
920     /* We are creating worker threads right now */
921     for (i=0; i < threads_to_start; i++) {
922         /* start_thread shouldn't fail here */
923         if (!start_thread()) {
924             break;
925         }
926     }
927
928     /* This thread will be the one responsible for handling signals */
929     sigemptyset(&sig_mask);
930     sigaddset(&sig_mask, SIGTERM);
931     sigaddset(&sig_mask, SIGINT);
932     ap_sigwait(&sig_mask, &signal_received);
933     switch (signal_received) {
934         case SIGTERM:
935         case SIGINT:
936             just_die(signal_received);
937             break;
938         default:
939             ap_log_error(APLOG_MARK, APLOG_ALERT, errno, ap_server_conf,
940             "received impossible signal: %d", signal_received);
941             just_die(SIGTERM);
942     }
943 }
944
945 static int make_child(server_rec *s, int slot, time_t now)
946 {
947     int pid;
948
949     if (slot + 1 > ap_max_daemons_limit) {
950         ap_max_daemons_limit = slot + 1;
951     }
952
953     if (one_process) {
954         set_signals();
955         ap_child_table[slot].pid = getpid();
956         ap_child_table[slot].status = SERVER_ALIVE;
957         child_main(slot);
958     }
959
960     if ((pid = fork()) == -1) {
961         ap_log_error(APLOG_MARK, APLOG_ERR, errno, s,
962                      "fork: Unable to fork new process");
963         /* In case system resources are maxxed out, we don't want
964            Apache running away with the CPU trying to fork over and
965            over and over again. */
966         sleep(10);
967
968         return -1;
969     }
970
971     if (!pid) {
972 #ifdef AIX_BIND_PROCESSOR
973       /* By default, AIX binds to a single processor.  This bit unbinds
974          children which will then bind to another CPU.
975       */
976 #include <sys/processor.h>
977         int status = bindprocessor(BINDPROCESS, (int)getpid(),
978                                PROCESSOR_CLASS_ANY);
979         if (status != OK)
980             ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, errno, 
981                          ap_server_conf, "processor unbind failed %d", status);
982 #endif
983
984         RAISE_SIGSTOP(MAKE_CHILD);
985
986         /* XXX - For an unthreaded server, a signal handler will be necessary
987         ap_signal(SIGTERM, just_die);
988         */
989         child_main(slot);
990
991         return 0;
992     }
993     /* else */
994     ap_child_table[slot].pid = pid;
995     ap_child_table[slot].status = SERVER_ALIVE;
996
997     return 0;
998 }
999
1000 /* start up a bunch of children */
1001 static int startup_children(int number_to_start)
1002 {
1003     int i;
1004
1005     for (i = 0; number_to_start && i < num_daemons; ++i) {
1006         if (ap_child_table[i].pid) {
1007             continue;
1008         }
1009         if (make_child(ap_server_conf, i, 0) < 0) {
1010             break;
1011         }
1012         --number_to_start;
1013     }
1014     return number_to_start;
1015 }
1016
1017
1018 /*
1019  * spawn_rate is the number of children that will be spawned on the
1020  * next maintenance cycle if there aren't enough servers.  It is
1021  * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by
1022  * without the need to spawn.
1023  */
1024 static int spawn_rate = 1;
1025 #ifndef MAX_SPAWN_RATE
1026 #define MAX_SPAWN_RATE  (32)
1027 #endif
1028 static int hold_off_on_exponential_spawning;
1029
1030 static void perform_child_maintenance(void)
1031 {
1032     int i;
1033     time_t now = 0;
1034     int free_length;
1035     int free_slots[MAX_SPAWN_RATE];
1036     int last_non_dead = -1;
1037
1038     /* initialize the free_list */
1039     free_length = 0;
1040     
1041     for (i = 0; i < num_daemons; ++i) {
1042         if (ap_child_table[i].pid == 0) {
1043             if (free_length < spawn_rate) {
1044                 free_slots[free_length] = i;
1045                 ++free_length;
1046             }
1047         }
1048         else {
1049             last_non_dead = i;
1050         }
1051
1052         if (i >= ap_max_daemons_limit && free_length >= spawn_rate) {
1053             break;
1054         }
1055     }
1056     ap_max_daemons_limit = last_non_dead + 1;
1057
1058     if (free_length > 0) {
1059         for (i = 0; i < free_length; ++i) {
1060             make_child(ap_server_conf, free_slots[i], now);
1061         }
1062         /* the next time around we want to spawn twice as many if this
1063          * wasn't good enough, but not if we've just done a graceful
1064          */
1065         if (hold_off_on_exponential_spawning) {
1066             --hold_off_on_exponential_spawning;
1067         }
1068         else if (spawn_rate < MAX_SPAWN_RATE) {
1069             spawn_rate *= 2;
1070         }
1071     }
1072     else {
1073         spawn_rate = 1;
1074     }
1075 }
1076
1077 static void server_main_loop(int remaining_children_to_start)
1078 {
1079     int child_slot;
1080     ap_wait_t status;
1081     ap_proc_t pid;
1082     int i;
1083
1084     while (!restart_pending && !shutdown_pending) {
1085         ap_wait_or_timeout(&status, &pid, pconf);
1086         
1087         if (pid.pid != -1) {
1088             ap_process_child_status(&pid, status);
1089             /* non-fatal death... note that it's gone in the child table and
1090              * clean out the status table. */
1091             child_slot = -1;
1092             for (i = 0; i < ap_max_daemons_limit; ++i) {
1093                 if (ap_child_table[i].pid == pid.pid) {
1094                     int j;
1095
1096                     child_slot = i;
1097                     for (j = 0; j < HARD_THREAD_LIMIT; j++) {
1098                         ap_perchild_force_reset_connection_status(i * HARD_THREAD_LIMIT + j);
1099                     }
1100                     break;
1101                 }
1102             }
1103             if (child_slot >= 0) {
1104                 ap_child_table[child_slot].pid = 0;
1105                 
1106                 if (remaining_children_to_start
1107                     && child_slot < num_daemons) {
1108                     /* we're still doing a 1-for-1 replacement of dead
1109                      * children with new children
1110                      */
1111                     make_child(ap_server_conf, child_slot, time(NULL));
1112                     --remaining_children_to_start;
1113                 }
1114 #if APR_HAS_OTHER_CHILD
1115             }
1116             else if (ap_reap_other_child(&pid, status) == 0) {
1117                 /* handled */
1118 #endif
1119             }
1120             else if (is_graceful) {
1121                 /* Great, we've probably just lost a slot in the
1122                  * child table.  Somehow we don't know about this
1123                  * child.
1124                  */
1125                 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, 
1126                              ap_server_conf,
1127                             "long lost child came home! (pid %ld)", 
1128                              (long)pid.pid);
1129             }
1130             /* Don't perform idle maintenance when a child dies,
1131              * only do it when there's a timeout.  Remember only a
1132              * finite number of children can die, and it's pretty
1133              * pathological for a lot to die suddenly.
1134              */
1135             continue;
1136         }
1137         else if (remaining_children_to_start) {
1138             /* we hit a 1 second timeout in which none of the previous
1139              * generation of children needed to be reaped... so assume
1140              * they're all done, and pick up the slack if any is left.
1141              */
1142             remaining_children_to_start = \
1143                 startup_children(remaining_children_to_start);
1144             /* In any event we really shouldn't do the code below because
1145              * few of the servers we just started are in the IDLE state
1146              * yet, so we'd mistakenly create an extra server.
1147              */
1148             continue;
1149         }
1150
1151         perform_child_maintenance();
1152     }
1153 }
1154
1155 int ap_mpm_run(ap_pool_t *_pconf, ap_pool_t *plog, server_rec *s)
1156 {
1157     int remaining_children_to_start;
1158     int i;
1159     ap_status_t rv;
1160     ap_ssize_t one = 1;
1161
1162     pconf = _pconf;
1163     ap_server_conf = s;
1164     if ((rv = ap_create_pipe(&pipe_of_death_in, &pipe_of_death_out, pconf)) 
1165         != APR_SUCCESS) {
1166         ap_log_error(APLOG_MARK, APLOG_ERR, rv,
1167                      (const server_rec*) ap_server_conf,
1168                      "ap_create_pipe (pipe_of_death)");
1169         exit(1);
1170     }
1171     if ((rv = ap_set_pipe_timeout(pipe_of_death_in, 0)) != APR_SUCCESS) {
1172         ap_log_error(APLOG_MARK, APLOG_ERR, rv,
1173                      (const server_rec*) ap_server_conf,
1174                      "ap_set_pipe_timeout (pipe_of_death)");
1175         exit(1);
1176     }
1177     ap_server_conf = s;
1178     if ((num_listenfds = ap_setup_listeners(ap_server_conf)) < 1) {
1179         /* XXX: hey, what's the right way for the mpm to indicate a fatal error? */
1180         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ALERT, 0, s,
1181             "no listening sockets available, shutting down");
1182         return 1;
1183     }
1184     ap_log_pid(pconf, ap_pid_fname);
1185
1186     /* Create all of the sockets for the child processes. */
1187     for (i = 0; i <= socket_num; i++) {
1188         int sd;
1189         int j;
1190
1191         sd = create_child_socket(i, pchild);
1192        
1193         for(j = i; ;) {
1194             if (child_info_table[j].num == i) {
1195                 child_info_table[j].sd = sd;
1196                 j++;
1197             }
1198             else {
1199                 break;
1200             }
1201         }
1202         if (j >= num_daemons) { 
1203             break;
1204         }
1205     } 
1206
1207     /* Initialize cross-process accept lock */
1208     lock_fname = ap_psprintf(_pconf, "%s.%u",
1209                              ap_server_root_relative(_pconf, lock_fname),
1210                              my_pid);
1211     rv = SAFE_ACCEPT(ap_create_lock(&process_accept_mutex, APR_MUTEX,
1212                                     APR_CROSS_PROCESS, lock_fname, _pconf));
1213     if (rv != APR_SUCCESS) {
1214         ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
1215                      "Couldn't create cross-process lock");
1216         return 1;
1217     }
1218
1219     if (!is_graceful) {
1220         reinit_scoreboard(pconf);
1221     }
1222     /* Initialize the child table */
1223     if (!is_graceful) {
1224         for (i = 0; i < HARD_SERVER_LIMIT; i++) {
1225             ap_child_table[i].pid = 0;
1226         }
1227     }
1228
1229     set_signals();
1230
1231     /* If we're doing a graceful_restart then we're going to see a lot
1232      * of children exiting immediately when we get into the main loop
1233      * below (because we just sent them SIGWINCH).  This happens pretty
1234      * rapidly... and for each one that exits we'll start a new one until
1235      * we reach at least daemons_min_free.  But we may be permitted to
1236      * start more than that, so we'll just keep track of how many we're
1237      * supposed to start up without the 1 second penalty between each fork.
1238      */
1239     remaining_children_to_start = num_daemons;
1240     if (!is_graceful) {
1241         remaining_children_to_start = \
1242             startup_children(remaining_children_to_start);
1243     }
1244     else {
1245         /* give the system some time to recover before kicking into
1246             * exponential mode */
1247         hold_off_on_exponential_spawning = 10;
1248     }
1249
1250     ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, ap_server_conf,
1251                 "%s configured -- resuming normal operations",
1252                 ap_get_server_version());
1253     ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0, ap_server_conf,
1254                 "Server built: %s", ap_get_server_built());
1255     restart_pending = shutdown_pending = 0;
1256
1257     server_main_loop(remaining_children_to_start);
1258
1259     if (shutdown_pending) {
1260         /* Time to gracefully shut down:
1261          * Kill child processes, tell them to call child_exit, etc...
1262          */
1263         if (unixd_killpg(getpgrp(), SIGTERM) < 0) {
1264             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
1265                          "killpg SIGTERM");
1266         }
1267         ap_reclaim_child_processes(1);          /* Start with SIGTERM */
1268     
1269         /* cleanup pid file on normal shutdown */
1270         {
1271             const char *pidfile = NULL;
1272             pidfile = ap_server_root_relative (pconf, ap_pid_fname);
1273             if ( pidfile != NULL && unlink(pidfile) == 0)
1274                 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0,
1275                          ap_server_conf,
1276                          "removed PID file %s (pid=%ld)",
1277                          pidfile, (long)getpid());
1278         }
1279     
1280         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0,
1281                      ap_server_conf, "caught SIGTERM, shutting down");
1282     
1283         return 1;
1284     }
1285
1286     /* we've been told to restart */
1287     ap_signal(SIGHUP, SIG_IGN);
1288
1289     if (one_process) {
1290         /* not worth thinking about */
1291         return 1;
1292     }
1293
1294     if (is_graceful) {
1295         char char_of_death = '!';
1296
1297         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0, ap_server_conf,
1298                     "SIGWINCH received.  Doing graceful restart");
1299
1300         /* This is mostly for debugging... so that we know what is still
1301          * gracefully dealing with existing request.
1302          */
1303         
1304         for (i = 0; i < num_daemons; ++i) {
1305             if (ap_child_table[i].pid) {
1306                 ap_child_table[i].status = SERVER_DYING;
1307             } 
1308         }
1309         /* give the children the signal to die */
1310         for (i = 0; i < num_daemons;) {
1311             if ((rv = ap_write(pipe_of_death_out, &char_of_death, &one)) != APR_SUCCESS) {
1312                 if (ap_canonical_error(rv) == APR_EINTR) continue;
1313                 ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf,
1314                              "write pipe_of_death");
1315             }
1316             i++;
1317         }
1318     }
1319     else {
1320       /* Kill 'em all.  Since the child acts the same on the parents SIGTERM 
1321        * and a SIGHUP, we may as well use the same signal, because some user
1322        * pthreads are stealing signals from us left and right.
1323        */
1324         if (unixd_killpg(getpgrp(), SIGTERM) < 0) {
1325             ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
1326                          "killpg SIGTERM");
1327         }
1328         ap_reclaim_child_processes(1);          /* Start with SIGTERM */
1329         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, 0,
1330                      ap_server_conf, "SIGHUP received.  Attempting to restart");
1331     }
1332     return 0;
1333 }
1334
1335 static void perchild_pre_config(ap_pool_t *p, ap_pool_t *plog, ap_pool_t *ptemp)
1336 {
1337     static int restart_num = 0;
1338     int no_detach = 0;
1339     int i;
1340
1341     one_process = !!getenv("ONE_PROCESS");
1342     no_detach = !!getenv("NO_DETACH");
1343
1344     /* sigh, want this only the second time around */
1345     if (restart_num++ == 1) {
1346         is_graceful = 0;
1347
1348         if (!one_process && !no_detach) {
1349             ap_detach();
1350         }
1351
1352         my_pid = getpid();
1353     }
1354
1355     unixd_pre_config();
1356     ap_listen_pre_config();
1357     num_daemons = DEFAULT_NUM_DAEMON;
1358     threads_to_start = DEFAULT_START_THREAD;
1359     min_spare_threads = DEFAULT_MIN_SPARE_THREAD;
1360     max_spare_threads = DEFAULT_MAX_SPARE_THREAD;
1361     max_threads = HARD_THREAD_LIMIT;
1362     ap_pid_fname = DEFAULT_PIDLOG;
1363     ap_scoreboard_fname = DEFAULT_SCOREBOARD;
1364     lock_fname = DEFAULT_LOCKFILE;
1365     max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD;
1366     ap_perchild_set_maintain_connection_status(1);
1367     curr_child_num = 0;
1368     socket_num = 0;
1369
1370     ap_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir));
1371
1372     for (i = 0; i < HARD_SERVER_LIMIT; i++) {
1373         child_info_table[i].uid = -1;
1374         child_info_table[i].gid = -1;
1375         child_info_table[i].name = NULL;
1376         child_info_table[i].num = -1;
1377     }
1378 }
1379
1380 static void perchild_post_config(ap_pool_t *p, ap_pool_t *plog, ap_pool_t *ptemp, server_rec *s)
1381 {
1382     int i;
1383
1384     for (i = 0; i < num_daemons; i++) {
1385         if (child_info_table[i].name == NULL) {
1386             child_info_table[i].name = ap_pstrdup(p, "DEFAULT");
1387             child_info_table[i].num = socket_num;
1388         }
1389     }
1390 }
1391
1392 static int perchild_post_read(request_rec *r)
1393 {
1394     const char *hostname = ap_table_get(r->headers_in, "Host");
1395     char *process_num;
1396     int num;
1397
1398 fprintf(stderr, "In perchild_post_read\n");
1399     fflush(stderr);
1400     process_num = ap_hash_get(socket_info_table, hostname, 0);
1401     if (process_num) {
1402         num = atoi(process_num);
1403     }
1404     else {
1405         num = socket_num;
1406     }
1407
1408     if (num != child_info_table[child_num].num) {
1409         /* package the request and send it to another child */
1410 fprintf(stderr, "leaving DECLINED %d %d\n", num, child_num);
1411     fflush(stderr);
1412         return DECLINED;
1413     }
1414     return OK;
1415 }
1416
1417 static void perchild_hooks(void)
1418 {
1419     INIT_SIGLIST()
1420     one_process = 0;
1421
1422     ap_hook_pre_config(perchild_pre_config, NULL, NULL, AP_HOOK_MIDDLE); 
1423     ap_hook_post_config(perchild_post_config, NULL, NULL, AP_HOOK_MIDDLE); 
1424     /* This must be run absolutely first.  If this request isn't for this
1425      * server then we need to forward it to the proper child.  No sense
1426      * tying up this server running more post_read request hooks if it is
1427      * just going to be forwarded along.
1428      */
1429     ap_hook_post_read_request(perchild_post_read, NULL, NULL, AP_HOOK_REALLY_FIRST);
1430 }
1431
1432 static const char *set_pidfile(cmd_parms *cmd, void *dummy, const char *arg) 
1433 {
1434     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1435     if (err != NULL) {
1436         return err;
1437     }
1438
1439     if (cmd->server->is_virtual) {
1440         return "PidFile directive not allowed in <VirtualHost>";
1441     }
1442     ap_pid_fname = arg;
1443     return NULL;
1444 }
1445
1446 static const char *set_scoreboard(cmd_parms *cmd, void *dummy, const char *arg)
1447 {
1448     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1449     if (err != NULL) {
1450         return err;
1451     }
1452
1453     ap_scoreboard_fname = arg;
1454     return NULL;
1455 }
1456
1457 static const char *set_lockfile(cmd_parms *cmd, void *dummy, const char *arg) 
1458 {
1459     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1460     if (err != NULL) {
1461         return err;
1462     }
1463
1464     lock_fname = arg;
1465     return NULL;
1466 }
1467 static const char *set_num_daemons (cmd_parms *cmd, void *dummy, const char *arg) 
1468 {
1469     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1470     if (err != NULL) {
1471         return err;
1472     }
1473
1474     num_daemons = atoi(arg);
1475     if (num_daemons > HARD_SERVER_LIMIT) {
1476        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1477                     "WARNING: NumServers of %d exceeds compile time limit "
1478                     "of %d servers,", num_daemons, HARD_SERVER_LIMIT);
1479        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1480                     " lowering NumServers to %d.  To increase, please "
1481                     "see the", HARD_SERVER_LIMIT);
1482        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1483                     " HARD_SERVER_LIMIT define in %s.",
1484                     AP_MPM_HARD_LIMITS_FILE);
1485        num_daemons = HARD_SERVER_LIMIT;
1486     } 
1487     else if (num_daemons < 1) {
1488         ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1489                      "WARNING: Require NumServers > 0, setting to 1");
1490         num_daemons = 1;
1491     }
1492     return NULL;
1493 }
1494
1495 static const char *set_threads_to_start (cmd_parms *cmd, void *dummy, const char *arg) 
1496 {
1497     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1498     if (err != NULL) {
1499         return err;
1500     }
1501
1502     threads_to_start = atoi(arg);
1503     if (threads_to_start > HARD_THREAD_LIMIT) {
1504         ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1505                      "WARNING: StartThreads of %d exceeds compile time"
1506                      " limit of %d threads,", threads_to_start,
1507                      HARD_THREAD_LIMIT);
1508         ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1509                      " lowering StartThreads to %d. To increase, please"
1510                      " see the", HARD_THREAD_LIMIT);
1511         ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1512                      " HARD_THREAD_LIMIT define in %s.",
1513                      AP_MPM_HARD_LIMITS_FILE);
1514     }
1515     else if (threads_to_start < 1) {
1516         ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1517                      "WARNING: Require StartThreads > 0, setting to 1");
1518         threads_to_start = 1;
1519     }
1520     return NULL;
1521 }
1522
1523 static const char *set_min_spare_threads(cmd_parms *cmd, void *dummy, const char *arg)
1524 {
1525     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1526     if (err != NULL) {
1527         return err;
1528     }
1529
1530     min_spare_threads = atoi(arg);
1531     if (min_spare_threads <= 0) {
1532        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1533                     "WARNING: detected MinSpareThreads set to non-positive.");
1534        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1535                     "Resetting to 1 to avoid almost certain Apache failure.");
1536        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1537                     "Please read the documentation.");
1538        min_spare_threads = 1;
1539     }
1540        
1541     return NULL;
1542 }
1543
1544 static const char *set_max_spare_threads(cmd_parms *cmd, void *dummy, const char *arg)
1545 {
1546     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1547     if (err != NULL) {
1548         return err;
1549     }
1550
1551     max_spare_threads = atoi(arg);
1552     if (max_spare_threads >= HARD_THREAD_LIMIT) {
1553        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1554                     "WARNING: detected MinSpareThreads set higher than");
1555        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1556                     "HARD_THREAD_LIMIT. Resetting to %d", HARD_THREAD_LIMIT);
1557        max_spare_threads = HARD_THREAD_LIMIT;
1558     }
1559     return NULL;
1560 }
1561
1562 static const char *set_max_threads(cmd_parms *cmd, void *dummy, const char *arg)
1563 {
1564     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1565     if (err != NULL) {
1566         return err;
1567     }
1568
1569     max_threads = atoi(arg);
1570     if (max_threads > HARD_THREAD_LIMIT) {
1571        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1572                     "WARNING: detected MaxThreadsPerChild set higher than");
1573        ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, 
1574                     "HARD_THREAD_LIMIT. Resetting to %d", HARD_THREAD_LIMIT);
1575        max_threads = HARD_THREAD_LIMIT;
1576     }
1577     return NULL;
1578 }
1579
1580 static const char *set_max_requests(cmd_parms *cmd, void *dummy, const char *arg) 
1581 {
1582     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1583     if (err != NULL) {
1584         return err;
1585     }
1586
1587     max_requests_per_child = atoi(arg);
1588
1589     return NULL;
1590 }
1591
1592 static const char *set_maintain_connection_status(cmd_parms *cmd,
1593                                                   void *dummy, int arg) 
1594 {
1595     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1596     if (err != NULL) {
1597         return err;
1598     }
1599
1600     ap_perchild_set_maintain_connection_status(arg != 0);
1601     return NULL;
1602 }
1603
1604 static const char *set_coredumpdir (cmd_parms *cmd, void *dummy, const char *arg) 
1605 {
1606     ap_finfo_t finfo;
1607     const char *fname;
1608     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1609     if (err != NULL) {
1610         return err;
1611     }
1612
1613     fname = ap_server_root_relative(cmd->pool, arg);
1614     if ((ap_stat(&finfo, fname, cmd->pool) != APR_SUCCESS) || 
1615         (finfo.filetype != APR_DIR)) {
1616         return ap_pstrcat(cmd->pool, "CoreDumpDirectory ", fname, 
1617                           " does not exist or is not a directory", NULL);
1618     }
1619     ap_cpystrn(ap_coredump_dir, fname, sizeof(ap_coredump_dir));
1620     return NULL;
1621 }
1622
1623 static const char *set_child_per_uid(cmd_parms *cmd, void *dummy, const char *u,
1624                                      const char *g, const char *num)
1625 {
1626     int i;
1627     int max_this_time = atoi(num) + curr_child_num;
1628     for (i = curr_child_num; i < max_this_time; i++, curr_child_num++); {
1629         child_info_t *ug = &child_info_table[i - 1];
1630
1631         if (i > num_daemons) {
1632             return "Trying to use more child ID's than NumServers.  Increase "
1633                    "NumServers in your config file.";
1634         }
1635     
1636         ug->uid = atoi(u);
1637         ug->gid = atoi(g); 
1638         ug->name = ap_pstrcat(cmd->pool, u, ":", g, NULL);
1639         ug->num = socket_num;
1640     }
1641     socket_num++;
1642     return NULL;
1643 }
1644
1645 static const char *set_socket_name(cmd_parms *cmd, void *dummy, const char *arg)
1646 {
1647     server_rec *s = cmd->server;
1648     perchild_server_conf *conf = (perchild_server_conf *) 
1649                   ap_get_module_config(s->module_config, &mpm_perchild_module);
1650
1651     conf->sockname = ap_server_root_relative(cmd->pool, arg);
1652     return NULL;
1653 }
1654     
1655 static ap_status_t cleanup_hash(void *dptr)
1656 {
1657     socket_info_table = NULL;
1658     return APR_SUCCESS;
1659 }
1660
1661 static const char *assign_childuid(cmd_parms *cmd, void *dummy, const char *uid,
1662                                    const char *gid)
1663 {
1664     char *socketname = ap_pstrcat(cmd->pool, uid, ":", gid, NULL);
1665     if (socket_info_table == NULL) {
1666         socket_info_table = ap_make_hash(cmd->pool);
1667         ap_register_cleanup(cmd->pool, socket_info_table, cleanup_hash, NULL);
1668     }
1669     ap_hash_set(socket_info_table, cmd->server->server_hostname, 0, socketname);
1670     return NULL;
1671 }
1672
1673
1674 static const command_rec perchild_cmds[] = {
1675 UNIX_DAEMON_COMMANDS
1676 LISTEN_COMMANDS
1677 AP_INIT_TAKE1("PidFile", set_pidfile, NULL, RSRC_CONF,
1678               "A file for logging the server process ID"),
1679 AP_INIT_TAKE1("ScoreBoardFile", set_scoreboard, NULL, RSRC_CONF,
1680               "A file for Apache to maintain runtime process management information"),
1681 AP_INIT_TAKE1("LockFile", set_lockfile, NULL, RSRC_CONF,
1682               "The lockfile used when Apache needs to lock the accept() call"),
1683 AP_INIT_TAKE1("NumServers", set_num_daemons, NULL, RSRC_CONF,
1684               "Number of children alive at the same time"),
1685 AP_INIT_TAKE1("StartThreads", set_threads_to_start, NULL, RSRC_CONF,
1686               "Number of threads each child creates"),
1687 AP_INIT_TAKE1("MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF,
1688               "Minimum number of idle threads per child, to handle request spikes"),
1689 AP_INIT_TAKE1("MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF,
1690               "Maximum number of idle threads per child"),
1691 AP_INIT_TAKE1("MaxThreadsPerChild", set_max_threads, NULL, RSRC_CONF,
1692               "Maximum number of threads per child"),
1693 AP_INIT_TAKE1("MaxRequestsPerChild", set_max_requests, NULL, RSRC_CONF,
1694               "Maximum number of requests a particular child serves before dying."),
1695 AP_INIT_FLAG("ConnectionStatus", set_maintain_connection_status, NULL, RSRC_CONF,
1696              "Whether or not to maintain status information on current connections"),
1697 AP_INIT_TAKE1("CoreDumpDirectory", set_coredumpdir, NULL, RSRC_CONF,
1698               "The location of the directory Apache changes to before dumping core"),
1699 AP_INIT_TAKE3("ChildperUserID", set_child_per_uid, NULL, RSRC_CONF,
1700               "Specify a User and Group for a specific child process."),
1701 AP_INIT_TAKE2("AssignUserID", assign_childuid, NULL, RSRC_CONF,
1702               "Tie a virtual host to a specific child process."),
1703 AP_INIT_TAKE1("ChildSockName", set_socket_name, NULL, RSRC_CONF,
1704               "the base name of the socket to use for communication between "
1705               "child processes.  The actual socket will be "
1706               "basename.childnum"),
1707 { NULL }
1708 };
1709
1710 static void *perchild_create_config(ap_pool_t *p, server_rec *s)
1711 {
1712     perchild_server_conf *c =
1713     (perchild_server_conf *) ap_pcalloc(p, sizeof(perchild_server_conf));
1714
1715     c->sockname = ap_server_root_relative(p, DEFAULT_PERCHILD_SOCKET);
1716     return c;
1717 }
1718
1719 module MODULE_VAR_EXPORT mpm_perchild_module = {
1720     MPM20_MODULE_STUFF,
1721     NULL,                       /* hook to run before apache parses args */
1722     NULL,                       /* create per-directory config structure */
1723     NULL,                       /* merge per-directory config structures */
1724     perchild_create_config,     /* create per-server config structure */
1725     NULL,                       /* merge per-server config structures */
1726     perchild_cmds,              /* command ap_table_t */
1727     NULL,                       /* handlers */
1728     perchild_hooks              /* register_hooks */
1729 };
1730