1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

s3:smbd: use signal events for SIGTERM, SIGHUP and SIGCHLD

metze
This commit is contained in:
Stefan Metzmacher 2009-01-21 23:24:18 +01:00
parent 27f812f3a8
commit ac61f650ae
6 changed files with 107 additions and 111 deletions

View 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,

View 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;
}

View 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;

View 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;

View 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;
}

View 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) {