summaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
authorStelios Fragkakis <52996999+stelfrag@users.noreply.github.com>2021-03-23 18:09:34 +0200
committerGitHub <noreply@github.com>2021-03-23 18:09:34 +0200
commit7ebb0a4da20465016a32a3c0b28635277926b815 (patch)
treea68ec215e14e968d9a8214f857e84672699b1c18 /web
parentefe2a951ad9826e61a1f3e4229b6b8bd61e961ef (diff)
Fix memory leak when archived data is requested (#10837)
Diffstat (limited to 'web')
-rw-r--r--web/api/formatters/json_wrapper.c4
-rw-r--r--web/api/formatters/rrd2json.c54
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;
}