summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2009-01-21 23:24:18 +0100
committerStefan Metzmacher <metze@samba.org>2009-01-27 15:28:07 +0100
commitac61f650ae640c13beee9d48304d7939f700aa11 (patch)
treeb512f8c4cdd63260bbbb1ee2d50807b98d99cab1 /source3/smbd
parent27f812f3a85ce21ca79143f59c823913f57fa507 (diff)
downloadsamba-ac61f650ae640c13beee9d48304d7939f700aa11.tar.gz
samba-ac61f650ae640c13beee9d48304d7939f700aa11.tar.bz2
samba-ac61f650ae640c13beee9d48304d7939f700aa11.zip
s3:smbd: use signal events for SIGTERM, SIGHUP and SIGCHLD
metze
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/globals.c3
-rw-r--r--source3/smbd/globals.h3
-rw-r--r--source3/smbd/process.c65
-rw-r--r--source3/smbd/server.c127
4 files changed, 102 insertions, 96 deletions
diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c
index c5681223f9..d99f2b0680 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 2c4f8b5821..15085d9d35 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 a07b71e5ac..2326bdab90 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 c5d3c8932a..e6ea5f3986 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -114,35 +114,6 @@ static void smb_stat_cache_delete(struct messaging_context *msg,
}
/****************************************************************************
- 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) {