]> arthur.barton.de Git - netdata.git/commitdiff
localhost is now dynamic
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Sat, 18 Feb 2017 11:03:53 +0000 (13:03 +0200)
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Tue, 21 Feb 2017 23:00:20 +0000 (01:00 +0200)
19 files changed:
src/Makefile.am
src/backends.c
src/health.c
src/ipc.c
src/log.c
src/log.h
src/main.c
src/plugins_d.c
src/proc_net_stat_conntrack.c
src/registry.c
src/registry.h
src/registry_init.c
src/registry_internals.c
src/registry_internals.h
src/rrd.h
src/rrd2json.c
src/rrdhost.c
src/rrdset.c
src/web_client.c

index c562b27e7c53629bdefa7fdd4a0b8aa3d3ca0278..0421ce38cd56142f1575186c9ff2b720f6c28655 100644 (file)
@@ -30,7 +30,7 @@ endif
 
 netdata_SOURCES = \
        appconfig.c appconfig.h \
-       adaptive_resortable_list.c \adaptive_resortable_list.h \
+       adaptive_resortable_list.c adaptive_resortable_list.h \
        avl.c avl.h \
        backends.c backends.h \
        clocks.c clocks.h \
index b1c10d9d0631e3cad91b22fb135a20bfd6202b18..c95a93a5c3f8eee153b74681530d770fbf1bdcbe 100644 (file)
@@ -157,7 +157,7 @@ void *backends_main(void *ptr) {
     const char *type = config_get("backend", "type", "graphite");
     const char *destination = config_get("backend", "destination", "localhost");
     const char *prefix = config_get("backend", "prefix", "netdata");
-    const char *hostname = config_get("backend", "hostname", localhost.hostname);
+    const char *hostname = config_get("backend", "hostname", localhost->hostname);
     int frequency = (int)config_get_number("backend", "update every", 10);
     int buffer_on_failures = (int)config_get_number("backend", "buffer on failures", 10);
     long timeoutms = config_get_number("backend", "timeout ms", frequency * 2 * 1000);
@@ -310,19 +310,19 @@ void *backends_main(void *ptr) {
         if(unlikely(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &pthreadoldcancelstate) != 0))
             error("Cannot set pthread cancel state to DISABLE.");
 
-        rrdhost_rdlock(&localhost);
-        for(st = localhost.rrdset_root; st ;st = st->next) {
+        rrdhost_rdlock(localhost);
+        for(st = localhost->rrdset_root; st ;st = st->next) {
             pthread_rwlock_rdlock(&st->rwlock);
 
             RRDDIM *rd;
             for(rd = st->dimensions; rd ;rd = rd->next) {
                 if(rd->last_collected_time.tv_sec >= after)
-                    chart_buffered_metrics += backend_request_formatter(b, prefix, &localhost, hostname, st, rd, after, before, options);
+                    chart_buffered_metrics += backend_request_formatter(b, prefix, localhost, hostname, st, rd, after, before, options);
             }
 
             pthread_rwlock_unlock(&st->rwlock);
         }
-        rrdhost_unlock(&localhost);
+        rrdhost_unlock(localhost);
 
         if(unlikely(pthread_setcancelstate(pthreadoldcancelstate, NULL) != 0))
             error("Cannot set pthread cancel state to RESTORE (%d).", pthreadoldcancelstate);
index 9df2e241fe9619406c2a3a45138866dbd22765e7..f60c702b993adbc3e6e16a2da48322f9a550983d 100644 (file)
@@ -1555,7 +1555,7 @@ static inline int rrdcalc_add_alarm_from_config(RRDHOST *host, RRDCALC *rc) {
     if (rrdcalc_exists(host, rc->chart, rc->name, rc->hash_chart, rc->hash))
         return 0;
 
-    rc->id = rrdcalc_get_unique_id(&localhost, rc->chart, rc->name, &rc->next_event_id);
+    rc->id = rrdcalc_get_unique_id(localhost, rc->chart, rc->name, &rc->next_event_id);
 
     debug(D_HEALTH, "Health configuration adding alarm '%s.%s' (%u): exec '%s', recipient '%s', green %Lf, red %Lf, lookup: group %d, after %d, before %d, options %u, dimensions '%s', update every %d, calculation '%s', warning '%s', critical '%s', source '%s', delay up %d, delay down %d, delay max %d, delay_multiplier %f",
           rc->chart?rc->chart:"NOCHART",
@@ -2040,12 +2040,12 @@ int health_readfile(const char *path, const char *filename) {
         uint32_t hash = simple_uhash(key);
 
         if(hash == hash_alarm && !strcasecmp(key, HEALTH_ALARM_KEY)) {
-            if(rc && !rrdcalc_add_alarm_from_config(&localhost, rc))
-                rrdcalc_free(&localhost, rc);
+            if(rc && !rrdcalc_add_alarm_from_config(localhost, rc))
+                rrdcalc_free(localhost, rc);
 
             if(rt) {
-                if (!rrdcalctemplate_add_template_from_config(&localhost, rt))
-                    rrdcalctemplate_free(&localhost, rt);
+                if (!rrdcalctemplate_add_template_from_config(localhost, rt))
+                    rrdcalctemplate_free(localhost, rt);
                 rt = NULL;
             }
 
@@ -2065,13 +2065,13 @@ int health_readfile(const char *path, const char *filename) {
         }
         else if(hash == hash_template && !strcasecmp(key, HEALTH_TEMPLATE_KEY)) {
             if(rc) {
-                if(!rrdcalc_add_alarm_from_config(&localhost, rc))
-                    rrdcalc_free(&localhost, rc);
+                if(!rrdcalc_add_alarm_from_config(localhost, rc))
+                    rrdcalc_free(localhost, rc);
                 rc = NULL;
             }
 
-            if(rt && !rrdcalctemplate_add_template_from_config(&localhost, rt))
-                rrdcalctemplate_free(&localhost, rt);
+            if(rt && !rrdcalctemplate_add_template_from_config(localhost, rt))
+                rrdcalctemplate_free(localhost, rt);
 
             rt = callocz(1, sizeof(RRDCALCTEMPLATE));
             rt->name = strdupz(value);
@@ -2332,11 +2332,11 @@ int health_readfile(const char *path, const char *filename) {
         }
     }
 
-    if(rc && !rrdcalc_add_alarm_from_config(&localhost, rc))
-        rrdcalc_free(&localhost, rc);
+    if(rc && !rrdcalc_add_alarm_from_config(localhost, rc))
+        rrdcalc_free(localhost, rc);
 
-    if(rt && !rrdcalctemplate_add_template_from_config(&localhost, rt))
-        rrdcalctemplate_free(&localhost, rt);
+    if(rt && !rrdcalctemplate_add_template_from_config(localhost, rt))
+        rrdcalctemplate_free(localhost, rt);
 
     fclose(fp);
     return 1;
@@ -2410,7 +2410,7 @@ void health_init(void) {
     snprintfz(filename, FILENAME_MAX, "%s/health-log.db", pathname);
     health.log_filename = config_get("health", "health db file", filename);
 
-    health_alarm_log_load(&localhost);
+    health_alarm_log_load(localhost);
     health_alarm_log_open();
 
     char *path = health_config_dir();
@@ -2418,16 +2418,16 @@ void health_init(void) {
     snprintfz(filename, FILENAME_MAX, "%s/alarm-notify.sh", netdata_configured_plugins_dir);
     health.health_default_exec = config_get("health", "script to execute on alarm", filename);
 
-    long n = config_get_number("health", "in memory max health log entries", (long)localhost.health_log.max);
+    long n = config_get_number("health", "in memory max health log entries", (long)localhost->health_log.max);
     if(n < 10) {
-        error("Health configuration has invalid max log entries %ld. Using default %u", n, localhost.health_log.max);
-        config_set_number("health", "in memory max health log entries", (long)localhost.health_log.max);
+        error("Health configuration has invalid max log entries %ld. Using default %u", n, localhost->health_log.max);
+        config_set_number("health", "in memory max health log entries", (long)localhost->health_log.max);
     }
-    else localhost.health_log.max = (unsigned int)n;
+    else localhost->health_log.max = (unsigned int)n;
 
-    rrdhost_rwlock(&localhost);
+    rrdhost_rwlock(localhost);
     health_readdir(path);
-    rrdhost_unlock(&localhost);
+    rrdhost_unlock(localhost);
 }
 
 // ----------------------------------------------------------------------------
@@ -2651,7 +2651,7 @@ static inline void health_rrdcalc2json_nolock(BUFFER *wb, RRDCALC *rc) {
 void health_alarms2json(RRDHOST *host, BUFFER *wb, int all) {
     int i;
 
-    rrdhost_rdlock(&localhost);
+    rrdhost_rdlock(localhost);
     buffer_sprintf(wb, "{\n\t\"hostname\": \"%s\","
                         "\n\t\"latest_alarm_log_unique_id\": %u,"
                         "\n\t\"status\": %s,"
@@ -2681,7 +2681,7 @@ void health_alarms2json(RRDHOST *host, BUFFER *wb, int all) {
 //        health_rrdcalctemplate2json_nolock(wb, rt);
 
     buffer_strcat(wb, "\n\t}\n}\n");
-    rrdhost_unlock(&localhost);
+    rrdhost_unlock(localhost);
 }
 
 
@@ -2705,37 +2705,37 @@ void health_reload(void) {
     char *path = health_config_dir();
 
     // free all running alarms
-    rrdhost_rwlock(&localhost);
-    health_free_all_nolock(&localhost);
-    rrdhost_unlock(&localhost);
+    rrdhost_rwlock(localhost);
+    health_free_all_nolock(localhost);
+    rrdhost_unlock(localhost);
 
     // invalidate all previous entries in the alarm log
     ALARM_ENTRY *t;
-    for(t = localhost.health_log.alarms ; t ; t = t->next) {
+    for(t = localhost->health_log.alarms ; t ; t = t->next) {
         if(t->new_status != RRDCALC_STATUS_REMOVED)
             t->flags |= HEALTH_ENTRY_FLAG_UPDATED;
     }
 
     // reset all thresholds to all charts
     RRDSET *st;
-    for(st = localhost.rrdset_root; st ; st = st->next) {
+    for(st = localhost->rrdset_root; st ; st = st->next) {
         st->green = NAN;
         st->red = NAN;
     }
 
     // load the new alarms
-    rrdhost_rwlock(&localhost);
+    rrdhost_rwlock(localhost);
     health_readdir(path);
-    rrdhost_unlock(&localhost);
+    rrdhost_unlock(localhost);
 
     // link the loaded alarms to their charts
-    for(st = localhost.rrdset_root; st ; st = st->next) {
-        rrdhost_rwlock(&localhost);
+    for(st = localhost->rrdset_root; st ; st = st->next) {
+        rrdhost_rwlock(localhost);
 
         rrdsetcalc_link_matching(st);
         rrdcalctemplate_link_matching(st);
 
-        rrdhost_unlock(&localhost);
+        rrdhost_unlock(localhost);
     }
 }
 
@@ -3013,10 +3013,10 @@ void *health_main(void *ptr) {
         if(unlikely(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate) != 0))
             error("Cannot set pthread cancel state to DISABLE.");
 
-        rrdhost_rdlock(&localhost);
+        rrdhost_rdlock(localhost);
 
         // the first loop is to lookup values from the db
-        for(rc = localhost.alarms; rc; rc = rc->next) {
+        for(rc = localhost->alarms; rc; rc = rc->next) {
             if(unlikely(!rrdcalc_isrunnable(rc, now, &next_run))) {
                 if(unlikely(rc->rrdcalc_flags & RRDCALC_FLAG_RUNNABLE))
                     rc->rrdcalc_flags &= ~RRDCALC_FLAG_RUNNABLE;
@@ -3121,12 +3121,12 @@ void *health_main(void *ptr) {
                 }
             }
         }
-        rrdhost_unlock(&localhost);
+        rrdhost_unlock(localhost);
 
         if(unlikely(runnable && !netdata_exit)) {
-            rrdhost_rdlock(&localhost);
+            rrdhost_rdlock(localhost);
 
-            for(rc = localhost.alarms; rc; rc = rc->next) {
+            for(rc = localhost->alarms; rc; rc = rc->next) {
                 if(unlikely(!(rc->rrdcalc_flags & RRDCALC_FLAG_RUNNABLE)))
                     continue;
 
@@ -3251,7 +3251,7 @@ void *health_main(void *ptr) {
                     rc->delay_last = delay;
                     rc->delay_up_to_timestamp = now + delay;
                     health_alarm_log(
-                            &localhost,
+                            localhost,
                             rc->id,
                             rc->next_event_id++,
                             now,
@@ -3282,7 +3282,7 @@ void *health_main(void *ptr) {
                     next_run = rc->next_update;
             }
 
-            rrdhost_unlock(&localhost);
+            rrdhost_unlock(localhost);
         }
 
         if (unlikely(pthread_setcancelstate(oldstate, NULL) != 0))
@@ -3293,7 +3293,7 @@ void *health_main(void *ptr) {
 
         // execute notifications
         // and cleanup
-        health_alarm_log_process(&localhost);
+        health_alarm_log_process(localhost);
 
         if(unlikely(netdata_exit))
             break;
index b66d65272a917ddb31f5baefc518bdffd2a56967..0d13d1ef935d90e3494108d8671c3edadf451863 100644 (file)
--- a/src/ipc.c
+++ b/src/ipc.c
@@ -184,8 +184,8 @@ int do_ipc(int update_every, usec_t dt) {
             return 1;
         }
 
-        arrays_max     = rrdvar_custom_host_variable_create(&localhost, "ipc.semaphores.arrays.max");
-        semaphores_max = rrdvar_custom_host_variable_create(&localhost, "ipc.semaphores.max");
+        arrays_max     = rrdvar_custom_host_variable_create(localhost, "ipc.semaphores.arrays.max");
+        semaphores_max = rrdvar_custom_host_variable_create(localhost, "ipc.semaphores.max");
 
         if(arrays_max)     rrdvar_custom_host_variable_set(arrays_max, limits.semmni);
         if(semaphores_max) rrdvar_custom_host_variable_set(semaphores_max, limits.semmns);
index d4c7fa14d904a6ee9007863e03f6ef73418ae0b9..02cbca40e244ce29e0389e50be3451d802bdd51c 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -1,7 +1,7 @@
 #include "common.h"
 
 const char *program_name = "";
-unsigned long long debug_flags = DEBUG;
+uint64_t debug_flags = DEBUG;
 
 int access_log_syslog = 1;
 int error_log_syslog = 1;
index e61ffdd08ab596b2cc77d9638f7952a66d10abd1..24b971e2cf7c44a51e5434ecd81671e207ec05fd 100644 (file)
--- a/src/log.h
+++ b/src/log.h
@@ -1,38 +1,39 @@
 #ifndef NETDATA_LOG_H
 #define NETDATA_LOG_H 1
 
-#define D_WEB_BUFFER        0x00000001
-#define D_WEB_CLIENT        0x00000002
-#define D_LISTENER          0x00000004
-#define D_WEB_DATA          0x00000008
-#define D_OPTIONS           0x00000010
-#define D_PROCNETDEV_LOOP   0x00000020
-#define D_RRD_STATS         0x00000040
-#define D_WEB_CLIENT_ACCESS 0x00000080
-#define D_TC_LOOP           0x00000100
-#define D_DEFLATE           0x00000200
-#define D_CONFIG            0x00000400
-#define D_PLUGINSD          0x00000800
-#define D_CHILDS            0x00001000
-#define D_EXIT              0x00002000
-#define D_CHECKS            0x00004000
-#define D_NFACCT_LOOP       0x00008000
-#define D_PROCFILE          0x00010000
-#define D_RRD_CALLS         0x00020000
-#define D_DICTIONARY        0x00040000
-#define D_MEMORY            0x00080000
-#define D_CGROUP            0x00100000
-#define D_REGISTRY          0x00200000
-#define D_VARIABLES         0x00400000
-#define D_HEALTH            0x00800000
-#define D_CONNECT_TO        0x01000000
-#define D_SYSTEM            0x80000000
+#define D_WEB_BUFFER        0x0000000000000001
+#define D_WEB_CLIENT        0x0000000000000002
+#define D_LISTENER          0x0000000000000004
+#define D_WEB_DATA          0x0000000000000008
+#define D_OPTIONS           0x0000000000000010
+#define D_PROCNETDEV_LOOP   0x0000000000000020
+#define D_RRD_STATS         0x0000000000000040
+#define D_WEB_CLIENT_ACCESS 0x0000000000000080
+#define D_TC_LOOP           0x0000000000000100
+#define D_DEFLATE           0x0000000000000200
+#define D_CONFIG            0x0000000000000400
+#define D_PLUGINSD          0x0000000000000800
+#define D_CHILDS            0x0000000000001000
+#define D_EXIT              0x0000000000002000
+#define D_CHECKS            0x0000000000004000
+#define D_NFACCT_LOOP       0x0000000000008000
+#define D_PROCFILE          0x0000000000010000
+#define D_RRD_CALLS         0x0000000000020000
+#define D_DICTIONARY        0x0000000000040000
+#define D_MEMORY            0x0000000000080000
+#define D_CGROUP            0x0000000000100000
+#define D_REGISTRY          0x0000000000200000
+#define D_VARIABLES         0x0000000000400000
+#define D_HEALTH            0x0000000000800000
+#define D_CONNECT_TO        0x0000000001000000
+#define D_RRDHOST           0x0000000002000000
+#define D_SYSTEM            0x8000000000000000
 
 //#define DEBUG (D_WEB_CLIENT_ACCESS|D_LISTENER|D_RRD_STATS)
 //#define DEBUG 0xffffffff
 #define DEBUG (0)
 
-extern unsigned long long debug_flags;
+extern uint64_t debug_flags;
 
 extern const char *program_name;
 
index 61e2fa39d28cb51e9ebab4a5c7c00c772891787a..28cd5cbdd42278c7592835433dba2e6c8e7ed09c 100644 (file)
@@ -23,6 +23,7 @@ void netdata_cleanup_and_exit(int ret) {
     //kill_childs();
 
     // free database
+    sleep(2);
     rrdhost_free_all();
 #endif
 
@@ -578,11 +579,11 @@ int main(int argc, char **argv) {
 
     char *user = NULL;
     {
-        char *flags = config_get("global", "debug flags",  "0x00000000");
+        char *flags = config_get("global", "debug flags",  "0x0000000000000000");
         setenv("NETDATA_DEBUG_FLAGS", flags, 1);
 
         debug_flags = strtoull(flags, NULL, 0);
-        debug(D_OPTIONS, "Debug flags set to '0x%8llx'.", debug_flags);
+        debug(D_OPTIONS, "Debug flags set to '0x%" PRIX64 "'.", debug_flags);
 
         if(debug_flags != 0) {
             struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY };
@@ -795,14 +796,14 @@ int main(int argc, char **argv) {
     }
 
     // ------------------------------------------------------------------------
-    // initialize rrd host
+    // initialize the registry
 
-    rrdhost_init(hostname);
+    registry_init();
 
     // ------------------------------------------------------------------------
-    // initialize the registry
+    // initialize rrd host
 
-    registry_init();
+    rrd_init(hostname);
 
     // ------------------------------------------------------------------------
     // initialize health monitoring
index c40f221d9b97711e1853d2e47e60599b47521cfe..b79608effd59c1423f493bc6181240496631b4da 100644 (file)
@@ -109,7 +109,7 @@ void *pluginsd_worker_thread(void *arg) {
 #endif
 
     size_t count = 0;
-    RRDHOST *host = &localhost;
+    RRDHOST *host = localhost;
 
     for(;;) {
         if(unlikely(netdata_exit)) break;
index 3088383b37061bb40eb27635a487059bdb1a74cd..c5dbaa9f7a54d4c2ebfcf5cd93700033387e84cd 100644 (file)
@@ -47,7 +47,7 @@ int do_proc_net_stat_conntrack(int update_every, usec_t dt) {
         if(!do_sockets && !read_full)
             return 1;
 
-        rrdvar_max = rrdvar_custom_host_variable_create(&localhost, "netfilter.conntrack.max");
+        rrdvar_max = rrdvar_custom_host_variable_create(localhost, "netfilter.conntrack.max");
     }
 
     if(likely(read_full)) {
index 302028229d1f8789f6fdb62fc5b1cc4b9ef53099..58f6ae5fd201da73c0b0ef71145cbaea87640992 100644 (file)
@@ -45,7 +45,7 @@ static inline void registry_json_header(struct web_client *w, const char *action
     buffer_flush(w->response.data);
     w->response.data->contenttype = CT_APPLICATION_JSON;
     buffer_sprintf(w->response.data, "{\n\t\"action\": \"%s\",\n\t\"status\": \"%s\",\n\t\"hostname\": \"%s\",\n\t\"machine_guid\": \"%s\"",
-            action, status, registry.hostname, localhost.machine_guid);
+            action, status, registry.hostname, localhost->machine_guid);
 }
 
 static inline void registry_json_footer(struct web_client *w) {
index 4947486c4351bc5ae6088fcd76ac97287cafdf1b..3f109b116839a243e84afc5bae70499888704323 100644 (file)
@@ -69,4 +69,6 @@ extern int registry_request_hello_json(struct web_client *w);
 // update the registry monitoring charts
 extern void registry_statistics(void);
 
+extern char *registry_get_this_machine_guid(void);
+
 #endif /* NETDATA_REGISTRY_H */
index a846f861174ba2059365357517b1f4ba7d1c949f..6d24ea2da97715981a660db9fd4bfbd5ec8bcbab 100644 (file)
@@ -15,7 +15,6 @@ int registry_init(void) {
     // filenames
     snprintfz(filename, FILENAME_MAX, "%s/netdata.public.unique.id", registry.pathname);
     registry.machine_guid_filename = config_get("registry", "netdata unique id file", filename);
-    registry_get_this_machine_guid();
 
     snprintfz(filename, FILENAME_MAX, "%s/registry.db", registry.pathname);
     registry.db_filename = config_get("registry", "registry db file", filename);
@@ -28,7 +27,7 @@ int registry_init(void) {
     registry.persons_expiration = config_get_number("registry", "registry expire idle persons days", 365) * 86400;
     registry.registry_domain = config_get("registry", "registry domain", "");
     registry.registry_to_announce = config_get("registry", "registry to announce", "https://registry.my-netdata.io");
-    registry.hostname = config_get("registry", "registry hostname", config_get("global", "hostname", localhost.hostname));
+    registry.hostname = config_get("registry", "registry hostname", config_get("global", "hostname", "localhost"));
     registry.verify_cookies_redirects = config_get_boolean("registry", "verify browser cookies support", 1);
 
     setenv("NETDATA_REGISTRY_HOSTNAME", registry.hostname, 1);
index 04fcf347455772e7a51145f45f3456d86f2a0bf4..df330cc8a73ff84bb3284e79e85928a4ace400a3 100644 (file)
@@ -275,8 +275,10 @@ static inline int is_machine_guid_blacklisted(const char *guid) {
 }
 
 char *registry_get_this_machine_guid(void) {
-    if(likely(localhost.machine_guid[0]))
-        return localhost.machine_guid;
+    static char guid[GUID_LEN + 1] = "";
+
+    if(likely(guid[0]))
+        return guid;
 
     // read it from disk
     int fd = open(registry.machine_guid_filename, O_RDONLY);
@@ -286,38 +288,38 @@ char *registry_get_this_machine_guid(void) {
             error("Failed to read machine GUID from '%s'", registry.machine_guid_filename);
         else {
             buf[GUID_LEN] = '\0';
-            if(registry_regenerate_guid(buf, localhost.machine_guid) == -1) {
+            if(registry_regenerate_guid(buf, guid) == -1) {
                 error("Failed to validate machine GUID '%s' from '%s'. Ignoring it - this might mean this netdata will appear as duplicate in the registry.",
                         buf, registry.machine_guid_filename);
 
-                localhost.machine_guid[0] = '\0';
+                guid[0] = '\0';
             }
-            else if(is_machine_guid_blacklisted(localhost.machine_guid))
-                localhost.machine_guid[0] = '\0';
+            else if(is_machine_guid_blacklisted(guid))
+                guid[0] = '\0';
         }
         close(fd);
     }
 
     // generate a new one?
-    if(!localhost.machine_guid[0]) {
+    if(!guid[0]) {
         uuid_t uuid;
 
         uuid_generate_time(uuid);
-        uuid_unparse_lower(uuid, localhost.machine_guid);
-        localhost.machine_guid[GUID_LEN] = '\0';
+        uuid_unparse_lower(uuid, guid);
+        guid[GUID_LEN] = '\0';
 
         // save it
         fd = open(registry.machine_guid_filename, O_WRONLY|O_CREAT|O_TRUNC, 444);
         if(fd == -1)
             fatal("Cannot create unique machine id file '%s'. Please fix this.", registry.machine_guid_filename);
 
-        if(write(fd, localhost.machine_guid, GUID_LEN) != GUID_LEN)
+        if(write(fd, guid, GUID_LEN) != GUID_LEN)
             fatal("Cannot write the unique machine id file '%s'. Please fix this.", registry.machine_guid_filename);
 
         close(fd);
     }
 
-    setenv("NETDATA_REGISTRY_UNIQUE_ID", localhost.machine_guid, 1);
+    setenv("NETDATA_REGISTRY_UNIQUE_ID", guid, 1);
 
-    return localhost.machine_guid;
+    return guid;
 }
index 42c36620a9a6f9e31648eb492e6c34cabd21e40f..8aef16b22ab94d66bac89dd2cd0aed4d5deae3bb 100644 (file)
@@ -68,8 +68,6 @@ extern int registry_regenerate_guid(const char *guid, char *result);
 
 extern struct registry registry;
 
-extern char *registry_get_this_machine_guid(void);
-
 // REGISTRY LOW-LEVEL REQUESTS (in registry-internals.c)
 extern REGISTRY_PERSON *registry_request_access(char *person_guid, char *machine_guid, char *url, char *name, time_t when);
 extern REGISTRY_PERSON *registry_request_delete(char *person_guid, char *machine_guid, char *url, char *delete_url, time_t when);
index d09fe6283669e79f3f549179a20db0ed1ee7def0..ceae9963b98885d3ab2771e711b164ad6ff62fab 100644 (file)
--- a/src/rrd.h
+++ b/src/rrd.h
@@ -120,7 +120,7 @@ struct rrddim {
                                                     // (the user overwrites the name of the charts)
                                                     // DO NOT FREE THIS - IT IS ALLOCATED IN CONFIG
 
-    RRD_ALGORITHM algorithm;                     // the algorithm that is applied to add new collected values
+    RRD_ALGORITHM algorithm;                        // the algorithm that is applied to add new collected values
     RRD_MEMORY_MODE memory_mode;                    // the memory mode for this dimension
 
     collected_number multiplier;                    // the multiplier of the collected values
@@ -297,7 +297,10 @@ struct rrdhost {
     avl avl;
 
     char *hostname;
+    uint32_t hash_hostname;
+
     char machine_guid[GUID_LEN + 1];
+    uint32_t hash_machine_guid;
 
     RRDSET *rrdset_root;
     pthread_rwlock_t rrdset_root_rwlock;
@@ -326,8 +329,12 @@ struct rrdhost {
     struct rrdhost *next;
 };
 typedef struct rrdhost RRDHOST;
-extern RRDHOST localhost;
-extern void rrdhost_init(char *hostname);
+
+extern RRDHOST *localhost;
+
+extern void rrd_init(char *hostname);
+
+extern RRDHOST *rrdhost_find(const char *guid, uint32_t hash);
 
 #ifdef NETDATA_INTERNAL_CHECKS
 #define rrdhost_check_wrlock(host) rrdhost_check_wrlock_int(host, __FILE__, __FUNCTION__, __LINE__)
@@ -345,7 +352,7 @@ extern void rrdhost_rdlock(RRDHOST *host);
 extern void rrdhost_unlock(RRDHOST *host);
 
 // ----------------------------------------------------------------------------
-// RRD SET functions
+// RRDSET functions
 
 extern void rrdset_set_name(RRDSET *st, const char *name);
 
@@ -367,13 +374,13 @@ extern void rrdhost_free(RRDHOST *host);
 extern void rrdhost_save(RRDHOST *host);
 
 extern RRDSET *rrdset_find(RRDHOST *host, const char *id);
-#define rrdset_find_localhost(id) rrdset_find(&localhost, id)
+#define rrdset_find_localhost(id) rrdset_find(localhost, id)
 
 extern RRDSET *rrdset_find_bytype(RRDHOST *host, const char *type, const char *id);
-#define rrdset_find_bytype_localhost(type, id) rrdset_find_bytype(&localhost, type, id)
+#define rrdset_find_bytype_localhost(type, id) rrdset_find_bytype(localhost, type, id)
 
 extern RRDSET *rrdset_find_byname(RRDHOST *host, const char *name);
-#define rrdset_find_byname_localhost(name)  rrdset_find_byname(&localhost, name)
+#define rrdset_find_byname_localhost(name)  rrdset_find_byname(localhost, name)
 
 extern void rrdset_next_usec_unfiltered(RRDSET *st, usec_t microseconds);
 extern void rrdset_next_usec(RRDSET *st, usec_t microseconds);
@@ -434,6 +441,8 @@ extern collected_number rrddim_set(RRDSET *st, const char *id, collected_number
 
 #ifdef NETDATA_RRD_INTERNALS
 
+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(const char *id);
 
index 21b013d0c329f3233c2bbf0dcafc74cf0a451403..b06fb4ae66118b780ec5eba0e76e9e6ae6b37409 100644 (file)
@@ -90,15 +90,15 @@ void rrd_stats_api_v1_charts(BUFFER *wb)
         ",\n\t\"update_every\": %d"
         ",\n\t\"history\": %d"
         ",\n\t\"charts\": {"
-        , localhost.hostname
+        , localhost->hostname
         , program_version
         , os_type
         , rrd_update_every
         , rrd_default_history_entries
         );
 
-    pthread_rwlock_rdlock(&localhost.rrdset_root_rwlock);
-    for(st = localhost.rrdset_root, c = 0; st ; st = st->next) {
+    pthread_rwlock_rdlock(&localhost->rrdset_root_rwlock);
+    for(st = localhost->rrdset_root, c = 0; st ; st = st->next) {
         if(st->enabled && st->dimensions) {
             if(c) buffer_strcat(wb, ",");
             buffer_strcat(wb, "\n\t\t\"");
@@ -110,11 +110,11 @@ void rrd_stats_api_v1_charts(BUFFER *wb)
     }
 
     RRDCALC *rc;
-    for(rc = localhost.alarms; rc ; rc = rc->next) {
+    for(rc = localhost->alarms; rc ; rc = rc->next) {
         if(rc->rrdset)
             alarms++;
     }
-    pthread_rwlock_unlock(&localhost.rrdset_root_rwlock);
+    pthread_rwlock_unlock(&localhost->rrdset_root_rwlock);
 
     buffer_sprintf(wb, "\n\t}"
                     ",\n\t\"charts_count\": %zu"
@@ -151,14 +151,14 @@ static inline size_t prometheus_name_copy(char *d, const char *s, size_t usable)
 
 void rrd_stats_api_v1_charts_allmetrics_prometheus(BUFFER *wb)
 {
-    pthread_rwlock_rdlock(&localhost.rrdset_root_rwlock);
+    pthread_rwlock_rdlock(&localhost->rrdset_root_rwlock);
 
     char host[PROMETHEUS_ELEMENT_MAX + 1];
     prometheus_name_copy(host, config_get("global", "hostname", "localhost"), PROMETHEUS_ELEMENT_MAX);
 
     // for each chart
     RRDSET *st;
-    for(st = localhost.rrdset_root; st ; st = st->next) {
+    for(st = localhost->rrdset_root; st ; st = st->next) {
         char chart[PROMETHEUS_ELEMENT_MAX + 1];
         prometheus_name_copy(chart, st->id, PROMETHEUS_ELEMENT_MAX);
 
@@ -201,7 +201,7 @@ void rrd_stats_api_v1_charts_allmetrics_prometheus(BUFFER *wb)
         }
     }
 
-    pthread_rwlock_unlock(&localhost.rrdset_root_rwlock);
+    pthread_rwlock_unlock(&localhost->rrdset_root_rwlock);
 }
 
 // ----------------------------------------------------------------------------
@@ -226,14 +226,14 @@ static inline size_t shell_name_copy(char *d, const char *s, size_t usable) {
 
 void rrd_stats_api_v1_charts_allmetrics_shell(BUFFER *wb)
 {
-    pthread_rwlock_rdlock(&localhost.rrdset_root_rwlock);
+    pthread_rwlock_rdlock(&localhost->rrdset_root_rwlock);
 
     char host[SHELL_ELEMENT_MAX + 1];
     shell_name_copy(host, config_get("global", "hostname", "localhost"), SHELL_ELEMENT_MAX);
 
     // for each chart
     RRDSET *st;
-    for(st = localhost.rrdset_root; st ; st = st->next) {
+    for(st = localhost->rrdset_root; st ; st = st->next) {
         calculated_number total = 0.0;
         char chart[SHELL_ELEMENT_MAX + 1];
         shell_name_copy(chart, st->id, SHELL_ELEMENT_MAX);
@@ -271,7 +271,7 @@ void rrd_stats_api_v1_charts_allmetrics_shell(BUFFER *wb)
     buffer_strcat(wb, "\n# NETDATA ALARMS RUNNING\n");
 
     RRDCALC *rc;
-    for(rc = localhost.alarms; rc ;rc = rc->next) {
+    for(rc = localhost->alarms; rc ;rc = rc->next) {
         if(!rc->rrdset) continue;
 
         char chart[SHELL_ELEMENT_MAX + 1];
@@ -292,7 +292,7 @@ void rrd_stats_api_v1_charts_allmetrics_shell(BUFFER *wb)
         buffer_sprintf(wb, "NETDATA_ALARM_%s_%s_STATUS=\"%s\"\n", chart, alarm, rrdcalc_status2string(rc->status));
     }
 
-    pthread_rwlock_unlock(&localhost.rrdset_root_rwlock);
+    pthread_rwlock_unlock(&localhost->rrdset_root_rwlock);
 }
 
 // ----------------------------------------------------------------------------
@@ -421,15 +421,15 @@ void rrd_stats_all_json(BUFFER *wb)
 
     buffer_strcat(wb, RRD_GRAPH_JSON_HEADER);
 
-    pthread_rwlock_rdlock(&localhost.rrdset_root_rwlock);
-    for(st = localhost.rrdset_root, c = 0; st ; st = st->next) {
+    pthread_rwlock_rdlock(&localhost->rrdset_root_rwlock);
+    for(st = localhost->rrdset_root, c = 0; st ; st = st->next) {
         if(st->enabled && st->dimensions) {
             if(c) buffer_strcat(wb, ",\n");
             memory += rrd_stats_one_json(st, NULL, wb);
             c++;
         }
     }
-    pthread_rwlock_unlock(&localhost.rrdset_root_rwlock);
+    pthread_rwlock_unlock(&localhost->rrdset_root_rwlock);
 
     buffer_sprintf(wb, "\n\t],\n"
         "\t\"hostname\": \"%s\",\n"
@@ -437,7 +437,7 @@ void rrd_stats_all_json(BUFFER *wb)
         "\t\"history\": %d,\n"
         "\t\"memory\": %lu\n"
         "}\n"
-        , localhost.hostname
+        , localhost->hostname
         , rrd_update_every
         , rrd_default_history_entries
         , memory
index 6ec171b15cf1b10053cbdff1f06d6e2ca55a9b2d..64a96c59a811412db6f26e2c279818d0fdf8b415 100644 (file)
@@ -2,46 +2,88 @@
 #include "common.h"
 
 // ----------------------------------------------------------------------------
-// RRDHOST
-
-RRDHOST localhost = {
-        .hostname = "localhost",
-        .machine_guid = "",
-        .rrdset_root = NULL,
-        .rrdset_root_rwlock = PTHREAD_RWLOCK_INITIALIZER,
-        .rrdset_root_index = {
-                { NULL, rrdset_compare },
-                AVL_LOCK_INITIALIZER
-        },
-        .rrdset_root_index_name = {
-                { NULL, rrdset_compare_name },
-                AVL_LOCK_INITIALIZER
-        },
-        .rrdfamily_root_index = {
-                { NULL, rrdfamily_compare },
-                AVL_LOCK_INITIALIZER
-        },
-        .variables_root_index = {
-                { NULL, rrdvar_compare },
-                AVL_LOCK_INITIALIZER
-        },
-        .health_log = {
-                .next_log_id = 1,
-                .next_alarm_id = 1,
-                .count = 0,
-                .max = 1000,
-                .alarms = NULL,
-                .alarm_log_rwlock = PTHREAD_RWLOCK_INITIALIZER
-        },
-        .next = NULL
+// RRDHOST index
+
+int rrdhost_compare(void* a, void* b) {
+    if(((RRDHOST *)a)->hash_machine_guid < ((RRDHOST *)b)->hash_machine_guid) return -1;
+    else if(((RRDHOST *)a)->hash_machine_guid > ((RRDHOST *)b)->hash_machine_guid) return 1;
+    else return strcmp(((RRDHOST *)a)->machine_guid, ((RRDHOST *)b)->machine_guid);
+}
+
+avl_tree_lock rrdhost_root_index = {
+        .avl_tree = { NULL, rrdhost_compare },
+        .rwlock = AVL_LOCK_INITIALIZER
 };
 
-void rrdhost_init(char *hostname) {
-    localhost.hostname = hostname;
-    localhost.health_log.next_log_id =
-        localhost.health_log.next_alarm_id = (uint32_t)now_realtime_sec();
+RRDHOST *rrdhost_find(const char *guid, uint32_t hash) {
+    RRDHOST tmp;
+    strncpyz(tmp.machine_guid, guid, GUID_LEN);
+    tmp.hash_machine_guid = (hash)?hash:simple_hash(tmp.machine_guid);
+
+    return (RRDHOST *)avl_search_lock(&(rrdhost_root_index), (avl *) &tmp);
 }
 
+#define rrdhost_index_add(rrdhost) (RRDHOST *)avl_insert_lock(&(rrdhost_root_index), (avl *)(rrdhost))
+#define rrdhost_index_del(rrdhost) (RRDHOST *)avl_remove_lock(&(rrdhost_root_index), (avl *)(rrdhost))
+
+
+// ----------------------------------------------------------------------------
+// RRDHOST - internal helpers
+
+static inline void rrdhost_init_hostname(RRDHOST *host, const char *hostname) {
+    freez(host->hostname);
+    host->hostname = strdupz(hostname);
+    host->hash_hostname = simple_hash(host->hostname);
+}
+
+static inline void rrdhost_init_machine_guid(RRDHOST *host, const char *machine_guid) {
+    strncpy(host->machine_guid, machine_guid, GUID_LEN);
+    host->machine_guid[GUID_LEN] = '\0';
+    host->hash_machine_guid = simple_hash(host->machine_guid);
+}
+
+// ----------------------------------------------------------------------------
+// RRDHOST - add a host
+
+RRDHOST *rrdhost_create(const char *hostname, const char *guid) {
+    RRDHOST *host = callocz(1, sizeof(RRDHOST));
+
+    pthread_rwlock_init(&(host->rrdset_root_rwlock), NULL);
+
+    rrdhost_init_hostname(host, hostname);
+    rrdhost_init_machine_guid(host, guid);
+
+    avl_init_lock(&(host->rrdset_root_index), rrdset_compare);
+    avl_init_lock(&(host->rrdset_root_index_name), rrdset_compare_name);
+    avl_init_lock(&(host->rrdfamily_root_index), rrdfamily_compare);
+    avl_init_lock(&(host->variables_root_index), rrdvar_compare);
+
+    host->health_log.next_log_id = 1;
+    host->health_log.next_alarm_id = 1;
+    host->health_log.max = 1000;
+    host->health_log.next_log_id =
+    host->health_log.next_alarm_id = (uint32_t)now_realtime_sec();
+    pthread_rwlock_init(&(host->health_log.alarm_log_rwlock), NULL);
+
+    if(rrdhost_index_add(host) != host)
+        fatal("Cannot add host '%s' to index. It already exists.", hostname);
+
+    debug(D_RRDHOST, "Added host '%s'", host->hostname);
+    return host;
+}
+
+// ----------------------------------------------------------------------------
+// RRDHOST global / startup initialization
+
+RRDHOST *localhost = NULL;
+
+void rrd_init(char *hostname) {
+    localhost = rrdhost_create(hostname, registry_get_this_machine_guid());
+}
+
+// ----------------------------------------------------------------------------
+// RRDHOST - locks
+
 void rrdhost_rwlock(RRDHOST *host) {
     pthread_rwlock_wrlock(&host->rrdset_root_rwlock);
 }
@@ -69,7 +111,9 @@ void rrdhost_check_wrlock_int(RRDHOST *host, const char *file, const char *funct
 }
 
 void rrdhost_free(RRDHOST *host) {
-    info("Freeing all memory...");
+    if(!host) return;
+
+    info("Freeing all memory for host '%s'...", host->hostname);
 
     rrdhost_rwlock(host);
 
@@ -110,13 +154,17 @@ void rrdhost_free(RRDHOST *host) {
     }
     host->rrdset_root = NULL;
 
+    freez(host->hostname);
     rrdhost_unlock(host);
+    freez(host);
 
-    info("Memory cleanup completed...");
+    info("Host memory cleanup completed...");
 }
 
 void rrdhost_save(RRDHOST *host) {
-    info("Saving database...");
+    if(!host) return;
+
+    info("Saving host '%s' database...", host->hostname);
 
     RRDSET *st;
     RRDDIM *rd;
@@ -147,21 +195,23 @@ void rrdhost_save(RRDHOST *host) {
 }
 
 void rrdhost_free_all(void) {
-    RRDHOST *host;
+    RRDHOST *host = localhost;
 
     // FIXME: lock all hosts
 
-    for(host = &localhost; host ;) {
+    while(host) {
         RRDHOST *next = host = host->next;
         rrdhost_free(host);
         host = next;
     }
 
+    localhost = NULL;
+
     // FIXME: unlock all hosts
 }
 
 void rrdhost_save_all(void) {
     RRDHOST *host;
-    for(host = &localhost; host ; host = host->next)
+    for(host = localhost; host ; host = host->next)
         rrdhost_save(host);
 }
index 60fc19af8e55c638835debc9227cdfb08207495e..4c07c121a9dbc80d28337a957bc6325926da8fcb 100644 (file)
@@ -210,7 +210,7 @@ static inline void timeval_align(struct timeval *tv, int update_every) {
 // RRDSET - create a chart
 
 RRDSET *rrdset_create(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) {
-    RRDHOST *host = &localhost;
+    RRDHOST *host = localhost;
 
     if(!type || !type[0]) {
         fatal("Cannot create rrd stats without a type.");
index 5b0ab6f934767cade80afff759fd3609f6850b61..e38d70b9e2a727d9397b29fa73313ae63eb4886d 100644 (file)
@@ -683,7 +683,7 @@ int web_client_api_request_v1_alarms(struct web_client *w, char *url)
 
     buffer_flush(w->response.data);
     w->response.data->contenttype = CT_APPLICATION_JSON;
-    health_alarms2json(&localhost, w->response.data, all);
+    health_alarms2json(localhost, w->response.data, all);
     return 200;
 }
 
@@ -704,7 +704,7 @@ int web_client_api_request_v1_alarm_log(struct web_client *w, char *url)
 
     buffer_flush(w->response.data);
     w->response.data->contenttype = CT_APPLICATION_JSON;
-    health_alarm_log2json(&localhost, w->response.data, after);
+    health_alarm_log2json(localhost, w->response.data, after);
     return 200;
 }
 
@@ -2202,7 +2202,7 @@ void web_client_process(struct web_client *w) {
                     debug(D_WEB_CLIENT_ACCESS, "%llu: Sending list of RRD_STATS...", w->id);
 
                     buffer_flush(w->response.data);
-                    RRDSET *st = localhost.rrdset_root;
+                    RRDSET *st = localhost->rrdset_root;
 
                     for ( ; st ; st = st->next )
                         buffer_sprintf(w->response.data, "%s\n", st->name);