diff options
author | Markos Fountoulakis <44345837+mfundul@users.noreply.github.com> | 2020-11-28 15:53:12 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-28 15:53:12 +0200 |
commit | 5ffba490e381705750c4e2e3eeda47dee6b3cb3d (patch) | |
tree | a32ead1a9109f166a0b43d77b94514ff6e599b6f /web | |
parent | 1a548d533ca18c9276a7b62e499ddfc0000437d7 (diff) |
Fix race condition in rrdset_first_entry_t() and rrdset_last_entry_t() (#10276)
Diffstat (limited to 'web')
-rw-r--r-- | web/api/exporters/shell/allmetrics_shell.c | 2 | ||||
-rw-r--r-- | web/api/formatters/json_wrapper.c | 6 | ||||
-rw-r--r-- | web/api/formatters/rrd2json.c | 6 | ||||
-rw-r--r-- | web/api/formatters/rrdset2json.c | 4 | ||||
-rw-r--r-- | web/api/queries/query.c | 14 |
5 files changed, 19 insertions, 13 deletions
diff --git a/web/api/exporters/shell/allmetrics_shell.c b/web/api/exporters/shell/allmetrics_shell.c index 90c63d443d..daa004992f 100644 --- a/web/api/exporters/shell/allmetrics_shell.c +++ b/web/api/exporters/shell/allmetrics_shell.c @@ -119,7 +119,7 @@ void rrd_stats_api_v1_charts_allmetrics_json(RRDHOST *host, BUFFER *wb) { , st->family , st->context , st->units - , rrdset_last_entry_t(st) + , rrdset_last_entry_t_nolock(st) ); chart_counter++; diff --git a/web/api/formatters/json_wrapper.c b/web/api/formatters/json_wrapper.c index e838a969f8..bfe172cfce 100644 --- a/web/api/formatters/json_wrapper.c +++ b/web/api/formatters/json_wrapper.c @@ -22,6 +22,7 @@ void rrdr_json_wrapper_begin(RRDR *r, BUFFER *wb, uint32_t format, RRDR_OPTIONS sq[0] = '"'; } + rrdset_rdlock(r->st); buffer_sprintf(wb, "{\n" " %sapi%s: 1,\n" " %sid%s: %s%s%s,\n" @@ -38,11 +39,12 @@ void rrdr_json_wrapper_begin(RRDR *r, BUFFER *wb, uint32_t format, RRDR_OPTIONS , kq, kq, sq, temp_rd?r->st->context:r->st->name, sq , kq, kq, r->update_every , kq, kq, r->st->update_every - , kq, kq, (uint32_t)rrdset_first_entry_t(r->st) - , kq, kq, (uint32_t)rrdset_last_entry_t(r->st) + , kq, kq, (uint32_t)rrdset_first_entry_t_nolock(r->st) + , kq, kq, (uint32_t)rrdset_last_entry_t_nolock(r->st) , kq, kq, (uint32_t)r->before , kq, kq, (uint32_t)r->after , kq, kq); + rrdset_unlock(r->st); for(c = 0, i = 0, rd = temp_rd?temp_rd:r->st->dimensions; rd && c < r->d ;c++, rd = rd->next) { if(unlikely(r->od[c] & RRDR_DIMENSION_HIDDEN)) continue; diff --git a/web/api/formatters/rrd2json.c b/web/api/formatters/rrd2json.c index 45ec3c2030..390659061c 100644 --- a/web/api/formatters/rrd2json.c +++ b/web/api/formatters/rrd2json.c @@ -45,12 +45,12 @@ void build_context_param_list(struct context_param **param_list, RRDSET *st) } RRDDIM *rd1; - (*param_list)->first_entry_t = MIN((*param_list)->first_entry_t, rrdset_first_entry_t(st)); - (*param_list)->last_entry_t = MAX((*param_list)->last_entry_t, rrdset_last_entry_t(st)); - st->last_accessed_time = now_realtime_sec(); rrdset_rdlock(st); + (*param_list)->first_entry_t = MIN((*param_list)->first_entry_t, rrdset_first_entry_t_nolock(st)); + (*param_list)->last_entry_t = MAX((*param_list)->last_entry_t, rrdset_last_entry_t_nolock(st)); + rrddim_foreach_read(rd1, st) { RRDDIM *rd = mallocz(rd1->memsize); memcpy(rd, rd1, rd1->memsize); diff --git a/web/api/formatters/rrdset2json.c b/web/api/formatters/rrdset2json.c index 373c23010f..251395eff5 100644 --- a/web/api/formatters/rrdset2json.c +++ b/web/api/formatters/rrdset2json.c @@ -7,8 +7,8 @@ void rrdset2json(RRDSET *st, BUFFER *wb, size_t *dimensions_count, size_t *memory_used, int skip_volatile) { rrdset_rdlock(st); - time_t first_entry_t = rrdset_first_entry_t(st); - time_t last_entry_t = rrdset_last_entry_t(st); + time_t first_entry_t = rrdset_first_entry_t_nolock(st); + time_t last_entry_t = rrdset_last_entry_t_nolock(st); buffer_sprintf(wb, "\t\t{\n" diff --git a/web/api/queries/query.c b/web/api/queries/query.c index 91eec84651..3b9077cd68 100644 --- a/web/api/queries/query.c +++ b/web/api/queries/query.c @@ -679,6 +679,7 @@ static void rrd2rrdr_log_request_response_metdata(RRDR *r //, size_t before_slot , const char *msg ) { + netdata_rwlock_rdlock(&r->st->rrdset_rwlock); info("INTERNAL ERROR: rrd2rrdr() on %s update every %d with %s grouping %s (group: %ld, resampling_time: %ld, resampling_group: %ld), " "after (got: %zu, want: %zu, req: %zu, db: %zu), " "before (got: %zu, want: %zu, req: %zu, db: %zu), " @@ -700,19 +701,19 @@ static void rrd2rrdr_log_request_response_metdata(RRDR *r , (size_t)r->after , (size_t)after_wanted , (size_t)after_requested - , (size_t)rrdset_first_entry_t(r->st) + , (size_t)rrdset_first_entry_t_nolock(r->st) // before , (size_t)r->before , (size_t)before_wanted , (size_t)before_requested - , (size_t)rrdset_last_entry_t(r->st) + , (size_t)rrdset_last_entry_t_nolock(r->st) // duration , (size_t)(r->before - r->after + r->st->update_every) , (size_t)(before_wanted - after_wanted + r->st->update_every) , (size_t)(before_requested - after_requested) - , (size_t)((rrdset_last_entry_t(r->st) - rrdset_first_entry_t(r->st)) + r->st->update_every) + , (size_t)((rrdset_last_entry_t_nolock(r->st) - rrdset_first_entry_t_nolock(r->st)) + r->st->update_every) // slot /* @@ -730,6 +731,7 @@ static void rrd2rrdr_log_request_response_metdata(RRDR *r // message , msg ); + netdata_rwlock_unlock(&r->st->rrdset_rwlock); } #endif // NETDATA_INTERNAL_CHECKS @@ -1575,8 +1577,10 @@ RRDR *rrd2rrdr( first_entry_t = context_param_list->first_entry_t; last_entry_t = context_param_list->last_entry_t; } else { - first_entry_t = rrdset_first_entry_t(st); - last_entry_t = rrdset_last_entry_t(st); + rrdset_rdlock(st); + first_entry_t = rrdset_first_entry_t_nolock(st); + last_entry_t = rrdset_last_entry_t_nolock(st); + rrdset_unlock(st); } rrd_update_every = st->update_every; |