From 53ac493fa391a126ed737a8d6dfeae7acfe61bc6 Mon Sep 17 00:00:00 2001 From: Sam Liddicott Date: Fri, 19 Apr 2013 11:33:17 +0100 Subject: [PATCH] standard process mode restart crashed task services Although it should not happen task services can crash and leave the whole server set unusable, see bug #9806 This patch has the process_standard model restart crashed servcies. Signed-off-by: Sam Liddicott --- source4/smbd/process_standard.c | 45 ++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/source4/smbd/process_standard.c b/source4/smbd/process_standard.c index c5377b3..dce9c3b 100644 --- a/source4/smbd/process_standard.c +++ b/source4/smbd/process_standard.c @@ -172,18 +172,39 @@ static void standard_new_task(struct tevent_context *ev, standard_pipe_handler, NULL); close(child_pipe[1]); - /* Ensure that the forked children do not expose identical random streams */ - set_need_random_reseed(); - - setproctitle("task %s server_id[%d]", service_name, (int)pid); - - /* setup this new task. Cluster ID is PID based for this process model */ - new_task(ev, lp_ctx, cluster_id(pid, 0), private_data); - - /* we can't return to the top level here, as that event context is gone, - so we now process events in the new event context until there are no - more to process */ - tevent_loop_wait(ev); + setproctitle("*%s*", service_name); + signal(SIGCHLD, SIG_DFL); + + while(1) { + int status; + pid_t cpid = fork(); + + if (cpid == 0) { + /* Ensure that the forked children do not expose identical random streams */ + set_need_random_reseed(); + + setproctitle("task %s server_id[%d]", service_name, (int)pid); + + /* setup this new task. Cluster ID is PID based for this process model */ + new_task(ev, lp_ctx, cluster_id(pid, 0), private_data); + + /* we can't return to the top level here, as that event context is gone, + so we now process events in the new event context until there are no + more to process */ + tevent_loop_wait(ev); + + talloc_free(ev); + exit(0); + } + + DEBUG(0, ("waiting for child %d %s\n", (int)cpid, service_name)); + waitpid(cpid, &status, 0); + if (WIFEXITED(status)) { + DEBUG(0, ("Exit after %d from child %d %s\n", status, (int)cpid, service_name)); + break; + } + DEBUG(0, ("Restart after %d from child %d %s\n", status, (int)cpid, service_name)); + } talloc_free(ev); exit(0); -- 1.7.10.4