aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2013-01-08 18:24:24 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2013-01-08 18:24:24 +0400
commit3ac18652e5190623b1c36dd45a5684ca809acd3c (patch)
tree97a46e30be0f6915d506dad439b66c4e3f07ae00
parent5bf70b4761c7df13ec8271ee0a50068531ffbc80 (diff)
downloadrspamd-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.h2
-rw-r--r--src/cfg_xml.c6
-rw-r--r--src/main.c10
-rw-r--r--src/map.c10
-rw-r--r--src/map.h2
-rw-r--r--src/roll_history.c65
-rw-r--r--src/roll_history.h16
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);
diff --git a/src/map.c b/src/map.c
index 09b4df8df..07e13b7ef 100644
--- a/src/map.c
+++ b/src/map.c
@@ -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);
}
diff --git a/src/map.h b/src/map.h
index 5005786dc..8623e6845 100644
--- a/src/map.h
+++ b/src/map.h
@@ -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_ */