diff options
author | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2013-01-08 18:24:24 +0400 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2013-01-08 18:24:24 +0400 |
commit | 3ac18652e5190623b1c36dd45a5684ca809acd3c (patch) | |
tree | 97a46e30be0f6915d506dad439b66c4e3f07ae00 | |
parent | 5bf70b4761c7df13ec8271ee0a50068531ffbc80 (diff) | |
download | rspamd-3ac18652e5190623b1c36dd45a5684ca809acd3c.tar.gz rspamd-3ac18652e5190623b1c36dd45a5684ca809acd3c.zip |
Add locking for maps.
Add ability to save rolling history in a file.
-rw-r--r-- | src/cfg_file.h | 2 | ||||
-rw-r--r-- | src/cfg_xml.c | 6 | ||||
-rw-r--r-- | src/main.c | 10 | ||||
-rw-r--r-- | src/map.c | 10 | ||||
-rw-r--r-- | src/map.h | 2 | ||||
-rw-r--r-- | src/roll_history.c | 65 | ||||
-rw-r--r-- | src/roll_history.h | 16 |
7 files changed, 111 insertions, 0 deletions
diff --git a/src/cfg_file.h b/src/cfg_file.h index 538167ea8..e3e24759e 100644 --- a/src/cfg_file.h +++ b/src/cfg_file.h @@ -359,6 +359,8 @@ struct config_file { gchar* rrd_file; /**< rrd file to store statistics */ + gchar* history_file; /**< file to save rolling history */ + guint32 dns_timeout; /**< timeout in milliseconds for waiting for dns reply */ guint32 dns_retransmits; /**< maximum retransmits count */ guint32 dns_throttling_errors; /**< maximum errors for starting resolver throttling */ diff --git a/src/cfg_xml.c b/src/cfg_xml.c index f81492d77..71767cc3c 100644 --- a/src/cfg_xml.c +++ b/src/cfg_xml.c @@ -330,6 +330,12 @@ static struct xml_parser_rule grammar[] = { G_STRUCT_OFFSET (struct config_file, rrd_file), NULL }, + { + "history_file", + xml_handle_string, + G_STRUCT_OFFSET (struct config_file, history_file), + NULL + }, NULL_ATTR }, NULL_DEF_ATTR diff --git a/src/main.c b/src/main.c index c450500ad..e50b223aa 100644 --- a/src/main.c +++ b/src/main.c @@ -1093,6 +1093,11 @@ main (gint argc, gchar **argv, gchar **env) /* Preload all statfiles */ preload_statfiles (rspamd_main); + /* Maybe read roll history */ + if (rspamd_main->cfg->history_file) { + rspamd_roll_history_load (rspamd_main->history, rspamd_main->cfg->history_file); + } + /* Spawn workers */ rspamd_main->workers = g_hash_table_new (g_direct_hash, g_direct_equal); spawn_workers (rspamd_main); @@ -1181,6 +1186,11 @@ main (gint argc, gchar **argv, gchar **env) /* Wait for workers termination */ g_hash_table_foreach_remove (rspamd_main->workers, wait_for_workers, NULL); + /* Maybe save roll history */ + if (rspamd_main->cfg->history_file) { + rspamd_roll_history_save (rspamd_main->history, rspamd_main->cfg->history_file); + } + msg_info ("terminating..."); statfile_pool_delete (rspamd_main->statfile_pool); @@ -761,6 +761,11 @@ file_callback (gint fd, short what, void *ud) map->tv.tv_usec = 0; evtimer_add (&map->ev, &map->tv); + if (g_atomic_int_get (map->locked)) { + msg_info ("don't try to reread map as it is locked by other process, will reread it later"); + return; + } + if (stat (data->filename, &st) != -1 && (st.st_mtime > data->st.st_mtime || data->st.st_mtime == -1)) { /* File was modified since last check */ memcpy (&data->st, &st, sizeof (struct stat)); @@ -882,6 +887,10 @@ http_callback (gint fd, short what, void *ud) map->tv.tv_usec = 0; evtimer_add (&map->ev, &map->tv); + if (g_atomic_int_get (map->locked)) { + msg_info ("don't try to reread map as it is locked by other process, will reread it later"); + return; + } /* Connect asynced */ if ((sock = connect_http (map, data, TRUE)) == -1) { return; @@ -1011,6 +1020,7 @@ add_map (struct config_file *cfg, const gchar *map_line, const gchar *descriptio new_map->cfg = cfg; new_map->uri = memory_pool_strdup (cfg->cfg_pool, proto == MAP_PROTO_FILE ? def : map_line); new_map->id = g_random_int (); + new_map->locked = memory_pool_alloc0_shared (cfg->cfg_pool, sizeof (gint)); if (description != NULL) { new_map->description = memory_pool_strdup (cfg->cfg_pool, description); } @@ -73,6 +73,8 @@ struct rspamd_map { gchar *uri; gchar *description; guint32 id; + /* Shared lock for temporary disabling of map reading (e.g. when this map is written by UI) */ + gint *locked; }; /** diff --git a/src/roll_history.c b/src/roll_history.c index fec13045a..69f141762 100644 --- a/src/roll_history.c +++ b/src/roll_history.c @@ -143,3 +143,68 @@ rspamd_roll_history_update (struct roll_history *history, struct worker_task *ta row->len = task->msg->len; row->completed = TRUE; } + +/** + * Load previously saved history from file + * @param history roll history object + * @param filename filename to load from + * @return TRUE if history has been loaded + */ +gboolean +rspamd_roll_history_load (struct roll_history *history, const gchar *filename) +{ + gint fd; + struct stat st; + + if (stat (filename, &st) == -1) { + msg_info ("cannot load history from %s: %s", filename, strerror (errno)); + return FALSE; + } + + if (st.st_size != sizeof (history->rows)) { + msg_info ("cannot load history from %s: size mismatch", filename); + return FALSE; + } + + if ((fd = open (filename, O_RDONLY)) == -1) { + msg_info ("cannot load history from %s: %s", filename, strerror (errno)); + return FALSE; + } + + if (read (fd, history->rows, sizeof (history->rows)) == -1) { + close (fd); + msg_info ("cannot read history from %s: %s", filename, strerror (errno)); + return FALSE; + } + + close (fd); + + return TRUE; +} + +/** + * Save history to file + * @param history roll history object + * @param filename filename to load from + * @return TRUE if history has been saved + */ +gboolean +rspamd_roll_history_save (struct roll_history *history, const gchar *filename) +{ + gint fd; + + if ((fd = open (filename, O_WRONLY | O_CREAT | O_TRUNC, 00600)) == -1) { + msg_info ("cannot save history to %s: %s", filename, strerror (errno)); + return FALSE; + } + + if (write (fd, history->rows, sizeof (history->rows)) == -1) { + close (fd); + msg_info ("cannot write history to %s: %s", filename, strerror (errno)); + return FALSE; + } + + close (fd); + + return TRUE; +} diff --git a/src/roll_history.h b/src/roll_history.h index c2e378bf9..58ce6e9d9 100644 --- a/src/roll_history.h +++ b/src/roll_history.h @@ -87,4 +87,20 @@ struct roll_history* rspamd_roll_history_new (memory_pool_t *pool); */ void rspamd_roll_history_update (struct roll_history *history, struct worker_task *task); +/** + * Load previously saved history from file + * @param history roll history object + * @param filename filename to load from + * @return TRUE if history has been loaded + */ +gboolean rspamd_roll_history_load (struct roll_history *history, const gchar *filename); + +/** + * Save history to file + * @param history roll history object + * @param filename filename to load from + * @return TRUE if history has been saved + */ +gboolean rspamd_roll_history_save (struct roll_history *history, const gchar *filename); + #endif /* ROLL_HISTORY_H_ */ |