]> arthur.barton.de Git - netdata.git/commitdiff
hosts except localhost save files in subdirectory in /var/cache/netdata and /var...
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Sat, 18 Feb 2017 21:50:54 +0000 (23:50 +0200)
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Tue, 21 Feb 2017 23:00:24 +0000 (01:00 +0200)
src/rrd.c
src/rrd.h
src/rrddim.c
src/rrdhost.c
src/rrdset.c

index 5cc72faee69928acb505ee81791653beb9f7830f..0a9599f5c58a4e146f1f7e1da3503d16a3580bae 100644 (file)
--- a/src/rrd.c
+++ b/src/rrd.c
@@ -113,15 +113,15 @@ const char *rrdset_type_name(RRDSET_TYPE chart_type) {
 // ----------------------------------------------------------------------------
 // RRD - cache directory
 
-char *rrdset_cache_dir(RRDHOST *host, const char *id) {
+char *rrdset_cache_dir(RRDHOST *host, const char *id, const char *config_section) {
     char *ret = NULL;
 
     char b[FILENAME_MAX + 1];
     char n[FILENAME_MAX + 1];
     rrdset_strncpyz_name(b, id, FILENAME_MAX);
 
-    snprintfz(n, FILENAME_MAX, "%s/%s", netdata_configured_cache_dir, b);
-    ret = config_get(id, "cache directory", n);
+    snprintfz(n, FILENAME_MAX, "%s/%s", host->cache_dir, b);
+    ret = config_get(config_section, "cache directory", n);
 
     if(host->rrd_memory_mode == RRD_MEMORY_MODE_MAP || host->rrd_memory_mode == RRD_MEMORY_MODE_SAVE) {
         int r = mkdir(ret, 0775);
index 0b91bf2fc0fedae6b9aebcee88376ce20825268c..a471b329dd6a640ca5b2ee78f0d0093597bd8f33 100644 (file)
--- a/src/rrd.h
+++ b/src/rrd.h
@@ -216,6 +216,8 @@ struct rrdset {
                                                     // since the config always has a higher priority
                                                     // (the user overwrites the name of the charts)
 
+    char *config_section;                           // the config section for the chart
+
     char *type;                                     // the type of graph RRD_TYPE_* (a category, for determining graphing options)
     char *family;                                   // grouping sets under the same family
     char *title;                                    // title shown to user
@@ -325,6 +327,9 @@ struct rrdhost {
     avl_tree_lock rrdfamily_root_index;             // the host's chart families index
     avl_tree_lock variables_root_index;             // the host's chart variables index
 
+    char *cache_dir;                                // the directory to save RRD cache files
+    char *varlib_dir;                               // the directory to save health log
+
     // all RRDCALCs are primarily allocated and linked here
     // RRDCALCs may be linked to charts at any point
     // (charts may or may not exist when these are loaded)
@@ -385,7 +390,7 @@ extern RRDSET *rrdset_create(RRDHOST *host
                              , const char *units
                              , long priority
                              , int update_every
-                             , int chart_type);
+                             , RRDSET_TYPE chart_type);
 
 #define rrdset_create_localhost(type, id, name, family, context, title, units, priority, update_every, chart_type) rrdset_create(localhost, type, id, name, family, context, title, units, priority, update_every, chart_type)
 
@@ -463,10 +468,11 @@ extern collected_number rrddim_set(RRDSET *st, const char *id, collected_number
 
 #ifdef NETDATA_RRD_INTERNALS
 
+extern void rrdset_free(RRDSET *st);
 extern avl_tree_lock rrdhost_root_index;
 
 extern char *rrdset_strncpyz_name(char *to, const char *from, size_t length);
-extern char *rrdset_cache_dir(RRDHOST *host, const char *id);
+extern char *rrdset_cache_dir(RRDHOST *host, const char *id, const char *config_section);
 
 extern void rrdset_reset(RRDSET *st);
 
index 6b648fffafc4b7717fa1528b766b548ef435cfc3..7049f73cdf08804618a544b425e6cae3248d60c7 100644 (file)
@@ -43,7 +43,7 @@ inline void rrddim_set_name(RRDSET *st, RRDDIM *rd, const char *name) {
 
     char varname[CONFIG_MAX_NAME + 1];
     snprintfz(varname, CONFIG_MAX_NAME, "dim %s name", rd->id);
-    rd->name = config_set_default(st->id, varname, name);
+    rd->name = config_set_default(st->config_section, varname, name);
     rd->hash_name = simple_hash(rd->name);
 
     rrddimvar_rename_all(rd);
@@ -84,7 +84,6 @@ RRDDIM *rrddim_add(RRDSET *st, const char *id, const char *name, collected_numbe
             rd->variables = NULL;
             rd->next = NULL;
             rd->rrdset = NULL;
-            rd->rrd_memory_mode = st->rrd_memory_mode;
 
             struct timeval now;
             now_realtime_timeval(&now);
@@ -124,6 +123,10 @@ RRDDIM *rrddim_add(RRDSET *st, const char *id, const char *name, collected_numbe
                 error("File %s does not have the expected algorithm (expected %u '%s', found %u '%s'). Previous values may be wrong."
                       , fullfilename, algorithm, rrd_algorithm_name(algorithm), rd->algorithm,
                         rrd_algorithm_name(rd->algorithm));
+
+            // make sure we have the right memory mode
+            // even if we cleared the memory
+            rd->rrd_memory_mode = st->rrd_memory_mode;
         }
     }
 
@@ -143,17 +146,17 @@ RRDDIM *rrddim_add(RRDSET *st, const char *id, const char *name, collected_numbe
     rd->cache_filename = strdupz(fullfilename);
 
     snprintfz(varname, CONFIG_MAX_NAME, "dim %s name", rd->id);
-    rd->name = config_get(st->id, varname, (name && *name)?name:rd->id);
+    rd->name = config_get(st->config_section, varname, (name && *name)?name:rd->id);
     rd->hash_name = simple_hash(rd->name);
 
     snprintfz(varname, CONFIG_MAX_NAME, "dim %s algorithm", rd->id);
-    rd->algorithm = rrd_algorithm_id(config_get(st->id, varname, rrd_algorithm_name(algorithm)));
+    rd->algorithm = rrd_algorithm_id(config_get(st->config_section, varname, rrd_algorithm_name(algorithm)));
 
     snprintfz(varname, CONFIG_MAX_NAME, "dim %s multiplier", rd->id);
-    rd->multiplier = config_get_number(st->id, varname, multiplier);
+    rd->multiplier = config_get_number(st->config_section, varname, multiplier);
 
     snprintfz(varname, CONFIG_MAX_NAME, "dim %s divisor", rd->id);
-    rd->divisor = config_get_number(st->id, varname, divisor);
+    rd->divisor = config_get_number(st->config_section, varname, divisor);
     if(!rd->divisor) rd->divisor = 1;
 
     rd->entries = st->entries;
index 20f7223363136c2782e6b5a1f254ffc13a4d340a..67f16a73b4e413aeb44ca5fc8cdb674509420b00 100644 (file)
@@ -93,13 +93,38 @@ RRDHOST *rrdhost_create(const char *hostname, const char *guid) {
 
     if(!localhost) {
         // this is localhost
-        snprintfz(filename, FILENAME_MAX, "%s/health/health-log.db", netdata_configured_varlib_dir);
+
+        host->cache_dir = strdupz(netdata_configured_cache_dir);
+        host->varlib_dir = strdupz(netdata_configured_varlib_dir);
+
+        snprintfz(filename, FILENAME_MAX, "%s/health/health-log.db", host->varlib_dir);
         host->health_log_filename = strdupz(config_get("health", "health db file", filename));
+
     }
     else {
         // this is not localhost - append our GUID to localhost path
-        snprintfz(filename, FILENAME_MAX, "%s.%s", localhost->health_log_filename, host->machine_guid);
+
+        snprintfz(filename, FILENAME_MAX, "%s/%s", netdata_configured_cache_dir, host->machine_guid);
+        host->cache_dir = strdupz(filename);
+
+        if(host->rrd_memory_mode == RRD_MEMORY_MODE_MAP || host->rrd_memory_mode == RRD_MEMORY_MODE_SAVE) {
+            int r = mkdir(host->cache_dir, 0775);
+            if(r != 0 && errno != EEXIST)
+                error("Cannot create directory '%s'", host->cache_dir);
+        }
+
+        snprintfz(filename, FILENAME_MAX, "%s/%s", netdata_configured_varlib_dir, host->machine_guid);
+        host->varlib_dir = strdupz(filename);
+
+        if(host->health_enabled) {
+            int r = mkdir(host->varlib_dir, 0775);
+            if(r != 0 && errno != EEXIST)
+                error("Cannot create directory '%s'", host->varlib_dir);
+        }
+
+        snprintfz(filename, FILENAME_MAX, "%s/health/health-log.db", host->varlib_dir);
         host->health_log_filename = strdupz(filename);
+
     }
 
     snprintfz(filename, FILENAME_MAX, "%s/alarm-notify.sh", netdata_configured_plugins_dir);
@@ -191,34 +216,14 @@ void rrdhost_free(RRDHOST *host) {
     for(st = host->rrdset_root; st ;) {
         RRDSET *next = st->next;
 
-        pthread_rwlock_wrlock(&st->rwlock);
-
-        while(st->variables)  rrdsetvar_free(st->variables);
-        while(st->alarms)     rrdsetcalc_unlink(st->alarms);
-        while(st->dimensions) rrddim_free(st, st->dimensions);
-
-        if(unlikely(rrdset_index_del(host, st) != st))
-            error("RRDSET: INTERNAL ERROR: attempt to remove from index chart '%s', removed a different chart.", st->id);
-
-        rrdset_index_del_name(host, st);
-
-        st->rrdfamily->use_count--;
-        if(!st->rrdfamily->use_count)
-            rrdfamily_free(host, st->rrdfamily);
-
-        pthread_rwlock_unlock(&st->rwlock);
-
-        if(st->rrd_memory_mode == RRD_MEMORY_MODE_SAVE || st->rrd_memory_mode == RRD_MEMORY_MODE_MAP) {
-            debug(D_RRD_CALLS, "Unmapping stats '%s'.", st->name);
-            munmap(st, st->memsize);
-        }
-        else
-            freez(st);
+        rrdset_free(st);
 
         st = next;
     }
     host->rrdset_root = NULL;
 
+    freez(host->cache_dir);
+    freez(host->varlib_dir);
     freez(host->health_default_exec);
     freez(host->health_default_recipient);
     freez(host->health_log_filename);
index 3d6b2f8028718c588fa93e693837a9efa4cceee7..fe5158eedb200841fdaaf9dc2eac52543a35f126 100644 (file)
@@ -133,12 +133,12 @@ void rrdset_set_name(RRDSET *st, const char *name) {
 
     if(st->name) {
         rrdset_index_del_name(st->rrdhost, st);
-        st->name = config_set_default(st->id, "name", b);
+        st->name = config_set_default(st->config_section, "name", b);
         st->hash_name = simple_hash(st->name);
         rrdsetvar_rename_all(st);
     }
     else {
-        st->name = config_get(st->id, "name", b);
+        st->name = config_get(st->config_section, "name", b);
         st->hash_name = simple_hash(st->name);
     }
 
@@ -206,12 +206,44 @@ static inline void timeval_align(struct timeval *tv, int update_every) {
     tv->tv_usec = 500000;
 }
 
+// ----------------------------------------------------------------------------
+// RRDSET - free a chart
+
+void rrdset_free(RRDSET *st) {
+    pthread_rwlock_wrlock(&st->rwlock);
+
+    while(st->variables)  rrdsetvar_free(st->variables);
+    while(st->alarms)     rrdsetcalc_unlink(st->alarms);
+    while(st->dimensions) rrddim_free(st, st->dimensions);
+
+    if(unlikely(rrdset_index_del(st->rrdhost, st) != st))
+        error("RRDSET: INTERNAL ERROR: attempt to remove from index chart '%s', removed a different chart.", st->id);
+
+    rrdset_index_del_name(st->rrdhost, st);
+
+    st->rrdfamily->use_count--;
+    if(!st->rrdfamily->use_count)
+        rrdfamily_free(st->rrdhost, st->rrdfamily);
+
+    pthread_rwlock_unlock(&st->rwlock);
+
+    // free directly allocated memory
+    freez(st->config_section);
+
+    if(st->rrd_memory_mode == RRD_MEMORY_MODE_SAVE || st->rrd_memory_mode == RRD_MEMORY_MODE_MAP) {
+        debug(D_RRD_CALLS, "Unmapping stats '%s'.", st->name);
+        munmap(st, st->memsize);
+    }
+    else
+        freez(st);
+}
+
 // ----------------------------------------------------------------------------
 // RRDSET - create a chart
 
 RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const char *name, const char *family
                       , const char *context, const char *title, const char *units, long priority
-                      , int update_every, int chart_type) {
+                      , int update_every, RRDSET_TYPE chart_type) {
 
     if(!type || !type[0]) {
         fatal("Cannot create rrd stats without a type.");
@@ -223,9 +255,10 @@ RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const cha
         return NULL;
     }
 
-    char fullid[RRD_ID_LENGTH_MAX + 1];
-    char fullfilename[FILENAME_MAX + 1];
+    // ------------------------------------------------------------------------
+    // check if it already exists
 
+    char fullid[RRD_ID_LENGTH_MAX + 1];
     snprintfz(fullid, RRD_ID_LENGTH_MAX, "%s.%s", type, id);
 
     RRDSET *st = rrdset_find(host, fullid);
@@ -234,77 +267,101 @@ RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const cha
         return st;
     }
 
-    long rentries = config_get_number(fullid, "history", host->rrd_history_entries);
+    char fullfilename[FILENAME_MAX + 1];
+
+    // ------------------------------------------------------------------------
+    // compose the config_section for this chart
+
+    char config_section[RRD_ID_LENGTH_MAX + 1];
+    if(host == localhost)
+        strcpy(config_section, fullid);
+    else
+        snprintfz(config_section, RRD_ID_LENGTH_MAX, "%s/%s", host->machine_guid, fullid);
+
+    // ------------------------------------------------------------------------
+    // get the options from the config, we need to create it
+
+    long rentries = config_get_number(config_section, "history", host->rrd_history_entries);
     long entries = align_entries_to_pagesize(rentries);
-    if(entries != rentries) entries = config_set_number(fullid, "history", entries);
+    if(entries != rentries) entries = config_set_number(config_section, "history", entries);
 
-    int enabled = config_get_boolean(fullid, "enabled", 1);
+    int enabled = config_get_boolean(config_section, "enabled", 1);
     if(!enabled) entries = 5;
 
     unsigned long size = sizeof(RRDSET);
-    char *cache_dir = rrdset_cache_dir(host, fullid);
+    char *cache_dir = rrdset_cache_dir(host, fullid, config_section);
+
+    // ------------------------------------------------------------------------
+    // load it or allocate it
 
     debug(D_RRD_CALLS, "Creating RRD_STATS for '%s.%s'.", type, id);
 
     snprintfz(fullfilename, FILENAME_MAX, "%s/main.db", cache_dir);
-    if(host->rrd_memory_mode != RRD_MEMORY_MODE_RAM) st = (RRDSET *)mymmap(fullfilename, size, ((host->rrd_memory_mode == RRD_MEMORY_MODE_MAP)?MAP_SHARED:MAP_PRIVATE), 0);
-    if(st) {
-        if(strcmp(st->magic, RRDSET_MAGIC) != 0) {
-            errno = 0;
-            info("Initializing file %s.", fullfilename);
-            memset(st, 0, size);
-        }
-        else if(strcmp(st->id, fullid) != 0) {
-            errno = 0;
-            error("File %s contents are not for chart %s. Clearing it.", fullfilename, fullid);
-            // munmap(st, size);
-            // st = NULL;
-            memset(st, 0, size);
-        }
-        else if(st->memsize != size || st->entries != entries) {
-            errno = 0;
-            error("File %s does not have the desired size. Clearing it.", fullfilename);
-            memset(st, 0, size);
-        }
-        else if(st->update_every != update_every) {
-            errno = 0;
-            error("File %s does not have the desired update frequency. Clearing it.", fullfilename);
-            memset(st, 0, size);
-        }
-        else if((now_realtime_sec() - st->last_updated.tv_sec) > update_every * entries) {
-            errno = 0;
-            error("File %s is too old. Clearing it.", fullfilename);
-            memset(st, 0, size);
-        }
+    if(host->rrd_memory_mode != RRD_MEMORY_MODE_RAM) {
+        st = (RRDSET *) mymmap(fullfilename, size, ((host->rrd_memory_mode == RRD_MEMORY_MODE_MAP) ? MAP_SHARED : MAP_PRIVATE), 0);
+        if(st) {
+            memset(&st->avl, 0, sizeof(avl));
+            memset(&st->avlname, 0, sizeof(avl));
+            memset(&st->variables_root_index, 0, sizeof(avl_tree_lock));
+            memset(&st->dimensions_index, 0, sizeof(avl_tree_lock));
+            memset(&st->rwlock, 0, sizeof(pthread_rwlock_t));
+
+            st->name = NULL;
+            st->type = NULL;
+            st->family = NULL;
+            st->context = NULL;
+            st->title = NULL;
+            st->units = NULL;
+            st->dimensions = NULL;
+            st->next = NULL;
+            st->variables = NULL;
+            st->alarms = NULL;
+            st->flags = 0x00000000;
+
+            if(strcmp(st->magic, RRDSET_MAGIC) != 0) {
+                errno = 0;
+                info("Initializing file %s.", fullfilename);
+                memset(st, 0, size);
+            }
+            else if(strcmp(st->id, fullid) != 0) {
+                errno = 0;
+                error("File %s contents are not for chart %s. Clearing it.", fullfilename, fullid);
+                // munmap(st, size);
+                // st = NULL;
+                memset(st, 0, size);
+            }
+            else if(st->memsize != size || st->entries != entries) {
+                errno = 0;
+                error("File %s does not have the desired size. Clearing it.", fullfilename);
+                memset(st, 0, size);
+            }
+            else if(st->update_every != update_every) {
+                errno = 0;
+                error("File %s does not have the desired update frequency. Clearing it.", fullfilename);
+                memset(st, 0, size);
+            }
+            else if((now_realtime_sec() - st->last_updated.tv_sec) > update_every * entries) {
+                errno = 0;
+                error("File %s is too old. Clearing it.", fullfilename);
+                memset(st, 0, size);
+            }
 
-        // make sure the database is aligned
-        if(st->last_updated.tv_sec)
-            timeval_align(&st->last_updated, update_every);
-    }
+            // make sure the database is aligned
+            if(st->last_updated.tv_sec)
+                timeval_align(&st->last_updated, update_every);
 
-    if(st) {
-        st->name = NULL;
-        st->type = NULL;
-        st->family = NULL;
-        st->context = NULL;
-        st->title = NULL;
-        st->units = NULL;
-        st->dimensions = NULL;
-        st->next = NULL;
-        st->rrd_memory_mode = host->rrd_memory_mode;
-        st->variables = NULL;
-        st->alarms = NULL;
-        memset(&st->rwlock, 0, sizeof(pthread_rwlock_t));
-        memset(&st->avl, 0, sizeof(avl));
-        memset(&st->avlname, 0, sizeof(avl));
-        memset(&st->variables_root_index, 0, sizeof(avl_tree_lock));
-        memset(&st->dimensions_index, 0, sizeof(avl_tree_lock));
+            // make sure we have the right memory mode
+            // even if we cleared the memory
+            st->rrd_memory_mode = host->rrd_memory_mode;
+        }
     }
-    else {
+
+    if(unlikely(!st)) {
         st = callocz(1, size);
         st->rrd_memory_mode = RRD_MEMORY_MODE_RAM;
     }
 
+    st->config_section = strdup(config_section);
     st->rrdhost = host;
     st->memsize = size;
     st->entries = entries;
@@ -320,15 +377,15 @@ RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const cha
 
     st->cache_dir = cache_dir;
 
-    st->chart_type = rrdset_type_id(config_get(st->id, "chart type", rrdset_type_name(chart_type)));
-    st->type       = config_get(st->id, "type", type);
-    st->family     = config_get(st->id, "family", family?family:st->type);
-    st->units      = config_get(st->id, "units", units?units:"");
+    st->chart_type = rrdset_type_id(config_get(st->config_section, "chart type", rrdset_type_name(chart_type)));
+    st->type       = config_get(st->config_section, "type", type);
+    st->family     = config_get(st->config_section, "family", family?family:st->type);
+    st->units      = config_get(st->config_section, "units", units?units:"");
 
-    st->context    = config_get(st->id, "context", context?context:st->id);
+    st->context    = config_get(st->config_section, "context", context?context:st->id);
     st->hash_context = simple_hash(st->context);
 
-    st->priority = config_get_number(st->id, "priority", priority);
+    st->priority = config_get_number(st->config_section, "priority", priority);
     if(enabled)
         rrdset_flag_set(st, RRDSET_FLAG_ENABLED);
     else
@@ -351,7 +408,7 @@ RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const cha
     st->counter_done = 0;
 
     st->gap_when_lost_iterations_above = (int) (
-            config_get_number(st->id, "gap when lost iterations above", RRD_DEFAULT_GAP_INTERPOLATIONS) + 2);
+            config_get_number(st->config_section, "gap when lost iterations above", RRD_DEFAULT_GAP_INTERPOLATIONS) + 2);
 
     avl_init_lock(&st->dimensions_index, rrddim_compare);
     avl_init_lock(&st->variables_root_index, rrdvar_compare);
@@ -367,7 +424,7 @@ RRDSET *rrdset_create(RRDHOST *host, const char *type, const char *id, const cha
         char varvalue2[CONFIG_MAX_VALUE + 1];
         snprintfz(varvalue, CONFIG_MAX_VALUE, "%s (%s)", title?title:"", st->name);
         json_escape_string(varvalue2, varvalue, sizeof(varvalue2));
-        st->title = config_get(st->id, "title", varvalue2);
+        st->title = config_get(st->config_section, "title", varvalue2);
     }
 
     st->rrdfamily = rrdfamily_create(host, st->family);