s4 smdb standard: Limit processes forked on accept.
[metze/samba/wip.git] / source4 / smbd / process_standard.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    process model: standard (1 process per client connection)
5
6    Copyright (C) Andrew Tridgell 1992-2005
7    Copyright (C) James J Myers 2003 <myersjj@samba.org>
8    Copyright (C) Stefan (metze) Metzmacher 2004
9    
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25 #include "lib/events/events.h"
26 #include "smbd/process_model.h"
27 #include "system/filesys.h"
28 #include "cluster/cluster.h"
29 #include "param/param.h"
30 #include "ldb_wrap.h"
31 #include "lib/messaging/messaging.h"
32 #include "lib/util/debug.h"
33 #include "source3/lib/messages_dgm.h"
34
35 static unsigned connections_active = 0;
36 static unsigned smbd_max_processes = 0;
37
38 struct standard_child_state {
39         const char *name;
40         pid_t pid;
41         int to_parent_fd;
42         int from_child_fd;
43         struct tevent_fd *from_child_fde;
44 };
45
46 NTSTATUS process_model_standard_init(TALLOC_CTX *);
47 struct process_context {
48         char *name;
49         int from_parent_fd;
50         bool inhibit_fork_on_accept;
51         bool forked_on_accept;
52 };
53
54 /*
55   called when the process model is selected
56 */
57 static void standard_model_init(void)
58 {
59 }
60
61 static void sighup_signal_handler(struct tevent_context *ev,
62                                 struct tevent_signal *se,
63                                 int signum, int count, void *siginfo,
64                                 void *private_data)
65 {
66         debug_schedule_reopen_logs();
67 }
68
69 static void sigterm_signal_handler(struct tevent_context *ev,
70                                 struct tevent_signal *se,
71                                 int signum, int count, void *siginfo,
72                                 void *private_data)
73 {
74 #ifdef HAVE_GETPGRP
75         if (getpgrp() == getpid()) {
76                 /*
77                  * We're the process group leader, send
78                  * SIGTERM to our process group.
79                  */
80                 DBG_ERR("SIGTERM: killing children\n");
81                 kill(-getpgrp(), SIGTERM);
82         }
83 #endif
84         DBG_ERR("Exiting pid %u on SIGTERM\n", (unsigned int)getpid());
85         talloc_free(ev);
86         exit(127);
87 }
88
89 /*
90   handle EOF on the parent-to-all-children pipe in the child
91 */
92 static void standard_pipe_handler(struct tevent_context *event_ctx, struct tevent_fd *fde, 
93                                   uint16_t flags, void *private_data)
94 {
95         DBG_DEBUG("Child %d exiting\n", (int)getpid());
96         talloc_free(event_ctx);
97         exit(0);
98 }
99
100 /*
101   handle EOF on the child pipe in the parent, so we know when a
102   process terminates without using SIGCHLD or waiting on all possible pids.
103
104   We need to ensure we do not ignore SIGCHLD because we need it to
105   work to get a valid error code from samba_runcmd_*().
106  */
107 static void standard_child_pipe_handler(struct tevent_context *ev,
108                                         struct tevent_fd *fde,
109                                         uint16_t flags,
110                                         void *private_data)
111 {
112         struct standard_child_state *state
113                 = talloc_get_type_abort(private_data, struct standard_child_state);
114         int status = 0;
115         pid_t pid;
116
117         messaging_dgm_cleanup(state->pid);
118
119         /* the child has closed the pipe, assume its dead */
120         errno = 0;
121         pid = waitpid(state->pid, &status, 0);
122
123         if (pid != state->pid) {
124                 if (errno == ECHILD) {
125                         /*
126                          * this happens when the
127                          * parent has set SIGCHLD to
128                          * SIG_IGN. In that case we
129                          * can only get error
130                          * information for the child
131                          * via its logging. We should
132                          * stop using SIG_IGN on
133                          * SIGCHLD in the standard
134                          * process model.
135                          */
136                         DBG_ERR("Error in waitpid() unexpectedly got ECHILD "
137                                 "for child %d (%s) - %s, someone has set SIGCHLD "
138                                 "to SIG_IGN!\n",
139                                 (int)state->pid, state->name,
140                                 strerror(errno));
141                         TALLOC_FREE(state);
142                         return;
143                 }
144                 DBG_ERR("Error in waitpid() for child %d (%s) - %s \n",
145                         (int)state->pid, state->name, strerror(errno));
146                 if (errno == 0) {
147                         errno = ECHILD;
148                 }
149                 goto done;
150         }
151         if (WIFEXITED(status)) {
152                 status = WEXITSTATUS(status);
153                 if (status != 0) {
154                         DBG_ERR("Child %d (%s) exited with status %d\n",
155                                 (int)state->pid, state->name, status);
156                 }
157         } else if (WIFSIGNALED(status)) {
158                 status = WTERMSIG(status);
159                 DBG_ERR("Child %d (%s) terminated with signal %d\n",
160                         (int)state->pid, state->name, status);
161         }
162 done:
163         TALLOC_FREE(state);
164         if (smbd_max_processes > 0) {
165                 if (connections_active < 1) {
166                         DBG_ERR("Number of active connections "
167                                 "less than 1 (%d)\n",
168                                 connections_active);
169                         connections_active = 1;
170                 }
171                 connections_active--;
172         }
173         return;
174 }
175
176 static struct standard_child_state *setup_standard_child_pipe(struct tevent_context *ev,
177                                                               const char *name)
178 {
179         struct standard_child_state *state;
180         int parent_child_pipe[2];
181         int ret;
182
183         /*
184          * Prepare a pipe to allow us to know when the child exits,
185          * because it will trigger a read event on this private
186          * pipe.
187          *
188          * We do all this before the accept and fork(), so we can
189          * clean up if it fails.
190          */
191         state = talloc_zero(ev, struct standard_child_state);
192         if (state == NULL) {
193                 return NULL;
194         }
195
196         if (name == NULL) {
197                 name = "";
198         }
199
200         state->name = talloc_strdup(state, name);
201         if (state->name == NULL) {
202                 TALLOC_FREE(state);
203                 return NULL;
204         }
205
206         ret = pipe(parent_child_pipe);
207         if (ret == -1) {
208                 DBG_ERR("Failed to create parent-child pipe to handle "
209                         "SIGCHLD to track new process for socket\n");
210                 TALLOC_FREE(state);
211                 return NULL;
212         }
213
214         smb_set_close_on_exec(parent_child_pipe[0]);
215         smb_set_close_on_exec(parent_child_pipe[1]);
216
217         state->from_child_fd = parent_child_pipe[0];
218         state->to_parent_fd = parent_child_pipe[1];
219
220         /*
221          * The basic purpose of calling this handler is to ensure we
222          * call waitpid() and so avoid zombies (now that we no longer
223          * user SIGIGN on for SIGCHLD), but it also allows us to clean
224          * up other resources in the future.
225          */
226         state->from_child_fde = tevent_add_fd(ev, state,
227                                               state->from_child_fd,
228                                               TEVENT_FD_READ,
229                                               standard_child_pipe_handler,
230                                               state);
231         if (state->from_child_fde == NULL) {
232                 TALLOC_FREE(state);
233                 return NULL;
234         }
235         tevent_fd_set_auto_close(state->from_child_fde);
236
237         return state;
238 }
239
240 /*
241   called when a listening socket becomes readable. 
242 */
243 static void standard_accept_connection(
244                 struct tevent_context *ev,
245                 struct loadparm_context *lp_ctx,
246                 struct socket_context *sock,
247                 void (*new_conn)(struct tevent_context *,
248                                 struct loadparm_context *,
249                                 struct socket_context *,
250                                 struct server_id,
251                                 void *,
252                                 void *),
253                 void *private_data,
254                 void *process_context)
255 {
256         NTSTATUS status;
257         struct socket_context *sock2;
258         pid_t pid;
259         struct socket_address *c, *s;
260         struct standard_child_state *state;
261         struct tevent_fd *fde = NULL;
262         struct tevent_signal *se = NULL;
263         struct process_context *proc_ctx = NULL;
264
265
266         /* accept an incoming connection. */
267         status = socket_accept(sock, &sock2);
268         if (!NT_STATUS_IS_OK(status)) {
269                 DBG_DEBUG("standard_accept_connection: accept: %s\n",
270                           nt_errstr(status));
271                 /* this looks strange, but is correct. We need to throttle
272                  * things until the system clears enough resources to handle
273                  * this new socket
274                  */
275                 sleep(1);
276                 return;
277         }
278
279         proc_ctx = talloc_get_type_abort(process_context,
280                                          struct process_context);
281
282         if (proc_ctx->inhibit_fork_on_accept) {
283                 pid = getpid();
284                 /*
285                  * Service does not support forking a new process on a
286                  * new connection, either it's maintaining shared
287                  * state or the overhead of forking a new process is a
288                  * significant fraction of the response time.
289                  */
290                 talloc_steal(private_data, sock2);
291                 new_conn(ev, lp_ctx, sock2,
292                          cluster_id(pid, socket_get_fd(sock2)), private_data,
293                          process_context);
294                 return;
295         }
296
297         if (smbd_max_processes > 0) {
298                 if (connections_active >= smbd_max_processes) {
299                         DBG_ERR("(%d) connections already active, "
300                                 "maximum is (%d). Dropping request\n",
301                                 connections_active,
302                                 smbd_max_processes);
303                         /*
304                          * Drop the connection as we're overloaded at the moment
305                          */
306                         talloc_free(sock2);
307                         return;
308                 }
309                 connections_active++;
310         }
311
312         state = setup_standard_child_pipe(ev, NULL);
313         if (state == NULL) {
314                 return;
315         }
316         pid = fork();
317
318         if (pid != 0) {
319                 close(state->to_parent_fd);
320                 state->to_parent_fd = -1;
321
322                 if (pid > 0) {
323                         state->pid = pid;
324                 } else {
325                         TALLOC_FREE(state);
326                 }
327
328                 /* parent or error code ... */
329                 talloc_free(sock2);
330                 /* go back to the event loop */
331                 return;
332         }
333
334         /* this leaves state->to_parent_fd open */
335         TALLOC_FREE(state);
336
337         /* Now in the child code so indicate that we forked
338          * so the terminate code knows what to do
339          */
340         proc_ctx->forked_on_accept = true;
341
342         pid = getpid();
343         setproctitle("task[%s] standard worker", proc_ctx->name);
344
345         /* This is now the child code. We need a completely new event_context to work with */
346
347         if (tevent_re_initialise(ev) != 0) {
348                 smb_panic("Failed to re-initialise tevent after fork");
349         }
350
351         /* this will free all the listening sockets and all state that
352            is not associated with this new connection */
353         talloc_free(sock);
354
355         /* we don't care if the dup fails, as its only a select()
356            speed optimisation */
357         socket_dup(sock2);
358                         
359         /* tdb needs special fork handling */
360         ldb_wrap_fork_hook();
361
362         /* Must be done after a fork() to reset messaging contexts. */
363         status = imessaging_reinit_all();
364         if (!NT_STATUS_IS_OK(status)) {
365                 smb_panic("Failed to re-initialise imessaging after fork");
366         }
367
368         fde = tevent_add_fd(ev, ev, proc_ctx->from_parent_fd, TEVENT_FD_READ,
369                       standard_pipe_handler, NULL);
370         if (fde == NULL) {
371                 smb_panic("Failed to add fd handler after fork");
372         }
373
374         se = tevent_add_signal(ev,
375                                 ev,
376                                 SIGHUP,
377                                 0,
378                                 sighup_signal_handler,
379                                 NULL);
380         if (se == NULL) {
381                 smb_panic("Failed to add SIGHUP handler after fork");
382         }
383
384         se = tevent_add_signal(ev,
385                                 ev,
386                                 SIGTERM,
387                                 0,
388                                 sigterm_signal_handler,
389                                 NULL);
390         if (se == NULL) {
391                 smb_panic("Failed to add SIGTERM handler after fork");
392         }
393
394         /* setup the process title */
395         c = socket_get_peer_addr(sock2, ev);
396         s = socket_get_my_addr(sock2, ev);
397         if (s && c) {
398                 setproctitle("conn c[%s:%u] s[%s:%u] server_id[%d]",
399                              c->addr, c->port, s->addr, s->port, (int)pid);
400         }
401         talloc_free(c);
402         talloc_free(s);
403
404         /* setup this new connection.  Cluster ID is PID based for this process model */
405         new_conn(ev, lp_ctx, sock2, cluster_id(pid, 0), private_data,
406                  process_context);
407
408         /* we can't return to the top level here, as that event context is gone,
409            so we now process events in the new event context until there are no
410            more to process */      
411         tevent_loop_wait(ev);
412
413         talloc_free(ev);
414         exit(0);
415 }
416
417 /*
418   called to create a new server task
419 */
420 static void standard_new_task(struct tevent_context *ev,
421                               struct loadparm_context *lp_ctx,
422                               const char *service_name,
423                               struct task_server *(*new_task)(struct tevent_context *, struct loadparm_context *lp_ctx, struct server_id , void *, void *),
424                               void *private_data,
425                               const struct service_details *service_details,
426                               int from_parent_fd)
427 {
428         pid_t pid;
429         NTSTATUS status;
430         struct standard_child_state *state;
431         struct tevent_fd *fde = NULL;
432         struct tevent_signal *se = NULL;
433         struct process_context *proc_ctx = NULL;
434         struct task_server* task = NULL;
435
436         state = setup_standard_child_pipe(ev, service_name);
437         if (state == NULL) {
438                 return;
439         }
440
441         pid = fork();
442
443         if (pid != 0) {
444                 close(state->to_parent_fd);
445                 state->to_parent_fd = -1;
446
447                 if (pid > 0) {
448                         state->pid = pid;
449                 } else {
450                         TALLOC_FREE(state);
451                 }
452
453                 /* parent or error code ... go back to the event loop */
454                 return;
455         }
456
457         /* this leaves state->to_parent_fd open */
458         TALLOC_FREE(state);
459
460         pid = getpid();
461
462         /* this will free all the listening sockets and all state that
463            is not associated with this new connection */
464         if (tevent_re_initialise(ev) != 0) {
465                 smb_panic("Failed to re-initialise tevent after fork");
466         }
467
468         /* ldb/tdb need special fork handling */
469         ldb_wrap_fork_hook();
470
471         /* Must be done after a fork() to reset messaging contexts. */
472         status = imessaging_reinit_all();
473         if (!NT_STATUS_IS_OK(status)) {
474                 smb_panic("Failed to re-initialise imessaging after fork");
475         }
476
477         fde = tevent_add_fd(ev, ev, from_parent_fd, TEVENT_FD_READ,
478                       standard_pipe_handler, NULL);
479         if (fde == NULL) {
480                 smb_panic("Failed to add fd handler after fork");
481         }
482
483         se = tevent_add_signal(ev,
484                                 ev,
485                                 SIGHUP,
486                                 0,
487                                 sighup_signal_handler,
488                                 NULL);
489         if (se == NULL) {
490                 smb_panic("Failed to add SIGHUP handler after fork");
491         }
492
493         se = tevent_add_signal(ev,
494                                 ev,
495                                 SIGTERM,
496                                 0,
497                                 sigterm_signal_handler,
498                                 NULL);
499         if (se == NULL) {
500                 smb_panic("Failed to add SIGTERM handler after fork");
501         }
502
503         setproctitle("task[%s]", service_name);
504
505         /*
506          * Set up the process context to be passed through to the terminate
507          * and accept_connection functions
508          */
509         proc_ctx = talloc(ev, struct process_context);
510         proc_ctx->name = talloc_strdup(ev, service_name);
511         proc_ctx->from_parent_fd = from_parent_fd;
512         proc_ctx->inhibit_fork_on_accept  =
513                 service_details->inhibit_fork_on_accept;
514         proc_ctx->forked_on_accept = false;
515
516         smbd_max_processes = lpcfg_max_smbd_processes(lp_ctx);
517
518         /* setup this new task.  Cluster ID is PID based for this process model */
519         task = new_task(ev, lp_ctx, cluster_id(pid, 0), private_data, proc_ctx);
520         /*
521          * Currently we don't support the post_fork functionality in the
522          * standard model, i.e. it is only called here not after a new process
523          * is forked in standard_accept_connection.
524          */
525         if (task != NULL && service_details->post_fork != NULL) {
526                 struct process_details pd = initial_process_details;
527                 service_details->post_fork(task, &pd);
528         }
529
530
531         /* we can't return to the top level here, as that event context is gone,
532            so we now process events in the new event context until there are no
533            more to process */
534         tevent_loop_wait(ev);
535
536         talloc_free(ev);
537         exit(0);
538 }
539
540
541 /* called when a task goes down */
542 static void standard_terminate_task(struct tevent_context *ev,
543                                     struct loadparm_context *lp_ctx,
544                                     const char *reason,
545                                     bool fatal,
546                                     void *process_context)
547 {
548         if (fatal == true) {
549                 exit(127);
550         }
551         exit(0);
552 }
553
554 /* called when a connection terminates*/
555 static void standard_terminate_connection(struct tevent_context *ev,
556                                           struct loadparm_context *lp_ctx,
557                                           const char *reason,
558                                           void *process_context)
559 {
560         struct process_context *proc_ctx = NULL;
561
562         DBG_DEBUG("connection terminating reason[%s]\n", reason);
563         if (process_context == NULL) {
564                 smb_panic("Panicking process_context is NULL");
565         }
566
567         proc_ctx = talloc_get_type(process_context, struct process_context);
568         if (proc_ctx->forked_on_accept == false) {
569                 /*
570                  * The current task was not forked on accept, so it needs to
571                  * keep running and process requests from other connections
572                  */
573                 return;
574         }
575         /*
576          * The current process was forked on accept to handle a single
577          * connection/request. That request has now finished and the process
578          * should terminate
579          */
580
581         /* this reload_charcnv() has the effect of freeing the iconv context memory,
582            which makes leak checking easier */
583         reload_charcnv(lp_ctx);
584
585         /* Always free event context last before exit. */
586         talloc_free(ev);
587
588         /* terminate this process */
589         exit(0);
590 }
591 /* called to set a title of a task or connection */
592 static void standard_set_title(struct tevent_context *ev, const char *title) 
593 {
594         if (title) {
595                 setproctitle("%s", title);
596         } else {
597                 setproctitle(NULL);
598         }
599 }
600
601 static const struct model_ops standard_ops = {
602         .name                   = "standard",
603         .model_init             = standard_model_init,
604         .accept_connection      = standard_accept_connection,
605         .new_task               = standard_new_task,
606         .terminate_task         = standard_terminate_task,
607         .terminate_connection   = standard_terminate_connection,
608         .set_title              = standard_set_title,
609 };
610
611 /*
612   initialise the standard process model, registering ourselves with the process model subsystem
613  */
614 NTSTATUS process_model_standard_init(TALLOC_CTX *ctx)
615 {
616         return register_process_model(&standard_ops);
617 }