blob: a66560acb7393e329b77402b3d214746caaa4ca1 [file] [log] [blame]
Igor Sysoevfa73aac2003-05-21 13:28:21 +00001
Igor Sysoevd90282d2004-09-28 08:34:51 +00002/*
Igor Sysoevff8da912004-09-29 16:00:49 +00003 * Copyright (C) Igor Sysoev
Igor Sysoevd90282d2004-09-28 08:34:51 +00004 */
5
6
Igor Sysoevfa73aac2003-05-21 13:28:21 +00007#include <ngx_config.h>
8#include <ngx_core.h>
Igor Sysoev899b44e2005-05-12 14:58:06 +00009#include <ngx_setproctitle.h>
Igor Sysoevfa73aac2003-05-21 13:28:21 +000010
11
Igor Sysoev42b12b32004-12-02 18:40:46 +000012ngx_int_t ngx_ncpu;
13ngx_int_t ngx_max_sockets;
14ngx_uint_t ngx_inherited_nonblocking;
15ngx_uint_t ngx_tcp_nodelay_and_tcp_nopush;
Igor Sysoevaad1b892004-10-03 20:02:06 +000016
17
18struct rlimit rlmt;
Igor Sysoevfa73aac2003-05-21 13:28:21 +000019
20
Igor Sysoevd09f7a12004-06-15 17:47:16 +000021#if (NGX_POSIX_IO)
22
23ngx_os_io_t ngx_os_io = {
24 ngx_unix_recv,
25 ngx_readv_chain,
26 NULL,
27 ngx_writev_chain,
28 0
29};
30
31
Igor Sysoev8184d1b2005-03-04 14:06:57 +000032ngx_int_t ngx_os_init(ngx_log_t *log)
Igor Sysoevd09f7a12004-06-15 17:47:16 +000033{
34 return ngx_posix_init(log);
35}
36
37
Igor Sysoevc0edbcc2004-10-21 15:34:38 +000038void ngx_os_status(ngx_log_t *log)
39{
40 ngx_posix_status(log);
41}
42
43
Igor Sysoevd09f7a12004-06-15 17:47:16 +000044#endif
45
46
Igor Sysoevdc867cd2003-12-14 20:10:27 +000047void ngx_signal_handler(int signo);
Igor Sysoev7349bef2003-07-03 16:30:22 +000048
49
Igor Sysoevdc867cd2003-12-14 20:10:27 +000050typedef struct {
51 int signo;
52 char *signame;
Igor Sysoevdc867cd2003-12-14 20:10:27 +000053 void (*handler)(int signo);
54} ngx_signal_t;
55
56
57ngx_signal_t signals[] = {
Igor Sysoev3c3ca172004-01-05 20:55:48 +000058 { ngx_signal_value(NGX_RECONFIGURE_SIGNAL),
59 "SIG" ngx_value(NGX_RECONFIGURE_SIGNAL),
Igor Sysoevdc867cd2003-12-14 20:10:27 +000060 ngx_signal_handler },
61
Igor Sysoev3c3ca172004-01-05 20:55:48 +000062 { ngx_signal_value(NGX_REOPEN_SIGNAL),
63 "SIG" ngx_value(NGX_REOPEN_SIGNAL),
Igor Sysoevdc867cd2003-12-14 20:10:27 +000064 ngx_signal_handler },
65
Igor Sysoev49783fc2004-01-13 16:43:23 +000066 { ngx_signal_value(NGX_NOACCEPT_SIGNAL),
67 "SIG" ngx_value(NGX_NOACCEPT_SIGNAL),
Igor Sysoev3c3ca172004-01-05 20:55:48 +000068 ngx_signal_handler },
69
70 { ngx_signal_value(NGX_TERMINATE_SIGNAL),
71 "SIG" ngx_value(NGX_TERMINATE_SIGNAL),
Igor Sysoevdc867cd2003-12-14 20:10:27 +000072 ngx_signal_handler },
73
74 { ngx_signal_value(NGX_SHUTDOWN_SIGNAL),
75 "SIG" ngx_value(NGX_SHUTDOWN_SIGNAL),
Igor Sysoevdc867cd2003-12-14 20:10:27 +000076 ngx_signal_handler },
77
Igor Sysoev3c3ca172004-01-05 20:55:48 +000078 { ngx_signal_value(NGX_CHANGEBIN_SIGNAL),
79 "SIG" ngx_value(NGX_CHANGEBIN_SIGNAL),
Igor Sysoev3c3ca172004-01-05 20:55:48 +000080 ngx_signal_handler },
81
Igor Sysoev81233322004-01-28 20:38:54 +000082 { SIGALRM, "SIGALRM", ngx_signal_handler },
83
Igor Sysoev80340f02004-01-13 21:33:59 +000084 { SIGINT, "SIGINT", ngx_signal_handler },
85
Igor Sysoev87350f22004-06-15 07:55:11 +000086 { SIGIO, "SIGIO", ngx_signal_handler },
87
Igor Sysoevf2954c32004-01-08 21:02:06 +000088 { SIGCHLD, "SIGCHLD", ngx_signal_handler },
Igor Sysoevdc867cd2003-12-14 20:10:27 +000089
Igor Sysoevf2954c32004-01-08 21:02:06 +000090 { SIGPIPE, "SIGPIPE, SIG_IGN", SIG_IGN },
Igor Sysoevdc867cd2003-12-14 20:10:27 +000091
Igor Sysoevf2954c32004-01-08 21:02:06 +000092 { 0, NULL, NULL }
Igor Sysoevdc867cd2003-12-14 20:10:27 +000093};
94
95
Igor Sysoevaad1b892004-10-03 20:02:06 +000096ngx_int_t ngx_posix_init(ngx_log_t *log)
Igor Sysoevfa73aac2003-05-21 13:28:21 +000097{
Igor Sysoevdc867cd2003-12-14 20:10:27 +000098 ngx_signal_t *sig;
Igor Sysoevdc867cd2003-12-14 20:10:27 +000099 struct sigaction sa;
Igor Sysoevfa73aac2003-05-21 13:28:21 +0000100
Igor Sysoev899b44e2005-05-12 14:58:06 +0000101 ngx_init_setproctitle(log);
102
Igor Sysoev0ab91b92004-06-06 19:49:18 +0000103 ngx_pagesize = getpagesize();
104
Igor Sysoev078d1b22004-06-30 15:30:41 +0000105 if (ngx_ncpu == 0) {
106 ngx_ncpu = 1;
107 }
108
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000109 for (sig = signals; sig->signo != 0; sig++) {
110 ngx_memzero(&sa, sizeof(struct sigaction));
111 sa.sa_handler = sig->handler;
112 sigemptyset(&sa.sa_mask);
113 if (sigaction(sig->signo, &sa, NULL) == -1) {
114 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
115 "sigaction(%s) failed", sig->signame);
116 return NGX_ERROR;
117 }
Igor Sysoevfa73aac2003-05-21 13:28:21 +0000118 }
119
Igor Sysoevfa73aac2003-05-21 13:28:21 +0000120 if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
121 ngx_log_error(NGX_LOG_ALERT, log, errno,
122 "getrlimit(RLIMIT_NOFILE) failed)");
123 return NGX_ERROR;
124 }
125
Igor Sysoevfa73aac2003-05-21 13:28:21 +0000126 ngx_max_sockets = rlmt.rlim_cur;
127
Igor Sysoevf6906042004-11-25 16:17:31 +0000128#if (NGX_HAVE_INHERITED_NONBLOCK)
Igor Sysoevfa73aac2003-05-21 13:28:21 +0000129 ngx_inherited_nonblocking = 1;
130#else
131 ngx_inherited_nonblocking = 0;
132#endif
133
134 return NGX_OK;
135}
136
137
Igor Sysoevaad1b892004-10-03 20:02:06 +0000138void ngx_posix_status(ngx_log_t *log)
139{
140 ngx_log_error(NGX_LOG_INFO, log, 0,
Igor Sysoev1b735832004-11-11 14:07:14 +0000141 "getrlimit(RLIMIT_NOFILE): %r:%r",
Igor Sysoevaad1b892004-10-03 20:02:06 +0000142 rlmt.rlim_cur, rlmt.rlim_max);
143}
144
145
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000146void ngx_signal_handler(int signo)
147{
Igor Sysoevf2954c32004-01-08 21:02:06 +0000148 char *action;
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000149 struct timeval tv;
Igor Sysoev80340f02004-01-13 21:33:59 +0000150 ngx_int_t ignore;
Igor Sysoeva9030eb2004-01-06 16:49:34 +0000151 ngx_err_t err;
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000152 ngx_signal_t *sig;
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000153
Igor Sysoev80340f02004-01-13 21:33:59 +0000154 ignore = 0;
Igor Sysoev49783fc2004-01-13 16:43:23 +0000155
Igor Sysoeva9030eb2004-01-06 16:49:34 +0000156 err = ngx_errno;
157
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000158 for (sig = signals; sig->signo != 0; sig++) {
159 if (sig->signo == signo) {
160 break;
161 }
162 }
163
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000164 ngx_gettimeofday(&tv);
165 ngx_time_update(tv.tv_sec);
Igor Sysoeve89c4582003-12-19 08:15:11 +0000166
Igor Sysoevf2954c32004-01-08 21:02:06 +0000167 action = "";
168
169 switch (ngx_process) {
170
171 case NGX_PROCESS_MASTER:
Igor Sysoevd8e1f072004-01-22 06:47:28 +0000172 case NGX_PROCESS_SINGLE:
Igor Sysoevf2954c32004-01-08 21:02:06 +0000173 switch (signo) {
174
175 case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):
176 ngx_quit = 1;
Igor Sysoev5c8c52f2004-01-23 09:26:18 +0000177 action = ", shutting down";
Igor Sysoevf2954c32004-01-08 21:02:06 +0000178 break;
179
180 case ngx_signal_value(NGX_TERMINATE_SIGNAL):
Igor Sysoev49783fc2004-01-13 16:43:23 +0000181 case SIGINT:
Igor Sysoevf2954c32004-01-08 21:02:06 +0000182 ngx_terminate = 1;
183 action = ", exiting";
184 break;
185
Igor Sysoev49783fc2004-01-13 16:43:23 +0000186 case ngx_signal_value(NGX_NOACCEPT_SIGNAL):
187 ngx_noaccept = 1;
Igor Sysoevc1571722005-03-19 12:38:37 +0000188 action = ", stop accepting connections";
Igor Sysoevf2954c32004-01-08 21:02:06 +0000189 break;
190
191 case ngx_signal_value(NGX_RECONFIGURE_SIGNAL):
192 ngx_reconfigure = 1;
193 action = ", reconfiguring";
194 break;
195
196 case ngx_signal_value(NGX_REOPEN_SIGNAL):
Igor Sysoevc5371672004-02-04 20:30:08 +0000197 ngx_reopen = 1;
Igor Sysoevb1dfe472004-12-21 12:30:30 +0000198 action = ", reopening logs";
Igor Sysoevc5371672004-02-04 20:30:08 +0000199 break;
Igor Sysoevf2954c32004-01-08 21:02:06 +0000200
201 case ngx_signal_value(NGX_CHANGEBIN_SIGNAL):
Igor Sysoev92602942004-02-05 16:58:36 +0000202 if (getppid() > 1 || ngx_new_binary > 0) {
203
Igor Sysoev80340f02004-01-13 21:33:59 +0000204 /*
205 * Ignore the signal in the new binary if its parent is
206 * not the init process, i.e. the old binary's process
207 * is still running. Or ingore the signal in the old binary's
208 * process if the new binary's process is already running.
209 */
210
211 action = ", ignoring";
212 ignore = 1;
213 break;
214 }
215
Igor Sysoevf2954c32004-01-08 21:02:06 +0000216 ngx_change_binary = 1;
217 action = ", changing binary";
218 break;
219
Igor Sysoev81233322004-01-28 20:38:54 +0000220 case SIGALRM:
221 if (!ngx_terminate) {
222 ngx_timer = 1;
Igor Sysoev87350f22004-06-15 07:55:11 +0000223 action = ", shutting down old worker processes";
Igor Sysoev81233322004-01-28 20:38:54 +0000224 }
225
226 break;
227
Igor Sysoev87350f22004-06-15 07:55:11 +0000228 case SIGIO:
229 ngx_sigio = 1;
230 break;
231
Igor Sysoevf2954c32004-01-08 21:02:06 +0000232 case SIGCHLD:
233 ngx_reap = 1;
234 break;
235 }
236
237 break;
238
239 case NGX_PROCESS_WORKER:
240 switch (signo) {
241
Igor Sysoevb1dfe472004-12-21 12:30:30 +0000242 case ngx_signal_value(NGX_NOACCEPT_SIGNAL):
243 ngx_debug_quit = 1;
Igor Sysoevf2954c32004-01-08 21:02:06 +0000244 case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):
245 ngx_quit = 1;
Igor Sysoev5c8c52f2004-01-23 09:26:18 +0000246 action = ", shutting down";
Igor Sysoevf2954c32004-01-08 21:02:06 +0000247 break;
248
249 case ngx_signal_value(NGX_TERMINATE_SIGNAL):
Igor Sysoev49783fc2004-01-13 16:43:23 +0000250 case SIGINT:
Igor Sysoevf2954c32004-01-08 21:02:06 +0000251 ngx_terminate = 1;
252 action = ", exiting";
253 break;
254
Igor Sysoevf2954c32004-01-08 21:02:06 +0000255 case ngx_signal_value(NGX_REOPEN_SIGNAL):
256 ngx_reopen = 1;
Igor Sysoevb1dfe472004-12-21 12:30:30 +0000257 action = ", reopening logs";
Igor Sysoevf2954c32004-01-08 21:02:06 +0000258 break;
Igor Sysoevf2954c32004-01-08 21:02:06 +0000259
260 case ngx_signal_value(NGX_RECONFIGURE_SIGNAL):
Igor Sysoevf2954c32004-01-08 21:02:06 +0000261 case ngx_signal_value(NGX_CHANGEBIN_SIGNAL):
Igor Sysoev87350f22004-06-15 07:55:11 +0000262 case SIGIO:
Igor Sysoevf2954c32004-01-08 21:02:06 +0000263 action = ", ignoring";
264 break;
265 }
266
267 break;
268 }
269
Igor Sysoevb1dfe472004-12-21 12:30:30 +0000270 ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0,
Igor Sysoevf2954c32004-01-08 21:02:06 +0000271 "signal %d (%s) received%s", signo, sig->signame, action);
Igor Sysoeve89c4582003-12-19 08:15:11 +0000272
Igor Sysoev80340f02004-01-13 21:33:59 +0000273 if (ignore) {
274 ngx_log_error(NGX_LOG_CRIT, ngx_cycle->log, 0,
275 "the changing binary signal is ignored: "
276 "you should shutdown or terminate "
277 "before either old or new binary's process");
278 }
279
Igor Sysoevf2954c32004-01-08 21:02:06 +0000280 if (signo == SIGCHLD) {
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000281 ngx_process_get_status();
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000282 }
Igor Sysoeva9030eb2004-01-06 16:49:34 +0000283
284 ngx_set_errno(err);
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000285}
286
287
Igor Sysoev8184d1b2005-03-04 14:06:57 +0000288ngx_int_t ngx_posix_post_conf_init(ngx_log_t *log)
Igor Sysoevfa73aac2003-05-21 13:28:21 +0000289{
290 ngx_fd_t pp[2];
291
292 if (pipe(pp) == -1) {
293 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "pipe() failed");
294 return NGX_ERROR;
295 }
296
297 if (dup2(pp[1], STDERR_FILENO) == -1) {
298 ngx_log_error(NGX_LOG_EMERG, log, errno, "dup2(STDERR) failed");
299 return NGX_ERROR;
300 }
301
302 if (pp[1] > STDERR_FILENO) {
303 if (close(pp[1]) == -1) {
304 ngx_log_error(NGX_LOG_EMERG, log, errno, "close() failed");
305 return NGX_ERROR;
306 }
307 }
308
309 return NGX_OK;
310}