Add ability to save rolling history in a 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 */
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
/* 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);
/* 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);
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));
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;
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);
}
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;
};
/**
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;
+}
*/
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_ */