]> source.dussan.org Git - rspamd.git/commitdiff
Enable core files limits for rspamd
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 11 Dec 2015 17:35:58 +0000 (17:35 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 11 Dec 2015 17:35:58 +0000 (17:35 +0000)
config.h.in
src/libserver/worker_util.c
src/rspamd.c
src/rspamd.h

index 6615deadf4dcd50634ca1e7a970275c67822eea2..90827801376c847545cd0e63327685da0cd2a880 100644 (file)
@@ -52,6 +52,7 @@
 #cmakedefine HAVE_NANOSLEEP      1
 #cmakedefine HAVE_NETDB_H        1
 #cmakedefine HAVE_NETINET_IN_H   1
+#cmakedefine HAVE_NFTW           1
 #cmakedefine HAVE_OASYNC         1
 #cmakedefine HAVE_OPENSSL               1
 #cmakedefine HAVE_O_DIRECT       1
index ef2b8857891d1d622a2ff14148141f56c5c880f3..9733bda3f3fb7f738ba20e25922ee732a03cc02b 100644 (file)
@@ -423,16 +423,28 @@ rspamd_worker_set_limits (struct rspamd_main *rspamd_main,
                }
        }
 
-       if (cf->rlimit_maxcore != 0) {
-               rlmt.rlim_cur = (rlim_t) cf->rlimit_maxcore;
-               rlmt.rlim_max = (rlim_t) cf->rlimit_maxcore;
+       if (rspamd_main->cores_throttling) {
+               msg_info_main ("disable core files for the new worker, as limits are reached");
+               rlmt.rlim_cur = 0;
+               rlmt.rlim_max = 0;
 
                if (setrlimit (RLIMIT_CORE, &rlmt) == -1) {
-                       msg_warn_main ("cannot set max core rlimit: %d, %s",
-                                       cf->rlimit_maxcore,
+                       msg_warn_main ("cannot disable core: %s",
                                        strerror (errno));
                }
        }
+       else {
+               if (cf->rlimit_maxcore != 0) {
+                       rlmt.rlim_cur = (rlim_t) cf->rlimit_maxcore;
+                       rlmt.rlim_max = (rlim_t) cf->rlimit_maxcore;
+
+                       if (setrlimit (RLIMIT_CORE, &rlmt) == -1) {
+                               msg_warn_main ("cannot set max core rlimit: %d, %s",
+                                               cf->rlimit_maxcore,
+                                               strerror (errno));
+                       }
+               }
+       }
 }
 
 struct rspamd_worker *
index 6f2e500f8f1736caa1d244b11de9e2053d48b4b1..004e726b653bc3df1141b0603243c7931813ccb5 100644 (file)
 #include <grp.h>
 #endif
 
+#ifdef HAVE_NFTW
+#include <ftw.h>
+#endif
+
 #include <signal.h>
 #ifdef HAVE_SYS_WAIT_H
 #include <sys/wait.h>
@@ -610,6 +614,96 @@ wait_for_workers (gpointer key, gpointer value, gpointer unused)
        return TRUE;
 }
 
+struct core_check_cbdata {
+       struct rspamd_config *cfg;
+       gsize total_count;
+       gsize total_size;
+};
+
+#ifdef HAVE_NFTW
+
+static struct core_check_cbdata cores_cbdata;
+
+static gint
+rspamd_check_core_cb (const gchar *path, const struct stat *st,
+               gint flag, struct FTW *ft)
+{
+       if (S_ISREG (st->st_mode)) {
+               cores_cbdata.total_count ++;
+               cores_cbdata.total_size += st->st_size;
+       }
+
+       return 0;
+}
+
+#endif
+
+static void
+rspamd_check_core_limits (struct rspamd_main *rspamd_main)
+{
+#ifdef HAVE_NFTW
+       struct rspamd_config *cfg = rspamd_main->cfg;
+
+       cores_cbdata.cfg = cfg;
+       cores_cbdata.total_count = 0;
+       cores_cbdata.total_size = 0;
+
+       if (cfg->cores_dir && (cfg->max_cores_count || cfg->max_cores_size)) {
+               if (nftw (cfg->cores_dir, rspamd_check_core_cb, 20, FTW_MOUNT|FTW_PHYS)
+                                       == -1) {
+                       msg_err_main ("nftw failed for path %s: %s", cfg->cores_dir,
+                                       strerror (errno));
+               }
+               else {
+                       if (!rspamd_main->cores_throttling) {
+                               if (cfg->max_cores_size &&
+                                               cores_cbdata.total_size > cfg->max_cores_size) {
+                                       msg_warn_main (
+                                                       "enable cores throttling as size of cores in"
+                                                                       " %s is %Hz, limit is %Hz",
+                                                       cfg->cores_dir,
+                                                       cores_cbdata.total_size,
+                                                       cfg->max_cores_size);
+                                       rspamd_main->cores_throttling = TRUE;
+                               }
+                               if (cfg->max_cores_count &&
+                                               cores_cbdata.total_count > cfg->max_cores_count) {
+                                       msg_warn_main (
+                                                       "enable cores throttling as count of cores in"
+                                                                       " %s is %z, limit is %z",
+                                                       cfg->cores_dir,
+                                                       cores_cbdata.total_count,
+                                                       cfg->max_cores_count);
+                                       rspamd_main->cores_throttling = TRUE;
+                               }
+                       }
+                       else {
+                               if (cfg->max_cores_size &&
+                                               cores_cbdata.total_size < cfg->max_cores_size) {
+                                       msg_info_main (
+                                                       "disable cores throttling as size of cores in"
+                                                                       " %s is now %Hz, limit is %Hz",
+                                                       cfg->cores_dir,
+                                                       cores_cbdata.total_size,
+                                                       cfg->max_cores_size);
+                                       rspamd_main->cores_throttling = FALSE;
+                               }
+                               if (cfg->max_cores_count &&
+                                               cores_cbdata.total_count < cfg->max_cores_count) {
+                                       msg_info_main (
+                                                       "disable cores throttling as count of cores in"
+                                                                       " %s is %z, limit is %z",
+                                                       cfg->cores_dir,
+                                                       cores_cbdata.total_count,
+                                                       cfg->max_cores_count);
+                                       rspamd_main->cores_throttling = FALSE;
+                               }
+                       }
+               }
+       }
+#endif
+}
+
 static void
 reopen_log_handler (gpointer key, gpointer value, gpointer unused)
 {
@@ -721,6 +815,7 @@ rspamd_hup_handler (gint signo, short what, gpointer arg)
        g_hash_table_foreach (rspamd_main->workers, kill_old_workers, NULL);
        rspamd_map_remove_all (rspamd_main->cfg);
        reread_config (rspamd_main);
+       rspamd_check_core_limits (rspamd_main);
        spawn_workers (rspamd_main, rspamd_main->ev_base);
 }
 
@@ -785,6 +880,7 @@ rspamd_cld_handler (gint signo, short what, gpointer arg)
                                                WEXITSTATUS (res));
                        }
                        /* Fork another worker in replace of dead one */
+                       rspamd_check_core_limits (rspamd_main);
                        rspamd_fork_delayed (cur->cf, cur->index, rspamd_main);
                }
 
@@ -1116,6 +1212,7 @@ main (gint argc, gchar **argv, gchar **env)
        event_base_set (ev_base, &usr1_ev);
        event_add (&usr1_ev, NULL);
 
+       rspamd_check_core_limits (rspamd_main);
        spawn_workers (rspamd_main, ev_base);
 
        if (control_fd != -1) {
index 61ef25cd4e74f0eeec24e1f255e64b47bf879bce..0095cc093090b9751185ba896607b7a2328c35da 100644 (file)
@@ -172,6 +172,7 @@ struct rspamd_main {
        uid_t workers_uid;                                          /**< worker's uid running to                        */
        gid_t workers_gid;                                          /**< worker's gid running to                                                */
        gboolean is_privilleged;                                    /**< true if run in privilleged mode                */
+       gboolean cores_throttling;                                  /**< turn off cores when limits are exceeded                */
        struct roll_history *history;                               /**< rolling history                                                                */
        struct event_base *ev_base;
 };