s3:smbd: use signal events for SIGTERM, SIGHUP and SIGCHLD
authorStefan Metzmacher <metze@samba.org>
Wed, 21 Jan 2009 22:24:18 +0000 (23:24 +0100)
committerStefan Metzmacher <metze@samba.org>
Tue, 27 Jan 2009 14:28:07 +0000 (15:28 +0100)
metze

source3/include/proto.h
source3/printing/printing.c
source3/smbd/globals.c
source3/smbd/globals.h
source3/smbd/process.c
source3/smbd/server.c

index c02a41a67822dc315ee79f43f59774a94f2273ae..d625f98186d86a6c8b985548582a10f64560c234 100644 (file)
@@ -7115,6 +7115,8 @@ SEC_DESC *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname);
 
 /* The following definitions come from smbd/process.c  */
 
+void smbd_setup_sig_term_handler(void);
+void smbd_setup_sig_hup_handler(void);
 bool srv_send_smb(int fd, char *buffer, bool do_encrypt);
 int srv_set_message(char *buf,
                         int num_words,
index bb293800078d1204b39238591325b4a83b8d0918..0721713c019da7b1126779c76982a4317c15406a 100644 (file)
@@ -22,8 +22,6 @@
 #include "includes.h"
 #include "printing.h"
 
-extern SIG_ATOMIC_T got_sig_term;
-extern SIG_ATOMIC_T reload_after_sighup;
 extern struct current_user current_user;
 extern userdom_struct current_user_info;
 
@@ -1427,6 +1425,9 @@ void start_background_queue(void)
                        smb_panic("reinit_after_fork() failed");
                }
 
+               smbd_setup_sig_term_handler();
+               smbd_setup_sig_hup_handler();
+
                claim_connection( NULL, "smbd lpq backend",
                        FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
 
@@ -1483,19 +1484,6 @@ void start_background_queue(void)
                                 exit_server_cleanly(NULL);
                        }
 
-                       /* check for some essential signals first */
-
-                        if (got_sig_term) {
-                                exit_server_cleanly(NULL);
-                        }
-
-                        if (reload_after_sighup) {
-                                change_to_root_user();
-                                DEBUG(1,("Reloading services after SIGHUP\n"));
-                                reload_services(False);
-                                reload_after_sighup = 0;
-                        }
-
                        if (run_events(smbd_event_context(), ret, &r_fds, &w_fds)) {
                                continue;
                        }
index c5681223f914ad8e3f9cb25cf65e62e1b5239751..d99f2b0680e2d84c0777c3ca13e742ca603cc377 100644 (file)
@@ -125,8 +125,6 @@ int max_send = BUFFER_SIZE;
  * Can be modified by the max xmit parameter.
  */
 int max_recv = BUFFER_SIZE;
-SIG_ATOMIC_T reload_after_sighup = 0;
-SIG_ATOMIC_T got_sig_term = 0;
 uint16 last_session_tag = UID_FIELD_INVALID;
 int trans_num = 0;
 char *orig_inbuf = NULL;
@@ -186,7 +184,6 @@ struct kernel_oplocks *koplocks = NULL;
 struct notify_mid_map *notify_changes_by_mid = NULL;
 
 int am_parent = 1;
-SIG_ATOMIC_T got_sig_cld = 0;
 int server_fd = -1;
 struct event_context *smbd_event_ctx = NULL;
 struct messaging_context *smbd_msg_ctx = NULL;
index 2c4f8b5821273c8ccd4e3043a4fcf2668f2b678d..15085d9d3540d32d6b9633d486457a721d27b9db 100644 (file)
@@ -124,8 +124,6 @@ extern int max_send;
  * Can be modified by the max xmit parameter.
  */
 extern int max_recv;
-extern SIG_ATOMIC_T reload_after_sighup;
-extern SIG_ATOMIC_T got_sig_term;
 extern uint16 last_session_tag;
 extern int trans_num;
 extern char *orig_inbuf;
@@ -199,7 +197,6 @@ extern struct kernel_oplocks *koplocks;
 extern struct notify_mid_map *notify_changes_by_mid;
 
 extern int am_parent;
-extern SIG_ATOMIC_T got_sig_cld;
 extern int server_fd;
 extern struct event_context *smbd_event_ctx;
 extern struct messaging_context *smbd_msg_ctx;
index a07b71e5ac3df0fe55d292117dc23b13400b2e64..2326bdab90a2548b29edb9b6a46fa8d0fe12ae27 100644 (file)
@@ -692,6 +692,56 @@ struct idle_event *event_add_idle(struct event_context *event_ctx,
        return result;
 }
 
+static void smbd_sig_term_handler(struct tevent_context *ev,
+                                 struct tevent_signal *se,
+                                 int signum,
+                                 int count,
+                                 void *siginfo,
+                                 void *private_data)
+{
+       exit_server_cleanly("termination signal");
+}
+
+void smbd_setup_sig_term_handler(void)
+{
+       struct tevent_signal *se;
+
+       se = tevent_add_signal(smbd_event_context(),
+                              smbd_event_context(),
+                              SIGTERM, 0,
+                              smbd_sig_term_handler,
+                              NULL);
+       if (!se) {
+               exit_server("failed to setup SIGTERM handler");
+       }
+}
+
+static void smbd_sig_hup_handler(struct tevent_context *ev,
+                                 struct tevent_signal *se,
+                                 int signum,
+                                 int count,
+                                 void *siginfo,
+                                 void *private_data)
+{
+       change_to_root_user();
+       DEBUG(1,("Reloading services after SIGHUP\n"));
+       reload_services(False);
+}
+
+void smbd_setup_sig_hup_handler(void)
+{
+       struct tevent_signal *se;
+
+       se = tevent_add_signal(smbd_event_context(),
+                              smbd_event_context(),
+                              SIGHUP, 0,
+                              smbd_sig_hup_handler,
+                              NULL);
+       if (!se) {
+               exit_server("failed to setup SIGHUP handler");
+       }
+}
+
 /****************************************************************************
  Do all async processing in here. This includes kernel oplock messages, change
  notify events etc.
@@ -709,18 +759,6 @@ static void async_processing(void)
           select and may have eaten our signal. */
        /* Is this till true? -- vl */
        process_aio_queue();
-
-       if (got_sig_term) {
-               exit_server_cleanly("termination signal");
-       }
-
-       /* check for sighup processing */
-       if (reload_after_sighup) {
-               change_to_root_user();
-               DEBUG(1,("Reloading services after SIGHUP\n"));
-               reload_services(False);
-               reload_after_sighup = 0;
-       }
 }
 
 /****************************************************************************
@@ -1830,9 +1868,8 @@ void check_reload(time_t t)
                mypid = getpid();
        }
 
-       if (reload_after_sighup || (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK)) {
+       if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
                reload_services(True);
-               reload_after_sighup = False;
                last_smb_conf_reload_time = t;
        }
 
index c5d3c8932a0be8ff9046af50ec9e966fcf1b1769..e6ea5f39865ec8bcd592b28688196a78183451f3 100644 (file)
@@ -113,35 +113,6 @@ static void smb_stat_cache_delete(struct messaging_context *msg,
        stat_cache_delete(name);
 }
 
-/****************************************************************************
- Terminate signal.
-****************************************************************************/
-
-static void sig_term(void)
-{
-       got_sig_term = 1;
-       sys_select_signal(SIGTERM);
-}
-
-/****************************************************************************
- Catch a sighup.
-****************************************************************************/
-
-static void sig_hup(int sig)
-{
-       reload_after_sighup = 1;
-       sys_select_signal(SIGHUP);
-}
-
-/****************************************************************************
- Catch a sigcld
-****************************************************************************/
-static void sig_cld(int sig)
-{
-       got_sig_cld = 1;
-       sys_select_signal(SIGCLD);
-}
-
 /****************************************************************************
   Send a SIGTERM to our process group.
 *****************************************************************************/
@@ -298,6 +269,50 @@ static bool allowable_number_of_smbd_processes(void)
        return num_children < max_processes;
 }
 
+static void smbd_sig_chld_handler(struct tevent_context *ev,
+                                 struct tevent_signal *se,
+                                 int signum,
+                                 int count,
+                                 void *siginfo,
+                                 void *private_data)
+{
+       pid_t pid;
+       int status;
+
+       while ((pid = sys_waitpid(-1, &status, WNOHANG)) > 0) {
+               bool unclean_shutdown = False;
+
+               /* If the child terminated normally, assume
+                  it was an unclean shutdown unless the
+                  status is 0
+               */
+               if (WIFEXITED(status)) {
+                       unclean_shutdown = WEXITSTATUS(status);
+               }
+               /* If the child terminated due to a signal
+                  we always assume it was unclean.
+               */
+               if (WIFSIGNALED(status)) {
+                       unclean_shutdown = True;
+               }
+               remove_child_pid(pid, unclean_shutdown);
+       }
+}
+
+static void smbd_setup_sig_chld_handler(void)
+{
+       struct tevent_signal *se;
+
+       se = tevent_add_signal(smbd_event_context(),
+                              smbd_event_context(),
+                              SIGCHLD, 0,
+                              smbd_sig_chld_handler,
+                              NULL);
+       if (!se) {
+               exit_server("failed to setup SIGCHLD handler");
+       }
+}
+
 /****************************************************************************
  Open the socket communication.
 ****************************************************************************/
@@ -324,7 +339,7 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
 #endif
 
        /* Stop zombies */
-       CatchSignal(SIGCLD, sig_cld);
+       smbd_setup_sig_chld_handler();
 
        FD_ZERO(&listen_set);
 
@@ -550,32 +565,6 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
                fd_set r_fds, w_fds;
                int num;
 
-               if (got_sig_cld) {
-                       pid_t pid;
-                       int status;
-
-                       got_sig_cld = False;
-
-                       while ((pid = sys_waitpid(-1, &status, WNOHANG)) > 0) {
-                               bool unclean_shutdown = False;
-                               
-                               /* If the child terminated normally, assume
-                                  it was an unclean shutdown unless the
-                                  status is 0 
-                               */
-                               if (WIFEXITED(status)) {
-                                       unclean_shutdown = WEXITSTATUS(status);
-                               }
-                               /* If the child terminated due to a signal
-                                  we always assume it was unclean.
-                               */
-                               if (WIFSIGNALED(status)) {
-                                       unclean_shutdown = True;
-                               }
-                               remove_child_pid(pid, unclean_shutdown);
-                       }
-               }
-
                if (run_events(smbd_event_context(), 0, NULL, NULL)) {
                        continue;
                }
@@ -605,23 +594,6 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
                        continue;
                }
 
-               if (num == -1 && errno == EINTR) {
-                       if (got_sig_term) {
-                               exit_server_cleanly(NULL);
-                       }
-
-                       /* check for sighup processing */
-                       if (reload_after_sighup) {
-                               change_to_root_user();
-                               DEBUG(1,("Reloading services after SIGHUP\n"));
-                               reload_services(False);
-                               reload_after_sighup = 0;
-                       }
-
-                       continue;
-               }
-               
-
                /* If the idle timeout fired and we don't have any connected
                 * users, exit gracefully. We should be running under a process
                 * controller that will restart us if necessry.
@@ -698,6 +670,9 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
                                        smb_panic("reinit_after_fork() failed");
                                }
 
+                               smbd_setup_sig_term_handler();
+                               smbd_setup_sig_hup_handler();
+
                                return True;
                        }
                        /* The parent doesn't need this socket */
@@ -1078,9 +1053,6 @@ extern void build_options(bool screen);
        fault_setup((void (*)(void *))exit_server_fault);
        dump_core_setup("smbd");
 
-       CatchSignal(SIGTERM , SIGNAL_CAST sig_term);
-       CatchSignal(SIGHUP,SIGNAL_CAST sig_hup);
-       
        /* we are never interested in SIGPIPE */
        BlockSignals(True,SIGPIPE);
 
@@ -1190,6 +1162,9 @@ extern void build_options(bool screen);
                exit(1);
        }
 
+       smbd_setup_sig_term_handler();
+       smbd_setup_sig_hup_handler();
+
        /* Setup all the TDB's - including CLEAR_IF_FIRST tdb's. */
 
        if (smbd_memcache() == NULL) {