]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Feature] Improve subprocesses termination handle
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Sun, 17 Sep 2017 09:36:07 +0000 (10:36 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Sun, 17 Sep 2017 09:36:07 +0000 (10:36 +0100)
src/libserver/worker_util.c
src/libserver/worker_util.h
src/lua/lua_common.c
src/rspamd.c

index 2edaa2612b833739a64b2fb497d0881195199677..38e58aa838ac9d866be5c14fac540e8c9015bea3 100644 (file)
@@ -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 ();
 
@@ -662,6 +690,20 @@ rspamd_worker_block_signals (void)
        sigprocmask (SIG_BLOCK, &set, NULL);
 }
 
+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)
 {
index d8decbac8313407b838c7455d7993e72be47bdf8..3af9c961dc04bc781e75995edb5988ec5b5468b0 100644 (file)
@@ -30,6 +30,12 @@ typedef void (*rspamd_sig_handler_t) (gint, siginfo_t *, void *);
 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
@@ -123,6 +129,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
index 2aed2f7a9baf5c00772b67b6a80c8f198147b76c..b72c80a15edb90d23319145076cc2a1659da25b2 100644 (file)
@@ -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 */
index 01377e7cf4fbdec0509af51ba07c34ec421f62fe..1b24fd67aaf791f144e47f15f8835a581bb8611e 100644 (file)
@@ -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,