]> source.dussan.org Git - rspamd.git/commitdiff
* Fix config reloading
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 13 May 2010 13:07:20 +0000 (17:07 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 13 May 2010 13:07:20 +0000 (17:07 +0400)
* Add ability to register variables in memory pools (hash with known lifetime)
* Avoid of using of some global variables

src/expressions.c
src/expressions.h
src/fuzzy_storage.c
src/main.c
src/mem_pool.c
src/mem_pool.h
src/plugins/regexp.c
src/symbols_cache.c
src/symbols_cache.h

index e52745541b9a98f27c639148cfa2548c83ad773c..103da5553ea2911c91c4a159a324486b9045ac47 100644 (file)
@@ -90,23 +90,31 @@ fl_cmp (const void *s1, const void *s2)
 }
 
 /* Cache for regular expressions that are used in functions */
-static GHashTable              *re_cache = NULL;
-
 void                           *
-re_cache_check (const char *line)
+re_cache_check (const char *line, memory_pool_t *pool)
 {
+       GHashTable              *re_cache;
+       
+       re_cache = memory_pool_get_variable (pool, "re_cache");
+
        if (re_cache == NULL) {
                re_cache = g_hash_table_new (g_str_hash, g_str_equal);
+               memory_pool_set_variable (pool, "re_cache", re_cache, (pool_destruct_func)g_hash_table_destroy);
                return NULL;
        }
        return g_hash_table_lookup (re_cache, line);
 }
 
 void
-re_cache_add (char *line, void *pointer)
+re_cache_add (char *line, void *pointer, memory_pool_t *pool)
 {
+       GHashTable              *re_cache;
+       
+       re_cache = memory_pool_get_variable (pool, "re_cache");
+
        if (re_cache == NULL) {
                re_cache = g_hash_table_new (g_str_hash, g_str_equal);
+               memory_pool_set_variable (pool, "re_cache", re_cache, (pool_destruct_func)g_hash_table_destroy);
        }
 
        g_hash_table_insert (re_cache, line, pointer);
@@ -677,7 +685,7 @@ parse_regexp (memory_pool_t * pool, char *line, gboolean raw_mode)
        }
 
        /* Avoid multiply regexp structures for similar regexps */
-       if ((check = (struct rspamd_regexp *)re_cache_check (begin)) != NULL) {
+       if ((check = (struct rspamd_regexp *)re_cache_check (begin, pool)) != NULL) {
                /* Additional check for headers */
                if (result->type == REGEXP_HEADER || result->type == REGEXP_RAW_HEADER) {
                        if (result->header && check->header) {
@@ -714,7 +722,7 @@ parse_regexp (memory_pool_t * pool, char *line, gboolean raw_mode)
        }
 
        /* Add to cache for further usage */
-       re_cache_add (result->regexp_text, result);
+       re_cache_add (result->regexp_text, result, pool);
        return result;
 }
 
@@ -986,13 +994,13 @@ rspamd_content_type_compare_param (struct worker_task * task, GList * args, void
                }
                if (*param_pattern == '/') {
                        /* This is regexp, so compile and create g_regexp object */
-                       if ((re = re_cache_check (param_pattern)) == NULL) {
+                       if ((re = re_cache_check (param_pattern, task->cfg->cfg_pool)) == NULL) {
                                re = parse_regexp (task->cfg->cfg_pool, param_pattern, task->cfg->raw_mode);
                                if (re == NULL) {
                                        msg_warn ("cannot compile regexp for function");
                                        return FALSE;
                                }
-                               re_cache_add (param_pattern, re);
+                               re_cache_add (param_pattern, re, task->cfg->cfg_pool);
                        }
                        if ((r = task_cache_check (task, re)) == -1) {
                                if (g_regex_match (re->regexp, param_data, 0, NULL) == TRUE) {
@@ -1084,13 +1092,13 @@ rspamd_content_type_is_subtype (struct worker_task *task, GList * args, void *un
 
                if (*param_pattern == '/') {
                        /* This is regexp, so compile and create g_regexp object */
-                       if ((re = re_cache_check (param_pattern)) == NULL) {
+                       if ((re = re_cache_check (param_pattern, task->cfg->cfg_pool)) == NULL) {
                                re = parse_regexp (task->cfg->cfg_pool, param_pattern, task->cfg->raw_mode);
                                if (re == NULL) {
                                        msg_warn ("cannot compile regexp for function");
                                        return FALSE;
                                }
-                               re_cache_add (param_pattern, re);
+                               re_cache_add (param_pattern, re, task->cfg->cfg_pool);
                        }
                        if ((r = task_cache_check (task, re)) == -1) {
                                if (g_regex_match (re->regexp, ct->subtype, 0, NULL) == TRUE) {
@@ -1143,13 +1151,13 @@ rspamd_content_type_is_type (struct worker_task * task, GList * args, void *unus
 
                if (*param_pattern == '/') {
                        /* This is regexp, so compile and create g_regexp object */
-                       if ((re = re_cache_check (param_pattern)) == NULL) {
+                       if ((re = re_cache_check (param_pattern, task->cfg->cfg_pool)) == NULL) {
                                re = parse_regexp (task->cfg->cfg_pool, param_pattern, task->cfg->raw_mode);
                                if (re == NULL) {
                                        msg_warn ("cannot compile regexp for function");
                                        return FALSE;
                                }
-                               re_cache_add (param_pattern, re);
+                               re_cache_add (param_pattern, re, task->cfg->cfg_pool);
                        }
                        if ((r = task_cache_check (task, re)) == -1) {
                                if (g_regex_match (re->regexp, ct->type, 0, NULL) == TRUE) {
@@ -1326,13 +1334,13 @@ compare_subtype (struct worker_task *task, const localContentType * ct, char *su
 
        if (*subtype == '/') {
                /* This is regexp, so compile and create g_regexp object */
-               if ((re = re_cache_check (subtype)) == NULL) {
+               if ((re = re_cache_check (subtype, task->cfg->cfg_pool)) == NULL) {
                        re = parse_regexp (task->cfg->cfg_pool, subtype, task->cfg->raw_mode);
                        if (re == NULL) {
                                msg_warn ("cannot compile regexp for function");
                                return FALSE;
                        }
-                       re_cache_add (subtype, re);
+                       re_cache_add (subtype, re, task->cfg->cfg_pool);
                }
                if ((r = task_cache_check (task, re)) == -1) {
                        if (g_regex_match (re->regexp, subtype, 0, NULL) == TRUE) {
@@ -1393,14 +1401,14 @@ common_has_content_part (struct worker_task * task, char *param_type, char *para
 
                if (*param_type == '/') {
                        /* This is regexp, so compile and create g_regexp object */
-                       if ((re = re_cache_check (param_type)) == NULL) {
+                       if ((re = re_cache_check (param_type, task->cfg->cfg_pool)) == NULL) {
                                re = parse_regexp (task->cfg->cfg_pool, param_type, task->cfg->raw_mode);
                                if (re == NULL) {
                                        msg_warn ("cannot compile regexp for function");
                                        cur = g_list_next (cur);
                                        continue;
                                }
-                               re_cache_add (param_type, re);
+                               re_cache_add (param_type, re, task->cfg->cfg_pool);
                        }
                        if ((r = task_cache_check (task, re)) == -1) {
                                if (g_regex_match (re->regexp, ct->type, 0, NULL) == TRUE) {
index 519efc6daa17f05a4385cdc384491c59a260b574..14ae03f4f8cf3fc8227c64f5ce5a996e9f122bb5 100644 (file)
@@ -87,14 +87,14 @@ void register_expression_function (const char *name, rspamd_internal_func_t func
  * @param line symbolic representation
  * @param pointer regexp data
  */
-void re_cache_add (char *line, void *pointer);
+void re_cache_add (char *line, void *pointer, memory_pool_t *pool);
 
 /**
  * Check regexp in cache
  * @param line symbolic representation
  * @return pointer to regexp data or NULL if regexp is not found
  */
-void * re_cache_check (const char *line);
+void * re_cache_check (const char *line, memory_pool_t *pool);
 
 /**
  * Add regexp to regexp task cache
index 8957c9d353801eea17df35257b00c9310b2fa0e7..62f2711d7e30ddb45c34072ceeb59b73f776fa7c 100644 (file)
@@ -318,6 +318,7 @@ read_hashes_file (struct rspamd_worker *wrk)
                                msg_err ("unsupported version of fuzzy hash file: %d", version);
                                return FALSE;
                        }
+                       msg_info ("reading fuzzy hashes storage file of version %d of size %d", version, (int)(st.st_size - sizeof (header)) / sizeof (struct rspamd_fuzzy_node));
                }
                else {
                        /* Old version */
index e13ccb77cdd9ff2822211f94868994750c898f21..5672817e472124caf682cfc4ebafb29f2394f881 100644 (file)
@@ -52,7 +52,7 @@
 rspamd_hash_t                  *counters;
 
 static struct rspamd_worker    *fork_worker (struct rspamd_main *, struct worker_conf *);
-static gboolean                 load_rspamd_config (struct config_file *cfg);
+static gboolean                 load_rspamd_config (struct config_file *cfg, gboolean init_modules);
 static void                     init_metrics_cache (struct config_file *cfg);
 
 sig_atomic_t                    do_restart;
@@ -266,7 +266,7 @@ reread_config (struct rspamd_main *rspamd)
                tmp_cfg->cfg_name = cfg_file;
                init_lua (tmp_cfg);
 
-               if (! load_rspamd_config (tmp_cfg)) {
+               if (! load_rspamd_config (tmp_cfg, FALSE)) {
                        msg_err ("cannot parse new config file, revert to old one");
                        free_config (tmp_cfg);
                }
@@ -276,7 +276,6 @@ reread_config (struct rspamd_main *rspamd)
                        close_log ();
                        g_free (rspamd->cfg);
                        rspamd->cfg = tmp_cfg;
-                       post_load_config (rspamd->cfg);
                        config_logger (rspamd, FALSE);
                        /* Perform modules configuring */
                        l = g_list_first (rspamd->cfg->filters);
@@ -285,6 +284,7 @@ reread_config (struct rspamd_main *rspamd)
                                filt = l->data;
                                if (filt->module) {
                                        (void)filt->module->module_reconfig_func (rspamd->cfg);
+                                       msg_info ("reconfig of %s", filt->module->name);
                                }
                                l = g_list_next (l);
                        }
@@ -630,7 +630,7 @@ convert_old_config (struct rspamd_main *rspamd)
 }
 
 static gboolean
-load_rspamd_config (struct config_file *cfg)
+load_rspamd_config (struct config_file *cfg, gboolean init_modules)
 {
        GList                          *l;
        struct filter                  *filt;
@@ -653,19 +653,21 @@ load_rspamd_config (struct config_file *cfg)
 
        /* Do post-load actions */
        post_load_config (cfg);
+       
+       if (init_modules) {
+               /* Init C modules */
+               l = g_list_first (cfg->filters);
 
-       /* Init C modules */
-       l = g_list_first (cfg->filters);
-
-       while (l) {
-               filt = l->data;
-               if (filt->module) {
-                       cur_module = memory_pool_alloc (cfg->cfg_pool, sizeof (struct module_ctx));
-                       if (filt->module->module_init_func (cfg, &cur_module) == 0) {
-                               g_hash_table_insert (cfg->c_modules, (gpointer) filt->module->name, cur_module);
+               while (l) {
+                       filt = l->data;
+                       if (filt->module) {
+                               cur_module = memory_pool_alloc (cfg->cfg_pool, sizeof (struct module_ctx));
+                               if (filt->module->module_init_func (cfg, &cur_module) == 0) {
+                                       g_hash_table_insert (cfg->c_modules, (gpointer) filt->module->name, cur_module);
+                               }
                        }
+                       l = g_list_next (l);
                }
-               l = g_list_next (l);
        }
        
        return TRUE;
@@ -798,7 +800,7 @@ main (int argc, char **argv, char **env)
                }
        }
 
-       if (! load_rspamd_config (rspamd->cfg)) {
+       if (! load_rspamd_config (rspamd->cfg, TRUE)) {
                exit (EXIT_FAILURE);
        }
 
index 23907d2603875b8dbf0273c5820bac3fe42d12f7..11f74f2f36518875b372e640f72dfd37731a7631 100644 (file)
@@ -148,6 +148,8 @@ memory_pool_new (memory_pool_ssize_t size)
        new->shared_pool = NULL;
        new->first_pool = new->cur_pool;
        new->destructors = NULL;
+       /* Set it upon first call of set variable */
+       new->variables = NULL;
 
        mem_pool_stat->pools_allocated++;
 
@@ -460,6 +462,9 @@ memory_pool_delete (memory_pool_t * pool)
                mem_pool_stat->chunks_freed++;
                STAT_UNLOCK ();
        }
+       if (pool->variables) {
+               g_hash_table_destroy (pool->variables);
+       }
 
        mem_pool_stat->pools_freed++;
        g_slice_free (memory_pool_t, pool);
@@ -570,6 +575,30 @@ memory_pool_wunlock_rwlock (memory_pool_rwlock_t * lock)
        memory_pool_unlock_mutex (lock->__w_lock);
 }
 
+void 
+memory_pool_set_variable (memory_pool_t *pool, const gchar *name, gpointer value, pool_destruct_func destructor)
+{
+       if (pool->variables == NULL) {
+               pool->variables = g_hash_table_new (g_str_hash, g_str_equal);
+       }
+
+       g_hash_table_insert (pool->variables, memory_pool_strdup (pool, name), value);
+       if (destructor != NULL) {
+               memory_pool_add_destructor (pool, destructor, value);
+       }
+}
+
+gpointer
+memory_pool_get_variable (memory_pool_t *pool, const gchar *name)
+{
+       if (pool->variables == NULL) {
+               return NULL;
+       }
+
+       return g_hash_table_lookup (pool->variables, name);
+}
+
+
 /*
  * vi:ts=4
  */
index b55670c9537b5cbd60adf4bfa411ddfbd7b96987..81d4a85fae2422643cb64d07447957a94ac47091 100644 (file)
@@ -74,6 +74,7 @@ typedef struct memory_pool_s {
        struct _pool_chain *first_pool;                 /**< first page                                                         */
        struct _pool_chain_shared *shared_pool; /**< shared chain                                                       */
        struct _pool_destructors *destructors;  /**< destructors chain                                          */
+       GHashTable *variables;                                  /**< private memory pool variables                      */
 } memory_pool_t;
 
 /**
@@ -235,6 +236,24 @@ void memory_pool_stat (memory_pool_stat_t *st);
  */
 memory_pool_ssize_t memory_pool_get_size ();
 
+/**
+ * Set memory pool variable
+ * @param pool memory pool object
+ * @param name name of variable
+ * @param gpointer value value of variable
+ * @param destructor pointer to function-destructor
+ */
+void memory_pool_set_variable (memory_pool_t *pool, const gchar *name, gpointer value, pool_destruct_func destructor);
+
+/**
+ * Get memory pool variable
+ * @param pool memory pool object
+ * @param name name of variable
+ * @return NULL or pointer to variable data
+ */
+gpointer memory_pool_get_variable (memory_pool_t *pool, const gchar *name);
+
+
 /**
  * Macro that return free space in pool page
  * @param x pool page struct
index d129664fd0c846ffbfc3368f06bd9fcd6f33f3c4..33aa60f298f64de44f6447951113f70182755399 100644 (file)
@@ -78,7 +78,7 @@ regexp_module_init (struct config_file *cfg, struct module_ctx **ctx)
        regexp_module_ctx = g_malloc (sizeof (struct regexp_ctx));
 
        regexp_module_ctx->filter = regexp_common_filter;
-       regexp_module_ctx->regexp_pool = memory_pool_new (1024);
+       regexp_module_ctx->regexp_pool = memory_pool_new (memory_pool_get_size ());
        regexp_module_ctx->autolearn_symbols = g_hash_table_new (g_str_hash, g_str_equal);
 
        *ctx = (struct module_ctx *)regexp_module_ctx;
@@ -231,7 +231,7 @@ int
 regexp_module_reconfig (struct config_file *cfg)
 {
        memory_pool_delete (regexp_module_ctx->regexp_pool);
-       regexp_module_ctx->regexp_pool = memory_pool_new (1024);
+       regexp_module_ctx->regexp_pool = memory_pool_new (memory_pool_get_size ());
 
        return regexp_module_config (cfg);
 }
index 060a0418732d0809deeefb75a6f8686cd5664960..48eaf95ad204ee3e384e167b391a756d835ee67c 100644 (file)
@@ -120,8 +120,18 @@ post_cache_init (struct symbols_cache *cache)
        qsort (cache->items, cache->used_items, sizeof (struct cache_item), cache_logic_cmp);
 }
 
+/* Unmap cache file */
+static void
+unmap_cache_file (gpointer arg)
+{
+       struct symbols_cache           *cache = arg;
+       
+       /* A bit ugly usage */
+       munmap (cache->map, cache->used_items * sizeof (struct saved_cache_item));
+}
+
 static                          gboolean
-mmap_cache_file (struct symbols_cache *cache, int fd)
+mmap_cache_file (struct symbols_cache *cache, int fd, memory_pool_t *pool)
 {
        void                           *map;
        int                             i;
@@ -134,19 +144,21 @@ mmap_cache_file (struct symbols_cache *cache, int fd)
        }
        /* Close descriptor as it would never be used */
        close (fd);
+       cache->map = map;
        /* Now free old values for saved cache items and fill them with mmapped ones */
        for (i = 0; i < cache->used_items; i++) {
                g_free (cache->items[i].s);
                cache->items[i].s = ((struct saved_cache_item *)map) + i;
        }
-
+       
        post_cache_init (cache);
+
        return TRUE;
 }
 
 /* Fd must be opened for writing, after creating file is mmapped */
 static                          gboolean
-create_cache_file (struct symbols_cache *cache, const char *filename, int fd)
+create_cache_file (struct symbols_cache *cache, const char *filename, int fd, memory_pool_t *pool)
 {
        int                             i;
        GChecksum                      *cksum;
@@ -193,7 +205,7 @@ create_cache_file (struct symbols_cache *cache, const char *filename, int fd)
                return FALSE;
        }
 
-       return mmap_cache_file (cache, fd);
+       return mmap_cache_file (cache, fd, pool);
 }
 
 void
@@ -205,6 +217,7 @@ register_symbol (struct symbols_cache **cache, const char *name, double weight,
        if (*cache == NULL) {
                *cache = g_new0 (struct symbols_cache, 1);
        }
+
        if ((*cache)->items == NULL) {
                (*cache)->cur_items = MIN_CACHE;
                (*cache)->used_items = 0;
@@ -228,9 +241,29 @@ register_symbol (struct symbols_cache **cache, const char *name, double weight,
        item->user_data = user_data;
        item->s->weight = weight;
        (*cache)->used_items++;
+       msg_info ("used items: %d, added symbol: %s", (*cache)->used_items, name);
        set_counter (item->s->symbol, 0);
 }
 
+static void
+free_cache (gpointer arg)
+{
+       struct symbols_cache           *cache = arg;
+       int                             i;
+       
+       if (cache->map == NULL) {
+               /* Free items in memory, otherwise  */
+               for (i = 0; i < cache->cur_items; i++) {
+                       g_free (cache->items[i].s);
+               }
+       }
+       else {
+               unmap_cache_file (cache);
+       }
+
+       g_free (cache);
+}
+
 gboolean
 init_symbols_cache (memory_pool_t * pool, struct symbols_cache *cache, const char *filename)
 {
@@ -239,6 +272,7 @@ init_symbols_cache (memory_pool_t * pool, struct symbols_cache *cache, const cha
        GChecksum                      *cksum;
        u_char                         *mem_sum, *file_sum;
        gsize                           cklen;
+       gboolean                        res;
 
        if (cache == NULL || cache->items == NULL) {
                return FALSE;
@@ -255,6 +289,7 @@ init_symbols_cache (memory_pool_t * pool, struct symbols_cache *cache, const cha
                post_cache_init (cache);
                return TRUE;
        }
+       
 
        /* First of all try to stat file */
        if (stat (filename, &st) == -1) {
@@ -266,7 +301,7 @@ init_symbols_cache (memory_pool_t * pool, struct symbols_cache *cache, const cha
                                return FALSE;
                        }
                        else {
-                               return create_cache_file (cache, filename, fd);
+                               return create_cache_file (cache, filename, fd, pool);
                        }
                }
                else {
@@ -323,7 +358,7 @@ init_symbols_cache (memory_pool_t * pool, struct symbols_cache *cache, const cha
                        return FALSE;
                }
                else {
-                       return create_cache_file (cache, filename, fd);
+                       return create_cache_file (cache, filename, fd, pool);
                }
        }
 
@@ -331,7 +366,9 @@ init_symbols_cache (memory_pool_t * pool, struct symbols_cache *cache, const cha
        g_free (file_sum);
        g_checksum_free (cksum);
        /* MMap cache file and copy saved_cache structures */
-       return mmap_cache_file (cache, fd);
+       res = mmap_cache_file (cache, fd, pool);
+       memory_pool_add_destructor (pool, (pool_destruct_func)free_cache, cache);
+       return res;
 }
 
 gboolean
index 65028cfcca7abd737198f802bfae0e089f007777..2462052609aa74eb81e7fce9ceb1e831ed37bfa5 100644 (file)
@@ -27,6 +27,7 @@ struct symbols_cache {
        guint cur_items;
        guint used_items;
        guint uses;
+       gpointer map;
        memory_pool_rwlock_t *lock;
 };