s4: server: Add a tevent signal handler for SIGTERM.
authorJeremy Allison <jra@samba.org>
Fri, 31 Mar 2017 19:38:14 +0000 (12:38 -0700)
committerJeremy Allison <jra@samba.org>
Mon, 17 Apr 2017 17:13:07 +0000 (19:13 +0200)
Simplify by removing global state we don't need now
we're called by tevent (and in the short window where
we're installed by CatchSignal but before we install
the tevent handler we don't need the complex global
state handling as we have no forked children).

We now have access to struct server_state on all
exit paths - next commits will stop using talloc autofree context.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
source4/smbd/server.c

index 1e5d57940cec7451c7856405f90621c9157e78e2..98148374e5bced23491d8da13966a3d00e6cfcf5 100644 (file)
@@ -115,10 +115,12 @@ static void sig_hup(int sig)
 static void sig_term(int sig)
 {
 #if HAVE_GETPGRP
-       static int done_sigterm;
-       if (done_sigterm == 0 && getpgrp() == getpid()) {
+       if (getpgrp() == getpid()) {
+               /*
+                * We're the process group leader, send
+                * SIGTERM to our process group.
+                */
                DEBUG(0,("SIGTERM: killing children\n"));
-               done_sigterm = 1;
                kill(-getpgrp(), SIGTERM);
        }
 #endif
@@ -126,6 +128,18 @@ static void sig_term(int sig)
        exit(127);
 }
 
+static void sigterm_signal_handler(struct tevent_context *ev,
+                               struct tevent_signal *se,
+                               int signum, int count, void *siginfo,
+                               void *private_data)
+{
+       struct server_state *state = talloc_get_type_abort(
+                private_data, struct server_state);
+
+       DEBUG(10,("Process %s got SIGTERM\n", state->binary_name));
+       sig_term(SIGTERM);
+}
+
 /*
   setup signal masks
 */
@@ -358,6 +372,7 @@ static int binary_smbd_main(const char *binary_name,
                { NULL }
        };
        struct server_state *state = NULL;
+       struct tevent_signal *se = NULL;
 
        pc = poptGetContext(binary_name, argc, argv, long_options, 0);
        while((opt = poptGetNextOpt(pc)) != -1) {
@@ -523,6 +538,16 @@ static int binary_smbd_main(const char *binary_name,
                }
        }
 
+       se = tevent_add_signal(state->event_ctx,
+                               state->event_ctx,
+                               SIGTERM,
+                               0,
+                               sigterm_signal_handler,
+                               state);
+       if (se == NULL) {
+               exit_daemon("Initialize SIGTERM handler failed", ENOMEM);
+       }
+
        if (lpcfg_server_role(cmdline_lp_ctx) != ROLE_ACTIVE_DIRECTORY_DC
            && !lpcfg_parm_bool(cmdline_lp_ctx, NULL,
                        "server role check", "inhibit", false)