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:
parent
27f812f3a8
commit
ac61f650ae
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user