From 9b6b141a936bb7ba89c431176fa53a5878b8a9bd Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Thu, 5 Nov 2009 18:09:54 +0300 Subject: [PATCH] * Add more advanced signal processing routine --- CMakeLists.txt | 1 + config.h.in | 2 ++ src/controller.c | 8 +++-- src/filter.c | 6 +--- src/fuzzy_storage.c | 5 +++ src/lmtp.c | 8 +++-- src/main.c | 87 +++++++++++++++++++++++++++++++++++++++++++-- src/util.c | 13 ++++++- src/util.h | 6 +++- src/worker.c | 8 +++-- 10 files changed, 128 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 528b99c62..a8f4b6768 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -249,6 +249,7 @@ CHECK_SYMBOL_EXISTS(MAP_SHARED sys/mman.h HAVE_MMAP_SHARED) CHECK_SYMBOL_EXISTS(MAP_ANON sys/mman.h HAVE_MMAP_ANON) CHECK_SYMBOL_EXISTS(_SC_NPROCESSORS_ONLN unistd.h HAVE_SC_NPROCESSORS_ONLN) CHECK_SYMBOL_EXISTS(CLOCK_PROCESS_CPUTIME_ID time.h HAVE_CLOCK_PROCESS_CPUTIME_ID) +CHECK_SYMBOL_EXISTS(SA_SIGINFO signal.h HAVE_SA_SIGINFO) CHECK_SYMBOL_EXISTS(CLOCK_VIRTUAL time.h HAVE_CLOCK_VIRTUAL) CHECK_C_SOURCE_COMPILES ("#include diff --git a/config.h.in b/config.h.in index b80f399e8..e672c6d88 100644 --- a/config.h.in +++ b/config.h.in @@ -94,6 +94,8 @@ #cmakedefine HAVE_FLOCK 1 +#cmakedefine HAVE_SA_SIGINFO 1 + #cmakedefine DEBUG_MODE 1 #cmakedefine GMIME24 1 diff --git a/src/controller.c b/src/controller.c index 64ef75d59..d59690da2 100644 --- a/src/controller.c +++ b/src/controller.c @@ -86,9 +86,13 @@ extern rspamd_hash_t *counters; static gboolean controller_write_socket (void *arg); -static - void +#ifndef HAVE_SA_SIGINFO +static void sig_handler (int signo) +#else +static void +sig_handler (int signo, siginfo_t *info, void *unused) +#endif { switch (signo) { case SIGINT: diff --git a/src/filter.c b/src/filter.c index fc23d81b9..11683d0d4 100644 --- a/src/filter.c +++ b/src/filter.c @@ -22,11 +22,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include -#include - +#include "config.h" #include "mem_pool.h" #include "filter.h" #include "main.h" diff --git a/src/fuzzy_storage.c b/src/fuzzy_storage.c index 68da96b44..74ad90694 100644 --- a/src/fuzzy_storage.c +++ b/src/fuzzy_storage.c @@ -66,8 +66,13 @@ struct rspamd_fuzzy_node { uint64_t time; }; +#ifndef HAVE_SA_SIGINFO static void sig_handler (int signo) +#else +static void +sig_handler (int signo, siginfo_t *info, void *unused) +#endif { switch (signo) { case SIGINT: diff --git a/src/lmtp.c b/src/lmtp.c index f9bd6f65e..e07971f5e 100644 --- a/src/lmtp.c +++ b/src/lmtp.c @@ -38,9 +38,13 @@ static struct timeval io_tv; static gboolean lmtp_write_socket (void *arg); -static - void +#ifndef HAVE_SA_SIGINFO +static void sig_handler (int signo) +#else +static void +sig_handler (int signo, siginfo_t *info, void *unused) +#endif { switch (signo) { case SIGINT: diff --git a/src/main.c b/src/main.c index 4a02fa159..df3945ae1 100644 --- a/src/main.c +++ b/src/main.c @@ -51,7 +51,6 @@ struct config_file *cfg; rspamd_hash_t *counters; -static void sig_handler (int); static struct rspamd_worker *fork_worker (struct rspamd_main *, struct worker_conf *); sig_atomic_t do_restart; @@ -59,6 +58,10 @@ sig_atomic_t do_terminate; sig_atomic_t child_dead; sig_atomic_t got_alarm; +#ifdef HAVE_SA_SIGINFO +GQueue *signals_info; +#endif + extern int yynerrs; extern FILE *yyin; @@ -73,10 +76,21 @@ extern PerlInterpreter *perl_interpreter; /* List of workers that are pending to start */ static GList *workers_pending = NULL; -static - void +#ifndef HAVE_SA_SIGINFO +static void sig_handler (int signo) +#else +static void +sig_handler (int signo, siginfo_t *info, void *unused) +#endif { +#ifdef HAVE_SA_SIGINFO + siginfo_t *new_info; + new_info = g_malloc (sizeof (siginfo_t)); + memcpy (new_info, info, sizeof (siginfo_t)); + g_queue_push_head (signals_info, new_info); +#endif + switch (signo) { case SIGHUP: do_restart = 1; @@ -98,6 +112,67 @@ sig_handler (int signo) } } +#ifdef HAVE_SA_SIGINFO + +static const char * +strsigcode (int code) +{ + switch (code) { + case SI_USER: + return "kill(2) or raise(3)"; + break; + case SI_KERNEL: + return "sent by the kernel"; + break; + case SI_TIMER: + return "POSIX timer expired"; + break; + case SI_SIGIO: + return "queued SIGIO"; + break; + default: + return "unknown reason"; + } +} + +static const char * +chldsigcode (int code) { + switch (code) { + case CLD_EXITED: + return "Child exited normally"; + case CLD_KILLED: + return "Child has terminated abnormally but did not create a core file"; + case CLD_DUMPED: + return "Child has terminated abnormally and created a core file"; + case CLD_TRAPPED: + return "Traced child has trapped"; + default: + return "Unknown reason"; + } +} + +/* Prints info about incoming signals by parsing siginfo structures */ +static void +print_signals_info () +{ + siginfo_t *inf; + + while ((inf = g_queue_pop_head (signals_info))) { + if (inf->si_signo == SIGCHLD) { + msg_info ("main: got SIGCHLD from child: %ld; reason: '%s'", + (long int)inf->si_pid, chldsigcode (inf->si_code)); + } + else { + msg_info ("main: got signal: '%s'; received from pid: %ld; uid: %ld; reason: '%s'", + g_strsignal (inf->si_signo), (long int)inf->si_pid, (long int)inf->si_uid, + strsigcode (inf->si_code)); + } + g_free (inf); + } +} +#endif + + static void read_cmd_line (int argc, char **argv, struct config_file *cfg) { @@ -506,6 +581,9 @@ main (int argc, char **argv, char **env) char *args[] = { "", "-e", "0", NULL }; #endif +#ifdef HAVE_SA_SIGINFO + signals_info = g_queue_new (); +#endif rspamd = (struct rspamd_main *)g_malloc (sizeof (struct rspamd_main)); bzero (rspamd, sizeof (struct rspamd_main)); rspamd->server_pool = memory_pool_new (memory_pool_get_size ()); @@ -734,6 +812,9 @@ main (int argc, char **argv, char **env) msg_debug ("main: calling sigsuspend"); sigemptyset (&signals.sa_mask); sigsuspend (&signals.sa_mask); +#ifdef HAVE_SA_SIGINFO + print_signals_info (); +#endif if (do_terminate) { msg_debug ("main: catch termination signal, waiting for childs"); pass_signal_worker (rspamd->workers, SIGTERM); diff --git a/src/util.c b/src/util.c index fbb5cb547..425aed439 100644 --- a/src/util.c +++ b/src/util.c @@ -305,8 +305,13 @@ write_pid (struct rspamd_main *main) return 0; } +#ifdef HAVE_SA_SIGINFO void -init_signals (struct sigaction *signals, sig_t sig_handler) +init_signals (struct sigaction *signals, void (*sig_handler)(int, siginfo_t *, void *)) +#else +void +init_signals (struct sigaction *signals, sighandler_t sig_handler) +#endif { struct sigaction sigpipe_act; /* Setting up signal handlers */ @@ -322,8 +327,14 @@ init_signals (struct sigaction *signals, sig_t sig_handler) sigaddset (&signals->sa_mask, SIGALRM); +#ifdef HAVE_SA_SIGINFO + signals->sa_flags = SA_SIGINFO; + signals->sa_handler = NULL; + signals->sa_sigaction = sig_handler; +#else signals->sa_handler = sig_handler; signals->sa_flags = 0; +#endif sigaction (SIGTERM, signals, NULL); sigaction (SIGINT, signals, NULL); sigaction (SIGHUP, signals, NULL); diff --git a/src/util.h b/src/util.h index dfc08aa7d..3def85b8a 100644 --- a/src/util.h +++ b/src/util.h @@ -25,7 +25,11 @@ int make_socket_blocking (int); /* Poll sync socket for specified events */ int poll_sync_socket (int fd, int timeout, short events); /* Init signals */ -void init_signals (struct sigaction *, sig_t); +#ifdef HAVE_SA_SIGINFO +void init_signals (struct sigaction *sa, void (*sig_handler)(int, siginfo_t *, void *)); +#else +void init_signals (struct sigaction *sa, sighandler_t); +#endif /* Send specified signal to each worker */ void pass_signal_worker (GHashTable *, int ); /* Convert string to lowercase */ diff --git a/src/worker.c b/src/worker.c index 222b36971..21fcc9041 100644 --- a/src/worker.c +++ b/src/worker.c @@ -56,9 +56,13 @@ static gboolean is_mime; static gboolean write_socket (void *arg); -static - void +#ifndef HAVE_SA_SIGINFO +static void sig_handler (int signo) +#else +static void +sig_handler (int signo, siginfo_t *info, void *unused) +#endif { switch (signo) { case SIGINT: -- 2.39.5