diff options
author | Stelios Fragkakis <52996999+stelfrag@users.noreply.github.com> | 2021-03-23 18:09:34 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-23 18:09:34 +0200 |
commit | 7ebb0a4da20465016a32a3c0b28635277926b815 (patch) | |
tree | a68ec215e14e968d9a8214f857e84672699b1c18 /web | |
parent | efe2a951ad9826e61a1f3e4229b6b8bd61e961ef (diff) |
Fix memory leak when archived data is requested (#10837)
Diffstat (limited to 'web')
-rw-r--r-- | web/api/formatters/json_wrapper.c | 4 | ||||
-rw-r--r-- | web/api/formatters/rrd2json.c | 54 |
2 files changed, 34 insertions, 24 deletions
diff --git a/web/api/formatters/json_wrapper.c b/web/api/formatters/json_wrapper.c index 1c06a8ff44..1d9c2472af 100644 --- a/web/api/formatters/json_wrapper.c +++ b/web/api/formatters/json_wrapper.c @@ -48,8 +48,8 @@ void rrdr_json_wrapper_begin(RRDR *r, BUFFER *wb, uint32_t format, RRDR_OPTIONS , kq, kq, sq, context_mode && temp_rd?r->st->context:r->st->name, sq , kq, kq, r->update_every , kq, kq, r->st->update_every - , kq, kq, (uint32_t) (context_param_list ? context_param_list->first_entry_t : rrdset_first_entry_t(r->st)) - , kq, kq, (uint32_t) (context_param_list ? context_param_list->last_entry_t : rrdset_last_entry_t(r->st)) + , kq, kq, (uint32_t) (context_param_list ? context_param_list->first_entry_t : rrdset_first_entry_t_nolock(r->st)) + , kq, kq, (uint32_t) (context_param_list ? context_param_list->last_entry_t : rrdset_last_entry_t_nolock(r->st)) , kq, kq, (uint32_t)r->before , kq, kq, (uint32_t)r->after , kq, kq); diff --git a/web/api/formatters/rrd2json.c b/web/api/formatters/rrd2json.c index 82be7627c1..5b12c89bac 100644 --- a/web/api/formatters/rrd2json.c +++ b/web/api/formatters/rrd2json.c @@ -2,7 +2,28 @@ #include "web/api/web_api_v1.h" -static inline void free_temp_rrddim(RRDDIM *temp_rd) +static inline void free_single_rrdrim(RRDDIM *temp_rd, int archive_mode) +{ + if (unlikely(!temp_rd)) + return; + + freez((char *)temp_rd->id); + freez((char *)temp_rd->name); + + if (unlikely(archive_mode)) { + temp_rd->rrdset->counter--; + if (!temp_rd->rrdset->counter) { + freez((char *)temp_rd->rrdset->name); + freez(temp_rd->rrdset->context); + freez(temp_rd->rrdset); + } + } + freez(temp_rd->state->metric_uuid); + freez(temp_rd->state); + freez(temp_rd); +} + +static inline void free_rrddim_list(RRDDIM *temp_rd, int archive_mode) { if (unlikely(!temp_rd)) return; @@ -10,14 +31,7 @@ static inline void free_temp_rrddim(RRDDIM *temp_rd) RRDDIM *t; while (temp_rd) { t = temp_rd->next; - freez((char *)temp_rd->id); - freez((char *)temp_rd->name); -#ifdef ENABLE_DBENGINE - if (temp_rd->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE) - freez(temp_rd->state->metric_uuid); -#endif - freez(temp_rd->state); - freez(temp_rd); + free_single_rrdrim(temp_rd, archive_mode); temp_rd = t; } } @@ -27,7 +41,7 @@ void free_context_param_list(struct context_param **param_list) if (unlikely(!param_list || !*param_list)) return; - free_temp_rrddim(((*param_list)->rd)); + free_rrddim_list(((*param_list)->rd), (*param_list)->flags & CONTEXT_FLAGS_ARCHIVE); freez((*param_list)); *param_list = NULL; } @@ -36,21 +50,17 @@ void rebuild_context_param_list(struct context_param *context_param_list, time_t { RRDDIM *temp_rd = context_param_list->rd; RRDDIM *new_rd_list = NULL, *t; + int is_archived = (context_param_list->flags & CONTEXT_FLAGS_ARCHIVE); while (temp_rd) { t = temp_rd->next; - if (rrdset_last_entry_t(temp_rd->rrdset) >= after_requested) { + RRDSET *st = temp_rd->rrdset; + time_t last_entry_t = is_archived ? st->last_entry_t : rrdset_last_entry_t(st); + + if (last_entry_t >= after_requested) { temp_rd->next = new_rd_list; new_rd_list = temp_rd; - } else { - freez((char *)temp_rd->id); - freez((char *)temp_rd->name); -#ifdef ENABLE_DBENGINE - if (temp_rd->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE) - freez(temp_rd->state->metric_uuid); -#endif - freez(temp_rd->state); - freez(temp_rd); - } + } else + free_single_rrdrim(temp_rd, is_archived); temp_rd = t; } context_param_list->rd = new_rd_list; @@ -65,7 +75,7 @@ void build_context_param_list(struct context_param **param_list, RRDSET *st) *param_list = mallocz(sizeof(struct context_param)); (*param_list)->first_entry_t = LONG_MAX; (*param_list)->last_entry_t = 0; - (*param_list)->flags = 0; + (*param_list)->flags = CONTEXT_FLAGS_CONTEXT; (*param_list)->rd = NULL; } |