1 #ifdef MULTI_THREADED
2 #ifndef _GNU_SOURCE
3 #define _GNU_SOURCE
4 #endif
5 #include <pthread.h>
6 #include <numa.h>
7 #include <sched.h>
8 #endif
9
10 #include "server.h"
11 #include "buffer.h"
12 #include "network.h"
13 #include "log.h"
14 #include "keyvalue.h"
15 #include "response.h"
16 #include "request.h"
17 #include "chunk.h"
18 #include "http_chunk.h"
19 #include "fdevent.h"
20 #include "connections.h"
21 #include "stat_cache.h"
22 #include "plugin.h"
23 #include "joblist.h"
24 #include "network_backends.h"
25 #include "version.h"
26
27 #include <sys/types.h>
28 #include <sys/time.h>
29 #include <sys/stat.h>
30
31 #include <string.h>
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <unistd.h>
35 #include <stdlib.h>
36 #include <time.h>
37 #include <signal.h>
38 #include <assert.h>
39 #include <locale.h>
40
41 #include <stdio.h>
42
43 #ifdef HAVE_GETOPT_H
44 # include <getopt.h>
45 #endif
46
47 #ifdef HAVE_VALGRIND_VALGRIND_H
48 # include <valgrind/valgrind.h>
49 #endif
50
51 #ifdef HAVE_SYS_WAIT_H
52 # include <sys/wait.h>
53 #endif
54
55 #ifdef HAVE_PWD_H
56 # include <grp.h>
57 # include <pwd.h>
58 #endif
59
60 #ifdef HAVE_SYS_RESOURCE_H
61 # include <sys/resource.h>
62 #endif
63
64 #ifdef HAVE_SYS_PRCTL_H
65 # include <sys/prctl.h>
66 #endif
67
68 #ifdef USE_OPENSSL
69 # include <openssl/err.h>
70 #endif
71 /*----------------------------------------------------------------------------*/
72 #ifndef __sgi
73 /* IRIX doesn't like the alarm based time() optimization */
74 /* #define USE_ALARM */
75 #endif
76
77 #ifdef HAVE_GETUID
78 # ifndef HAVE_ISSETUGID
79
80 static int
l_issetugid(void)81 l_issetugid(void) {
82 return (geteuid() != getuid() || getegid() != getgid());
83 }
84
85 # define issetugid l_issetugid
86 # endif
87 #endif
88
89 static volatile sig_atomic_t srv_shutdown = 0;
90 static volatile sig_atomic_t graceful_shutdown = 0;
91 static volatile sig_atomic_t handle_sig_alarm = 1;
92 static volatile sig_atomic_t handle_sig_hup = 0;
93 static volatile sig_atomic_t forwarded_sig_hup = 0;
94
95 #if defined(HAVE_SIGACTION) && defined(SA_SIGINFO)
96 static volatile siginfo_t last_sigterm_info;
97 static volatile siginfo_t last_sighup_info;
98 /*----------------------------------------------------------------------------*/
99 static void
sigaction_handler(int sig,siginfo_t * si,void * context)100 sigaction_handler(int sig, siginfo_t *si, void *context) {
101 static siginfo_t empty_siginfo;
102 UNUSED(context);
103
104 if (!si) si = &empty_siginfo;
105
106 switch (sig) {
107 case SIGTERM:
108 srv_shutdown = 1;
109 last_sigterm_info = *si;
110 break;
111 case SIGINT:
112 if (graceful_shutdown) {
113 srv_shutdown = 1;
114 } else {
115 graceful_shutdown = 1;
116 }
117 last_sigterm_info = *si;
118
119 break;
120 case SIGALRM:
121 handle_sig_alarm = 1;
122 break;
123 case SIGHUP:
124 /**
125 * we send the SIGHUP to all procs in the process-group
126 * this includes ourself
127 *
128 * make sure we only send it once and don't create a
129 * infinite loop
130 */
131 if (!forwarded_sig_hup) {
132 handle_sig_hup = 1;
133 last_sighup_info = *si;
134 } else {
135 forwarded_sig_hup = 0;
136 }
137 break;
138 case SIGCHLD:
139 break;
140 }
141 }
142 /*----------------------------------------------------------------------------*/
143 #elif defined(HAVE_SIGNAL) || defined(HAVE_SIGACTION)
144 static void
signal_handler(int sig)145 signal_handler(int sig) {
146 switch (sig) {
147 case SIGTERM: srv_shutdown = 1; break;
148 case SIGINT:
149 if (graceful_shutdown) srv_shutdown = 1;
150 else graceful_shutdown = 1;
151 break;
152 case SIGALRM: handle_sig_alarm = 1; break;
153 case SIGHUP: handle_sig_hup = 1; break;
154 case SIGCHLD: break;
155 }
156 }
157 #endif
158 /*----------------------------------------------------------------------------*/
159 #ifdef MULTI_THREADED
160 /* TODO - signal handling logic will be revised in future revisions */
161 static void
signal_handler(int sig)162 signal_handler(int sig) {
163 switch (sig) {
164 case SIGTERM: srv_shutdown = 1; break;
165 case SIGINT:
166 if (graceful_shutdown) srv_shutdown = 1;
167 else graceful_shutdown = 1;
168
169 break;
170 case SIGALRM: handle_sig_alarm = 1; break;
171 case SIGHUP: handle_sig_hup = 1; break;
172 case SIGCHLD: break;
173 }
174 #ifdef HAVE_LIBDPDK
175 exit(EXIT_SUCCESS);
176 #endif
177 }
178 #endif
179 /*----------------------------------------------------------------------------*/
180 #ifdef HAVE_FORK
181 static void
daemonize(void)182 daemonize(void) {
183 #ifdef SIGTTOU
184 signal(SIGTTOU, SIG_IGN);
185 #endif
186 #ifdef SIGTTIN
187 signal(SIGTTIN, SIG_IGN);
188 #endif
189 #ifdef SIGTSTP
190 signal(SIGTSTP, SIG_IGN);
191 #endif
192 if (0 != fork()) exit(EXIT_SUCCESS);
193
194 if (-1 == setsid()) exit(EXIT_SUCCESS);
195
196 signal(SIGHUP, SIG_IGN);
197
198 if (0 != fork()) exit(EXIT_SUCCESS);
199
200 if (0 != chdir("/")) exit(EXIT_SUCCESS);
201 }
202 #endif
203 /*----------------------------------------------------------------------------*/
204 static server *
server_init(void)205 server_init(void) {
206 int i;
207 FILE *frandom = NULL;
208
209 server *srv = calloc(1, sizeof(*srv));
210 assert(srv);
211 #define CLEAN(x) \
212 srv->x = buffer_init();
213
214 CLEAN(response_header);
215 CLEAN(parse_full_path);
216 CLEAN(ts_debug_str);
217 CLEAN(ts_date_str);
218 CLEAN(errorlog_buf);
219 CLEAN(response_range);
220 CLEAN(tmp_buf);
221 srv->empty_string = buffer_init_string("");
222 CLEAN(cond_check_buf);
223
224 CLEAN(srvconf.errorlog_file);
225 CLEAN(srvconf.breakagelog_file);
226 CLEAN(srvconf.groupname);
227 CLEAN(srvconf.username);
228 CLEAN(srvconf.changeroot);
229 CLEAN(srvconf.bindhost);
230 CLEAN(srvconf.event_handler);
231 CLEAN(srvconf.pid_file);
232
233 CLEAN(tmp_chunk_len);
234 #undef CLEAN
235
236 #define CLEAN(x) \
237 srv->x = array_init();
238
239 CLEAN(config_context);
240 CLEAN(config_touched);
241 CLEAN(status);
242 #undef CLEAN
243
244 for (i = 0; i < FILE_CACHE_MAX; i++) {
245 srv->mtime_cache[i].mtime = (time_t)-1;
246 srv->mtime_cache[i].str = buffer_init();
247 }
248
249 if ((NULL != (frandom = fopen("/dev/urandom", "rb")) || NULL != (frandom = fopen("/dev/random", "rb")))
250 && 1 == fread(srv->entropy, sizeof(srv->entropy), 1, frandom)) {
251 unsigned int e;
252 memcpy(&e, srv->entropy, sizeof(e) < sizeof(srv->entropy) ? sizeof(e) : sizeof(srv->entropy));
253 srand(e);
254 srv->is_real_entropy = 1;
255 } else {
256 unsigned int j;
257 srand(time(NULL) ^ getpid());
258 srv->is_real_entropy = 0;
259 for (j = 0; j < sizeof(srv->entropy); j++)
260 srv->entropy[j] = rand();
261 }
262 if (frandom) fclose(frandom);
263
264 srv->cur_ts = time(NULL);
265 srv->startup_ts = srv->cur_ts;
266
267 srv->conns = calloc(1, sizeof(*srv->conns));
268 assert(srv->conns);
269
270 srv->joblist = calloc(1, sizeof(*srv->joblist));
271 assert(srv->joblist);
272
273 srv->fdwaitqueue = calloc(1, sizeof(*srv->fdwaitqueue));
274 assert(srv->fdwaitqueue);
275
276 srv->srvconf.modules = array_init();
277 srv->srvconf.modules_dir = buffer_init_string(LIBRARY_DIR);
278 srv->srvconf.network_backend = buffer_init();
279 srv->srvconf.upload_tempdirs = array_init();
280 srv->srvconf.reject_expect_100_with_417 = 1;
281
282 /* use syslog */
283 srv->errorlog_fd = STDERR_FILENO;
284 srv->errorlog_mode = ERRORLOG_FD;
285
286 srv->split_vals = array_init();
287
288 return srv;
289 }
290 /*----------------------------------------------------------------------------*/
291 static void
server_free(server * srv)292 server_free(server *srv) {
293 size_t i;
294
295 for (i = 0; i < FILE_CACHE_MAX; i++) {
296 buffer_free(srv->mtime_cache[i].str);
297 }
298
299 #define CLEAN(x) \
300 buffer_free(srv->x);
301
302 CLEAN(response_header);
303 CLEAN(parse_full_path);
304 CLEAN(ts_debug_str);
305 CLEAN(ts_date_str);
306 CLEAN(errorlog_buf);
307 CLEAN(response_range);
308 CLEAN(tmp_buf);
309 CLEAN(empty_string);
310 CLEAN(cond_check_buf);
311
312 CLEAN(srvconf.errorlog_file);
313 CLEAN(srvconf.breakagelog_file);
314 CLEAN(srvconf.groupname);
315 CLEAN(srvconf.username);
316 CLEAN(srvconf.changeroot);
317 CLEAN(srvconf.bindhost);
318 CLEAN(srvconf.event_handler);
319 CLEAN(srvconf.pid_file);
320 CLEAN(srvconf.modules_dir);
321 CLEAN(srvconf.network_backend);
322
323 CLEAN(tmp_chunk_len);
324 #undef CLEAN
325
326 #if 0
327 fdevent_unregister(srv->ev, srv->fd);
328 #endif
329 fdevent_free(srv->ev);
330
331 free(srv->conns);
332
333 if (srv->config_storage) {
334 for (i = 0; i < srv->config_context->used; i++) {
335 specific_config *s = srv->config_storage[i];
336
337 if (!s) continue;
338
339 buffer_free(s->document_root);
340 buffer_free(s->server_name);
341 buffer_free(s->server_tag);
342 buffer_free(s->ssl_pemfile);
343 buffer_free(s->ssl_ca_file);
344 buffer_free(s->ssl_cipher_list);
345 buffer_free(s->ssl_dh_file);
346 buffer_free(s->ssl_ec_curve);
347 buffer_free(s->error_handler);
348 buffer_free(s->errorfile_prefix);
349 array_free(s->mimetypes);
350 buffer_free(s->ssl_verifyclient_username);
351 #ifdef USE_OPENSSL
352 SSL_CTX_free(s->ssl_ctx);
353 #endif
354 free(s);
355 }
356 free(srv->config_storage);
357 srv->config_storage = NULL;
358 }
359
360 #define CLEAN(x) \
361 array_free(srv->x);
362
363 CLEAN(config_context);
364 CLEAN(config_touched);
365 CLEAN(status);
366 CLEAN(srvconf.upload_tempdirs);
367 #undef CLEAN
368
369 joblist_free(srv, srv->joblist);
370 fdwaitqueue_free(srv, srv->fdwaitqueue);
371
372 if (srv->stat_cache) {
373 stat_cache_free(srv->stat_cache);
374 }
375
376 array_free(srv->srvconf.modules);
377 array_free(srv->split_vals);
378
379 #ifdef USE_OPENSSL
380 if (srv->ssl_is_init) {
381 CRYPTO_cleanup_all_ex_data();
382 ERR_free_strings();
383 ERR_remove_state(0);
384 EVP_cleanup();
385 }
386 #endif
387
388 free(srv);
389 }
390 /*----------------------------------------------------------------------------*/
391 static inline void
load_plugins(server * srv)392 load_plugins(server *srv)
393 {
394 if (HANDLER_GO_ON != plugins_call_init(srv)) {
395 log_error_write(srv, __FILE__, __LINE__, "s",
396 "Initialization of plugins failed. Going down.");
397 exit(EXIT_FAILURE);
398 }
399
400 }
401 /*----------------------------------------------------------------------------*/
402 static inline void
set_max_conns(server * srv,int restrict_limit)403 set_max_conns(server *srv, int restrict_limit)
404 {
405 if (restrict_limit) {
406 if (srv->srvconf.max_conns > srv->max_fds/2) {
407 /* we can't have more connections than max-fds/2 */
408 log_error_write(srv, __FILE__, __LINE__, "sdd",
409 "can't have more connections than fds/2: ",
410 srv->srvconf.max_conns, srv->max_fds);
411 srv->max_conns = srv->max_fds/2;
412 } else if (srv->srvconf.max_conns) {
413 /* otherwise respect the wishes of the user */
414 srv->max_conns = srv->srvconf.max_conns;
415 } else {
416 /* or use the default: we really don't want to hit max-fds */
417 srv->max_conns = srv->max_fds/3;
418 }
419 } else {
420 srv->max_conns = srv->srvconf.max_conns;
421 }
422 }
423 /*----------------------------------------------------------------------------*/
424 static inline void
initialize_fd_framework(server * srv)425 initialize_fd_framework(server *srv)
426 {
427 size_t i;
428
429 /* the 2nd arg of fdevent_init in case of libmtcp is ignored */
430 if (NULL == (srv->ev = fdevent_init(srv, srv->max_fds + 1, srv->event_handler))) {
431 log_error_write(srv, __FILE__, __LINE__,
432 "s", "fdevent_init failed");
433 exit(EXIT_FAILURE);
434 }
435
436 /*
437 * kqueue() is called here, select resets its internals,
438 * all server sockets get their handlers
439 *
440 * */
441 if (0 != network_register_fdevents(srv)) {
442 exit(EXIT_FAILURE);
443 }
444
445 /* might fail if user is using fam (not gamin) and famd isn't running */
446 if (NULL == (srv->stat_cache = stat_cache_init())) {
447 log_error_write(srv, __FILE__, __LINE__, "s",
448 "stat-cache could not be setup, dieing.");
449 exit(EXIT_FAILURE);
450 }
451
452 #ifdef HAVE_FAM_H
453 i hope this does not work
454 /* setup FAM */
455 if (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM) {
456 if (0 != FAMOpen2(srv->stat_cache->fam, "lighttpd")) {
457 log_error_write(srv, __FILE__, __LINE__, "s",
458 "could not open a fam connection, dieing.");
459 exit(EXIT_FAILURE);
460 }
461 #ifdef HAVE_FAMNOEXISTS
462 FAMNoExists(srv->stat_cache->fam);
463 #endif
464
465 srv->stat_cache->fam_fcce_ndx = -1;
466 fdevent_register(srv->ev, FAMCONNECTION_GETFD(srv->stat_cache->fam), stat_cache_handle_fdevent, NULL);
467 fdevent_event_set(srv->ev, &(srv->stat_cache->fam_fcce_ndx), FAMCONNECTION_GETFD(srv->stat_cache->fam), FDEVENT_IN);
468 }
469 #endif
470
471
472 /* get the current number of FDs */
473 srv->cur_fds = open("/dev/null", O_RDONLY);
474 close(srv->cur_fds);
475
476 for (i = 0; i < srv->srv_sockets.used; i++) {
477 server_socket *srv_socket = srv->srv_sockets.ptr[i];
478 if (-1 == fdevent_fcntl_set(srv->ev, srv_socket->fd)) {
479 log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed:", strerror(errno));
480 exit(EXIT_FAILURE);
481 }
482 }
483 }
484 /*----------------------------------------------------------------------------*/
485 #ifdef MULTI_THREADED
486 #ifdef USE_MTCP
487 static inline void
set_listen_backlog(server * srv)488 set_listen_backlog(server *srv)
489 {
490 fprintf(stderr, "Applying listen_backlog: %d\n", srv->srvconf.listen_backlog);
491 srv->listen_backlog = srv->srvconf.listen_backlog;
492 }
493 #endif
494 /*----------------------------------------------------------------------------*/
495 int
core_affinitize(int cpu)496 core_affinitize(int cpu)
497 {
498 cpu_set_t *cmask;
499 struct bitmask *bmask;
500 size_t n;
501 int ret;
502
503 n = sysconf(_SC_NPROCESSORS_ONLN);
504
505 if (cpu < 0 || cpu >= (int) n) {
506 errno = -EINVAL;
507 return -1;
508 }
509
510 cmask = CPU_ALLOC(n);
511 if (cmask == NULL)
512 return -1;
513
514 CPU_ZERO_S(n, cmask);
515 CPU_SET_S(cpu, n, cmask);
516
517 ret = sched_setaffinity(0, n, cmask);
518
519 CPU_FREE(cmask);
520
521 if (numa_max_node() == 0)
522 return ret;
523
524 bmask = numa_bitmask_alloc(16);
525 assert(bmask);
526
527 numa_bitmask_setbit(bmask, cpu % 2);
528 numa_set_membind(bmask);
529 numa_bitmask_free(bmask);
530
531 return ret;
532 }
533 /*----------------------------------------------------------------------------*/
534 static int
get_num_cpus(const char * strnum)535 get_num_cpus(const char *strnum)
536 {
537 return strtol(strnum, (char **) NULL, 10);
538 }
539 /*----------------------------------------------------------------------------*/
540 static void
init_server_states(server *** srv_states,int cpus,server * first_entry,const char * conf_file)541 init_server_states(server ***srv_states, int cpus,
542 server *first_entry, const char *conf_file)
543 {
544 int i;
545
546 /* initialize the array */
547 *srv_states = (server **)calloc(cpus, sizeof(server *));
548 if (NULL == *srv_states) {
549 fprintf(stderr, "%s: %d(%s) - Can't allocate memory for srv_states\n",
550 __FUNCTION__, __LINE__, __FILE__);
551 exit(EXIT_FAILURE);
552 }
553 /* put the first entry on index 0 */
554 (*srv_states)[0] = first_entry;
555 #if !(defined USE_MTCP || defined REUSEPORT)
556 //#ifndef USE_MTCP
557 ((*srv_states)[0])->first_entry = first_entry;
558 #else
559 #ifdef USE_MTCP
560 /* set listen-backlog */
561 set_listen_backlog(first_entry);
562 #endif
563 #endif
564
565 /* now do the same for all remaining reserved cpus */
566 for (i = 1; i < cpus; i++) {
567 /* initialize it */
568 if (NULL == ((*srv_states)[i] = server_init())) {
569 fprintf(stderr, "%s: %d(%s) - Can't allocate memory for %dth srv_state entry\n",
570 __FUNCTION__, __LINE__, __FILE__, i);
571 goto release_everything;
572 }
573 ((*srv_states)[i])->srvconf.port = 0;
574 ((*srv_states)[i])->srvconf.dont_daemonize =
575 first_entry->srvconf.dont_daemonize;
576 #if !(defined USE_MTCP || defined REUSEPORT)
577 //#ifndef USE_MTCP
578 ((*srv_states)[i])->first_entry = first_entry;
579 #endif
580
581 /* set the struct by reading the conf file again... */
582 if (config_read(((*srv_states)[i]), conf_file))
583 goto release_everything;
584 buffer_copy_string(((*srv_states)[i])->srvconf.modules_dir,
585 first_entry->srvconf.modules_dir->ptr);
586 /* ... and set the remaining as default. */
587 if (0 != config_set_defaults((*srv_states)[i])) {
588 log_error_write((*srv_states)[i], __FILE__, __LINE__, "s",
589 "setting default values failed");
590 goto release_everything;
591 }
592 /* load the plugins... i hope it doesn't mess things up */
593 if (plugins_load((*srv_states)[i])) {
594 log_error_write((*srv_states)[i], __FILE__, __LINE__, "s",
595 "loading plugins finally failed");
596 goto release_everything;
597 }
598 /* clone max_fds as well */
599 ((*srv_states)[i])->max_fds = first_entry->max_fds;
600 /* clone max_conns as well */
601 ((*srv_states)[i])->max_conns = first_entry->max_conns;
602 #ifdef USE_MTCP
603 /* clone listen backlog limit */
604 ((*srv_states)[i])->listen_backlog = first_entry->listen_backlog;
605 #endif
606 }
607 return;
608 release_everything:
609 /* release everything in reverse then */
610 while (i >= 0) {
611 server_free((*srv_states)[i]);
612 plugins_free((*srv_states)[i]);
613 i--;
614 }
615 free(*srv_states);
616 exit(EXIT_FAILURE);
617 }
618 /*----------------------------------------------------------------------------*/
619 void *
start_server(void * svrptr)620 start_server(void *svrptr)
621 {
622 server *srv = (server *)svrptr;
623 size_t cpu = srv->cpu;
624 size_t i;
625
626 /* affinitize server to core `cpu' */
627 core_affinitize(cpu);
628
629 #ifdef USE_MTCP
630 /* initialize the per-cpu mctx context */
631 /* creating mtcp context first */
632 srv->mctx = mtcp_create_context(cpu);
633 if (!srv->mctx) {
634 fprintf(stderr, "Failed to create mtcp context!\n");
635 exit(EXIT_FAILURE);
636 }
637
638 /* adjust max fds to max_conns * 3 */
639 srv->max_fds = srv->max_conns * 3;
640 #else
641 /* register SIGINT signal handler */
642 signal(SIGINT, signal_handler);
643
644 #endif /* !USE_MTCP */
645
646 /* network backend initialization */
647 if (network_init(srv) == -1)
648 exit(EXIT_FAILURE);
649 #ifdef USE_MTCP
650 set_max_conns(srv, 0);
651 #else
652 set_max_conns(srv, 1);
653 #endif
654 load_plugins(srv);
655
656 /* Close stderr ASAP in the child process to make sure that nothing
657 * is being written to that fd which may not be valid anymore. */
658 if (-1 == log_error_open(srv)) {
659 log_error_write(srv, __FILE__, __LINE__, "s",
660 "Opening errorlog failed. Going down.");
661 exit(EXIT_FAILURE);
662 }
663
664 if (HANDLER_GO_ON != plugins_call_set_defaults(srv)) {
665 log_error_write(srv, __FILE__, __LINE__, "s",
666 "Configuration of plugins failed. Going down.");
667 exit(EXIT_FAILURE);
668 }
669
670 /* register fdevent framework first */
671 initialize_fd_framework(srv);
672
673 /* and... finally the 'main-loop' */
674 /*-------------------------------------------------------------------------------*/
675 /* main-loop */
676 while (!srv_shutdown) {
677 int n;
678 size_t ndx;
679 time_t min_ts;
680
681 if (handle_sig_hup) {
682 handler_t r;
683
684 /* reset notification */
685 handle_sig_hup = 0;
686
687
688 /* cycle logfiles */
689
690 switch(r = plugins_call_handle_sighup(srv)) {
691 case HANDLER_GO_ON:
692 break;
693 default:
694 log_error_write(srv, __FILE__, __LINE__, "sd", "sighup-handler return with an error", r);
695 break;
696 }
697
698 if (-1 == log_error_cycle(srv)) {
699 log_error_write(srv, __FILE__, __LINE__, "s", "cycling errorlog failed, dying");
700
701 exit(EXIT_FAILURE);
702 } else {
703 #ifdef HAVE_SIGACTION
704 log_error_write(srv, __FILE__, __LINE__, "sdsd",
705 "logfiles cycled UID =",
706 last_sighup_info.si_uid,
707 "PID =",
708 last_sighup_info.si_pid);
709 #else
710 log_error_write(srv, __FILE__, __LINE__, "s",
711 "logfiles cycled");
712 #endif
713 }
714 }
715
716 if (handle_sig_alarm) {
717 /* a new second */
718
719 #ifdef USE_ALARM
720 /* reset notification */
721 handle_sig_alarm = 0;
722 #endif
723
724 /* get current time */
725 min_ts = time(NULL);
726
727 if (min_ts != srv->cur_ts) {
728 int cs = 0;
729 connections *conns = srv->conns;
730 handler_t r;
731
732 switch(r = plugins_call_handle_trigger(srv)) {
733 case HANDLER_GO_ON:
734 break;
735 case HANDLER_ERROR:
736 log_error_write(srv, __FILE__, __LINE__, "s", "one of the triggers failed");
737 break;
738 default:
739 log_error_write(srv, __FILE__, __LINE__, "d", r);
740 break;
741 }
742
743 /* trigger waitpid */
744 srv->cur_ts = min_ts;
745
746 /* cleanup stat-cache */
747 stat_cache_trigger_cleanup(srv);
748 /**
749 * check all connections for timeouts
750 *
751 */
752 for (ndx = 0; ndx < conns->used; ndx++) {
753 int changed = 0;
754 connection *con;
755 int t_diff;
756
757 con = conns->ptr[ndx];
758
759 if (con->state == CON_STATE_READ ||
760 con->state == CON_STATE_READ_POST) {
761 if (con->request_count == 1) {
762 if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) {
763 /* time - out */
764 #if 0
765 log_error_write(srv, __FILE__, __LINE__, "sd",
766 "connection closed - read-timeout:", con->fd);
767 #endif
768 connection_set_state(srv, con, CON_STATE_ERROR);
769 changed = 1;
770 }
771 } else {
772 if (srv->cur_ts - con->read_idle_ts > con->keep_alive_idle) {
773 /* time - out */
774 #if 0
775 log_error_write(srv, __FILE__, __LINE__, "sd",
776 "connection closed - read-timeout:", con->fd);
777 #endif
778 connection_set_state(srv, con, CON_STATE_ERROR);
779 changed = 1;
780 }
781 }
782 }
783
784 if ((con->state == CON_STATE_WRITE) &&
785 (con->write_request_ts != 0)) {
786 #if 0
787 if (srv->cur_ts - con->write_request_ts > 60) {
788 log_error_write(srv, __FILE__, __LINE__, "sdd",
789 "connection closed - pre-write-request-timeout:", con->fd, srv->cur_ts - con->write_request_ts);
790 }
791 #endif
792
793 if (srv->cur_ts - con->write_request_ts > con->conf.max_write_idle) {
794 /* time - out */
795 if (con->conf.log_timeouts) {
796 log_error_write(srv, __FILE__, __LINE__, "sbsosds",
797 "NOTE: a request for",
798 con->request.uri,
799 "timed out after writing",
800 con->bytes_written,
801 "bytes. We waited",
802 (int)con->conf.max_write_idle,
803 "seconds. If this a problem increase server.max-write-idle");
804 }
805 connection_set_state(srv, con, CON_STATE_ERROR);
806 changed = 1;
807 }
808 }
809
810 if (con->state == CON_STATE_CLOSE && (srv->cur_ts - con->close_timeout_ts > HTTP_LINGER_TIMEOUT)) {
811 changed = 1;
812 }
813
814 /* we don't like div by zero */
815 if (0 == (t_diff = srv->cur_ts - con->connection_start)) t_diff = 1;
816
817 if (con->traffic_limit_reached &&
818 (con->conf.kbytes_per_second == 0 ||
819 ((con->bytes_written / t_diff) < con->conf.kbytes_per_second * 1024))) {
820 /* enable connection again */
821 con->traffic_limit_reached = 0;
822
823 changed = 1;
824 }
825
826 if (changed) {
827 connection_state_machine(srv, con);
828 }
829 con->bytes_written_cur_second = 0;
830 *(con->conf.global_bytes_per_second_cnt_ptr) = 0;
831
832 #if 0
833 if (cs == 0) {
834 fprintf(stderr, "connection-state: ");
835 cs = 1;
836 }
837
838 fprintf(stderr, "c[%d,%d]: %s ",
839 con->fd,
840 con->fcgi.fd,
841 connection_get_state(con->state));
842 #endif
843 }
844
845 if (cs == 1) fprintf(stderr, "\n");
846 }
847 }
848
849 if (srv->sockets_disabled) {
850 /* our server sockets are disabled, why ? */
851
852 if ((srv->cur_fds + srv->want_fds < srv->max_fds * 8 / 10) && /* we have enough unused fds */
853 (srv->conns->used <= srv->max_conns * 9 / 10) &&
854 (0 == graceful_shutdown)) {
855 for (i = 0; i < srv->srv_sockets.used; i++) {
856 server_socket *srv_socket = srv->srv_sockets.ptr[i];
857 fdevent_event_set(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
858 }
859
860 log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets enabled again");
861
862 srv->sockets_disabled = 0;
863 }
864 } else {
865 if ((srv->cur_fds + srv->want_fds > srv->max_fds * 9 / 10) || /* out of fds */
866 (srv->conns->used >= srv->max_conns) || /* out of connections */
867 (graceful_shutdown)) { /* graceful_shutdown */
868
869 /* disable server-fds */
870
871 for (i = 0; i < srv->srv_sockets.used; i++) {
872 server_socket *srv_socket = srv->srv_sockets.ptr[i];
873 fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
874
875 if (graceful_shutdown) {
876 /* we don't want this socket anymore,
877 *
878 * closing it right away will make it possible for
879 * the next lighttpd to take over (graceful restart)
880 * */
881
882 fdevent_unregister(srv->ev, srv_socket->fd);
883 #ifdef USE_MTCP
884 mtcp_close(srv->mctx, srv_socket->fd);
885 #else
886 close(srv_socket->fd);
887 #endif
888 srv_socket->fd = -1;
889
890 /* network_close() will cleanup after us */
891
892 if (srv->srvconf.pid_file->used &&
893 srv->srvconf.changeroot->used == 0) {
894 if (0 != unlink(srv->srvconf.pid_file->ptr)) {
895 if (errno != EACCES && errno != EPERM) {
896 log_error_write(srv, __FILE__, __LINE__, "sbds",
897 "unlink failed for:",
898 srv->srvconf.pid_file,
899 errno,
900 strerror(errno));
901 }
902 }
903 }
904 }
905 }
906
907 if (graceful_shutdown) {
908 log_error_write(srv, __FILE__, __LINE__, "s", "[note] graceful shutdown started");
909 } else if (srv->conns->used >= srv->max_conns) {
910 log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, connection limit reached");
911 } else {
912 log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, out-of-fds");
913 }
914
915 srv->sockets_disabled = 1;
916 }
917 }
918
919 if (graceful_shutdown && srv->conns->used == 0) {
920 /* we are in graceful shutdown phase and all connections are closed
921 * we are ready to terminate without harming anyone */
922 srv_shutdown = 1;
923 }
924
925 /* we still have some fds to share */
926 if (srv->want_fds) {
927 /* check the fdwaitqueue for waiting fds */
928 int free_fds = srv->max_fds - srv->cur_fds - 16;
929 connection *con;
930
931 for (; free_fds > 0 && NULL != (con = fdwaitqueue_unshift(srv, srv->fdwaitqueue)); free_fds--) {
932 connection_state_machine(srv, con);
933
934 srv->want_fds--;
935 }
936 }
937
938 if ((n = fdevent_poll(srv->ev, -1/*1000*/)) > 0) {
939 /* n is the number of events */
940 int revents;
941 int fd_ndx;
942 #if 0
943 if (n > 0) {
944 log_error_write(srv, __FILE__, __LINE__, "sd",
945 "polls:", n);
946 }
947 #endif
948 fd_ndx = -1;
949 do {
950 fdevent_handler handler;
951 void *context;
952 handler_t r;
953 int fd;
954
955 fd_ndx = fdevent_event_next_fdndx (srv->ev, fd_ndx);
956 if (-1 == fd_ndx) break; /* not all fdevent handlers know how many fds got an event */
957
958 revents = fdevent_event_get_revent (srv->ev, fd_ndx);
959 fd = fdevent_event_get_fd (srv->ev, fd_ndx);
960 handler = fdevent_get_handler(srv->ev, fd);
961 context = fdevent_get_context(srv->ev, fd);
962
963 /* connection_handle_fdevent needs a joblist_append */
964 #if 0
965 log_error_write(srv, __FILE__, __LINE__, "sdd",
966 "event for", fd, revents);
967 #endif
968 switch (r = (*handler)(srv, context, revents)) {
969 case HANDLER_FINISHED:
970 case HANDLER_GO_ON:
971 case HANDLER_WAIT_FOR_EVENT:
972 case HANDLER_WAIT_FOR_FD:
973 break;
974 case HANDLER_ERROR:
975 /* should never happen */
976 SEGFAULT();
977 break;
978 default:
979 log_error_write(srv, __FILE__, __LINE__, "d", r);
980 break;
981 }
982 } while (--n > 0);
983 } else if (n < 0 && errno != EINTR) {
984 log_error_write(srv, __FILE__, __LINE__, "ss",
985 "fdevent_poll failed:",
986 strerror(errno));
987 }
988
989 for (ndx = 0; ndx < srv->joblist->used; ndx++) {
990 connection *con = srv->joblist->ptr[ndx];
991 handler_t r;
992
993 connection_state_machine(srv, con);
994
995 switch(r = plugins_call_handle_joblist(srv, con)) {
996 case HANDLER_FINISHED:
997 case HANDLER_GO_ON:
998 break;
999 default:
1000 log_error_write(srv, __FILE__, __LINE__, "d", r);
1001 break;
1002 }
1003
1004 con->in_joblist = 0;
1005 }
1006
1007 srv->joblist->used = 0;
1008 } /* end of `while (!srv_shutdown)` */
1009 /*-------------------------------------------------------------------------------*/
1010 #ifdef USE_MTCP
1011 /* TODO - this will go somewhere else */
1012 mtcp_destroy_context(srv->mctx);
1013 #endif
1014 pthread_exit(NULL);
1015
1016 return NULL;
1017 }
1018 #endif /* !MULTI_THREADED */
1019 /*----------------------------------------------------------------------------*/
1020 static void
show_version(void)1021 show_version (void) {
1022 #ifdef USE_OPENSSL
1023 # define TEXT_SSL " (ssl)"
1024 #else
1025 # define TEXT_SSL
1026 #endif
1027 char *b = PACKAGE_DESC TEXT_SSL \
1028 " - a light and fast webserver\n" \
1029 "Build-Date: " __DATE__ " " __TIME__ "\n";
1030 ;
1031 #undef TEXT_SSL
1032 write(STDOUT_FILENO, b, strlen(b));
1033 }
1034 /*----------------------------------------------------------------------------*/
1035 static void
show_features(void)1036 show_features(void) {
1037 const char features[] = ""
1038 #ifdef USE_SELECT
1039 "\t+ select (generic)\n"
1040 #else
1041 "\t- select (generic)\n"
1042 #endif
1043 #ifdef USE_POLL
1044 "\t+ poll (Unix)\n"
1045 #else
1046 "\t- poll (Unix)\n"
1047 #endif
1048 #ifdef USE_LINUX_SIGIO
1049 "\t+ rt-signals (Linux 2.4+)\n"
1050 #else
1051 "\t- rt-signals (Linux 2.4+)\n"
1052 #endif
1053 #ifdef USE_LINUX_EPOLL
1054 "\t+ epoll (Linux 2.6)\n"
1055 #else
1056 "\t- epoll (Linux 2.6)\n"
1057 #endif
1058 #ifdef USE_SOLARIS_DEVPOLL
1059 "\t+ /dev/poll (Solaris)\n"
1060 #else
1061 "\t- /dev/poll (Solaris)\n"
1062 #endif
1063 #ifdef USE_SOLARIS_PORT
1064 "\t+ eventports (Solaris)\n"
1065 #else
1066 "\t- eventports (Solaris)\n"
1067 #endif
1068 #ifdef USE_FREEBSD_KQUEUE
1069 "\t+ kqueue (FreeBSD)\n"
1070 #else
1071 "\t- kqueue (FreeBSD)\n"
1072 #endif
1073 #ifdef USE_LIBEV
1074 "\t+ libev (generic)\n"
1075 #else
1076 "\t- libev (generic)\n"
1077 #endif
1078 "\nNetwork handler:\n\n"
1079 #if defined USE_LINUX_SENDFILE
1080 "\t+ linux-sendfile\n"
1081 #else
1082 "\t- linux-sendfile\n"
1083 #endif
1084 #if defined USE_FREEBSD_SENDFILE
1085 "\t+ freebsd-sendfile\n"
1086 #else
1087 "\t- freebsd-sendfile\n"
1088 #endif
1089 #if defined USE_SOLARIS_SENDFILEV
1090 "\t+ solaris-sendfilev\n"
1091 #else
1092 "\t- solaris-sendfilev\n"
1093 #endif
1094 #if defined USE_WRITEV
1095 "\t+ writev\n"
1096 #else
1097 "\t- writev\n"
1098 #endif
1099 "\t+ write\n"
1100 #ifdef USE_MMAP
1101 "\t+ mmap support\n"
1102 #else
1103 "\t- mmap support\n"
1104 #endif
1105 "\nFeatures:\n\n"
1106 #ifdef HAVE_IPV6
1107 "\t+ IPv6 support\n"
1108 #else
1109 "\t- IPv6 support\n"
1110 #endif
1111 #if defined HAVE_ZLIB_H && defined HAVE_LIBZ
1112 "\t+ zlib support\n"
1113 #else
1114 "\t- zlib support\n"
1115 #endif
1116 #if defined HAVE_BZLIB_H && defined HAVE_LIBBZ2
1117 "\t+ bzip2 support\n"
1118 #else
1119 "\t- bzip2 support\n"
1120 #endif
1121 #ifdef HAVE_LIBCRYPT
1122 "\t+ crypt support\n"
1123 #else
1124 "\t- crypt support\n"
1125 #endif
1126 #ifdef USE_OPENSSL
1127 "\t+ SSL Support\n"
1128 #else
1129 "\t- SSL Support\n"
1130 #endif
1131 #ifdef USE_MTCP
1132 "\t+ MTCP Support\n"
1133 #else
1134 "\t- MTCP Support\n"
1135 #endif
1136 #ifdef HAVE_LIBPCRE
1137 "\t+ PCRE support\n"
1138 #else
1139 "\t- PCRE support\n"
1140 #endif
1141 #ifdef HAVE_MYSQL
1142 "\t+ mySQL support\n"
1143 #else
1144 "\t- mySQL support\n"
1145 #endif
1146 #if defined(HAVE_LDAP_H) && defined(HAVE_LBER_H) && defined(HAVE_LIBLDAP) && defined(HAVE_LIBLBER)
1147 "\t+ LDAP support\n"
1148 #else
1149 "\t- LDAP support\n"
1150 #endif
1151 #ifdef HAVE_MEMCACHE_H
1152 "\t+ memcached support\n"
1153 #else
1154 "\t- memcached support\n"
1155 #endif
1156 #ifdef HAVE_FAM_H
1157 "\t+ FAM support\n"
1158 #else
1159 "\t- FAM support\n"
1160 #endif
1161 #ifdef HAVE_LUA_H
1162 "\t+ LUA support\n"
1163 #else
1164 "\t- LUA support\n"
1165 #endif
1166 #ifdef HAVE_LIBXML_H
1167 "\t+ xml support\n"
1168 #else
1169 "\t- xml support\n"
1170 #endif
1171 #ifdef HAVE_SQLITE3_H
1172 "\t+ SQLite support\n"
1173 #else
1174 "\t- SQLite support\n"
1175 #endif
1176 #ifdef HAVE_GDBM_H
1177 "\t+ GDBM support\n"
1178 #else
1179 "\t- GDBM support\n"
1180 #endif
1181 "\n";
1182 show_version();
1183 printf("\nEvent Handlers:\n\n%s", features);
1184 }
1185 /*----------------------------------------------------------------------------*/
1186 static void
show_help(void)1187 show_help(void) {
1188 #ifdef USE_OPENSSL
1189 # define TEXT_SSL " (ssl)"
1190 #else
1191 # define TEXT_SSL
1192 #endif
1193 char *b = PACKAGE_DESC TEXT_SSL " ("__DATE__ " " __TIME__ ")" \
1194 " - a light and fast webserver\n" \
1195 "usage:\n" \
1196 " -f <name> filename of the config-file\n" \
1197 " -m <name> module directory (default: "LIBRARY_DIR")\n" \
1198 " -p print the parsed config-file in internal form, and exit\n" \
1199 " -n <#cpus> number of cpu cores that lighttpd will use\n" \
1200 " -t test the config-file, and exit\n" \
1201 " -D don't go to background (default: go to background)\n" \
1202 " -v show version\n" \
1203 " -V show compile-time features\n" \
1204 " -h show this help\n" \
1205 "\n"
1206 ;
1207 #undef TEXT_SSL
1208 #undef TEXT_IPV6
1209 write(STDOUT_FILENO, b, strlen(b));
1210 }
1211 /*----------------------------------------------------------------------------*/
1212 int
main(int argc,char ** argv)1213 main(int argc, char **argv) {
1214 #ifdef MULTI_THREADED
1215 server **srv_states = NULL;
1216 char *conf_file = NULL;
1217 #ifdef USE_MTCP
1218 struct mtcp_conf mcfg;
1219 #endif
1220 #endif
1221 /*
1222 * The introduction of MTCP slightly changes the purpose of *srv.
1223 * *srv will always hold the srv state info for core 0.
1224 *
1225 * When compiled without --lib-mtcp, *srv is used as the default
1226 * version.
1227 */
1228 server *srv = NULL;
1229 int print_config = 0;
1230 int test_config = 0;
1231 int i_am_root;
1232 int o;
1233 int num_childs = 0;
1234 int pid_fd = -1;
1235 size_t i;
1236 struct group *grp = NULL;
1237 struct passwd *pwd = NULL;
1238 #ifdef HAVE_SIGACTION
1239 struct sigaction act;
1240 #endif
1241 #ifdef HAVE_GETRLIMIT
1242 struct rlimit rlim;
1243 #endif
1244
1245 #ifdef USE_ALARM
1246 struct itimerval interval;
1247
1248 interval.it_interval.tv_sec = 1;
1249 interval.it_interval.tv_usec = 0;
1250 interval.it_value.tv_sec = 1;
1251 interval.it_value.tv_usec = 0;
1252 #endif
1253 #ifdef MULTI_THREADED
1254 /* create the cpu variable to facilitate multi-threading framework */
1255 size_t cpus = -1;
1256 #endif
1257
1258
1259 /* for nice %b handling in strfime() */
1260 setlocale(LC_TIME, "C");
1261
1262 if (NULL == (srv = server_init())) {
1263 fprintf(stderr, "did this really happen?\n");
1264 return EXIT_FAILURE;
1265 }
1266
1267 /* init structs done */
1268 #ifdef HAVE_GETUID
1269 i_am_root = (getuid() == 0);
1270 #else
1271 i_am_root = 0;
1272 #endif
1273
1274 srv->srvconf.port = 0;
1275 srv->srvconf.dont_daemonize = 0;
1276
1277 while(-1 != (o = getopt(argc, argv, "f:m:n:hvVDpt"))) {
1278 switch(o) {
1279 case 'f':
1280 if (srv->config_storage) {
1281 log_error_write(srv, __FILE__, __LINE__, "s",
1282 "Can only read one config file. Use the include command to use multiple config files.");
1283
1284 server_free(srv);
1285 return EXIT_FAILURE;
1286 }
1287 #ifdef MULTI_THREADED
1288 /* store the path to conf file for populating other srv structs as well */
1289 conf_file = strdup(optarg);
1290 if (NULL == conf_file) {
1291 fprintf(stderr, "Can't duplicate conf_file string\n");
1292 return EXIT_FAILURE;
1293 }
1294 #endif
1295 if (config_read(srv, optarg)) {
1296 server_free(srv);
1297 return EXIT_FAILURE;
1298 }
1299 break;
1300 case 'm':
1301 buffer_copy_string(srv->srvconf.modules_dir, optarg);
1302 break;
1303 case 'n':
1304 #ifdef MULTI_THREADED
1305 cpus = get_num_cpus(optarg);
1306 #else
1307 fprintf(stderr, "-n option only works with MTCP/MULTI_THREADED support!\n");
1308 exit(EXIT_FAILURE);
1309 #endif
1310 break;
1311 case 'p': print_config = 1; break;
1312 case 't': test_config = 1; break;
1313 case 'D':
1314 srv->srvconf.dont_daemonize = 1; break;
1315 case 'v': show_version(); return EXIT_SUCCESS;
1316 case 'V': show_features(); return EXIT_SUCCESS;
1317 case 'h': show_help(); return EXIT_SUCCESS;
1318 default:
1319 show_help();
1320 server_free(srv);
1321
1322 return EXIT_FAILURE;
1323 }
1324 }
1325
1326 if (!srv->config_storage) {
1327 log_error_write(srv, __FILE__, __LINE__, "s",
1328 "No configuration available. Try using -f option.");
1329
1330 server_free(srv);
1331 return EXIT_FAILURE;
1332 }
1333
1334 if (print_config) {
1335 data_unset *dc = srv->config_context->data[0];
1336 if (dc) {
1337 dc->print(dc, 0);
1338 fprintf(stdout, "\n");
1339 } else {
1340 /* shouldn't happend */
1341 fprintf(stderr, "global config not found\n");
1342 }
1343 }
1344
1345 if (test_config) {
1346 printf("Syntax OK\n");
1347 }
1348
1349 if (test_config || print_config) {
1350 server_free(srv);
1351 return EXIT_SUCCESS;
1352 }
1353
1354 /* close stdin and stdout, as they are not needed */
1355 openDevNull(STDIN_FILENO);
1356 openDevNull(STDOUT_FILENO);
1357
1358 if (0 != config_set_defaults(srv)) {
1359 log_error_write(srv, __FILE__, __LINE__, "s",
1360 "setting default values failed");
1361 server_free(srv);
1362 return EXIT_FAILURE;
1363 }
1364
1365 /* UID handling */
1366 #ifdef HAVE_GETUID
1367 if (!i_am_root && issetugid()) {
1368 /* we are setuid-root */
1369
1370 log_error_write(srv, __FILE__, __LINE__, "s",
1371 "Are you nuts ? Don't apply a SUID bit to this binary");
1372
1373 server_free(srv);
1374 return EXIT_FAILURE;
1375 }
1376 #endif
1377
1378 /* check document-root */
1379 if (srv->config_storage[0]->document_root->used <= 1) {
1380 log_error_write(srv, __FILE__, __LINE__, "s",
1381 "document-root is not set\n");
1382
1383 server_free(srv);
1384
1385 return EXIT_FAILURE;
1386 }
1387
1388 if (plugins_load(srv)) {
1389 log_error_write(srv, __FILE__, __LINE__, "s",
1390 "loading plugins finally failed");
1391
1392 plugins_free(srv);
1393 server_free(srv);
1394
1395 return EXIT_FAILURE;
1396 }
1397
1398 /* open pid file BEFORE chroot */
1399 if (srv->srvconf.pid_file->used) {
1400 if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
1401 struct stat st;
1402 if (errno != EEXIST) {
1403 log_error_write(srv, __FILE__, __LINE__, "sbs",
1404 "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
1405 return EXIT_FAILURE;
1406 }
1407
1408 if (0 != stat(srv->srvconf.pid_file->ptr, &st)) {
1409 log_error_write(srv, __FILE__, __LINE__, "sbs",
1410 "stating existing pid-file failed:", srv->srvconf.pid_file, strerror(errno));
1411 }
1412
1413 if (!S_ISREG(st.st_mode)) {
1414 log_error_write(srv, __FILE__, __LINE__, "sb",
1415 "pid-file exists and isn't regular file:", srv->srvconf.pid_file);
1416 return EXIT_FAILURE;
1417 }
1418
1419 if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
1420 log_error_write(srv, __FILE__, __LINE__, "sbs",
1421 "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
1422 return EXIT_FAILURE;
1423 }
1424 }
1425 }
1426
1427 if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
1428 /* select limits itself
1429 *
1430 * as it is a hard limit and will lead to a segfault we add some safety
1431 * */
1432 srv->max_fds = FD_SETSIZE - 200;
1433 } else {
1434 srv->max_fds = 4096;
1435 }
1436
1437 if (i_am_root) {
1438 int use_rlimit = 1;
1439
1440 #ifdef HAVE_VALGRIND_VALGRIND_H
1441 if (RUNNING_ON_VALGRIND) use_rlimit = 0;
1442 #endif
1443
1444 #ifdef HAVE_GETRLIMIT
1445 if (0 != getrlimit(RLIMIT_NOFILE, &rlim)) {
1446 log_error_write(srv, __FILE__, __LINE__,
1447 "ss", "couldn't get 'max filedescriptors'",
1448 strerror(errno));
1449 return EXIT_FAILURE;
1450 }
1451
1452 if (use_rlimit && srv->srvconf.max_fds) {
1453 /* set rlimits */
1454
1455 rlim.rlim_cur = srv->srvconf.max_fds;
1456 rlim.rlim_max = srv->srvconf.max_fds;
1457
1458 if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
1459 log_error_write(srv, __FILE__, __LINE__,
1460 "ss", "couldn't set 'max filedescriptors'",
1461 strerror(errno));
1462 return EXIT_FAILURE;
1463 }
1464 }
1465
1466 if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
1467 srv->max_fds = rlim.rlim_cur < ((int)FD_SETSIZE) - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
1468 } else {
1469 srv->max_fds = rlim.rlim_cur;
1470 }
1471
1472 /* set core file rlimit, if enable_cores is set */
1473 if (use_rlimit && srv->srvconf.enable_cores && getrlimit(RLIMIT_CORE, &rlim) == 0) {
1474 rlim.rlim_cur = rlim.rlim_max;
1475 setrlimit(RLIMIT_CORE, &rlim);
1476 }
1477 #endif
1478 if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
1479 /* don't raise the limit above FD_SET_SIZE */
1480 if (srv->max_fds > ((int)FD_SETSIZE) - 200) {
1481 log_error_write(srv, __FILE__, __LINE__, "sd",
1482 "can't raise max filedescriptors above", FD_SETSIZE - 200,
1483 "if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
1484 return EXIT_FAILURE;
1485 }
1486 }
1487
1488
1489 #ifdef HAVE_PWD_H
1490 /* set user and group */
1491 if (srv->srvconf.username->used) {
1492 if (NULL == (pwd = getpwnam(srv->srvconf.username->ptr))) {
1493 log_error_write(srv, __FILE__, __LINE__, "sb",
1494 "can't find username", srv->srvconf.username);
1495 return EXIT_FAILURE;
1496 }
1497
1498 if (pwd->pw_uid == 0) {
1499 log_error_write(srv, __FILE__, __LINE__, "s",
1500 "I will not set uid to 0\n");
1501 return EXIT_FAILURE;
1502 }
1503 }
1504
1505 if (srv->srvconf.groupname->used) {
1506 if (NULL == (grp = getgrnam(srv->srvconf.groupname->ptr))) {
1507 log_error_write(srv, __FILE__, __LINE__, "sb",
1508 "can't find groupname", srv->srvconf.groupname);
1509 return EXIT_FAILURE;
1510 }
1511 if (grp->gr_gid == 0) {
1512 log_error_write(srv, __FILE__, __LINE__, "s",
1513 "I will not set gid to 0\n");
1514 return EXIT_FAILURE;
1515 }
1516 }
1517 #endif
1518 } else {
1519
1520 #ifdef HAVE_GETRLIMIT
1521 if (0 != getrlimit(RLIMIT_NOFILE, &rlim)) {
1522 log_error_write(srv, __FILE__, __LINE__,
1523 "ss", "couldn't get 'max filedescriptors'",
1524 strerror(errno));
1525 return EXIT_FAILURE;
1526 }
1527
1528 /**
1529 * we are not root can can't increase the fd-limit, but we can reduce it
1530 */
1531 if (srv->srvconf.max_fds && srv->srvconf.max_fds < (int)rlim.rlim_cur) {
1532 /* set rlimits */
1533
1534 rlim.rlim_cur = srv->srvconf.max_fds;
1535
1536 if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
1537 log_error_write(srv, __FILE__, __LINE__,
1538 "ss", "couldn't set 'max filedescriptors'",
1539 strerror(errno));
1540 return EXIT_FAILURE;
1541 }
1542 }
1543
1544 if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
1545 srv->max_fds = rlim.rlim_cur < ((int)FD_SETSIZE) - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
1546 } else {
1547 srv->max_fds = rlim.rlim_cur;
1548 }
1549
1550 /* set core file rlimit, if enable_cores is set */
1551 if (srv->srvconf.enable_cores && getrlimit(RLIMIT_CORE, &rlim) == 0) {
1552 rlim.rlim_cur = rlim.rlim_max;
1553 setrlimit(RLIMIT_CORE, &rlim);
1554 }
1555
1556 #endif
1557 if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
1558 /* don't raise the limit above FD_SET_SIZE */
1559 if (srv->max_fds > ((int)FD_SETSIZE) - 200) {
1560 log_error_write(srv, __FILE__, __LINE__, "sd",
1561 "can't raise max filedescriptors above", FD_SETSIZE - 200,
1562 "if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
1563 return EXIT_FAILURE;
1564 }
1565 }
1566 }
1567 #ifdef MULTI_THREADED
1568
1569 #if defined HAVE_FORK
1570 /* network is up, let's deamonize ourself */
1571 if (srv->srvconf.dont_daemonize == 0) daemonize();
1572 #endif
1573 #ifdef USE_MTCP
1574 /* set max-conns */
1575 set_max_conns(srv, 0);
1576 #else
1577 /* set the first_entry field */
1578 srv->first_entry = srv;
1579
1580 /* set max-conns */
1581 set_max_conns(srv, 1);
1582 #endif
1583 /* thread-wide network initialization */
1584 /* first initialize srv_states */
1585 init_server_states(&srv_states, cpus, srv, conf_file);
1586
1587 #ifdef USE_MTCP
1588 /**
1589 * it is important that core limit is set
1590 * before mtcp_init() is called. You can
1591 * not set core_limit after mtcp_init()
1592 */
1593 // mtcp_getconf(&mcfg);
1594 // mcfg.num_cores = cpus;
1595 // mtcp_setconf(&mcfg);
1596 /* initialize the mtcp context */
1597 if (mtcp_init("mos.conf")) {
1598 fprintf(stderr, "Failed to initialize mtcp\n");
1599 goto clean_up;
1600 }
1601
1602 mtcp_getconf(&mcfg);
1603 mcfg.max_concurrency = mcfg.max_num_buffers = srv_states[0]->max_conns;
1604 mcfg.num_cores = cpus;
1605 mtcp_setconf(&mcfg);
1606
1607 /* register SIGINT signal handler */
1608 mtcp_register_signal(SIGINT, signal_handler);
1609 #endif
1610 /* now spawn the threads and initialize the underlying networking layer */
1611 for (i = 0; i < cpus; i++) {
1612 if (mcfg.cpu_mask & (1L << i)) {
1613 srv_states[i]->cpu = i;
1614 #if 0
1615 start_server((void *)srv_states[i]);
1616 #endif
1617 if (pthread_create(&srv_states[i]->running_thread, NULL,
1618 start_server, (void *)srv_states[i])) {
1619 goto clean_up;
1620 }
1621 }
1622 }
1623
1624 /*
1625 * ~~~ MTCP UPDATE ~~~
1626 * From this point onwards, the per-core `engine' running_thread does not execute
1627 * the following code.
1628 * The main thread, however, executes the remaining system-wide initialization logic
1629 * before it sleeps indefintely... (well... not quite... it waits till the threads
1630 * commit suicide)
1631 * ~~~ !MTCP UPDATE! ~~~
1632 */
1633 #else
1634 /* we need root-perms for port < 1024 */
1635 if (0 != network_init(srv)) {
1636 plugins_free(srv);
1637 server_free(srv);
1638
1639 return EXIT_FAILURE;
1640 }
1641 #endif /* !MULTI_THREADED */
1642
1643 if (i_am_root) {
1644 #ifdef HAVE_PWD_H
1645 /*
1646 * Change group before chroot, when we have access
1647 * to /etc/group
1648 * */
1649 if (NULL != grp) {
1650 setgid(grp->gr_gid);
1651 setgroups(0, NULL);
1652 if (srv->srvconf.username->used) {
1653 initgroups(srv->srvconf.username->ptr, grp->gr_gid);
1654 }
1655 }
1656 #endif
1657 #ifdef HAVE_CHROOT
1658 if (srv->srvconf.changeroot->used) {
1659 tzset();
1660
1661 if (-1 == chroot(srv->srvconf.changeroot->ptr)) {
1662 log_error_write(srv, __FILE__, __LINE__, "ss", "chroot failed: ", strerror(errno));
1663 return EXIT_FAILURE;
1664 }
1665 if (-1 == chdir("/")) {
1666 log_error_write(srv, __FILE__, __LINE__, "ss", "chdir failed: ", strerror(errno));
1667 return EXIT_FAILURE;
1668 }
1669 }
1670 #endif
1671 #ifdef HAVE_PWD_H
1672 /* drop root privs */
1673 if (NULL != pwd) {
1674 setuid(pwd->pw_uid);
1675 }
1676 #endif
1677 #if defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_DUMPABLE)
1678 /**
1679 * on IRIX 6.5.30 they have prctl() but no DUMPABLE
1680 */
1681 if (srv->srvconf.enable_cores) {
1682 prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
1683 }
1684 #endif
1685 }
1686
1687 #ifndef MULTI_THREADED
1688 /* set max-conns */
1689 set_max_conns(srv, 1);
1690 load_plugins(srv);
1691 #endif
1692
1693 #ifdef HAVE_FORK
1694 #ifndef MULTI_THREADED
1695 /* network is up, let's deamonize ourself */
1696 if (srv->srvconf.dont_daemonize == 0) daemonize();
1697 #endif
1698 #endif
1699
1700 srv->gid = getgid();
1701 srv->uid = getuid();
1702
1703 /* write pid file */
1704 if (pid_fd != -1) {
1705 buffer_copy_long(srv->tmp_buf, getpid());
1706 buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("\n"));
1707 write(pid_fd, srv->tmp_buf->ptr, srv->tmp_buf->used - 1);
1708 close(pid_fd);
1709 pid_fd = -1;
1710 }
1711
1712 #ifndef MULTI_THREADED
1713 /* Close stderr ASAP in the child process to make sure that nothing
1714 * is being written to that fd which may not be valid anymore. */
1715 if (-1 == log_error_open(srv)) {
1716 log_error_write(srv, __FILE__, __LINE__, "s", "Opening errorlog failed. Going down.");
1717
1718 plugins_free(srv);
1719 network_close(srv);
1720 server_free(srv);
1721 return EXIT_FAILURE;
1722 }
1723
1724 if (HANDLER_GO_ON != plugins_call_set_defaults(srv)) {
1725 log_error_write(srv, __FILE__, __LINE__, "s", "Configuration of plugins failed. Going down.");
1726
1727 plugins_free(srv);
1728 network_close(srv);
1729 server_free(srv);
1730
1731 return EXIT_FAILURE;
1732 }
1733 #endif
1734 /* dump unused config-keys */
1735 for (i = 0; i < srv->config_context->used; i++) {
1736 array *config = ((data_config *)srv->config_context->data[i])->value;
1737 size_t j;
1738
1739 for (j = 0; config && j < config->used; j++) {
1740 data_unset *du = config->data[j];
1741
1742 /* all var.* is known as user defined variable */
1743 if (strncmp(du->key->ptr, "var.", sizeof("var.") - 1) == 0) {
1744 continue;
1745 }
1746
1747 if (NULL == array_get_element(srv->config_touched, du->key->ptr)) {
1748 log_error_write(srv, __FILE__, __LINE__, "sbs",
1749 "WARNING: unknown config-key:",
1750 du->key,
1751 "(ignored)");
1752 }
1753 }
1754 }
1755
1756 if (srv->config_unsupported) {
1757 log_error_write(srv, __FILE__, __LINE__, "s",
1758 "Configuration contains unsupported keys. Going down.");
1759 }
1760
1761 if (srv->config_deprecated) {
1762 log_error_write(srv, __FILE__, __LINE__, "s",
1763 "Configuration contains deprecated keys. Going down.");
1764 }
1765
1766 if (srv->config_unsupported || srv->config_deprecated) {
1767 plugins_free(srv);
1768 network_close(srv);
1769 server_free(srv);
1770
1771 return EXIT_FAILURE;
1772 }
1773
1774 #ifdef HAVE_SIGACTION
1775 memset(&act, 0, sizeof(act));
1776 act.sa_handler = SIG_IGN;
1777 sigaction(SIGPIPE, &act, NULL);
1778 sigaction(SIGUSR1, &act, NULL);
1779 # if defined(SA_SIGINFO)
1780 act.sa_sigaction = sigaction_handler;
1781 sigemptyset(&act.sa_mask);
1782 act.sa_flags = SA_SIGINFO;
1783 # else
1784 act.sa_handler = signal_handler;
1785 sigemptyset(&act.sa_mask);
1786 act.sa_flags = 0;
1787 # endif
1788 #ifndef USE_MTCP
1789 sigaction(SIGINT, &act, NULL);
1790 #endif
1791 sigaction(SIGTERM, &act, NULL);
1792 sigaction(SIGHUP, &act, NULL);
1793 sigaction(SIGALRM, &act, NULL);
1794 sigaction(SIGCHLD, &act, NULL);
1795
1796 #elif defined(HAVE_SIGNAL)
1797 Control is not coming here
1798 /* ignore the SIGPIPE from sendfile() */
1799 signal(SIGPIPE, SIG_IGN);
1800 signal(SIGUSR1, SIG_IGN);
1801 signal(SIGALRM, signal_handler);
1802 signal(SIGTERM, signal_handler);
1803 signal(SIGHUP, signal_handler);
1804 signal(SIGCHLD, signal_handler);
1805 signal(SIGINT, signal_handler);
1806 #endif
1807
1808 #ifdef USE_ALARM
1809 signal(SIGALRM, signal_handler);
1810
1811 /* setup periodic timer (1 second) */
1812 if (setitimer(ITIMER_REAL, &interval, NULL)) {
1813 log_error_write(srv, __FILE__, __LINE__, "s", "setting timer failed");
1814 return EXIT_FAILURE;
1815 }
1816
1817 getitimer(ITIMER_REAL, &interval);
1818 #endif
1819
1820 #ifdef HAVE_FORK
1821 /* MTCP/MULTI_THREADED UPDATE: num_childs is always zero here. Ignoring this entire code snippet */
1822 /* start watcher and workers */
1823 num_childs = srv->srvconf.max_worker;
1824 if (num_childs > 0) {
1825 int child = 0;
1826 while (!child && !srv_shutdown && !graceful_shutdown) {
1827 if (num_childs > 0) {
1828 switch (fork()) {
1829 case -1:
1830 return EXIT_FAILURE;
1831 case 0:
1832 child = 1;
1833 break;
1834 default:
1835 num_childs--;
1836 break;
1837 }
1838 } else {
1839 int status;
1840
1841 if (-1 != wait(&status)) {
1842 /**
1843 * one of our workers went away
1844 */
1845 num_childs++;
1846 } else {
1847 switch (errno) {
1848 case EINTR:
1849 /**
1850 * if we receive a SIGHUP we have to close our logs ourself as we don't
1851 * have the mainloop who can help us here
1852 */
1853 if (handle_sig_hup) {
1854 handle_sig_hup = 0;
1855
1856 log_error_cycle(srv);
1857
1858 /**
1859 * forward to all procs in the process-group
1860 *
1861 * we also send it ourself
1862 */
1863 if (!forwarded_sig_hup) {
1864 forwarded_sig_hup = 1;
1865 kill(0, SIGHUP);
1866 }
1867 }
1868 break;
1869 default:
1870 break;
1871 }
1872 }
1873 }
1874 }
1875
1876 /**
1877 * for the parent this is the exit-point
1878 */
1879 if (!child) {
1880 /**
1881 * kill all children too
1882 */
1883 if (graceful_shutdown) {
1884 kill(0, SIGINT);
1885 } else if (srv_shutdown) {
1886 kill(0, SIGTERM);
1887 }
1888
1889 log_error_close(srv);
1890 network_close(srv);
1891 connections_free(srv);
1892 plugins_free(srv);
1893 server_free(srv);
1894 return EXIT_SUCCESS;
1895 }
1896 }
1897 #endif /* !HAVE_FORK */
1898
1899 #ifndef MULTI_THREADED
1900 initialize_fd_framework(srv);
1901
1902 /* libev backend overwrites our SIGCHLD handler and calls waitpid on SIGCHLD; we want our own SIGCHLD handling. */
1903 #ifdef HAVE_SIGACTION
1904 sigaction(SIGCHLD, &act, NULL);
1905 #elif defined(HAVE_SIGNAL)
1906 signal(SIGCHLD, signal_handler);
1907 #endif
1908
1909 /* This part of code is only executed in the single-process, single-threaded version (non-mtcp/non-multithreaded) */
1910 /* Under USE_MTCP settings, each individual `running_thread' executes the `main-loop' */
1911 /* main-loop */
1912 while (!srv_shutdown) {
1913 int n;
1914 size_t ndx;
1915 time_t min_ts;
1916
1917 if (handle_sig_hup) {
1918 handler_t r;
1919
1920 /* reset notification */
1921 handle_sig_hup = 0;
1922
1923
1924 /* cycle logfiles */
1925
1926 switch(r = plugins_call_handle_sighup(srv)) {
1927 case HANDLER_GO_ON:
1928 break;
1929 default:
1930 log_error_write(srv, __FILE__, __LINE__, "sd", "sighup-handler return with an error", r);
1931 break;
1932 }
1933
1934 if (-1 == log_error_cycle(srv)) {
1935 log_error_write(srv, __FILE__, __LINE__, "s", "cycling errorlog failed, dying");
1936
1937 return EXIT_FAILURE;
1938 } else {
1939 #ifdef HAVE_SIGACTION
1940 log_error_write(srv, __FILE__, __LINE__, "sdsd",
1941 "logfiles cycled UID =",
1942 last_sighup_info.si_uid,
1943 "PID =",
1944 last_sighup_info.si_pid);
1945 #else
1946 log_error_write(srv, __FILE__, __LINE__, "s",
1947 "logfiles cycled");
1948 #endif
1949 }
1950 }
1951
1952 if (handle_sig_alarm) {
1953 /* a new second */
1954
1955 #ifdef USE_ALARM
1956 /* reset notification */
1957 handle_sig_alarm = 0;
1958 #endif
1959
1960 /* get current time */
1961 min_ts = time(NULL);
1962
1963 if (min_ts != srv->cur_ts) {
1964 int cs = 0;
1965 connections *conns = srv->conns;
1966 handler_t r;
1967
1968 switch(r = plugins_call_handle_trigger(srv)) {
1969 case HANDLER_GO_ON:
1970 break;
1971 case HANDLER_ERROR:
1972 log_error_write(srv, __FILE__, __LINE__, "s", "one of the triggers failed");
1973 break;
1974 default:
1975 log_error_write(srv, __FILE__, __LINE__, "d", r);
1976 break;
1977 }
1978
1979 /* trigger waitpid */
1980 srv->cur_ts = min_ts;
1981
1982 /* cleanup stat-cache */
1983 stat_cache_trigger_cleanup(srv);
1984 /**
1985 * check all connections for timeouts
1986 *
1987 */
1988 for (ndx = 0; ndx < conns->used; ndx++) {
1989 int changed = 0;
1990 connection *con;
1991 int t_diff;
1992
1993 con = conns->ptr[ndx];
1994
1995 if (con->state == CON_STATE_READ ||
1996 con->state == CON_STATE_READ_POST) {
1997 if (con->request_count == 1) {
1998 if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) {
1999 /* time - out */
2000 #if 0
2001 log_error_write(srv, __FILE__, __LINE__, "sd",
2002 "connection closed - read-timeout:", con->fd);
2003 #endif
2004 connection_set_state(srv, con, CON_STATE_ERROR);
2005 changed = 1;
2006 }
2007 } else {
2008 if (srv->cur_ts - con->read_idle_ts > con->keep_alive_idle) {
2009 /* time - out */
2010 #if 0
2011 log_error_write(srv, __FILE__, __LINE__, "sd",
2012 "connection closed - read-timeout:", con->fd);
2013 #endif
2014 connection_set_state(srv, con, CON_STATE_ERROR);
2015 changed = 1;
2016 }
2017 }
2018 }
2019
2020 if ((con->state == CON_STATE_WRITE) &&
2021 (con->write_request_ts != 0)) {
2022 #if 0
2023 if (srv->cur_ts - con->write_request_ts > 60) {
2024 log_error_write(srv, __FILE__, __LINE__, "sdd",
2025 "connection closed - pre-write-request-timeout:", con->fd, srv->cur_ts - con->write_request_ts);
2026 }
2027 #endif
2028
2029 if (srv->cur_ts - con->write_request_ts > con->conf.max_write_idle) {
2030 /* time - out */
2031 if (con->conf.log_timeouts) {
2032 log_error_write(srv, __FILE__, __LINE__, "sbsosds",
2033 "NOTE: a request for",
2034 con->request.uri,
2035 "timed out after writing",
2036 con->bytes_written,
2037 "bytes. We waited",
2038 (int)con->conf.max_write_idle,
2039 "seconds. If this a problem increase server.max-write-idle");
2040 }
2041 connection_set_state(srv, con, CON_STATE_ERROR);
2042 changed = 1;
2043 }
2044 }
2045
2046 if (con->state == CON_STATE_CLOSE && (srv->cur_ts - con->close_timeout_ts > HTTP_LINGER_TIMEOUT)) {
2047 changed = 1;
2048 }
2049
2050 /* we don't like div by zero */
2051 if (0 == (t_diff = srv->cur_ts - con->connection_start)) t_diff = 1;
2052
2053 if (con->traffic_limit_reached &&
2054 (con->conf.kbytes_per_second == 0 ||
2055 ((con->bytes_written / t_diff) < con->conf.kbytes_per_second * 1024))) {
2056 /* enable connection again */
2057 con->traffic_limit_reached = 0;
2058
2059 changed = 1;
2060 }
2061
2062 if (changed) {
2063 connection_state_machine(srv, con);
2064 }
2065 con->bytes_written_cur_second = 0;
2066 *(con->conf.global_bytes_per_second_cnt_ptr) = 0;
2067
2068 #if 0
2069 if (cs == 0) {
2070 fprintf(stderr, "connection-state: ");
2071 cs = 1;
2072 }
2073
2074 fprintf(stderr, "c[%d,%d]: %s ",
2075 con->fd,
2076 con->fcgi.fd,
2077 connection_get_state(con->state));
2078 #endif
2079 }
2080
2081 if (cs == 1) fprintf(stderr, "\n");
2082 }
2083 }
2084
2085 if (srv->sockets_disabled) {
2086 /* our server sockets are disabled, why ? */
2087
2088 if ((srv->cur_fds + srv->want_fds < srv->max_fds * 8 / 10) && /* we have enough unused fds */
2089 (srv->conns->used <= srv->max_conns * 9 / 10) &&
2090 (0 == graceful_shutdown)) {
2091 for (i = 0; i < srv->srv_sockets.used; i++) {
2092 server_socket *srv_socket = srv->srv_sockets.ptr[i];
2093 fdevent_event_set(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
2094 }
2095
2096 log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets enabled again");
2097
2098 srv->sockets_disabled = 0;
2099 }
2100 } else {
2101 if ((srv->cur_fds + srv->want_fds > srv->max_fds * 9 / 10) || /* out of fds */
2102 (srv->conns->used >= srv->max_conns) || /* out of connections */
2103 (graceful_shutdown)) { /* graceful_shutdown */
2104
2105 /* disable server-fds */
2106
2107 for (i = 0; i < srv->srv_sockets.used; i++) {
2108 server_socket *srv_socket = srv->srv_sockets.ptr[i];
2109 fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
2110
2111 if (graceful_shutdown) {
2112 /* we don't want this socket anymore,
2113 *
2114 * closing it right away will make it possible for
2115 * the next lighttpd to take over (graceful restart)
2116 * */
2117
2118 fdevent_unregister(srv->ev, srv_socket->fd);
2119 close(srv_socket->fd);
2120 srv_socket->fd = -1;
2121
2122 /* network_close() will cleanup after us */
2123
2124 if (srv->srvconf.pid_file->used &&
2125 srv->srvconf.changeroot->used == 0) {
2126 if (0 != unlink(srv->srvconf.pid_file->ptr)) {
2127 if (errno != EACCES && errno != EPERM) {
2128 log_error_write(srv, __FILE__, __LINE__, "sbds",
2129 "unlink failed for:",
2130 srv->srvconf.pid_file,
2131 errno,
2132 strerror(errno));
2133 }
2134 }
2135 }
2136 }
2137 }
2138
2139 if (graceful_shutdown) {
2140 log_error_write(srv, __FILE__, __LINE__, "s", "[note] graceful shutdown started");
2141 } else if (srv->conns->used >= srv->max_conns) {
2142 log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, connection limit reached");
2143 } else {
2144 log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, out-of-fds");
2145 }
2146
2147 srv->sockets_disabled = 1;
2148 }
2149 }
2150
2151 if (graceful_shutdown && srv->conns->used == 0) {
2152 /* we are in graceful shutdown phase and all connections are closed
2153 * we are ready to terminate without harming anyone */
2154 srv_shutdown = 1;
2155 }
2156
2157 /* we still have some fds to share */
2158 if (srv->want_fds) {
2159 /* check the fdwaitqueue for waiting fds */
2160 int free_fds = srv->max_fds - srv->cur_fds - 16;
2161 connection *con;
2162
2163 for (; free_fds > 0 && NULL != (con = fdwaitqueue_unshift(srv, srv->fdwaitqueue)); free_fds--) {
2164 connection_state_machine(srv, con);
2165
2166 srv->want_fds--;
2167 }
2168 }
2169
2170 if ((n = fdevent_poll(srv->ev, 1000)) > 0) {
2171 /* n is the number of events */
2172 int revents;
2173 int fd_ndx;
2174 #if 0
2175 if (n > 0) {
2176 log_error_write(srv, __FILE__, __LINE__, "sd",
2177 "polls:", n);
2178 }
2179 #endif
2180 fd_ndx = -1;
2181 do {
2182 fdevent_handler handler;
2183 void *context;
2184 handler_t r;
2185 int fd;
2186
2187 fd_ndx = fdevent_event_next_fdndx (srv->ev, fd_ndx);
2188 if (-1 == fd_ndx) break; /* not all fdevent handlers know how many fds got an event */
2189
2190 revents = fdevent_event_get_revent (srv->ev, fd_ndx);
2191 fd = fdevent_event_get_fd (srv->ev, fd_ndx);
2192 handler = fdevent_get_handler(srv->ev, fd);
2193 context = fdevent_get_context(srv->ev, fd);
2194
2195 /* connection_handle_fdevent needs a joblist_append */
2196 #if 0
2197 log_error_write(srv, __FILE__, __LINE__, "sdd",
2198 "event for", fd, revents);
2199 #endif
2200 switch (r = (*handler)(srv, context, revents)) {
2201 case HANDLER_FINISHED:
2202 case HANDLER_GO_ON:
2203 case HANDLER_WAIT_FOR_EVENT:
2204 case HANDLER_WAIT_FOR_FD:
2205 break;
2206 case HANDLER_ERROR:
2207 /* should never happen */
2208 SEGFAULT();
2209 break;
2210 default:
2211 log_error_write(srv, __FILE__, __LINE__, "d", r);
2212 break;
2213 }
2214 } while (--n > 0);
2215 } else if (n < 0 && errno != EINTR) {
2216 log_error_write(srv, __FILE__, __LINE__, "ss",
2217 "fdevent_poll failed:",
2218 strerror(errno));
2219 }
2220
2221 for (ndx = 0; ndx < srv->joblist->used; ndx++) {
2222 connection *con = srv->joblist->ptr[ndx];
2223 handler_t r;
2224
2225 connection_state_machine(srv, con);
2226
2227 switch(r = plugins_call_handle_joblist(srv, con)) {
2228 case HANDLER_FINISHED:
2229 case HANDLER_GO_ON:
2230 break;
2231 default:
2232 log_error_write(srv, __FILE__, __LINE__, "d", r);
2233 break;
2234 }
2235
2236 con->in_joblist = 0;
2237 }
2238
2239 srv->joblist->used = 0;
2240 } /* end of `while (!srv_shutdown)` */
2241
2242 #if 0
2243 if (srv->srvconf.pid_file->used &&
2244 srv->srvconf.changeroot->used == 0 &&
2245 0 == graceful_shutdown) {
2246 if (0 != unlink(srv->srvconf.pid_file->ptr)) {
2247 if (errno != EACCES && errno != EPERM) {
2248 log_error_write(srv, __FILE__, __LINE__, "sbds",
2249 "unlink failed for:",
2250 srv->srvconf.pid_file,
2251 errno,
2252 strerror(errno));
2253 }
2254 }
2255 }
2256 #endif
2257 #ifdef HAVE_SIGACTION
2258 log_error_write(srv, __FILE__, __LINE__, "sdsd",
2259 "server stopped by UID =",
2260 last_sigterm_info.si_uid,
2261 "PID =",
2262 last_sigterm_info.si_pid);
2263 #else
2264 log_error_write(srv, __FILE__, __LINE__, "s",
2265 "server stopped");
2266 #endif
2267 #endif /* !MULTI_THREADED */
2268
2269 #ifdef MULTI_THREADED
2270 /* main thread waits... */
2271 for (i = 0; i < cpus; i++) {
2272 if (mcfg.cpu_mask & (1L << i))
2273 pthread_join(srv_states[i]->running_thread, NULL);
2274 }
2275 clean_up:
2276 #ifdef USE_MTCP
2277 /* destroy mtcp context */
2278 mtcp_destroy();
2279 #endif
2280 for (i = 0; i < cpus; i++) {
2281 srv = srv_states[i];
2282 #endif /* MULTI_THREADED */
2283 /* clean-up */
2284 log_error_close(srv);
2285 network_close(srv);
2286 connections_free(srv);
2287 plugins_free(srv);
2288 server_free(srv);
2289 #ifdef MULTI_THREADED
2290 }
2291 free(conf_file);
2292 free(srv_states);
2293 #endif /* !MULTI_THREADED */
2294 return EXIT_SUCCESS;
2295 }
2296 /*----------------------------------------------------------------------------*/
2297