diff options
author | Andrew Tridgell <tridge@samba.org> | 2009-08-07 17:21:54 +1000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2009-08-07 17:24:48 +1000 |
commit | c271dc998ba25101a46e7d4b2187567a07588ca2 (patch) | |
tree | 20270a68759dc336855a60ff704d201f91acc936 /source4/smbd | |
parent | cfc0cabb27c7323930b96dd93befa955bacd6cde (diff) | |
download | samba-c271dc998ba25101a46e7d4b2187567a07588ca2.tar.gz samba-c271dc998ba25101a46e7d4b2187567a07588ca2.tar.bz2 samba-c271dc998ba25101a46e7d4b2187567a07588ca2.zip |
ensure that child tasks die when the parent dies
Previously we relied on process groups and SIGTERM to ensure that
child tasks died in the standard process model when the parent task
died. This doesn't work when the server is run in interactive mode, as
in that case we don't call become_daemon() and don't get a separate
process group.
The fix is to have a pipe held open by the parent server process, and
inherited by child tasks. If the parent exits then the write side of
the pipe is implicitly closed, which causes an event in the child
tasks that causes them to exit
Diffstat (limited to 'source4/smbd')
-rw-r--r-- | source4/smbd/process_standard.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/source4/smbd/process_standard.c b/source4/smbd/process_standard.c index 137e0a7ce0..730e185e5a 100644 --- a/source4/smbd/process_standard.c +++ b/source4/smbd/process_standard.c @@ -44,15 +44,31 @@ static int none_setproctitle(const char *fmt, ...) } #endif +/* we hold a pipe open in the parent, and the any child + processes wait for EOF on that pipe. This ensures that + children die when the parent dies */ +static int child_pipe[2]; + /* called when the process model is selected */ static void standard_model_init(struct tevent_context *ev) { + pipe(child_pipe); signal(SIGCHLD, SIG_IGN); } /* + handle EOF on the child pipe +*/ +static void standard_pipe_handler(struct tevent_context *event_ctx, struct tevent_fd *fde, + uint16_t flags, void *private_data) +{ + DEBUG(10,("Child %d exiting\n", (int)getpid())); + exit(0); +} + +/* called when a listening socket becomes readable. */ static void standard_accept_connection(struct tevent_context *ev, @@ -114,6 +130,10 @@ static void standard_accept_connection(struct tevent_context *ev, DEBUG(0,("standard_accept_connection: tdb_reopen_all failed.\n")); } + tevent_add_fd(ev2, ev2, child_pipe[0], TEVENT_FD_READ, + standard_pipe_handler, NULL); + close(child_pipe[1]); + /* Ensure that the forked children do not expose identical random streams */ set_need_random_reseed(); @@ -177,6 +197,10 @@ static void standard_new_task(struct tevent_context *ev, DEBUG(0,("standard_accept_connection: tdb_reopen_all failed.\n")); } + tevent_add_fd(ev2, ev2, child_pipe[0], TEVENT_FD_READ, + standard_pipe_handler, NULL); + close(child_pipe[1]); + /* Ensure that the forked children do not expose identical random streams */ set_need_random_reseed(); |