summaryrefslogtreecommitdiffstats
path: root/database
diff options
context:
space:
mode:
authorStelios Fragkakis <52996999+stelfrag@users.noreply.github.com>2020-08-20 18:50:13 +0300
committerGitHub <noreply@github.com>2020-08-20 18:50:13 +0300
commitf5a85f7747f04ae3146f0a2cdf948531fed0d47c (patch)
tree9bd79317821c5f60df328e9c02d08ae20bdb2ef1 /database
parent334473f888733ba96936db9ca779944c8733d77b (diff)
Added code to release memory used by the global GUID map (#9729)
Fixed memory leak issues associated with the global GUID map during agent shutdown
Diffstat (limited to 'database')
-rw-r--r--database/engine/global_uuid_map/global_uuid_map.c87
-rw-r--r--database/engine/global_uuid_map/global_uuid_map.h5
-rw-r--r--database/rrddim.c9
-rw-r--r--database/rrdhost.c4
-rw-r--r--database/rrdset.c6
5 files changed, 71 insertions, 40 deletions
diff --git a/database/engine/global_uuid_map/global_uuid_map.c b/database/engine/global_uuid_map/global_uuid_map.c
index 83b9b1c84e..6669517ba1 100644
--- a/database/engine/global_uuid_map/global_uuid_map.c
+++ b/database/engine/global_uuid_map/global_uuid_map.c
@@ -9,6 +9,51 @@ static uv_rwlock_t object_lock;
static uv_rwlock_t global_lock;
+void free_global_guid_map()
+{
+ JudyHSFreeArray(&JGUID_map, PJE0);
+ JudyHSFreeArray(&JGUID_object_map, PJE0);
+}
+
+static void free_single_uuid(uuid_t *uuid)
+{
+ Pvoid_t *PValue, *PValue1;
+ char *existing_object;
+ Word_t size;
+
+ PValue = JudyHSGet(JGUID_map, (void *) uuid, (Word_t) sizeof(uuid_t));
+ if (likely(PValue)) {
+ existing_object = *PValue;
+ GUID_TYPE object_type = existing_object[0];
+ size = (Word_t)object_type ? (object_type * 16) + 1 : strlen((char *)existing_object + 1) + 2;
+ PValue1 = JudyHSGet(JGUID_object_map, (void *)existing_object, (Word_t)size);
+ if (PValue1 && *PValue1) {
+ freez(*PValue1);
+ }
+ JudyHSDel(&JGUID_object_map, (void *)existing_object,
+ (Word_t)object_type ? (object_type * 16) + 1 : strlen((char *)existing_object + 1) + 2, PJE0);
+ JudyHSDel(&JGUID_map, (void *)uuid, (Word_t)sizeof(uuid_t), PJE0);
+ freez(existing_object);
+ }
+}
+
+void free_uuid(uuid_t *uuid)
+{
+ GUID_TYPE ret;
+ char object[49];
+
+ ret = find_object_by_guid(uuid, object, sizeof(object));
+ if (GUID_TYPE_DIMENSION == ret)
+ free_single_uuid((uuid_t *)(object + 16 + 16));
+
+ if (GUID_TYPE_CHART == ret)
+ free_single_uuid((uuid_t *)(object + 16));
+
+ free_single_uuid(uuid);
+ return;
+}
+
+
void dump_object(uuid_t *index, void *object)
{
char uuid_s[36 + 1];
@@ -101,34 +146,6 @@ static inline int guid_store_nolock(uuid_t *uuid, void *object, GUID_TYPE object
}
-inline int guid_store(uuid_t *uuid, char *object, GUID_TYPE object_type)
-{
- uv_rwlock_wrlock(&global_lock);
- int rc = guid_store_nolock(uuid, object, object_type);
- uv_rwlock_wrunlock(&global_lock);
- return rc;
-}
-
-/*
- * This can be used to bulk load entries into the global map
- *
- * A lock must be aquired since it will call guid_store_nolock
- * with a "no lock" parameter.
- *
- * Note: object memory must be allocated by caller and not released
- */
-int guid_bulk_load(char *uuid, char *object)
-{
- uuid_t target_uuid;
- if (likely(!uuid_parse(uuid, target_uuid))) {
-#ifdef NETDATA_INTERNAL_CHECKS
- debug(D_GUIDLOG,"Mapping GUID [%s] on [%s]", uuid, object);
-#endif
- return guid_store_nolock(&target_uuid, object, GUID_TYPE_CHAR);
- }
- return 1;
-}
-
/*
* Given a GUID, find if an object is stored
* - Optionally return the object
@@ -151,15 +168,19 @@ GUID_TYPE find_object_by_guid(uuid_t *uuid, char *object, size_t max_bytes)
if (likely(object && max_bytes)) {
switch (value_type) {
case GUID_TYPE_CHAR:
- if (unlikely(max_bytes - 1 < strlen((char *) *PValue+1)))
+ if (unlikely(max_bytes - 1 < strlen((char *) *PValue+1))) {
+ uv_rwlock_rdunlock(&global_lock);
return GUID_TYPE_NOSPACE;
+ }
strncpyz(object, (char *) *PValue+1, max_bytes - 1);
break;
case GUID_TYPE_HOST:
case GUID_TYPE_CHART:
case GUID_TYPE_DIMENSION:
- if (unlikely(max_bytes < (size_t) value_type * 16))
+ if (unlikely(max_bytes < (size_t) value_type * 16)) {
+ uv_rwlock_rdunlock(&global_lock);
return GUID_TYPE_NOSPACE;
+ }
memcpy(object, *PValue+1, value_type * 16);
break;
default:
@@ -265,12 +286,6 @@ void init_global_guid_map()
fatal_assert(0 == uv_rwlock_init(&guid_lock));
fatal_assert(0 == uv_rwlock_init(&object_lock));
fatal_assert(0 == uv_rwlock_init(&global_lock));
-
-// int rc = guid_bulk_load("6fc56a64-05d7-47a7-bc82-7f3235d8cbda","d6b37186-74db-11ea-88b2-0bf5095b1f9e/cgroup_qemu_ubuntu18.04.cpu_per_core/cpu3");
-// rc = guid_bulk_load("75c6fa02-97cc-40c1-aacd-a0132190472e","d6b37186-74db-11ea-88b2-0bf5095b1f9e/services.throttle_io_ops_write/system.slice_setvtrgb.service");
-// if (rc == 0)
-// info("BULK GUID load successful");
-
return;
}
diff --git a/database/engine/global_uuid_map/global_uuid_map.h b/database/engine/global_uuid_map/global_uuid_map.h
index 3def854baf..f31f3c0079 100644
--- a/database/engine/global_uuid_map/global_uuid_map.h
+++ b/database/engine/global_uuid_map/global_uuid_map.h
@@ -16,11 +16,10 @@ typedef enum guid_type {
GUID_TYPE_NOSPACE
} GUID_TYPE;
-extern int guid_store(uuid_t *uuid, char *object, GUID_TYPE);
extern GUID_TYPE find_object_by_guid(uuid_t *uuid, char *object, size_t max_bytes);
extern int find_guid_by_object(char *object, uuid_t *uuid, GUID_TYPE);
extern void init_global_guid_map();
extern int find_or_generate_guid(void *object, uuid_t *uuid, GUID_TYPE object_type, int replace_instead_of_generate);
-
-
+extern void free_uuid(uuid_t *uuid);
+extern void free_global_guid_map();
#endif //NETDATA_GLOBAL_UUID_MAP_H
diff --git a/database/rrddim.c b/database/rrddim.c
index 25209dbe24..e2fe519a8c 100644
--- a/database/rrddim.c
+++ b/database/rrddim.c
@@ -487,7 +487,6 @@ void rrddim_free_custom(RRDSET *st, RRDDIM *rd, int db_rotated)
#endif
}
}
- freez(rd->state);
if(rd == st->dimensions)
st->dimensions = rd->next;
@@ -518,6 +517,7 @@ void rrddim_free_custom(RRDSET *st, RRDDIM *rd, int db_rotated)
debug(D_RRD_CALLS, "Unmapping dimension '%s'.", rd->name);
freez((void *)rd->id);
freez(rd->cache_filename);
+ freez(rd->state);
munmap(rd, rd->memsize);
break;
@@ -527,6 +527,13 @@ void rrddim_free_custom(RRDSET *st, RRDDIM *rd, int db_rotated)
debug(D_RRD_CALLS, "Removing dimension '%s'.", rd->name);
freez((void *)rd->id);
freez(rd->cache_filename);
+#ifdef ENABLE_DBENGINE
+ if (rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE) {
+ free_uuid(rd->state->metric_uuid);
+ freez(rd->state->metric_uuid);
+ }
+#endif
+ freez(rd->state);
freez(rd);
break;
}
diff --git a/database/rrdhost.c b/database/rrdhost.c
index f0a5c6b84b..d82a9099b4 100644
--- a/database/rrdhost.c
+++ b/database/rrdhost.c
@@ -879,6 +879,10 @@ void rrdhost_free(RRDHOST *host) {
netdata_rwlock_destroy(&host->labels_rwlock);
netdata_rwlock_destroy(&host->health_log.alarm_log_rwlock);
netdata_rwlock_destroy(&host->rrdhost_rwlock);
+
+#ifdef ENABLE_DBENGINE
+ free_uuid(&host->host_uuid);
+#endif
freez(host);
rrd_hosts_available--;
diff --git a/database/rrdset.c b/database/rrdset.c
index 4f0b4a160a..d957c1560c 100644
--- a/database/rrdset.c
+++ b/database/rrdset.c
@@ -388,6 +388,12 @@ void rrdset_free(RRDSET *st) {
case RRD_MEMORY_MODE_ALLOC:
case RRD_MEMORY_MODE_NONE:
case RRD_MEMORY_MODE_DBENGINE:
+#ifdef ENABLE_DBENGINE
+ if (st->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE) {
+ free_uuid(st->chart_uuid);
+ freez(st->chart_uuid);
+ }
+#endif
freez(st);
break;
}