aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2017-09-17 10:36:07 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2017-09-17 10:36:07 +0100
commit3e23c6b1128023a94a440b118eabf8df5b33090f (patch)
tree300824b9de818e5f4ddbcb64d1bb8b0d73a1a567 /src
parent609d4f862202c43241fdab06b0795db6281ca3f7 (diff)
downloadrspamd-3e23c6b1128023a94a440b118eabf8df5b33090f.tar.gz
rspamd-3e23c6b1128023a94a440b118eabf8df5b33090f.zip
[Feature] Improve subprocesses termination handle
Diffstat (limited to 'src')
-rw-r--r--src/libserver/worker_util.c46
-rw-r--r--src/libserver/worker_util.h11
-rw-r--r--src/lua/lua_common.c2
-rw-r--r--src/rspamd.c12
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,