aboutsummaryrefslogtreecommitdiffstats
path: root/src/libserver
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2021-12-22 20:47:13 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2021-12-22 20:47:13 +0000
commit6f2788b45b5982be1257832cb1c2546397117245 (patch)
treedcf6e429f02031abe38660513578b4d3f56577cf /src/libserver
parent9faf4e70cee731053c540931c1ab7eb353a5dadc (diff)
downloadrspamd-6f2788b45b5982be1257832cb1c2546397117245.tar.gz
rspamd-6f2788b45b5982be1257832cb1c2546397117245.zip
[Fix] Try to revert back maps content on errors properly
Diffstat (limited to 'src/libserver')
-rw-r--r--src/libserver/maps/map.c10
-rw-r--r--src/libserver/maps/map.h1
-rw-r--r--src/libserver/maps/map_helpers.c164
3 files changed, 113 insertions, 62 deletions
diff --git a/src/libserver/maps/map.c b/src/libserver/maps/map.c
index 531a7ce10..4d9b1584b 100644
--- a/src/libserver/maps/map.c
+++ b/src/libserver/maps/map.c
@@ -983,8 +983,8 @@ rspamd_map_periodic_dtor (struct map_periodic_cbdata *periodic)
map = periodic->map;
msg_debug_map ("periodic dtor %p", periodic);
- if (periodic->need_modify) {
- /* We are done */
+ if (periodic->need_modify || periodic->cbdata.errored) {
+ /* Need to notify the real data structure */
periodic->map->fin_callback (&periodic->cbdata, periodic->map->user_data);
}
else {
@@ -1138,7 +1138,6 @@ rspamd_map_schedule_periodic (struct rspamd_map *map, int how)
}
cbd = g_malloc0 (sizeof (*cbd));
- cbd->cbdata.state = 0;
cbd->cbdata.prev_data = *map->user_data;
cbd->cbdata.cur_data = NULL;
cbd->cbdata.map = map;
@@ -2000,7 +1999,7 @@ rspamd_map_process_periodic (struct map_periodic_cbdata *cbd)
}
if (cbd->errored) {
- /* We should not check other backends if some backend has failed */
+ /* We should not check other backends if some backend has failed*/
rspamd_map_schedule_periodic (cbd->map, RSPAMD_MAP_SCHEDULE_ERROR);
if (cbd->locked) {
@@ -2008,6 +2007,9 @@ rspamd_map_process_periodic (struct map_periodic_cbdata *cbd)
cbd->locked = FALSE;
}
+ /* Also set error flag for the map consumer */
+ cbd->cbdata.errored = true;
+
msg_debug_map ("unlocked map %s, refcount=%d", cbd->map->name,
cbd->ref.refcount);
MAP_RELEASE (cbd, "periodic");
diff --git a/src/libserver/maps/map.h b/src/libserver/maps/map.h
index 0812e1d44..6d77454fb 100644
--- a/src/libserver/maps/map.h
+++ b/src/libserver/maps/map.h
@@ -50,6 +50,7 @@ struct rspamd_map;
struct map_cb_data {
struct rspamd_map *map;
gint state;
+ bool errored;
void *prev_data;
void *cur_data;
};
diff --git a/src/libserver/maps/map_helpers.c b/src/libserver/maps/map_helpers.c
index a29467497..4eb6b2fee 100644
--- a/src/libserver/maps/map_helpers.c
+++ b/src/libserver/maps/map_helpers.c
@@ -940,22 +940,34 @@ rspamd_kv_list_fin (struct map_cb_data *data, void **target)
struct rspamd_map *map = data->map;
struct rspamd_hash_map_helper *htb;
- if (data->cur_data) {
- htb = (struct rspamd_hash_map_helper *)data->cur_data;
- msg_info_map ("read hash of %d elements from %s", kh_size (htb->htb),
- map->name);
- data->map->traverse_function = rspamd_map_helper_traverse_hash;
- data->map->nelts = kh_size (htb->htb);
- data->map->digest = rspamd_cryptobox_fast_hash_final (&htb->hst);
+ if (data->errored) {
+ /* Clean up the current data and do not touch prev data */
+ if (data->cur_data) {
+ msg_info_map ("cleanup unfinished new data as error occurred for %s",
+ map->name);
+ htb = (struct rspamd_hash_map_helper *) data->cur_data;
+ rspamd_map_helper_destroy_hash(htb);
+ data->cur_data = NULL;
+ }
}
+ else {
+ if (data->cur_data) {
+ htb = (struct rspamd_hash_map_helper *) data->cur_data;
+ msg_info_map ("read hash of %d elements from %s", kh_size(htb->htb),
+ map->name);
+ data->map->traverse_function = rspamd_map_helper_traverse_hash;
+ data->map->nelts = kh_size (htb->htb);
+ data->map->digest = rspamd_cryptobox_fast_hash_final(&htb->hst);
+ }
- if (target) {
- *target = data->cur_data;
- }
+ if (target) {
+ *target = data->cur_data;
+ }
- if (data->prev_data) {
- htb = (struct rspamd_hash_map_helper *)data->prev_data;
- rspamd_map_helper_destroy_hash (htb);
+ if (data->prev_data) {
+ htb = (struct rspamd_hash_map_helper *) data->prev_data;
+ rspamd_map_helper_destroy_hash(htb);
+ }
}
}
@@ -1000,22 +1012,34 @@ rspamd_radix_fin (struct map_cb_data *data, void **target)
struct rspamd_map *map = data->map;
struct rspamd_radix_map_helper *r;
- if (data->cur_data) {
- r = (struct rspamd_radix_map_helper *)data->cur_data;
- msg_info_map ("read radix trie of %z elements: %s",
- radix_get_size (r->trie), radix_get_info (r->trie));
- data->map->traverse_function = rspamd_map_helper_traverse_radix;
- data->map->nelts = kh_size (r->htb);
- data->map->digest = rspamd_cryptobox_fast_hash_final (&r->hst);
+ if (data->errored) {
+ /* Clean up the current data and do not touch prev data */
+ if (data->cur_data) {
+ msg_info_map ("cleanup unfinished new data as error occurred for %s",
+ map->name);
+ r = (struct rspamd_radix_map_helper *) data->cur_data;
+ rspamd_map_helper_destroy_radix(r);
+ data->cur_data = NULL;
+ }
}
+ else {
+ if (data->cur_data) {
+ r = (struct rspamd_radix_map_helper *) data->cur_data;
+ msg_info_map ("read radix trie of %z elements: %s",
+ radix_get_size(r->trie), radix_get_info(r->trie));
+ data->map->traverse_function = rspamd_map_helper_traverse_radix;
+ data->map->nelts = kh_size (r->htb);
+ data->map->digest = rspamd_cryptobox_fast_hash_final(&r->hst);
+ }
- if (target) {
- *target = data->cur_data;
- }
+ if (target) {
+ *target = data->cur_data;
+ }
- if (data->prev_data) {
- r = (struct rspamd_radix_map_helper *)data->prev_data;
- rspamd_map_helper_destroy_radix (r);
+ if (data->prev_data) {
+ r = (struct rspamd_radix_map_helper *) data->prev_data;
+ rspamd_map_helper_destroy_radix(r);
+ }
}
}
@@ -1494,33 +1518,45 @@ rspamd_regexp_list_fin (struct map_cb_data *data, void **target)
struct rspamd_regexp_map_helper *re_map = NULL, *old_re_map;
struct rspamd_map *map = data->map;
- if (data->cur_data) {
- re_map = data->cur_data;
- rspamd_cryptobox_hash_final (&re_map->hst, re_map->re_digest);
- memcpy (&data->map->digest, re_map->re_digest, sizeof (data->map->digest));
- rspamd_re_map_finalize (re_map);
- msg_info_map ("read regexp list of %ud elements",
- re_map->regexps->len);
- data->map->traverse_function = rspamd_map_helper_traverse_regexp;
- data->map->nelts = kh_size (re_map->htb);
+ if (data->errored) {
+ /* Clean up the current data and do not touch prev data */
+ if (data->cur_data) {
+ msg_info_map ("cleanup unfinished new data as error occurred for %s",
+ map->name);
+ re_map = (struct rspamd_regexp_map_helper *)data->cur_data;
+ rspamd_map_helper_destroy_regexp (re_map);
+ data->cur_data = NULL;
+ }
}
+ else {
+ if (data->cur_data) {
+ re_map = data->cur_data;
+ rspamd_cryptobox_hash_final(&re_map->hst, re_map->re_digest);
+ memcpy(&data->map->digest, re_map->re_digest, sizeof(data->map->digest));
+ rspamd_re_map_finalize(re_map);
+ msg_info_map ("read regexp list of %ud elements",
+ re_map->regexps->len);
+ data->map->traverse_function = rspamd_map_helper_traverse_regexp;
+ data->map->nelts = kh_size (re_map->htb);
+ }
- if (target) {
- *target = data->cur_data;
- }
+ if (target) {
+ *target = data->cur_data;
+ }
- if (data->prev_data) {
- old_re_map = data->prev_data;
+ if (data->prev_data) {
+ old_re_map = data->prev_data;
#ifdef WITH_HYPERSCAN
- if (re_map && memcmp (re_map->re_digest, old_re_map->re_digest,
- sizeof (re_map->re_digest)) != 0) {
- /* Cleanup old stuff */
- rspamd_re_map_cache_cleanup_old (old_re_map);
- }
+ if (re_map && memcmp(re_map->re_digest, old_re_map->re_digest,
+ sizeof(re_map->re_digest)) != 0) {
+ /* Cleanup old stuff */
+ rspamd_re_map_cache_cleanup_old(old_re_map);
+ }
#endif
- rspamd_map_helper_destroy_regexp (old_re_map);
+ rspamd_map_helper_destroy_regexp(old_re_map);
+ }
}
}
void
@@ -1889,21 +1925,33 @@ rspamd_cdb_list_fin (struct map_cb_data *data, void **target)
struct rspamd_map *map = data->map;
struct rspamd_cdb_map_helper *cdb_data;
- if (data->cur_data) {
- cdb_data = (struct rspamd_cdb_map_helper *)data->cur_data;
- msg_info_map ("read cdb of %Hz size", cdb_data->total_size);
- data->map->traverse_function = NULL;
- data->map->nelts = 0;
- data->map->digest = rspamd_cryptobox_fast_hash_final (&cdb_data->hst);
+ if (data->errored) {
+ /* Clean up the current data and do not touch prev data */
+ if (data->cur_data) {
+ msg_info_map ("cleanup unfinished new data as error occurred for %s",
+ map->name);
+ cdb_data = (struct rspamd_cdb_map_helper *) data->cur_data;
+ rspamd_map_helper_destroy_cdb(cdb_data);
+ data->cur_data = NULL;
+ }
}
+ else {
+ if (data->cur_data) {
+ cdb_data = (struct rspamd_cdb_map_helper *) data->cur_data;
+ msg_info_map ("read cdb of %Hz size", cdb_data->total_size);
+ data->map->traverse_function = NULL;
+ data->map->nelts = 0;
+ data->map->digest = rspamd_cryptobox_fast_hash_final(&cdb_data->hst);
+ }
- if (target) {
- *target = data->cur_data;
- }
+ if (target) {
+ *target = data->cur_data;
+ }
- if (data->prev_data) {
- cdb_data = (struct rspamd_cdb_map_helper *)data->prev_data;
- rspamd_map_helper_destroy_cdb (cdb_data);
+ if (data->prev_data) {
+ cdb_data = (struct rspamd_cdb_map_helper *) data->prev_data;
+ rspamd_map_helper_destroy_cdb(cdb_data);
+ }
}
}
void