Annotation of embedaddon/lighttpd/src/server.c, revision 1.1.1.2
1.1 misho 1: #include "server.h"
2: #include "buffer.h"
3: #include "network.h"
4: #include "log.h"
5: #include "keyvalue.h"
6: #include "response.h"
7: #include "request.h"
8: #include "chunk.h"
9: #include "http_chunk.h"
10: #include "fdevent.h"
11: #include "connections.h"
12: #include "stat_cache.h"
13: #include "plugin.h"
14: #include "joblist.h"
15: #include "network_backends.h"
16: #include "version.h"
17:
18: #include <sys/types.h>
19: #include <sys/time.h>
20: #include <sys/stat.h>
21:
22: #include <string.h>
23: #include <errno.h>
24: #include <fcntl.h>
25: #include <unistd.h>
26: #include <stdlib.h>
27: #include <time.h>
28: #include <signal.h>
29: #include <assert.h>
30: #include <locale.h>
31:
32: #include <stdio.h>
33:
34: #ifdef HAVE_GETOPT_H
35: # include <getopt.h>
36: #endif
37:
38: #ifdef HAVE_VALGRIND_VALGRIND_H
39: # include <valgrind/valgrind.h>
40: #endif
41:
42: #ifdef HAVE_SYS_WAIT_H
43: # include <sys/wait.h>
44: #endif
45:
46: #ifdef HAVE_PWD_H
47: # include <grp.h>
48: # include <pwd.h>
49: #endif
50:
51: #ifdef HAVE_SYS_RESOURCE_H
52: # include <sys/resource.h>
53: #endif
54:
55: #ifdef HAVE_SYS_PRCTL_H
56: # include <sys/prctl.h>
57: #endif
58:
59: #ifdef USE_OPENSSL
60: # include <openssl/err.h>
61: #endif
62:
63: #ifndef __sgi
64: /* IRIX doesn't like the alarm based time() optimization */
65: /* #define USE_ALARM */
66: #endif
67:
68: #ifdef HAVE_GETUID
69: # ifndef HAVE_ISSETUGID
70:
71: static int l_issetugid(void) {
72: return (geteuid() != getuid() || getegid() != getgid());
73: }
74:
75: # define issetugid l_issetugid
76: # endif
77: #endif
78:
79: static volatile sig_atomic_t srv_shutdown = 0;
80: static volatile sig_atomic_t graceful_shutdown = 0;
81: static volatile sig_atomic_t handle_sig_alarm = 1;
82: static volatile sig_atomic_t handle_sig_hup = 0;
83: static volatile sig_atomic_t forwarded_sig_hup = 0;
84:
85: #if defined(HAVE_SIGACTION) && defined(SA_SIGINFO)
86: static volatile siginfo_t last_sigterm_info;
87: static volatile siginfo_t last_sighup_info;
88:
89: static void sigaction_handler(int sig, siginfo_t *si, void *context) {
90: static siginfo_t empty_siginfo;
91: UNUSED(context);
92:
93: if (!si) si = &empty_siginfo;
94:
95: switch (sig) {
96: case SIGTERM:
97: srv_shutdown = 1;
98: last_sigterm_info = *si;
99: break;
100: case SIGINT:
101: if (graceful_shutdown) {
102: srv_shutdown = 1;
103: } else {
104: graceful_shutdown = 1;
105: }
106: last_sigterm_info = *si;
107:
108: break;
109: case SIGALRM:
110: handle_sig_alarm = 1;
111: break;
112: case SIGHUP:
113: /**
114: * we send the SIGHUP to all procs in the process-group
115: * this includes ourself
116: *
117: * make sure we only send it once and don't create a
118: * infinite loop
119: */
120: if (!forwarded_sig_hup) {
121: handle_sig_hup = 1;
122: last_sighup_info = *si;
123: } else {
124: forwarded_sig_hup = 0;
125: }
126: break;
127: case SIGCHLD:
128: break;
129: }
130: }
131: #elif defined(HAVE_SIGNAL) || defined(HAVE_SIGACTION)
132: static void signal_handler(int sig) {
133: switch (sig) {
134: case SIGTERM: srv_shutdown = 1; break;
135: case SIGINT:
136: if (graceful_shutdown) srv_shutdown = 1;
137: else graceful_shutdown = 1;
138:
139: break;
140: case SIGALRM: handle_sig_alarm = 1; break;
141: case SIGHUP: handle_sig_hup = 1; break;
142: case SIGCHLD: break;
143: }
144: }
145: #endif
146:
147: #ifdef HAVE_FORK
148: static void daemonize(void) {
149: #ifdef SIGTTOU
150: signal(SIGTTOU, SIG_IGN);
151: #endif
152: #ifdef SIGTTIN
153: signal(SIGTTIN, SIG_IGN);
154: #endif
155: #ifdef SIGTSTP
156: signal(SIGTSTP, SIG_IGN);
157: #endif
158: if (0 != fork()) exit(0);
159:
160: if (-1 == setsid()) exit(0);
161:
162: signal(SIGHUP, SIG_IGN);
163:
164: if (0 != fork()) exit(0);
165:
166: if (0 != chdir("/")) exit(0);
167: }
168: #endif
169:
170: static server *server_init(void) {
171: int i;
172: FILE *frandom = NULL;
173:
174: server *srv = calloc(1, sizeof(*srv));
1.1.1.2 ! misho 175: force_assert(srv);
1.1 misho 176: #define CLEAN(x) \
177: srv->x = buffer_init();
178:
179: CLEAN(response_header);
180: CLEAN(parse_full_path);
181: CLEAN(ts_debug_str);
182: CLEAN(ts_date_str);
183: CLEAN(errorlog_buf);
184: CLEAN(response_range);
185: CLEAN(tmp_buf);
186: srv->empty_string = buffer_init_string("");
187: CLEAN(cond_check_buf);
188:
189: CLEAN(srvconf.errorlog_file);
190: CLEAN(srvconf.breakagelog_file);
191: CLEAN(srvconf.groupname);
192: CLEAN(srvconf.username);
193: CLEAN(srvconf.changeroot);
194: CLEAN(srvconf.bindhost);
195: CLEAN(srvconf.event_handler);
196: CLEAN(srvconf.pid_file);
197:
198: CLEAN(tmp_chunk_len);
199: #undef CLEAN
200:
201: #define CLEAN(x) \
202: srv->x = array_init();
203:
204: CLEAN(config_context);
205: CLEAN(config_touched);
206: CLEAN(status);
207: #undef CLEAN
208:
209: for (i = 0; i < FILE_CACHE_MAX; i++) {
210: srv->mtime_cache[i].mtime = (time_t)-1;
211: srv->mtime_cache[i].str = buffer_init();
212: }
213:
214: if ((NULL != (frandom = fopen("/dev/urandom", "rb")) || NULL != (frandom = fopen("/dev/random", "rb")))
215: && 1 == fread(srv->entropy, sizeof(srv->entropy), 1, frandom)) {
216: unsigned int e;
217: memcpy(&e, srv->entropy, sizeof(e) < sizeof(srv->entropy) ? sizeof(e) : sizeof(srv->entropy));
218: srand(e);
219: srv->is_real_entropy = 1;
220: } else {
221: unsigned int j;
222: srand(time(NULL) ^ getpid());
223: srv->is_real_entropy = 0;
224: for (j = 0; j < sizeof(srv->entropy); j++)
225: srv->entropy[j] = rand();
226: }
227: if (frandom) fclose(frandom);
228:
229: srv->cur_ts = time(NULL);
230: srv->startup_ts = srv->cur_ts;
231:
232: srv->conns = calloc(1, sizeof(*srv->conns));
1.1.1.2 ! misho 233: force_assert(srv->conns);
1.1 misho 234:
235: srv->joblist = calloc(1, sizeof(*srv->joblist));
1.1.1.2 ! misho 236: force_assert(srv->joblist);
1.1 misho 237:
238: srv->fdwaitqueue = calloc(1, sizeof(*srv->fdwaitqueue));
1.1.1.2 ! misho 239: force_assert(srv->fdwaitqueue);
1.1 misho 240:
241: srv->srvconf.modules = array_init();
242: srv->srvconf.modules_dir = buffer_init_string(LIBRARY_DIR);
243: srv->srvconf.network_backend = buffer_init();
244: srv->srvconf.upload_tempdirs = array_init();
245: srv->srvconf.reject_expect_100_with_417 = 1;
246:
247: /* use syslog */
248: srv->errorlog_fd = STDERR_FILENO;
249: srv->errorlog_mode = ERRORLOG_FD;
250:
251: srv->split_vals = array_init();
252:
253: return srv;
254: }
255:
256: static void server_free(server *srv) {
257: size_t i;
258:
259: for (i = 0; i < FILE_CACHE_MAX; i++) {
260: buffer_free(srv->mtime_cache[i].str);
261: }
262:
263: #define CLEAN(x) \
264: buffer_free(srv->x);
265:
266: CLEAN(response_header);
267: CLEAN(parse_full_path);
268: CLEAN(ts_debug_str);
269: CLEAN(ts_date_str);
270: CLEAN(errorlog_buf);
271: CLEAN(response_range);
272: CLEAN(tmp_buf);
273: CLEAN(empty_string);
274: CLEAN(cond_check_buf);
275:
276: CLEAN(srvconf.errorlog_file);
277: CLEAN(srvconf.breakagelog_file);
278: CLEAN(srvconf.groupname);
279: CLEAN(srvconf.username);
280: CLEAN(srvconf.changeroot);
281: CLEAN(srvconf.bindhost);
282: CLEAN(srvconf.event_handler);
283: CLEAN(srvconf.pid_file);
284: CLEAN(srvconf.modules_dir);
285: CLEAN(srvconf.network_backend);
286:
287: CLEAN(tmp_chunk_len);
288: #undef CLEAN
289:
290: #if 0
291: fdevent_unregister(srv->ev, srv->fd);
292: #endif
293: fdevent_free(srv->ev);
294:
295: free(srv->conns);
296:
297: if (srv->config_storage) {
298: for (i = 0; i < srv->config_context->used; i++) {
299: specific_config *s = srv->config_storage[i];
300:
301: if (!s) continue;
302:
303: buffer_free(s->document_root);
304: buffer_free(s->server_name);
305: buffer_free(s->server_tag);
306: buffer_free(s->ssl_pemfile);
307: buffer_free(s->ssl_ca_file);
308: buffer_free(s->ssl_cipher_list);
309: buffer_free(s->ssl_dh_file);
310: buffer_free(s->ssl_ec_curve);
311: buffer_free(s->error_handler);
312: buffer_free(s->errorfile_prefix);
313: array_free(s->mimetypes);
314: buffer_free(s->ssl_verifyclient_username);
315: #ifdef USE_OPENSSL
316: SSL_CTX_free(s->ssl_ctx);
1.1.1.2 ! misho 317: EVP_PKEY_free(s->ssl_pemfile_pkey);
! 318: X509_free(s->ssl_pemfile_x509);
! 319: if (NULL != s->ssl_ca_file_cert_names) sk_X509_NAME_pop_free(s->ssl_ca_file_cert_names, X509_NAME_free);
1.1 misho 320: #endif
321: free(s);
322: }
323: free(srv->config_storage);
324: srv->config_storage = NULL;
325: }
326:
327: #define CLEAN(x) \
328: array_free(srv->x);
329:
330: CLEAN(config_context);
331: CLEAN(config_touched);
332: CLEAN(status);
333: CLEAN(srvconf.upload_tempdirs);
334: #undef CLEAN
335:
336: joblist_free(srv, srv->joblist);
337: fdwaitqueue_free(srv, srv->fdwaitqueue);
338:
339: if (srv->stat_cache) {
340: stat_cache_free(srv->stat_cache);
341: }
342:
343: array_free(srv->srvconf.modules);
344: array_free(srv->split_vals);
345:
346: #ifdef USE_OPENSSL
347: if (srv->ssl_is_init) {
348: CRYPTO_cleanup_all_ex_data();
349: ERR_free_strings();
350: ERR_remove_state(0);
351: EVP_cleanup();
352: }
353: #endif
354:
355: free(srv);
356: }
357:
358: static void show_version (void) {
359: #ifdef USE_OPENSSL
360: # define TEXT_SSL " (ssl)"
361: #else
362: # define TEXT_SSL
363: #endif
364: char *b = PACKAGE_DESC TEXT_SSL \
365: " - a light and fast webserver\n" \
366: "Build-Date: " __DATE__ " " __TIME__ "\n";
367: ;
368: #undef TEXT_SSL
369: write(STDOUT_FILENO, b, strlen(b));
370: }
371:
372: static void show_features (void) {
373: const char features[] = ""
374: #ifdef USE_SELECT
375: "\t+ select (generic)\n"
376: #else
377: "\t- select (generic)\n"
378: #endif
379: #ifdef USE_POLL
380: "\t+ poll (Unix)\n"
381: #else
382: "\t- poll (Unix)\n"
383: #endif
384: #ifdef USE_LINUX_SIGIO
385: "\t+ rt-signals (Linux 2.4+)\n"
386: #else
387: "\t- rt-signals (Linux 2.4+)\n"
388: #endif
389: #ifdef USE_LINUX_EPOLL
390: "\t+ epoll (Linux 2.6)\n"
391: #else
392: "\t- epoll (Linux 2.6)\n"
393: #endif
394: #ifdef USE_SOLARIS_DEVPOLL
395: "\t+ /dev/poll (Solaris)\n"
396: #else
397: "\t- /dev/poll (Solaris)\n"
398: #endif
399: #ifdef USE_SOLARIS_PORT
400: "\t+ eventports (Solaris)\n"
401: #else
402: "\t- eventports (Solaris)\n"
403: #endif
404: #ifdef USE_FREEBSD_KQUEUE
405: "\t+ kqueue (FreeBSD)\n"
406: #else
407: "\t- kqueue (FreeBSD)\n"
408: #endif
409: #ifdef USE_LIBEV
410: "\t+ libev (generic)\n"
411: #else
412: "\t- libev (generic)\n"
413: #endif
414: "\nNetwork handler:\n\n"
415: #if defined USE_LINUX_SENDFILE
416: "\t+ linux-sendfile\n"
417: #else
418: "\t- linux-sendfile\n"
419: #endif
420: #if defined USE_FREEBSD_SENDFILE
421: "\t+ freebsd-sendfile\n"
422: #else
423: "\t- freebsd-sendfile\n"
424: #endif
425: #if defined USE_SOLARIS_SENDFILEV
426: "\t+ solaris-sendfilev\n"
427: #else
428: "\t- solaris-sendfilev\n"
429: #endif
430: #if defined USE_WRITEV
431: "\t+ writev\n"
432: #else
433: "\t- writev\n"
434: #endif
435: "\t+ write\n"
436: #ifdef USE_MMAP
437: "\t+ mmap support\n"
438: #else
439: "\t- mmap support\n"
440: #endif
441: "\nFeatures:\n\n"
442: #ifdef HAVE_IPV6
443: "\t+ IPv6 support\n"
444: #else
445: "\t- IPv6 support\n"
446: #endif
447: #if defined HAVE_ZLIB_H && defined HAVE_LIBZ
448: "\t+ zlib support\n"
449: #else
450: "\t- zlib support\n"
451: #endif
452: #if defined HAVE_BZLIB_H && defined HAVE_LIBBZ2
453: "\t+ bzip2 support\n"
454: #else
455: "\t- bzip2 support\n"
456: #endif
457: #ifdef HAVE_LIBCRYPT
458: "\t+ crypt support\n"
459: #else
460: "\t- crypt support\n"
461: #endif
462: #ifdef USE_OPENSSL
463: "\t+ SSL Support\n"
464: #else
465: "\t- SSL Support\n"
466: #endif
467: #ifdef HAVE_LIBPCRE
468: "\t+ PCRE support\n"
469: #else
470: "\t- PCRE support\n"
471: #endif
472: #ifdef HAVE_MYSQL
473: "\t+ mySQL support\n"
474: #else
475: "\t- mySQL support\n"
476: #endif
477: #if defined(HAVE_LDAP_H) && defined(HAVE_LBER_H) && defined(HAVE_LIBLDAP) && defined(HAVE_LIBLBER)
478: "\t+ LDAP support\n"
479: #else
480: "\t- LDAP support\n"
481: #endif
482: #ifdef HAVE_MEMCACHE_H
483: "\t+ memcached support\n"
484: #else
485: "\t- memcached support\n"
486: #endif
487: #ifdef HAVE_FAM_H
488: "\t+ FAM support\n"
489: #else
490: "\t- FAM support\n"
491: #endif
492: #ifdef HAVE_LUA_H
493: "\t+ LUA support\n"
494: #else
495: "\t- LUA support\n"
496: #endif
497: #ifdef HAVE_LIBXML_H
498: "\t+ xml support\n"
499: #else
500: "\t- xml support\n"
501: #endif
502: #ifdef HAVE_SQLITE3_H
503: "\t+ SQLite support\n"
504: #else
505: "\t- SQLite support\n"
506: #endif
507: #ifdef HAVE_GDBM_H
508: "\t+ GDBM support\n"
509: #else
510: "\t- GDBM support\n"
511: #endif
512: "\n";
513: show_version();
514: printf("\nEvent Handlers:\n\n%s", features);
515: }
516:
517: static void show_help (void) {
518: #ifdef USE_OPENSSL
519: # define TEXT_SSL " (ssl)"
520: #else
521: # define TEXT_SSL
522: #endif
523: char *b = PACKAGE_DESC TEXT_SSL " ("__DATE__ " " __TIME__ ")" \
524: " - a light and fast webserver\n" \
525: "usage:\n" \
526: " -f <name> filename of the config-file\n" \
527: " -m <name> module directory (default: "LIBRARY_DIR")\n" \
528: " -p print the parsed config-file in internal form, and exit\n" \
529: " -t test the config-file, and exit\n" \
530: " -D don't go to background (default: go to background)\n" \
531: " -v show version\n" \
532: " -V show compile-time features\n" \
533: " -h show this help\n" \
534: "\n"
535: ;
536: #undef TEXT_SSL
537: #undef TEXT_IPV6
538: write(STDOUT_FILENO, b, strlen(b));
539: }
540:
541: int main (int argc, char **argv) {
542: server *srv = NULL;
543: int print_config = 0;
544: int test_config = 0;
545: int i_am_root;
546: int o;
547: int num_childs = 0;
548: int pid_fd = -1, fd;
549: size_t i;
550: #ifdef HAVE_SIGACTION
551: struct sigaction act;
552: #endif
553: #ifdef HAVE_GETRLIMIT
554: struct rlimit rlim;
555: #endif
556:
557: #ifdef USE_ALARM
558: struct itimerval interval;
559:
560: interval.it_interval.tv_sec = 1;
561: interval.it_interval.tv_usec = 0;
562: interval.it_value.tv_sec = 1;
563: interval.it_value.tv_usec = 0;
564: #endif
565:
566:
567: /* for nice %b handling in strfime() */
568: setlocale(LC_TIME, "C");
569:
570: if (NULL == (srv = server_init())) {
571: fprintf(stderr, "did this really happen?\n");
572: return -1;
573: }
574:
575: /* init structs done */
576:
577: srv->srvconf.port = 0;
578: #ifdef HAVE_GETUID
579: i_am_root = (getuid() == 0);
580: #else
581: i_am_root = 0;
582: #endif
583: srv->srvconf.dont_daemonize = 0;
584:
585: while(-1 != (o = getopt(argc, argv, "f:m:hvVDpt"))) {
586: switch(o) {
587: case 'f':
588: if (srv->config_storage) {
589: log_error_write(srv, __FILE__, __LINE__, "s",
590: "Can only read one config file. Use the include command to use multiple config files.");
591:
592: server_free(srv);
593: return -1;
594: }
595: if (config_read(srv, optarg)) {
596: server_free(srv);
597: return -1;
598: }
599: break;
600: case 'm':
601: buffer_copy_string(srv->srvconf.modules_dir, optarg);
602: break;
603: case 'p': print_config = 1; break;
604: case 't': test_config = 1; break;
605: case 'D': srv->srvconf.dont_daemonize = 1; break;
606: case 'v': show_version(); return 0;
607: case 'V': show_features(); return 0;
608: case 'h': show_help(); return 0;
609: default:
610: show_help();
611: server_free(srv);
612: return -1;
613: }
614: }
615:
616: if (!srv->config_storage) {
617: log_error_write(srv, __FILE__, __LINE__, "s",
618: "No configuration available. Try using -f option.");
619:
620: server_free(srv);
621: return -1;
622: }
623:
624: if (print_config) {
625: data_unset *dc = srv->config_context->data[0];
626: if (dc) {
627: dc->print(dc, 0);
628: fprintf(stdout, "\n");
629: } else {
630: /* shouldn't happend */
631: fprintf(stderr, "global config not found\n");
632: }
633: }
634:
635: if (test_config) {
636: printf("Syntax OK\n");
637: }
638:
639: if (test_config || print_config) {
640: server_free(srv);
641: return 0;
642: }
643:
644: /* close stdin and stdout, as they are not needed */
645: openDevNull(STDIN_FILENO);
646: openDevNull(STDOUT_FILENO);
647:
648: if (0 != config_set_defaults(srv)) {
649: log_error_write(srv, __FILE__, __LINE__, "s",
650: "setting default values failed");
651: server_free(srv);
652: return -1;
653: }
654:
655: /* UID handling */
656: #ifdef HAVE_GETUID
657: if (!i_am_root && issetugid()) {
658: /* we are setuid-root */
659:
660: log_error_write(srv, __FILE__, __LINE__, "s",
661: "Are you nuts ? Don't apply a SUID bit to this binary");
662:
663: server_free(srv);
664: return -1;
665: }
666: #endif
667:
668: /* check document-root */
669: if (srv->config_storage[0]->document_root->used <= 1) {
670: log_error_write(srv, __FILE__, __LINE__, "s",
671: "document-root is not set\n");
672:
673: server_free(srv);
674:
675: return -1;
676: }
677:
678: if (plugins_load(srv)) {
679: log_error_write(srv, __FILE__, __LINE__, "s",
680: "loading plugins finally failed");
681:
682: plugins_free(srv);
683: server_free(srv);
684:
685: return -1;
686: }
687:
688: /* open pid file BEFORE chroot */
689: if (srv->srvconf.pid_file->used) {
690: 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))) {
691: struct stat st;
692: if (errno != EEXIST) {
693: log_error_write(srv, __FILE__, __LINE__, "sbs",
694: "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
695: return -1;
696: }
697:
698: if (0 != stat(srv->srvconf.pid_file->ptr, &st)) {
699: log_error_write(srv, __FILE__, __LINE__, "sbs",
700: "stating existing pid-file failed:", srv->srvconf.pid_file, strerror(errno));
701: }
702:
703: if (!S_ISREG(st.st_mode)) {
704: log_error_write(srv, __FILE__, __LINE__, "sb",
705: "pid-file exists and isn't regular file:", srv->srvconf.pid_file);
706: return -1;
707: }
708:
709: if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
710: log_error_write(srv, __FILE__, __LINE__, "sbs",
711: "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
712: return -1;
713: }
714: }
715: }
716:
717: if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
718: /* select limits itself
719: *
720: * as it is a hard limit and will lead to a segfault we add some safety
721: * */
722: srv->max_fds = FD_SETSIZE - 200;
723: } else {
724: srv->max_fds = 4096;
725: }
726:
727: if (i_am_root) {
728: struct group *grp = NULL;
729: struct passwd *pwd = NULL;
730: int use_rlimit = 1;
731:
732: #ifdef HAVE_VALGRIND_VALGRIND_H
733: if (RUNNING_ON_VALGRIND) use_rlimit = 0;
734: #endif
735:
736: #ifdef HAVE_GETRLIMIT
737: if (0 != getrlimit(RLIMIT_NOFILE, &rlim)) {
738: log_error_write(srv, __FILE__, __LINE__,
739: "ss", "couldn't get 'max filedescriptors'",
740: strerror(errno));
741: return -1;
742: }
743:
744: if (use_rlimit && srv->srvconf.max_fds) {
745: /* set rlimits */
746:
747: rlim.rlim_cur = srv->srvconf.max_fds;
748: rlim.rlim_max = srv->srvconf.max_fds;
749:
750: if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
751: log_error_write(srv, __FILE__, __LINE__,
752: "ss", "couldn't set 'max filedescriptors'",
753: strerror(errno));
754: return -1;
755: }
756: }
757:
758: if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
759: srv->max_fds = rlim.rlim_cur < ((int)FD_SETSIZE) - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
760: } else {
761: srv->max_fds = rlim.rlim_cur;
762: }
763:
764: /* set core file rlimit, if enable_cores is set */
765: if (use_rlimit && srv->srvconf.enable_cores && getrlimit(RLIMIT_CORE, &rlim) == 0) {
766: rlim.rlim_cur = rlim.rlim_max;
767: setrlimit(RLIMIT_CORE, &rlim);
768: }
769: #endif
770: if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
771: /* don't raise the limit above FD_SET_SIZE */
772: if (srv->max_fds > ((int)FD_SETSIZE) - 200) {
773: log_error_write(srv, __FILE__, __LINE__, "sd",
774: "can't raise max filedescriptors above", FD_SETSIZE - 200,
775: "if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
776: return -1;
777: }
778: }
779:
780:
781: #ifdef HAVE_PWD_H
782: /* set user and group */
783: if (srv->srvconf.username->used) {
784: if (NULL == (pwd = getpwnam(srv->srvconf.username->ptr))) {
785: log_error_write(srv, __FILE__, __LINE__, "sb",
786: "can't find username", srv->srvconf.username);
787: return -1;
788: }
789:
790: if (pwd->pw_uid == 0) {
791: log_error_write(srv, __FILE__, __LINE__, "s",
792: "I will not set uid to 0\n");
793: return -1;
794: }
795: }
796:
797: if (srv->srvconf.groupname->used) {
798: if (NULL == (grp = getgrnam(srv->srvconf.groupname->ptr))) {
799: log_error_write(srv, __FILE__, __LINE__, "sb",
800: "can't find groupname", srv->srvconf.groupname);
801: return -1;
802: }
803: if (grp->gr_gid == 0) {
804: log_error_write(srv, __FILE__, __LINE__, "s",
805: "I will not set gid to 0\n");
806: return -1;
807: }
808: }
809: #endif
810: /* we need root-perms for port < 1024 */
811: if (0 != network_init(srv)) {
812: plugins_free(srv);
813: server_free(srv);
814:
815: return -1;
816: }
817: #ifdef HAVE_PWD_H
818: /*
819: * Change group before chroot, when we have access
820: * to /etc/group
821: * */
822: if (NULL != grp) {
1.1.1.2 ! misho 823: if (-1 == setgid(grp->gr_gid)) {
! 824: log_error_write(srv, __FILE__, __LINE__, "ss", "setgid failed: ", strerror(errno));
! 825: return -1;
! 826: }
! 827: if (-1 == setgroups(0, NULL)) {
! 828: log_error_write(srv, __FILE__, __LINE__, "ss", "setgroups failed: ", strerror(errno));
! 829: return -1;
! 830: }
1.1 misho 831: if (srv->srvconf.username->used) {
832: initgroups(srv->srvconf.username->ptr, grp->gr_gid);
833: }
834: }
835: #endif
836: #ifdef HAVE_CHROOT
837: if (srv->srvconf.changeroot->used) {
838: tzset();
839:
840: if (-1 == chroot(srv->srvconf.changeroot->ptr)) {
841: log_error_write(srv, __FILE__, __LINE__, "ss", "chroot failed: ", strerror(errno));
842: return -1;
843: }
844: if (-1 == chdir("/")) {
845: log_error_write(srv, __FILE__, __LINE__, "ss", "chdir failed: ", strerror(errno));
846: return -1;
847: }
848: }
849: #endif
850: #ifdef HAVE_PWD_H
851: /* drop root privs */
852: if (NULL != pwd) {
1.1.1.2 ! misho 853: if (-1 == setuid(pwd->pw_uid)) {
! 854: log_error_write(srv, __FILE__, __LINE__, "ss", "setuid failed: ", strerror(errno));
! 855: return -1;
! 856: }
1.1 misho 857: }
858: #endif
859: #if defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_DUMPABLE)
860: /**
861: * on IRIX 6.5.30 they have prctl() but no DUMPABLE
862: */
863: if (srv->srvconf.enable_cores) {
864: prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
865: }
866: #endif
867: } else {
868:
869: #ifdef HAVE_GETRLIMIT
870: if (0 != getrlimit(RLIMIT_NOFILE, &rlim)) {
871: log_error_write(srv, __FILE__, __LINE__,
872: "ss", "couldn't get 'max filedescriptors'",
873: strerror(errno));
874: return -1;
875: }
876:
877: /**
878: * we are not root can can't increase the fd-limit, but we can reduce it
879: */
880: if (srv->srvconf.max_fds && srv->srvconf.max_fds < rlim.rlim_cur) {
881: /* set rlimits */
882:
883: rlim.rlim_cur = srv->srvconf.max_fds;
884:
885: if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
886: log_error_write(srv, __FILE__, __LINE__,
887: "ss", "couldn't set 'max filedescriptors'",
888: strerror(errno));
889: return -1;
890: }
891: }
892:
893: if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
894: srv->max_fds = rlim.rlim_cur < ((int)FD_SETSIZE) - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
895: } else {
896: srv->max_fds = rlim.rlim_cur;
897: }
898:
899: /* set core file rlimit, if enable_cores is set */
900: if (srv->srvconf.enable_cores && getrlimit(RLIMIT_CORE, &rlim) == 0) {
901: rlim.rlim_cur = rlim.rlim_max;
902: setrlimit(RLIMIT_CORE, &rlim);
903: }
904:
905: #endif
906: if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
907: /* don't raise the limit above FD_SET_SIZE */
908: if (srv->max_fds > ((int)FD_SETSIZE) - 200) {
909: log_error_write(srv, __FILE__, __LINE__, "sd",
910: "can't raise max filedescriptors above", FD_SETSIZE - 200,
911: "if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
912: return -1;
913: }
914: }
915:
916: if (0 != network_init(srv)) {
917: plugins_free(srv);
918: server_free(srv);
919:
920: return -1;
921: }
922: }
923:
924: /* set max-conns */
925: if (srv->srvconf.max_conns > srv->max_fds/2) {
926: /* we can't have more connections than max-fds/2 */
927: log_error_write(srv, __FILE__, __LINE__, "sdd", "can't have more connections than fds/2: ", srv->srvconf.max_conns, srv->max_fds);
928: srv->max_conns = srv->max_fds/2;
929: } else if (srv->srvconf.max_conns) {
930: /* otherwise respect the wishes of the user */
931: srv->max_conns = srv->srvconf.max_conns;
932: } else {
933: /* or use the default: we really don't want to hit max-fds */
934: srv->max_conns = srv->max_fds/3;
935: }
936:
937: if (HANDLER_GO_ON != plugins_call_init(srv)) {
938: log_error_write(srv, __FILE__, __LINE__, "s", "Initialization of plugins failed. Going down.");
939:
940: plugins_free(srv);
941: network_close(srv);
942: server_free(srv);
943:
944: return -1;
945: }
946:
947: #ifdef HAVE_FORK
948: /* network is up, let's deamonize ourself */
949: if (srv->srvconf.dont_daemonize == 0) daemonize();
950: #endif
951:
952:
953: #ifdef HAVE_SIGACTION
954: memset(&act, 0, sizeof(act));
955: act.sa_handler = SIG_IGN;
956: sigaction(SIGPIPE, &act, NULL);
957: sigaction(SIGUSR1, &act, NULL);
958: # if defined(SA_SIGINFO)
959: act.sa_sigaction = sigaction_handler;
960: sigemptyset(&act.sa_mask);
961: act.sa_flags = SA_SIGINFO;
962: # else
963: act.sa_handler = signal_handler;
964: sigemptyset(&act.sa_mask);
965: act.sa_flags = 0;
966: # endif
967: sigaction(SIGINT, &act, NULL);
968: sigaction(SIGTERM, &act, NULL);
969: sigaction(SIGHUP, &act, NULL);
970: sigaction(SIGALRM, &act, NULL);
971: sigaction(SIGCHLD, &act, NULL);
972:
973: #elif defined(HAVE_SIGNAL)
974: /* ignore the SIGPIPE from sendfile() */
975: signal(SIGPIPE, SIG_IGN);
976: signal(SIGUSR1, SIG_IGN);
977: signal(SIGALRM, signal_handler);
978: signal(SIGTERM, signal_handler);
979: signal(SIGHUP, signal_handler);
980: signal(SIGCHLD, signal_handler);
981: signal(SIGINT, signal_handler);
982: #endif
983:
984: #ifdef USE_ALARM
985: signal(SIGALRM, signal_handler);
986:
987: /* setup periodic timer (1 second) */
988: if (setitimer(ITIMER_REAL, &interval, NULL)) {
989: log_error_write(srv, __FILE__, __LINE__, "s", "setting timer failed");
990: return -1;
991: }
992:
993: getitimer(ITIMER_REAL, &interval);
994: #endif
995:
996:
997: srv->gid = getgid();
998: srv->uid = getuid();
999:
1000: /* write pid file */
1001: if (pid_fd != -1) {
1002: buffer_copy_long(srv->tmp_buf, getpid());
1003: buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("\n"));
1.1.1.2 ! misho 1004: force_assert(srv->tmp_buf->used > 0);
1.1 misho 1005: write(pid_fd, srv->tmp_buf->ptr, srv->tmp_buf->used - 1);
1006: close(pid_fd);
1007: pid_fd = -1;
1008: }
1009:
1010: /* Close stderr ASAP in the child process to make sure that nothing
1011: * is being written to that fd which may not be valid anymore. */
1012: if (-1 == log_error_open(srv)) {
1013: log_error_write(srv, __FILE__, __LINE__, "s", "Opening errorlog failed. Going down.");
1014:
1015: plugins_free(srv);
1016: network_close(srv);
1017: server_free(srv);
1018: return -1;
1019: }
1020:
1021: if (HANDLER_GO_ON != plugins_call_set_defaults(srv)) {
1022: log_error_write(srv, __FILE__, __LINE__, "s", "Configuration of plugins failed. Going down.");
1023:
1024: plugins_free(srv);
1025: network_close(srv);
1026: server_free(srv);
1027:
1028: return -1;
1029: }
1030:
1031: /* dump unused config-keys */
1032: for (i = 0; i < srv->config_context->used; i++) {
1033: array *config = ((data_config *)srv->config_context->data[i])->value;
1034: size_t j;
1035:
1036: for (j = 0; config && j < config->used; j++) {
1037: data_unset *du = config->data[j];
1038:
1039: /* all var.* is known as user defined variable */
1040: if (strncmp(du->key->ptr, "var.", sizeof("var.") - 1) == 0) {
1041: continue;
1042: }
1043:
1044: if (NULL == array_get_element(srv->config_touched, du->key->ptr)) {
1045: log_error_write(srv, __FILE__, __LINE__, "sbs",
1046: "WARNING: unknown config-key:",
1047: du->key,
1048: "(ignored)");
1049: }
1050: }
1051: }
1052:
1053: if (srv->config_unsupported) {
1054: log_error_write(srv, __FILE__, __LINE__, "s",
1055: "Configuration contains unsupported keys. Going down.");
1056: }
1057:
1058: if (srv->config_deprecated) {
1059: log_error_write(srv, __FILE__, __LINE__, "s",
1060: "Configuration contains deprecated keys. Going down.");
1061: }
1062:
1063: if (srv->config_unsupported || srv->config_deprecated) {
1064: plugins_free(srv);
1065: network_close(srv);
1066: server_free(srv);
1067:
1068: return -1;
1069: }
1070:
1071:
1072: #ifdef HAVE_FORK
1073: /* start watcher and workers */
1074: num_childs = srv->srvconf.max_worker;
1075: if (num_childs > 0) {
1076: int child = 0;
1077: while (!child && !srv_shutdown && !graceful_shutdown) {
1078: if (num_childs > 0) {
1079: switch (fork()) {
1080: case -1:
1081: return -1;
1082: case 0:
1083: child = 1;
1084: break;
1085: default:
1086: num_childs--;
1087: break;
1088: }
1089: } else {
1090: int status;
1091:
1092: if (-1 != wait(&status)) {
1093: /**
1094: * one of our workers went away
1095: */
1096: num_childs++;
1097: } else {
1098: switch (errno) {
1099: case EINTR:
1100: /**
1101: * if we receive a SIGHUP we have to close our logs ourself as we don't
1102: * have the mainloop who can help us here
1103: */
1104: if (handle_sig_hup) {
1105: handle_sig_hup = 0;
1106:
1107: log_error_cycle(srv);
1108:
1109: /**
1110: * forward to all procs in the process-group
1111: *
1112: * we also send it ourself
1113: */
1114: if (!forwarded_sig_hup) {
1115: forwarded_sig_hup = 1;
1116: kill(0, SIGHUP);
1117: }
1118: }
1119: break;
1120: default:
1121: break;
1122: }
1123: }
1124: }
1125: }
1126:
1127: /**
1128: * for the parent this is the exit-point
1129: */
1130: if (!child) {
1131: /**
1132: * kill all children too
1133: */
1134: if (graceful_shutdown) {
1135: kill(0, SIGINT);
1136: } else if (srv_shutdown) {
1137: kill(0, SIGTERM);
1138: }
1139:
1140: log_error_close(srv);
1141: network_close(srv);
1142: connections_free(srv);
1143: plugins_free(srv);
1144: server_free(srv);
1145: return 0;
1146: }
1147: }
1148: #endif
1149:
1150: if (NULL == (srv->ev = fdevent_init(srv, srv->max_fds + 1, srv->event_handler))) {
1151: log_error_write(srv, __FILE__, __LINE__,
1152: "s", "fdevent_init failed");
1153: return -1;
1154: }
1155:
1156: /* libev backend overwrites our SIGCHLD handler and calls waitpid on SIGCHLD; we want our own SIGCHLD handling. */
1157: #ifdef HAVE_SIGACTION
1158: sigaction(SIGCHLD, &act, NULL);
1159: #elif defined(HAVE_SIGNAL)
1160: signal(SIGCHLD, signal_handler);
1161: #endif
1162:
1163: /*
1164: * kqueue() is called here, select resets its internals,
1165: * all server sockets get their handlers
1166: *
1167: * */
1168: if (0 != network_register_fdevents(srv)) {
1169: plugins_free(srv);
1170: network_close(srv);
1171: server_free(srv);
1172:
1173: return -1;
1174: }
1175:
1176: /* might fail if user is using fam (not gamin) and famd isn't running */
1177: if (NULL == (srv->stat_cache = stat_cache_init())) {
1178: log_error_write(srv, __FILE__, __LINE__, "s",
1179: "stat-cache could not be setup, dieing.");
1180: return -1;
1181: }
1182:
1183: #ifdef HAVE_FAM_H
1184: /* setup FAM */
1185: if (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM) {
1.1.1.2 ! misho 1186: if (0 != FAMOpen2(&srv->stat_cache->fam, "lighttpd")) {
1.1 misho 1187: log_error_write(srv, __FILE__, __LINE__, "s",
1188: "could not open a fam connection, dieing.");
1189: return -1;
1190: }
1191: #ifdef HAVE_FAMNOEXISTS
1.1.1.2 ! misho 1192: FAMNoExists(&srv->stat_cache->fam);
1.1 misho 1193: #endif
1194:
1.1.1.2 ! misho 1195: fdevent_register(srv->ev, FAMCONNECTION_GETFD(&srv->stat_cache->fam), stat_cache_handle_fdevent, NULL);
! 1196: fdevent_event_set(srv->ev, &(srv->stat_cache->fam_fcce_ndx), FAMCONNECTION_GETFD(&srv->stat_cache->fam), FDEVENT_IN);
1.1 misho 1197: }
1198: #endif
1199:
1200:
1201: /* get the current number of FDs */
1202: srv->cur_fds = open("/dev/null", O_RDONLY);
1203: close(srv->cur_fds);
1204:
1205: for (i = 0; i < srv->srv_sockets.used; i++) {
1206: server_socket *srv_socket = srv->srv_sockets.ptr[i];
1207: if (-1 == fdevent_fcntl_set(srv->ev, srv_socket->fd)) {
1208: log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed:", strerror(errno));
1209: return -1;
1210: }
1211: }
1212:
1213: /* main-loop */
1214: while (!srv_shutdown) {
1215: int n;
1216: size_t ndx;
1217: time_t min_ts;
1218:
1219: if (handle_sig_hup) {
1220: handler_t r;
1221:
1222: /* reset notification */
1223: handle_sig_hup = 0;
1224:
1225:
1226: /* cycle logfiles */
1227:
1228: switch(r = plugins_call_handle_sighup(srv)) {
1229: case HANDLER_GO_ON:
1230: break;
1231: default:
1232: log_error_write(srv, __FILE__, __LINE__, "sd", "sighup-handler return with an error", r);
1233: break;
1234: }
1235:
1236: if (-1 == log_error_cycle(srv)) {
1237: log_error_write(srv, __FILE__, __LINE__, "s", "cycling errorlog failed, dying");
1238:
1239: return -1;
1240: } else {
1241: #ifdef HAVE_SIGACTION
1242: log_error_write(srv, __FILE__, __LINE__, "sdsd",
1243: "logfiles cycled UID =",
1244: last_sighup_info.si_uid,
1245: "PID =",
1246: last_sighup_info.si_pid);
1247: #else
1248: log_error_write(srv, __FILE__, __LINE__, "s",
1249: "logfiles cycled");
1250: #endif
1251: }
1252: }
1253:
1254: if (handle_sig_alarm) {
1255: /* a new second */
1256:
1257: #ifdef USE_ALARM
1258: /* reset notification */
1259: handle_sig_alarm = 0;
1260: #endif
1261:
1262: /* get current time */
1263: min_ts = time(NULL);
1264:
1265: if (min_ts != srv->cur_ts) {
1266: int cs = 0;
1267: connections *conns = srv->conns;
1268: handler_t r;
1269:
1270: switch(r = plugins_call_handle_trigger(srv)) {
1271: case HANDLER_GO_ON:
1272: break;
1273: case HANDLER_ERROR:
1274: log_error_write(srv, __FILE__, __LINE__, "s", "one of the triggers failed");
1275: break;
1276: default:
1277: log_error_write(srv, __FILE__, __LINE__, "d", r);
1278: break;
1279: }
1280:
1281: /* trigger waitpid */
1282: srv->cur_ts = min_ts;
1283:
1284: /* cleanup stat-cache */
1285: stat_cache_trigger_cleanup(srv);
1286: /**
1287: * check all connections for timeouts
1288: *
1289: */
1290: for (ndx = 0; ndx < conns->used; ndx++) {
1291: int changed = 0;
1292: connection *con;
1293: int t_diff;
1294:
1295: con = conns->ptr[ndx];
1296:
1297: if (con->state == CON_STATE_READ ||
1298: con->state == CON_STATE_READ_POST) {
1299: if (con->request_count == 1) {
1300: if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) {
1301: /* time - out */
1302: #if 0
1303: log_error_write(srv, __FILE__, __LINE__, "sd",
1304: "connection closed - read-timeout:", con->fd);
1305: #endif
1306: connection_set_state(srv, con, CON_STATE_ERROR);
1307: changed = 1;
1308: }
1309: } else {
1310: if (srv->cur_ts - con->read_idle_ts > con->keep_alive_idle) {
1311: /* time - out */
1312: #if 0
1313: log_error_write(srv, __FILE__, __LINE__, "sd",
1314: "connection closed - read-timeout:", con->fd);
1315: #endif
1316: connection_set_state(srv, con, CON_STATE_ERROR);
1317: changed = 1;
1318: }
1319: }
1320: }
1321:
1322: if ((con->state == CON_STATE_WRITE) &&
1323: (con->write_request_ts != 0)) {
1324: #if 0
1325: if (srv->cur_ts - con->write_request_ts > 60) {
1326: log_error_write(srv, __FILE__, __LINE__, "sdd",
1327: "connection closed - pre-write-request-timeout:", con->fd, srv->cur_ts - con->write_request_ts);
1328: }
1329: #endif
1330:
1331: if (srv->cur_ts - con->write_request_ts > con->conf.max_write_idle) {
1332: /* time - out */
1333: if (con->conf.log_timeouts) {
1334: log_error_write(srv, __FILE__, __LINE__, "sbsosds",
1335: "NOTE: a request for",
1336: con->request.uri,
1337: "timed out after writing",
1338: con->bytes_written,
1339: "bytes. We waited",
1340: (int)con->conf.max_write_idle,
1341: "seconds. If this a problem increase server.max-write-idle");
1342: }
1343: connection_set_state(srv, con, CON_STATE_ERROR);
1344: changed = 1;
1345: }
1346: }
1347:
1348: if (con->state == CON_STATE_CLOSE && (srv->cur_ts - con->close_timeout_ts > HTTP_LINGER_TIMEOUT)) {
1349: changed = 1;
1350: }
1351:
1352: /* we don't like div by zero */
1353: if (0 == (t_diff = srv->cur_ts - con->connection_start)) t_diff = 1;
1354:
1355: if (con->traffic_limit_reached &&
1356: (con->conf.kbytes_per_second == 0 ||
1357: ((con->bytes_written / t_diff) < con->conf.kbytes_per_second * 1024))) {
1358: /* enable connection again */
1359: con->traffic_limit_reached = 0;
1360:
1361: changed = 1;
1362: }
1363:
1364: if (changed) {
1365: connection_state_machine(srv, con);
1366: }
1367: con->bytes_written_cur_second = 0;
1368: *(con->conf.global_bytes_per_second_cnt_ptr) = 0;
1369:
1370: #if 0
1371: if (cs == 0) {
1372: fprintf(stderr, "connection-state: ");
1373: cs = 1;
1374: }
1375:
1376: fprintf(stderr, "c[%d,%d]: %s ",
1377: con->fd,
1378: con->fcgi.fd,
1379: connection_get_state(con->state));
1380: #endif
1381: }
1382:
1383: if (cs == 1) fprintf(stderr, "\n");
1384: }
1385: }
1386:
1387: if (srv->sockets_disabled) {
1388: /* our server sockets are disabled, why ? */
1389:
1390: if ((srv->cur_fds + srv->want_fds < srv->max_fds * 8 / 10) && /* we have enough unused fds */
1391: (srv->conns->used <= srv->max_conns * 9 / 10) &&
1392: (0 == graceful_shutdown)) {
1393: for (i = 0; i < srv->srv_sockets.used; i++) {
1394: server_socket *srv_socket = srv->srv_sockets.ptr[i];
1395: fdevent_event_set(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
1396: }
1397:
1398: log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets enabled again");
1399:
1400: srv->sockets_disabled = 0;
1401: }
1402: } else {
1403: if ((srv->cur_fds + srv->want_fds > srv->max_fds * 9 / 10) || /* out of fds */
1404: (srv->conns->used >= srv->max_conns) || /* out of connections */
1405: (graceful_shutdown)) { /* graceful_shutdown */
1406:
1407: /* disable server-fds */
1408:
1409: for (i = 0; i < srv->srv_sockets.used; i++) {
1410: server_socket *srv_socket = srv->srv_sockets.ptr[i];
1411: fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
1412:
1413: if (graceful_shutdown) {
1414: /* we don't want this socket anymore,
1415: *
1416: * closing it right away will make it possible for
1417: * the next lighttpd to take over (graceful restart)
1418: * */
1419:
1420: fdevent_unregister(srv->ev, srv_socket->fd);
1421: close(srv_socket->fd);
1422: srv_socket->fd = -1;
1423:
1424: /* network_close() will cleanup after us */
1425:
1426: if (srv->srvconf.pid_file->used &&
1427: srv->srvconf.changeroot->used == 0) {
1428: if (0 != unlink(srv->srvconf.pid_file->ptr)) {
1429: if (errno != EACCES && errno != EPERM) {
1430: log_error_write(srv, __FILE__, __LINE__, "sbds",
1431: "unlink failed for:",
1432: srv->srvconf.pid_file,
1433: errno,
1434: strerror(errno));
1435: }
1436: }
1437: }
1438: }
1439: }
1440:
1441: if (graceful_shutdown) {
1442: log_error_write(srv, __FILE__, __LINE__, "s", "[note] graceful shutdown started");
1443: } else if (srv->conns->used >= srv->max_conns) {
1444: log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, connection limit reached");
1445: } else {
1446: log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, out-of-fds");
1447: }
1448:
1449: srv->sockets_disabled = 1;
1450: }
1451: }
1452:
1453: if (graceful_shutdown && srv->conns->used == 0) {
1454: /* we are in graceful shutdown phase and all connections are closed
1455: * we are ready to terminate without harming anyone */
1456: srv_shutdown = 1;
1457: }
1458:
1459: /* we still have some fds to share */
1460: if (srv->want_fds) {
1461: /* check the fdwaitqueue for waiting fds */
1462: int free_fds = srv->max_fds - srv->cur_fds - 16;
1463: connection *con;
1464:
1465: for (; free_fds > 0 && NULL != (con = fdwaitqueue_unshift(srv, srv->fdwaitqueue)); free_fds--) {
1466: connection_state_machine(srv, con);
1467:
1468: srv->want_fds--;
1469: }
1470: }
1471:
1472: if ((n = fdevent_poll(srv->ev, 1000)) > 0) {
1473: /* n is the number of events */
1474: int revents;
1475: int fd_ndx;
1476: #if 0
1477: if (n > 0) {
1478: log_error_write(srv, __FILE__, __LINE__, "sd",
1479: "polls:", n);
1480: }
1481: #endif
1482: fd_ndx = -1;
1483: do {
1484: fdevent_handler handler;
1485: void *context;
1486: handler_t r;
1487:
1488: fd_ndx = fdevent_event_next_fdndx (srv->ev, fd_ndx);
1489: if (-1 == fd_ndx) break; /* not all fdevent handlers know how many fds got an event */
1490:
1491: revents = fdevent_event_get_revent (srv->ev, fd_ndx);
1492: fd = fdevent_event_get_fd (srv->ev, fd_ndx);
1493: handler = fdevent_get_handler(srv->ev, fd);
1494: context = fdevent_get_context(srv->ev, fd);
1495:
1496: /* connection_handle_fdevent needs a joblist_append */
1497: #if 0
1498: log_error_write(srv, __FILE__, __LINE__, "sdd",
1499: "event for", fd, revents);
1500: #endif
1501: switch (r = (*handler)(srv, context, revents)) {
1502: case HANDLER_FINISHED:
1503: case HANDLER_GO_ON:
1504: case HANDLER_WAIT_FOR_EVENT:
1505: case HANDLER_WAIT_FOR_FD:
1506: break;
1507: case HANDLER_ERROR:
1508: /* should never happen */
1509: SEGFAULT();
1510: break;
1511: default:
1512: log_error_write(srv, __FILE__, __LINE__, "d", r);
1513: break;
1514: }
1515: } while (--n > 0);
1516: } else if (n < 0 && errno != EINTR) {
1517: log_error_write(srv, __FILE__, __LINE__, "ss",
1518: "fdevent_poll failed:",
1519: strerror(errno));
1520: }
1521:
1522: for (ndx = 0; ndx < srv->joblist->used; ndx++) {
1523: connection *con = srv->joblist->ptr[ndx];
1524: handler_t r;
1525:
1526: connection_state_machine(srv, con);
1527:
1528: switch(r = plugins_call_handle_joblist(srv, con)) {
1529: case HANDLER_FINISHED:
1530: case HANDLER_GO_ON:
1531: break;
1532: default:
1533: log_error_write(srv, __FILE__, __LINE__, "d", r);
1534: break;
1535: }
1536:
1537: con->in_joblist = 0;
1538: }
1539:
1540: srv->joblist->used = 0;
1541: }
1542:
1543: if (srv->srvconf.pid_file->used &&
1544: srv->srvconf.changeroot->used == 0 &&
1545: 0 == graceful_shutdown) {
1546: if (0 != unlink(srv->srvconf.pid_file->ptr)) {
1547: if (errno != EACCES && errno != EPERM) {
1548: log_error_write(srv, __FILE__, __LINE__, "sbds",
1549: "unlink failed for:",
1550: srv->srvconf.pid_file,
1551: errno,
1552: strerror(errno));
1553: }
1554: }
1555: }
1556:
1557: #ifdef HAVE_SIGACTION
1558: log_error_write(srv, __FILE__, __LINE__, "sdsd",
1559: "server stopped by UID =",
1560: last_sigterm_info.si_uid,
1561: "PID =",
1562: last_sigterm_info.si_pid);
1563: #else
1564: log_error_write(srv, __FILE__, __LINE__, "s",
1565: "server stopped");
1566: #endif
1567:
1568: /* clean-up */
1569: log_error_close(srv);
1570: network_close(srv);
1571: connections_free(srv);
1572: plugins_free(srv);
1573: server_free(srv);
1574:
1575: return 0;
1576: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>