}
#endif
+static struct rspamd_main *saved_main = NULL;
+static gboolean
+rspamd_crash_propagate (gpointer key, gpointer value, gpointer unused)
+{
+ struct rspamd_worker *w = value;
+
+ /* Kill children softly */
+ kill (w->pid, SIGTERM);
+
+ return TRUE;
+}
+
static void
rspamd_crash_sig_handler (int sig, siginfo_t *info, void *ctx)
{
struct sigaction sa;
ucontext_t *uap = ctx;
+ pid_t pid;
+ pid = getpid ();
msg_err ("caught fatal signal %d(%s), "
"pid: %P, trace: ",
- sig, strsignal (sig), getpid ());
+ sig, strsignal (sig), pid);
(void)uap;
#ifdef WITH_LIBUNWIND
rspamd_print_crash (uap);
#endif
+ if (saved_main) {
+ if (pid == saved_main->pid) {
+ /*
+ * Main process has crashed, propagate crash further to trigger
+ * monitoring alerts and mass panic
+ */
+ g_hash_table_foreach_remove (saved_main->workers,
+ rspamd_crash_propagate, NULL);
+ }
+ }
+
/*
* Invoke signal with the default handler
*/
sa.sa_handler = SIG_DFL;
sa.sa_flags = 0;
sigaction (sig, &sa, NULL);
- kill (getpid (), sig);
+ kill (pid, sig);
}
#endif
void
-rspamd_set_crash_handler (struct rspamd_main *main)
+rspamd_set_crash_handler (struct rspamd_main *rspamd_main)
{
#ifdef HAVE_SA_SIGINFO
struct sigaction sa;
ss.ss_sp = g_malloc0 (ss.ss_size);
sigaltstack (&ss, NULL);
#endif
-
- sigemptyset(&sa.sa_mask);
+ saved_main = rspamd_main;
+ sigemptyset (&sa.sa_mask);
sa.sa_sigaction = &rspamd_crash_sig_handler;
sa.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
- sigaction(SIGSEGV, &sa, NULL);
- sigaction(SIGBUS, &sa, NULL);
- sigaction(SIGABRT, &sa, NULL);
- sigaction(SIGFPE, &sa, NULL);
- sigaction(SIGSYS, &sa, NULL);
+ sigaction (SIGSEGV, &sa, NULL);
+ sigaction (SIGBUS, &sa, NULL);
+ sigaction (SIGABRT, &sa, NULL);
+ sigaction (SIGFPE, &sa, NULL);
+ sigaction (SIGSYS, &sa, NULL);
#endif
}
\ No newline at end of file
struct event term_ev, int_ev, cld_ev, hup_ev, usr1_ev, control_ev;
struct timeval term_tv;
struct rspamd_main *rspamd_main;
- gboolean skip_pid = FALSE;
+ gboolean skip_pid = FALSE, valgrind_mode = FALSE;
#if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION <= 30))
g_thread_init (NULL);
rspamd_spair_equal, g_free, rspamd_spair_close);
rspamd_main->start_mtx = rspamd_mempool_get_mutex (rspamd_main->server_pool);
+ if (getenv ("VALGRIND") != NULL) {
+ valgrind_mode = TRUE;
+ }
+
#ifndef HAVE_SETPROCTITLE
init_title (rspamd_main, argc, argv, env);
#endif
}
type = g_quark_from_static_string ("main");
- rspamd_set_crash_handler (rspamd_main);
/* First set logger to console logger */
rspamd_main->cfg->log_type = RSPAMD_LOG_CONSOLE;
rspamd_main->pid = getpid ();
rspamd_main->type = type;
+ if (!valgrind_mode) {
+ rspamd_set_crash_handler (rspamd_main);
+ }
+
/* Ignore SIGPIPE as we handle write errors manually */
sigemptyset (&sigpipe_act.sa_mask);
sigaddset (&sigpipe_act.sa_mask, SIGPIPE);
close (control_fd);
}
- if (getenv ("VALGRIND") != NULL) {
+ if (valgrind_mode) {
/* Special case if we are likely running with valgrind */
term_attempts = TERMINATION_ATTEMPTS * 10;
}