From ac61f650ae640c13beee9d48304d7939f700aa11 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Jan 2009 23:24:18 +0100 Subject: [PATCH] s3:smbd: use signal events for SIGTERM, SIGHUP and SIGCHLD metze --- source3/include/proto.h | 2 + source3/printing/printing.c | 18 +---- source3/smbd/globals.c | 3 - source3/smbd/globals.h | 3 - source3/smbd/process.c | 65 ++++++++++++++---- source3/smbd/server.c | 127 +++++++++++++++--------------------- 6 files changed, 107 insertions(+), 111 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index c02a41a67822..d625f98186d8 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -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, diff --git a/source3/printing/printing.c b/source3/printing/printing.c index bb293800078d..0721713c019d 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -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; } diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c index c5681223f914..d99f2b0680e2 100644 --- a/source3/smbd/globals.c +++ b/source3/smbd/globals.c @@ -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; diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 2c4f8b582127..15085d9d3540 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -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; diff --git a/source3/smbd/process.c b/source3/smbd/process.c index a07b71e5ac3d..2326bdab90a2 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -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; } diff --git a/source3/smbd/server.c b/source3/smbd/server.c index c5d3c8932a0b..e6ea5f39865e 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -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) { -- 2.34.1