diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2017-09-17 10:36:07 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2017-09-17 10:36:07 +0100 |
commit | 3e23c6b1128023a94a440b118eabf8df5b33090f (patch) | |
tree | 300824b9de818e5f4ddbcb64d1bb8b0d73a1a567 /src | |
parent | 609d4f862202c43241fdab06b0795db6281ca3f7 (diff) | |
download | rspamd-3e23c6b1128023a94a440b118eabf8df5b33090f.tar.gz rspamd-3e23c6b1128023a94a440b118eabf8df5b33090f.zip |
[Feature] Improve subprocesses termination handle
Diffstat (limited to 'src')
-rw-r--r-- | src/libserver/worker_util.c | 46 | ||||
-rw-r--r-- | src/libserver/worker_util.h | 11 | ||||
-rw-r--r-- | src/lua/lua_common.c | 2 | ||||
-rw-r--r-- | src/rspamd.c | 12 |
4 files changed, 69 insertions, 2 deletions
diff --git a/src/libserver/worker_util.c b/src/libserver/worker_util.c index 2edaa2612..38e58aa83 100644 --- a/src/libserver/worker_util.c +++ b/src/libserver/worker_util.c @@ -186,6 +186,34 @@ rspamd_worker_ignore_signal (int signo) sigaction (signo, &sig, NULL); } +static void +rspamd_worker_default_signal (int signo) +{ + struct sigaction sig; + + sigemptyset (&sig.sa_mask); + sigaddset (&sig.sa_mask, signo); + sig.sa_handler = SIG_DFL; + sig.sa_flags = 0; + sigaction (signo, &sig, NULL); +} + +static void +rspamd_sigh_free (void *p) +{ + struct rspamd_worker_signal_handler *sigh = p; + struct rspamd_worker_signal_cb *cb, *tmp; + + DL_FOREACH_SAFE (sigh->cb, cb, tmp) { + DL_DELETE (sigh->cb, cb); + g_free (cb); + } + + event_del (&sigh->ev); + rspamd_worker_default_signal (sigh->signo); + g_free (sigh); +} + void rspamd_worker_set_signal_handler (int signo, struct rspamd_worker *worker, struct event_base *base, @@ -219,7 +247,7 @@ rspamd_worker_set_signal_handler (int signo, struct rspamd_worker *worker, DL_APPEND (sigh->cb, cb); } -static void +void rspamd_worker_init_signals (struct rspamd_worker *worker, struct event_base *base) { struct sigaction signals; @@ -274,7 +302,7 @@ rspamd_prepare_worker (struct rspamd_worker *worker, const char *name, worker->srv->pid = getpid (); worker->signal_events = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, g_free); + NULL, rspamd_sigh_free); ev_base = event_init (); @@ -663,6 +691,20 @@ rspamd_worker_block_signals (void) } void +rspamd_worker_unblock_signals (void) +{ + sigset_t set; + + sigemptyset (&set); + sigaddset (&set, SIGTERM); + sigaddset (&set, SIGINT); + sigaddset (&set, SIGHUP); + sigaddset (&set, SIGUSR1); + sigaddset (&set, SIGUSR2); + sigprocmask (SIG_UNBLOCK, &set, NULL); +} + +void rspamd_hard_terminate (struct rspamd_main *rspamd_main) { GHashTableIter it; diff --git a/src/libserver/worker_util.h b/src/libserver/worker_util.h index d8decbac8..3af9c961d 100644 --- a/src/libserver/worker_util.h +++ b/src/libserver/worker_util.h @@ -31,6 +31,12 @@ struct rspamd_worker; struct rspamd_worker_signal_handler; /** + * Init basic signals for a worker + * @param worker + * @param base + */ +void rspamd_worker_init_signals (struct rspamd_worker *worker, struct event_base *base); +/** * Prepare worker's startup * @param worker worker structure * @param name name of the worker @@ -124,6 +130,11 @@ void rspamd_worker_stop_accept (struct rspamd_worker *worker); void rspamd_worker_block_signals (void); /** + * Unblock signals + */ +void rspamd_worker_unblock_signals (void); + +/** * Kill rspamd main and all workers * @param rspamd_main */ diff --git a/src/lua/lua_common.c b/src/lua/lua_common.c index 2aed2f7a9..b72c80a15 100644 --- a/src/lua/lua_common.c +++ b/src/lua/lua_common.c @@ -1695,6 +1695,8 @@ lua_worker_spawn_process (lua_State *L) /* Here we assume that we can block on writing results */ rspamd_socket_blocking (cbdata->sp[1]); event_reinit (cbdata->ev_base); + g_hash_table_remove_all (w->signal_events); + rspamd_worker_unblock_signals (); rspamd_lua_execute_lua_subprocess (L, cbdata); /* Wait for parent to reply and exit */ diff --git a/src/rspamd.c b/src/rspamd.c index 01377e7cf..1b24fd67a 100644 --- a/src/rspamd.c +++ b/src/rspamd.c @@ -730,10 +730,22 @@ wait_for_workers (gpointer key, gpointer value, gpointer unused) } } } + else if (nowait) { + kill (w->pid, 0); + + if (errno != ESRCH) { + return FALSE; + } + else { + goto finished; + } + } return FALSE; } + + finished: msg_info_main ("%s process %P terminated %s", g_quark_to_string (w->type), w->pid, |