]> source.dussan.org Git - rspamd.git/commitdiff
* Add more advanced signal processing routine
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 5 Nov 2009 15:09:54 +0000 (18:09 +0300)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 5 Nov 2009 15:09:54 +0000 (18:09 +0300)
CMakeLists.txt
config.h.in
src/controller.c
src/filter.c
src/fuzzy_storage.c
src/lmtp.c
src/main.c
src/util.c
src/util.h
src/worker.c

index 528b99c62df5017ecabb34e2c7fbd5990eb2d2ff..a8f4b67683348d80b78ee32444b1ae6048122eb8 100644 (file)
@@ -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 <sys/types.h>
index b80f399e8baeba6190045edceee399adf8853869..e672c6d8873288dac7d630ff5fb88d85e9a58336 100644 (file)
@@ -94,6 +94,8 @@
 
 #cmakedefine HAVE_FLOCK          1
 
+#cmakedefine HAVE_SA_SIGINFO     1
+
 #cmakedefine DEBUG_MODE          1
 
 #cmakedefine GMIME24             1
index 64ef75d59a19bf946afc40f1cc9d514934bde339..d59690da2d1e9bfad945cdcd58bee5343d7fd573 100644 (file)
@@ -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:
index fc23d81b902bd7bbe73d08b4b63fb2b2ee277635..11683d0d485c2f02b6cdfbf8815229699ef0173c 100644 (file)
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <sys/types.h>
-#include <glib.h>
-#include <string.h>
-#include <stdlib.h>
-
+#include "config.h"
 #include "mem_pool.h"
 #include "filter.h"
 #include "main.h"
index 68da96b44fe717b7bfd747f35df9c14d4098b4f0..74ad906940017bccbeec557e2fd259143960c552 100644 (file)
@@ -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:
index f9bd6f65e9db59ea275cde7ca7bacd4f84ff5bfa..e07971f5e4dd2f8f77be44549a6711d596817fb3 100644 (file)
@@ -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:
index 4a02fa1596de19f1f5e2d743cafd33b6e5c41a5d..df3945ae12581d31f40b0ead5177a18b5633ba32 100644 (file)
@@ -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);
index fbb5cb547e5c73af1f44332fc763598bf1da085f..425aed43915f1c9d38dd9a9cdefb85875d285f25 100644 (file)
@@ -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);
index dfc08aa7d2164a0fad7e01f60b1bcd873771184a..3def85b8a4e74b3b5826ff1cf24fb6820cdcbbc2 100644 (file)
@@ -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 */
index 222b36971ea39bd673fff3798f1d7c0d7465e2d6..21fcc904131336d91dc429f791252f07d76e4ecb 100644 (file)
@@ -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: