summaryrefslogtreecommitdiffstats
path: root/registry
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--registry/registry.c179
-rw-r--r--registry/registry.h2
-rw-r--r--registry/registry_db.c245
-rw-r--r--registry/registry_init.c182
-rw-r--r--registry/registry_internals.c135
-rw-r--r--registry/registry_internals.h29
-rw-r--r--registry/registry_log.c25
-rw-r--r--registry/registry_machine.c65
-rw-r--r--registry/registry_machine.h15
-rw-r--r--registry/registry_person.c158
-rw-r--r--registry/registry_person.h30
-rw-r--r--registry/registry_url.c88
-rw-r--r--registry/registry_url.h35
13 files changed, 633 insertions, 555 deletions
diff --git a/registry/registry.c b/registry/registry.c
index f8de470eb..b63c6db0f 100644
--- a/registry/registry.c
+++ b/registry/registry.c
@@ -8,6 +8,10 @@
#define REGISTRY_STATUS_FAILED "failed"
#define REGISTRY_STATUS_DISABLED "disabled"
+bool registry_is_valid_url(const char *url) {
+ return url && (*url == 'h' || *url == '*');
+}
+
// ----------------------------------------------------------------------------
// REGISTRY concurrency locking
@@ -23,19 +27,21 @@ static inline void registry_unlock(void) {
// COOKIES
static void registry_set_cookie(struct web_client *w, const char *guid) {
- char edate[100];
+ char e_date[100];
time_t et = now_realtime_sec() + registry.persons_expiration;
- struct tm etmbuf, *etm = gmtime_r(&et, &etmbuf);
- strftime(edate, sizeof(edate), "%a, %d %b %Y %H:%M:%S %Z", etm);
+ struct tm e_tm_buf, *etm = gmtime_r(&et, &e_tm_buf);
+ strftime(e_date, sizeof(e_date), "%a, %d %b %Y %H:%M:%S %Z", etm);
- buffer_sprintf(w->response.header, "Set-Cookie: " NETDATA_REGISTRY_COOKIE_NAME "=%s; Expires=%s\r\n", guid, edate);
+ buffer_sprintf(w->response.header, "Set-Cookie: " NETDATA_REGISTRY_COOKIE_NAME "=%s; Expires=%s\r\n", guid, e_date);
+ buffer_sprintf(w->response.header, "Set-Cookie: " NETDATA_REGISTRY_COOKIE_NAME "=%s; SameSite=Strict; Expires=%s\r\n", guid, e_date);
if(registry.enable_cookies_samesite_secure)
- buffer_sprintf(w->response.header, "Set-Cookie: " NETDATA_REGISTRY_COOKIE_NAME "=%s; Expires=%s; SameSite=None; Secure\r\n", guid, edate);
+ buffer_sprintf(w->response.header, "Set-Cookie: " NETDATA_REGISTRY_COOKIE_NAME "=%s; Expires=%s; SameSite=None; Secure\r\n", guid, e_date);
if(registry.registry_domain && *registry.registry_domain) {
- buffer_sprintf(w->response.header, "Set-Cookie: " NETDATA_REGISTRY_COOKIE_NAME "=%s; Expires=%s; Domain=%s\r\n", guid, edate, registry.registry_domain);
+ buffer_sprintf(w->response.header, "Set-Cookie: " NETDATA_REGISTRY_COOKIE_NAME "=%s; Expires=%s; Domain=%s\r\n", guid, e_date, registry.registry_domain);
+ buffer_sprintf(w->response.header, "Set-Cookie: " NETDATA_REGISTRY_COOKIE_NAME "=%s; Expires=%s; Domain=%s; SameSite=Strict\r\n", guid, e_date, registry.registry_domain);
if(registry.enable_cookies_samesite_secure)
- buffer_sprintf(w->response.header, "Set-Cookie: " NETDATA_REGISTRY_COOKIE_NAME "=%s; Expires=%s; Domain=%s; SameSite=None; Secure\r\n", guid, edate, registry.registry_domain);
+ buffer_sprintf(w->response.header, "Set-Cookie: " NETDATA_REGISTRY_COOKIE_NAME "=%s; Expires=%s; Domain=%s; SameSite=None; Secure\r\n", guid, e_date, registry.registry_domain);
}
w->response.has_cookies = true;
@@ -52,7 +58,7 @@ static inline void registry_set_person_cookie(struct web_client *w, REGISTRY_PER
static inline void registry_json_header(RRDHOST *host, struct web_client *w, const char *action, const char *status) {
buffer_flush(w->response.data);
w->response.data->content_type = CT_APPLICATION_JSON;
- buffer_json_initialize(w->response.data, "\"", "\"", 0, true, false);
+ buffer_json_initialize(w->response.data, "\"", "\"", 0, true, true);
buffer_json_member_add_string(w->response.data, "action", action);
buffer_json_member_add_string(w->response.data, "status", status);
buffer_json_member_add_string(w->response.data, "hostname", rrdhost_registry_hostname(host));
@@ -84,39 +90,44 @@ struct registry_json_walk_person_urls_callback {
int count;
};
+static STRING *asterisks = NULL;
+
// callback for rendering PERSON_URLs
-static int registry_json_person_url_callback(void *entry, void *data) {
- REGISTRY_PERSON_URL *pu = (REGISTRY_PERSON_URL *)entry;
- struct registry_json_walk_person_urls_callback *c = (struct registry_json_walk_person_urls_callback *)data;
+static int registry_json_person_url_callback(REGISTRY_PERSON_URL *pu, struct registry_json_walk_person_urls_callback *c) {
+ if(unlikely(!asterisks))
+ asterisks = string_strdupz("***");
+
struct web_client *w = c->w;
- if (!strcmp(pu->url->url,"***")) return 0;
+ if (pu->url == asterisks) return 0;
buffer_json_add_array_item_array(w->response.data);
buffer_json_add_array_item_string(w->response.data, pu->machine->guid);
- buffer_json_add_array_item_string(w->response.data, pu->url->url);
+ buffer_json_add_array_item_string(w->response.data, string2str(pu->url));
buffer_json_add_array_item_uint64(w->response.data, pu->last_t * (uint64_t) 1000);
buffer_json_add_array_item_uint64(w->response.data, pu->usages);
- buffer_json_add_array_item_string(w->response.data, pu->machine_name);
+ buffer_json_add_array_item_string(w->response.data, string2str(pu->machine_name));
buffer_json_array_close(w->response.data);
return 1;
}
// callback for rendering MACHINE_URLs
-static int registry_json_machine_url_callback(const DICTIONARY_ITEM *item __maybe_unused, void *entry, void *data) {
- REGISTRY_MACHINE_URL *mu = (REGISTRY_MACHINE_URL *)entry;
- struct registry_json_walk_person_urls_callback *c = (struct registry_json_walk_person_urls_callback *)data;
+static int registry_json_machine_url_callback(REGISTRY_MACHINE_URL *mu, struct registry_json_walk_person_urls_callback *c, STRING *hostname) {
+ if(unlikely(!asterisks))
+ asterisks = string_strdupz("***");
+
struct web_client *w = c->w;
REGISTRY_MACHINE *m = c->m;
- if (!strcmp(mu->url->url,"***")) return 0;
+ if (mu->url == asterisks) return 0;
buffer_json_add_array_item_array(w->response.data);
buffer_json_add_array_item_string(w->response.data, m->guid);
- buffer_json_add_array_item_string(w->response.data, mu->url->url);
+ buffer_json_add_array_item_string(w->response.data, string2str(mu->url));
buffer_json_add_array_item_uint64(w->response.data, mu->last_t * (uint64_t) 1000);
buffer_json_add_array_item_uint64(w->response.data, mu->usages);
+ buffer_json_add_array_item_string(w->response.data, string2str(hostname));
buffer_json_array_close(w->response.data);
return 1;
@@ -130,9 +141,7 @@ struct registry_person_url_callback_verify_machine_exists_data {
int count;
};
-static inline int registry_person_url_callback_verify_machine_exists(void *entry, void *data) {
- struct registry_person_url_callback_verify_machine_exists_data *d = (struct registry_person_url_callback_verify_machine_exists_data *)data;
- REGISTRY_PERSON_URL *pu = (REGISTRY_PERSON_URL *)entry;
+static inline int registry_person_url_callback_verify_machine_exists(REGISTRY_PERSON_URL *pu, struct registry_person_url_callback_verify_machine_exists_data *d) {
REGISTRY_MACHINE *m = d->m;
if(pu->machine == m)
@@ -157,38 +166,84 @@ void registry_update_cloud_base_url() {
int registry_request_hello_json(RRDHOST *host, struct web_client *w) {
registry_json_header(host, w, "hello", REGISTRY_STATUS_OK);
+ if(host->node_id)
+ buffer_json_member_add_uuid(w->response.data, "node_id", host->node_id);
+
+ buffer_json_member_add_object(w->response.data, "agent");
+ {
+ buffer_json_member_add_string(w->response.data, "machine_guid", localhost->machine_guid);
+
+ if(localhost->node_id)
+ buffer_json_member_add_uuid(w->response.data, "node_id", localhost->node_id);
+
+ char *claim_id = get_agent_claimid();
+ if (claim_id) {
+ buffer_json_member_add_string(w->response.data, "claim_id", claim_id);
+ freez(claim_id);
+ }
+
+ buffer_json_member_add_boolean(w->response.data, "bearer_protection", netdata_is_protected_by_bearer);
+ }
+ buffer_json_object_close(w->response.data);
+
buffer_json_member_add_string(w->response.data, "registry", registry.registry_to_announce);
buffer_json_member_add_string(w->response.data, "cloud_base_url", registry.cloud_base_url);
buffer_json_member_add_boolean(w->response.data, "anonymous_statistics", netdata_anonymous_statistics_enabled);
+ buffer_json_member_add_array(w->response.data, "nodes");
+ RRDHOST *h;
+ dfe_start_read(rrdhost_root_index, h) {
+ buffer_json_add_array_item_object(w->response.data);
+ buffer_json_member_add_string(w->response.data, "machine_guid", h->machine_guid);
+
+ if(h->node_id)
+ buffer_json_member_add_uuid(w->response.data, "node_id", h->node_id);
+
+ buffer_json_member_add_string(w->response.data, "hostname", rrdhost_registry_hostname(h));
+ buffer_json_object_close(w->response.data);
+ }
+ dfe_done(h);
+ buffer_json_array_close(w->response.data); // nodes
+
registry_json_footer(w);
return HTTP_RESP_OK;
}
// ----------------------------------------------------------------------------
-//public ACCESS request
-
-#define REGISTRY_VERIFY_COOKIES_GUID "give-me-back-this-cookie-now--please"
+// public ACCESS request
// the main method for registering an access
int registry_request_access_json(RRDHOST *host, struct web_client *w, char *person_guid, char *machine_guid, char *url, char *name, time_t when) {
if(unlikely(!registry.enabled))
return registry_json_disabled(host, w, "access");
+ if(!registry_is_valid_url(url)) {
+ buffer_flush(w->response.data);
+ buffer_strcat(w->response.data, "Invalid URL given in the request");
+ return HTTP_RESP_BAD_REQUEST;
+ }
+
// ------------------------------------------------------------------------
- // verify the browser supports cookies
+ // verify the browser supports cookies or the bearer
if(registry.verify_cookies_redirects > 0 && !person_guid[0]) {
+ registry_lock();
+ registry_request_access(REGISTRY_VERIFY_COOKIES_GUID, machine_guid, url, name, when);
+ registry_unlock();
+
buffer_flush(w->response.data);
registry_set_cookie(w, REGISTRY_VERIFY_COOKIES_GUID);
w->response.data->content_type = CT_APPLICATION_JSON;
registry_json_header(host, w, "access", REGISTRY_STATUS_REDIRECT);
+ buffer_json_member_add_string(w->response.data, "person_guid", REGISTRY_VERIFY_COOKIES_GUID);
buffer_json_member_add_string(w->response.data, "registry", registry.registry_to_announce);
registry_json_footer(w);
return HTTP_RESP_OK;
}
- if(unlikely(person_guid[0] && !strcmp(person_guid, REGISTRY_VERIFY_COOKIES_GUID)))
+ if(unlikely(person_guid[0] && is_dummy_person(person_guid)))
+ // it passed the check - they gave us a different person_guid
+ // empty the dummy one, so that we will generate a new person_guid
person_guid[0] = '\0';
// ------------------------------------------------------------------------
@@ -212,7 +267,8 @@ int registry_request_access_json(RRDHOST *host, struct web_client *w, char *pers
buffer_json_member_add_array(w->response.data, "urls");
struct registry_json_walk_person_urls_callback c = { p, NULL, w, 0 };
- avl_traverse(&p->person_urls, registry_json_person_url_callback, &c);
+ for(REGISTRY_PERSON_URL *pu = p->person_urls; pu ;pu = pu->next)
+ registry_json_person_url_callback(pu, &c);
buffer_json_array_close(w->response.data); // urls
registry_json_footer(w);
@@ -228,6 +284,12 @@ int registry_request_delete_json(RRDHOST *host, struct web_client *w, char *pers
if(!registry.enabled)
return registry_json_disabled(host, w, "delete");
+ if(!registry_is_valid_url(url)) {
+ buffer_flush(w->response.data);
+ buffer_strcat(w->response.data, "Invalid URL given in the request");
+ return HTTP_RESP_BAD_REQUEST;
+ }
+
registry_lock();
REGISTRY_PERSON *p = registry_request_delete(person_guid, machine_guid, url, delete_url, when);
@@ -249,17 +311,25 @@ int registry_request_delete_json(RRDHOST *host, struct web_client *w, char *pers
// public SEARCH request
// the main method for searching the URLs of a netdata
-int registry_request_search_json(RRDHOST *host, struct web_client *w, char *person_guid, char *machine_guid, char *url, char *request_machine, time_t when) {
+int registry_request_search_json(RRDHOST *host, struct web_client *w, char *person_guid, char *request_machine) {
if(!registry.enabled)
return registry_json_disabled(host, w, "search");
+ if(!person_guid || !person_guid[0]) {
+ registry_json_header(host, w, "search", REGISTRY_STATUS_FAILED);
+ registry_json_footer(w);
+ return HTTP_RESP_PRECOND_FAIL;
+ }
+
registry_lock();
- REGISTRY_MACHINE *m = registry_request_machine(person_guid, machine_guid, url, request_machine, when);
+ STRING *hostname = NULL;
+ REGISTRY_MACHINE *m = registry_request_machine(person_guid, request_machine, &hostname);
if(!m) {
registry_json_header(host, w, "search", REGISTRY_STATUS_FAILED);
registry_json_footer(w);
registry_unlock();
+ string_freez(hostname);
return HTTP_RESP_NOT_FOUND;
}
@@ -267,11 +337,15 @@ int registry_request_search_json(RRDHOST *host, struct web_client *w, char *pers
buffer_json_member_add_array(w->response.data, "urls");
struct registry_json_walk_person_urls_callback c = { NULL, m, w, 0 };
- dictionary_walkthrough_read(m->machine_urls, registry_json_machine_url_callback, &c);
+
+ for(REGISTRY_MACHINE_URL *mu = m->machine_urls; mu ; mu = mu->next)
+ registry_json_machine_url_callback(mu, &c, hostname);
+
buffer_json_array_close(w->response.data);
registry_json_footer(w);
registry_unlock();
+ string_freez(hostname);
return HTTP_RESP_OK;
}
@@ -279,12 +353,21 @@ int registry_request_search_json(RRDHOST *host, struct web_client *w, char *pers
// SWITCH REQUEST
// the main method for switching user identity
-int registry_request_switch_json(RRDHOST *host, struct web_client *w, char *person_guid, char *machine_guid, char *url, char *new_person_guid, time_t when) {
+int registry_request_switch_json(RRDHOST *host, struct web_client *w, char *person_guid, char *machine_guid, char *url __maybe_unused, char *new_person_guid, time_t when __maybe_unused) {
if(!registry.enabled)
return registry_json_disabled(host, w, "switch");
- (void)url;
- (void)when;
+ if(!person_guid || !person_guid[0]) {
+ buffer_flush(w->response.data);
+ buffer_strcat(w->response.data, "Who are you? Person GUID is missing");
+ return HTTP_RESP_PRECOND_FAIL;
+ }
+
+ if(!registry_is_valid_url(url)) {
+ buffer_flush(w->response.data);
+ buffer_strcat(w->response.data, "Invalid URL given in the request");
+ return HTTP_RESP_BAD_REQUEST;
+ }
registry_lock();
@@ -315,7 +398,9 @@ int registry_request_switch_json(RRDHOST *host, struct web_client *w, char *pers
struct registry_person_url_callback_verify_machine_exists_data data = { m, 0 };
// verify the old person has access to this machine
- avl_traverse(&op->person_urls, registry_person_url_callback_verify_machine_exists, &data);
+ for(REGISTRY_PERSON_URL *pu = op->person_urls; pu ;pu = pu->next)
+ registry_person_url_callback_verify_machine_exists(pu, &data);
+
if(!data.count) {
registry_json_header(host, w, "switch", REGISTRY_STATUS_FAILED);
registry_json_footer(w);
@@ -325,7 +410,9 @@ int registry_request_switch_json(RRDHOST *host, struct web_client *w, char *pers
// verify the new person has access to this machine
data.count = 0;
- avl_traverse(&np->person_urls, registry_person_url_callback_verify_machine_exists, &data);
+ for(REGISTRY_PERSON_URL *pu = np->person_urls; pu ;pu = pu->next)
+ registry_person_url_callback_verify_machine_exists(pu, &data);
+
if(!data.count) {
registry_json_header(host, w, "switch", REGISTRY_STATUS_FAILED);
registry_json_footer(w);
@@ -396,14 +483,12 @@ void registry_statistics(void) {
rrddim_add(stc, "persons", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(stc, "machines", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
- rrddim_add(stc, "urls", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(stc, "persons_urls", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(stc, "machines_urls", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
}
rrddim_set(stc, "persons", (collected_number)registry.persons_count);
rrddim_set(stc, "machines", (collected_number)registry.machines_count);
- rrddim_set(stc, "urls", (collected_number)registry.urls_count);
rrddim_set(stc, "persons_urls", (collected_number)registry.persons_urls_count);
rrddim_set(stc, "machines_urls", (collected_number)registry.machines_urls_count);
rrdset_done(stc);
@@ -428,15 +513,21 @@ void registry_statistics(void) {
rrddim_add(stm, "persons", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(stm, "machines", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
- rrddim_add(stm, "urls", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(stm, "persons_urls", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
rrddim_add(stm, "machines_urls", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
}
- rrddim_set(stm, "persons", (collected_number)registry.persons_memory + dictionary_stats_for_registry(registry.persons));
- rrddim_set(stm, "machines", (collected_number)registry.machines_memory + dictionary_stats_for_registry(registry.machines));
- rrddim_set(stm, "urls", (collected_number)registry.urls_memory);
- rrddim_set(stm, "persons_urls", (collected_number)registry.persons_urls_memory);
- rrddim_set(stm, "machines_urls", (collected_number)registry.machines_urls_memory);
+ struct aral_statistics *p_aral_stats = aral_statistics(registry.persons_aral);
+ rrddim_set(stm, "persons", (collected_number)p_aral_stats->structures.allocated_bytes + (collected_number)p_aral_stats->malloc.allocated_bytes + (collected_number)p_aral_stats->mmap.allocated_bytes);
+
+ struct aral_statistics *m_aral_stats = aral_statistics(registry.machines_aral);
+ rrddim_set(stm, "machines", (collected_number)m_aral_stats->structures.allocated_bytes + (collected_number)m_aral_stats->malloc.allocated_bytes + (collected_number)m_aral_stats->mmap.allocated_bytes);
+
+ struct aral_statistics *pu_aral_stats = aral_statistics(registry.person_urls_aral);
+ rrddim_set(stm, "persons_urls", (collected_number)pu_aral_stats->structures.allocated_bytes + (collected_number)pu_aral_stats->malloc.allocated_bytes + (collected_number)pu_aral_stats->mmap.allocated_bytes);
+
+ struct aral_statistics *mu_aral_stats = aral_statistics(registry.machine_urls_aral);
+ rrddim_set(stm, "machines_urls", (collected_number)mu_aral_stats->structures.allocated_bytes + (collected_number)mu_aral_stats->malloc.allocated_bytes + (collected_number)mu_aral_stats->mmap.allocated_bytes);
+
rrdset_done(stm);
}
diff --git a/registry/registry.h b/registry/registry.h
index 6aa3f0a11..a572991c7 100644
--- a/registry/registry.h
+++ b/registry/registry.h
@@ -64,7 +64,7 @@ void registry_free(void);
// HTTP requests handled by the registry
int registry_request_access_json(RRDHOST *host, struct web_client *w, char *person_guid, char *machine_guid, char *url, char *name, time_t when);
int registry_request_delete_json(RRDHOST *host, struct web_client *w, char *person_guid, char *machine_guid, char *url, char *delete_url, time_t when);
-int registry_request_search_json(RRDHOST *host, struct web_client *w, char *person_guid, char *machine_guid, char *url, char *request_machine, time_t when);
+int registry_request_search_json(RRDHOST *host, struct web_client *w, char *person_guid, char *request_machine);
int registry_request_switch_json(RRDHOST *host, struct web_client *w, char *person_guid, char *machine_guid, char *url, char *new_person_guid, time_t when);
int registry_request_hello_json(RRDHOST *host, struct web_client *w);
diff --git a/registry/registry_db.c b/registry/registry_db.c
index ae74aa530..a5c3956a5 100644
--- a/registry/registry_db.c
+++ b/registry/registry_db.c
@@ -4,25 +4,22 @@
#include "registry_internals.h"
int registry_db_should_be_saved(void) {
- debug(D_REGISTRY, "log entries %llu, max %llu", registry.log_count, registry.save_registry_every_entries);
+ netdata_log_debug(D_REGISTRY, "log entries %llu, max %llu", registry.log_count, registry.save_registry_every_entries);
return registry.log_count > registry.save_registry_every_entries;
}
// ----------------------------------------------------------------------------
// INTERNAL FUNCTIONS FOR SAVING REGISTRY OBJECTS
-static int registry_machine_save_url(const DICTIONARY_ITEM *item __maybe_unused, void *entry, void *file) {
- REGISTRY_MACHINE_URL *mu = entry;
- FILE *fp = file;
-
- debug(D_REGISTRY, "Registry: registry_machine_save_url('%s')", mu->url->url);
+static int registry_machine_save_url(REGISTRY_MACHINE_URL *mu, FILE *fp) {
+ netdata_log_debug(D_REGISTRY, "REGISTRY: registry_machine_save_url('%s')", string2str(mu->url));
int ret = fprintf(fp, "V\t%08x\t%08x\t%08x\t%02x\t%s\n",
mu->first_t,
mu->last_t,
mu->usages,
mu->flags,
- mu->url->url
+ string2str(mu->url)
);
// error handling is done at registry_db_save()
@@ -35,7 +32,7 @@ static int registry_machine_save(const DICTIONARY_ITEM *item __maybe_unused, voi
REGISTRY_MACHINE *m = entry;
FILE *fp = file;
- debug(D_REGISTRY, "Registry: registry_machine_save('%s')", m->guid);
+ netdata_log_debug(D_REGISTRY, "REGISTRY: registry_machine_save('%s')", m->guid);
int ret = fprintf(fp, "M\t%08x\t%08x\t%08x\t%s\n",
m->first_t,
@@ -45,9 +42,13 @@ static int registry_machine_save(const DICTIONARY_ITEM *item __maybe_unused, voi
);
if(ret >= 0) {
- int ret2 = dictionary_walkthrough_read(m->machine_urls, registry_machine_save_url, fp);
- if(ret2 < 0) return ret2;
- ret += ret2;
+ for(REGISTRY_MACHINE_URL *mu = m->machine_urls; mu ; mu = mu->next) {
+ int rc = registry_machine_save_url(mu, fp);
+ if(rc < 0)
+ return rc;
+
+ ret += rc;
+ }
}
// error handling is done at registry_db_save()
@@ -55,11 +56,8 @@ static int registry_machine_save(const DICTIONARY_ITEM *item __maybe_unused, voi
return ret;
}
-static inline int registry_person_save_url(void *entry, void *file) {
- REGISTRY_PERSON_URL *pu = entry;
- FILE *fp = file;
-
- debug(D_REGISTRY, "Registry: registry_person_save_url('%s')", pu->url->url);
+static inline int registry_person_save_url(REGISTRY_PERSON_URL *pu, FILE *fp) {
+ netdata_log_debug(D_REGISTRY, "REGISTRY: registry_person_save_url('%s')", string2str(pu->url));
int ret = fprintf(fp, "U\t%08x\t%08x\t%08x\t%02x\t%s\t%s\t%s\n",
pu->first_t,
@@ -67,8 +65,8 @@ static inline int registry_person_save_url(void *entry, void *file) {
pu->usages,
pu->flags,
pu->machine->guid,
- pu->machine_name,
- pu->url->url
+ string2str(pu->machine_name),
+ string2str(pu->url)
);
// error handling is done at registry_db_save()
@@ -80,7 +78,7 @@ static inline int registry_person_save(const DICTIONARY_ITEM *item __maybe_unuse
REGISTRY_PERSON *p = entry;
FILE *fp = file;
- debug(D_REGISTRY, "Registry: registry_person_save('%s')", p->guid);
+ netdata_log_debug(D_REGISTRY, "REGISTRY: registry_person_save('%s')", p->guid);
int ret = fprintf(fp, "P\t%08x\t%08x\t%08x\t%s\n",
p->first_t,
@@ -90,10 +88,13 @@ static inline int registry_person_save(const DICTIONARY_ITEM *item __maybe_unuse
);
if(ret >= 0) {
- //int ret2 = dictionary_walkthrough_read(p->person_urls, registry_person_save_url, fp);
- int ret2 = avl_traverse(&p->person_urls, registry_person_save_url, fp);
- if (ret2 < 0) return ret2;
- ret += ret2;
+ for(REGISTRY_PERSON_URL *pu = p->person_urls; pu ;pu = pu->next) {
+ int rc = registry_person_save_url(pu, fp);
+ if(rc < 0)
+ return rc;
+ else
+ ret += rc;
+ }
}
// error handling is done at registry_db_save()
@@ -119,42 +120,42 @@ int registry_db_save(void) {
snprintfz(old_filename, FILENAME_MAX, "%s.old", registry.db_filename);
snprintfz(tmp_filename, FILENAME_MAX, "%s.tmp", registry.db_filename);
- debug(D_REGISTRY, "Registry: Creating file '%s'", tmp_filename);
+ netdata_log_debug(D_REGISTRY, "REGISTRY: Creating file '%s'", tmp_filename);
FILE *fp = fopen(tmp_filename, "w");
if(!fp) {
- error("Registry: Cannot create file: %s", tmp_filename);
+ netdata_log_error("REGISTRY: Cannot create file: %s", tmp_filename);
error_log_limit_reset();
return -1;
}
// dictionary_walkthrough_read() has its own locking, so this is safe to do
- debug(D_REGISTRY, "Saving all machines");
+ netdata_log_debug(D_REGISTRY, "REGISTRY: saving all machines");
int bytes1 = dictionary_walkthrough_read(registry.machines, registry_machine_save, fp);
if(bytes1 < 0) {
- error("Registry: Cannot save registry machines - return value %d", bytes1);
+ netdata_log_error("REGISTRY: Cannot save registry machines - return value %d", bytes1);
fclose(fp);
error_log_limit_reset();
return bytes1;
}
- debug(D_REGISTRY, "Registry: saving machines took %d bytes", bytes1);
+ netdata_log_debug(D_REGISTRY, "REGISTRY: saving machines took %d bytes", bytes1);
- debug(D_REGISTRY, "Saving all persons");
+ netdata_log_debug(D_REGISTRY, "Saving all persons");
int bytes2 = dictionary_walkthrough_read(registry.persons, registry_person_save, fp);
if(bytes2 < 0) {
- error("Registry: Cannot save registry persons - return value %d", bytes2);
+ netdata_log_error("REGISTRY: Cannot save registry persons - return value %d", bytes2);
fclose(fp);
error_log_limit_reset();
return bytes2;
}
- debug(D_REGISTRY, "Registry: saving persons took %d bytes", bytes2);
+ netdata_log_debug(D_REGISTRY, "REGISTRY: saving persons took %d bytes", bytes2);
// save the totals
fprintf(fp, "T\t%016llx\t%016llx\t%016llx\t%016llx\t%016llx\t%016llx\n",
registry.persons_count,
registry.machines_count,
registry.usages_count + 1, // this is required - it is lost on db rotation
- registry.urls_count,
+ 0LLU, //registry.urls_count,
registry.persons_urls_count,
registry.machines_urls_count
);
@@ -164,36 +165,36 @@ int registry_db_save(void) {
errno = 0;
// remove the .old db
- debug(D_REGISTRY, "Registry: Removing old db '%s'", old_filename);
+ netdata_log_debug(D_REGISTRY, "REGISTRY: Removing old db '%s'", old_filename);
if(unlink(old_filename) == -1 && errno != ENOENT)
- error("Registry: cannot remove old registry file '%s'", old_filename);
+ netdata_log_error("REGISTRY: cannot remove old registry file '%s'", old_filename);
// rename the db to .old
- debug(D_REGISTRY, "Registry: Link current db '%s' to .old: '%s'", registry.db_filename, old_filename);
+ netdata_log_debug(D_REGISTRY, "REGISTRY: Link current db '%s' to .old: '%s'", registry.db_filename, old_filename);
if(link(registry.db_filename, old_filename) == -1 && errno != ENOENT)
- error("Registry: cannot move file '%s' to '%s'. Saving registry DB failed!", registry.db_filename, old_filename);
+ netdata_log_error("REGISTRY: cannot move file '%s' to '%s'. Saving registry DB failed!", registry.db_filename, old_filename);
else {
// remove the database (it is saved in .old)
- debug(D_REGISTRY, "Registry: removing db '%s'", registry.db_filename);
+ netdata_log_debug(D_REGISTRY, "REGISTRY: removing db '%s'", registry.db_filename);
if (unlink(registry.db_filename) == -1 && errno != ENOENT)
- error("Registry: cannot remove old registry file '%s'", registry.db_filename);
+ netdata_log_error("REGISTRY: cannot remove old registry file '%s'", registry.db_filename);
// move the .tmp to make it active
- debug(D_REGISTRY, "Registry: linking tmp db '%s' to active db '%s'", tmp_filename, registry.db_filename);
+ netdata_log_debug(D_REGISTRY, "REGISTRY: linking tmp db '%s' to active db '%s'", tmp_filename, registry.db_filename);
if (link(tmp_filename, registry.db_filename) == -1) {
- error("Registry: cannot move file '%s' to '%s'. Saving registry DB failed!", tmp_filename,
+ netdata_log_error("REGISTRY: cannot move file '%s' to '%s'. Saving registry DB failed!", tmp_filename,
registry.db_filename);
// move the .old back
- debug(D_REGISTRY, "Registry: linking old db '%s' to active db '%s'", old_filename, registry.db_filename);
+ netdata_log_debug(D_REGISTRY, "REGISTRY: linking old db '%s' to active db '%s'", old_filename, registry.db_filename);
if(link(old_filename, registry.db_filename) == -1)
- error("Registry: cannot move file '%s' to '%s'. Recovering the old registry DB failed!", old_filename, registry.db_filename);
+ netdata_log_error("REGISTRY: cannot move file '%s' to '%s'. Recovering the old registry DB failed!", old_filename, registry.db_filename);
}
else {
- debug(D_REGISTRY, "Registry: removing tmp db '%s'", tmp_filename);
+ netdata_log_debug(D_REGISTRY, "REGISTRY: removing tmp db '%s'", tmp_filename);
if(unlink(tmp_filename) == -1)
- error("Registry: cannot remove tmp registry file '%s'", tmp_filename);
+ netdata_log_error("REGISTRY: cannot remove tmp registry file '%s'", tmp_filename);
// it has been moved successfully
// discard the current registry log
@@ -215,75 +216,33 @@ size_t registry_db_load(void) {
char *s, buf[4096 + 1];
REGISTRY_PERSON *p = NULL;
REGISTRY_MACHINE *m = NULL;
- REGISTRY_URL *u = NULL;
+ STRING *u = NULL;
size_t line = 0;
- debug(D_REGISTRY, "Registry: loading active db from: '%s'", registry.db_filename);
+ netdata_log_debug(D_REGISTRY, "REGISTRY: loading active db from: '%s'", registry.db_filename);
FILE *fp = fopen(registry.db_filename, "r");
if(!fp) {
- error("Registry: cannot open registry file: '%s'", registry.db_filename);
+ netdata_log_error("REGISTRY: cannot open registry file: '%s'", registry.db_filename);
return 0;
}
+ REGISTRY_MACHINE_URL *mu;
size_t len = 0;
buf[4096] = '\0';
while((s = fgets_trim_len(buf, 4096, fp, &len))) {
line++;
- debug(D_REGISTRY, "Registry: read line %zu to length %zu: %s", line, len, s);
+ netdata_log_debug(D_REGISTRY, "REGISTRY: read line %zu to length %zu: %s", line, len, s);
switch(*s) {
- case 'T': // totals
- if(unlikely(len != 103 || s[1] != '\t' || s[18] != '\t' || s[35] != '\t' || s[52] != '\t' || s[69] != '\t' || s[86] != '\t' || s[103] != '\0')) {
- error("Registry totals line %zu is wrong (len = %zu).", line, len);
- continue;
- }
- registry.persons_count = strtoull(&s[2], NULL, 16);
- registry.machines_count = strtoull(&s[19], NULL, 16);
- registry.usages_count = strtoull(&s[36], NULL, 16);
- registry.urls_count = strtoull(&s[53], NULL, 16);
- registry.persons_urls_count = strtoull(&s[70], NULL, 16);
- registry.machines_urls_count = strtoull(&s[87], NULL, 16);
- break;
-
- case 'P': // person
- m = NULL;
- // verify it is valid
- if(unlikely(len != 65 || s[1] != '\t' || s[10] != '\t' || s[19] != '\t' || s[28] != '\t' || s[65] != '\0')) {
- error("Registry person line %zu is wrong (len = %zu).", line, len);
- continue;
- }
-
- s[1] = s[10] = s[19] = s[28] = '\0';
- p = registry_person_allocate(&s[29], strtoul(&s[2], NULL, 16));
- p->last_t = (uint32_t)strtoul(&s[11], NULL, 16);
- p->usages = (uint32_t)strtoul(&s[20], NULL, 16);
- debug(D_REGISTRY, "Registry loaded person '%s', first: %u, last: %u, usages: %u", p->guid, p->first_t, p->last_t, p->usages);
- break;
-
- case 'M': // machine
- p = NULL;
- // verify it is valid
- if(unlikely(len != 65 || s[1] != '\t' || s[10] != '\t' || s[19] != '\t' || s[28] != '\t' || s[65] != '\0')) {
- error("Registry person line %zu is wrong (len = %zu).", line, len);
- continue;
- }
-
- s[1] = s[10] = s[19] = s[28] = '\0';
- m = registry_machine_allocate(&s[29], strtoul(&s[2], NULL, 16));
- m->last_t = (uint32_t)strtoul(&s[11], NULL, 16);
- m->usages = (uint32_t)strtoul(&s[20], NULL, 16);
- debug(D_REGISTRY, "Registry loaded machine '%s', first: %u, last: %u, usages: %u", m->guid, m->first_t, m->last_t, m->usages);
- break;
-
case 'U': // person URL
if(unlikely(!p)) {
- error("Registry: ignoring line %zu, no person loaded: %s", line, s);
+ netdata_log_error("REGISTRY: ignoring line %zu, no person loaded: %s", line, s);
continue;
}
// verify it is valid
if(len < 69 || s[1] != '\t' || s[10] != '\t' || s[19] != '\t' || s[28] != '\t' || s[31] != '\t' || s[68] != '\t') {
- error("Registry person URL line %zu is wrong (len = %zu).", line, len);
+ netdata_log_error("REGISTRY: person URL line %zu is wrong (len = %zu).", line, len);
continue;
}
@@ -293,51 +252,125 @@ size_t registry_db_load(void) {
char *url = &s[69];
while(*url && *url != '\t') url++;
if(!*url) {
- error("Registry person URL line %zu does not have a url.", line);
+ netdata_log_error("REGISTRY: person URL line %zu does not have a url.", line);
continue;
}
*url++ = '\0';
- // u = registry_url_allocate_nolock(url, strlen(url));
- u = registry_url_get(url, strlen(url));
+ if(*url != 'h' && *url != '*') {
+ netdata_log_error("REGISTRY: person URL line %zu does not have a valid url: %s", line, url);
+ continue;
+ }
+
+ u = string_strdupz(url);
- time_t first_t = strtoul(&s[2], NULL, 16);
+ time_t first_t = (time_t)strtoul(&s[2], NULL, 16);
m = registry_machine_find(&s[32]);
if(!m) m = registry_machine_allocate(&s[32], first_t);
- REGISTRY_PERSON_URL *pu = registry_person_url_allocate(p, m, u, &s[69], strlen(&s[69]), first_t);
+ mu = registry_machine_url_find(m, u);
+ if(!mu) {
+ netdata_log_error("REGISTRY: person URL line %zu was not linked to the machine it refers to", line);
+ mu = registry_machine_url_allocate(m, u, first_t);
+ }
+
+ REGISTRY_PERSON_URL *pu = registry_person_url_index_find(p, u);
+ if(!pu)
+ pu = registry_person_url_allocate(p, m, u, &s[69], strlen(&s[69]), first_t);
+ else
+ netdata_log_error("REGISTRY: person URL line %zu is duplicate, reusing the old one.", line);
+
pu->last_t = (uint32_t)strtoul(&s[11], NULL, 16);
pu->usages = (uint32_t)strtoul(&s[20], NULL, 16);
pu->flags = (uint8_t)strtoul(&s[29], NULL, 16);
- debug(D_REGISTRY, "Registry loaded person URL '%s' with name '%s' of machine '%s', first: %u, last: %u, usages: %u, flags: %02x", u->url, pu->machine_name, m->guid, pu->first_t, pu->last_t, pu->usages, pu->flags);
+ netdata_log_debug(D_REGISTRY, "REGISTRY: loaded person URL '%s' with name '%s' of machine '%s', first: %u, last: %u, usages: %u, flags: %02x",
+ string2str(u), string2str(pu->machine_name), m->guid, pu->first_t, pu->last_t, pu->usages, pu->flags);
+
+ string_freez(u);
+ break;
+
+ case 'P': // person
+ m = NULL;
+ // verify it is valid
+ if(unlikely(len != 65 || s[1] != '\t' || s[10] != '\t' || s[19] != '\t' || s[28] != '\t' || s[65] != '\0')) {
+ netdata_log_error("REGISTRY: person line %zu is wrong (len = %zu).", line, len);
+ continue;
+ }
+
+ s[1] = s[10] = s[19] = s[28] = '\0';
+ p = registry_person_allocate(&s[29], (time_t)strtoul(&s[2], NULL, 16));
+ p->last_t = (uint32_t)strtoul(&s[11], NULL, 16);
+ p->usages = (uint32_t)strtoul(&s[20], NULL, 16);
+ netdata_log_debug(D_REGISTRY, "REGISTRY: loaded person '%s', first: %u, last: %u, usages: %u", p->guid, p->first_t, p->last_t, p->usages);
break;
case 'V': // machine URL
if(unlikely(!m)) {
- error("Registry: ignoring line %zu, no machine loaded: %s", line, s);
+ netdata_log_error("REGISTRY: ignoring line %zu, no machine loaded: %s", line, s);
continue;
}
// verify it is valid
if(len < 32 || s[1] != '\t' || s[10] != '\t' || s[19] != '\t' || s[28] != '\t' || s[31] != '\t') {
- error("Registry person URL line %zu is wrong (len = %zu).", line, len);
+ netdata_log_error("REGISTRY: person URL line %zu is wrong (len = %zu).", line, len);
continue;
}
s[1] = s[10] = s[19] = s[28] = s[31] = '\0';
- // u = registry_url_allocate_nolock(&s[32], strlen(&s[32]));
- u = registry_url_get(&s[32], strlen(&s[32]));
- REGISTRY_MACHINE_URL *mu = registry_machine_url_allocate(m, u, strtoul(&s[2], NULL, 16));
+ url = &s[32];
+ if(*url != 'h' && *url != '*') {
+ netdata_log_error("REGISTRY: machine URL line %zu does not have a valid url: %s", line, url);
+ continue;
+ }
+
+ u = string_strdupz(url);
+
+ mu = registry_machine_url_find(m, u);
+ if(!mu)
+ mu = registry_machine_url_allocate(m, u, (time_t)strtoul(&s[2], NULL, 16));
+ else
+ netdata_log_error("REGISTRY: machine URL line %zu is duplicate, reusing the old one.", line);
+
mu->last_t = (uint32_t)strtoul(&s[11], NULL, 16);
mu->usages = (uint32_t)strtoul(&s[20], NULL, 16);
mu->flags = (uint8_t)strtoul(&s[29], NULL, 16);
- debug(D_REGISTRY, "Registry loaded machine URL '%s', machine '%s', first: %u, last: %u, usages: %u, flags: %02x", u->url, m->guid, mu->first_t, mu->last_t, mu->usages, mu->flags);
+ netdata_log_debug(D_REGISTRY, "Registry loaded machine URL '%s', machine '%s', first: %u, last: %u, usages: %u, flags: %02x",
+ string2str(u), m->guid, mu->first_t, mu->last_t, mu->usages, mu->flags);
+
+ string_freez(u);
+ break;
+
+ case 'M': // machine
+ p = NULL;
+ // verify it is valid
+ if(unlikely(len != 65 || s[1] != '\t' || s[10] != '\t' || s[19] != '\t' || s[28] != '\t' || s[65] != '\0')) {
+ netdata_log_error("REGISTRY: person line %zu is wrong (len = %zu).", line, len);
+ continue;
+ }
+
+ s[1] = s[10] = s[19] = s[28] = '\0';
+ m = registry_machine_allocate(&s[29], (time_t)strtoul(&s[2], NULL, 16));
+ m->last_t = (uint32_t)strtoul(&s[11], NULL, 16);
+ m->usages = (uint32_t)strtoul(&s[20], NULL, 16);
+ netdata_log_debug(D_REGISTRY, "REGISTRY: loaded machine '%s', first: %u, last: %u, usages: %u", m->guid, m->first_t, m->last_t, m->usages);
+ break;
+
+ case 'T': // totals
+ if(unlikely(len != 103 || s[1] != '\t' || s[18] != '\t' || s[35] != '\t' || s[52] != '\t' || s[69] != '\t' || s[86] != '\t' || s[103] != '\0')) {
+ netdata_log_error("REGISTRY: totals line %zu is wrong (len = %zu).", line, len);
+ continue;
+ }
+ registry.persons_count = strtoull(&s[2], NULL, 16);
+ registry.machines_count = strtoull(&s[19], NULL, 16);
+ registry.usages_count = strtoull(&s[36], NULL, 16);
+ registry.persons_urls_count = strtoull(&s[70], NULL, 16);
+ registry.machines_urls_count = strtoull(&s[87], NULL, 16);
break;
default:
- error("Registry: ignoring line %zu of filename '%s': %s.", line, registry.db_filename, s);
+ netdata_log_error("REGISTRY: ignoring line %zu of filename '%s': %s.", line, registry.db_filename, s);
break;
}
}
diff --git a/registry/registry_init.c b/registry/registry_init.c
index ba4250ef3..79523e258 100644
--- a/registry/registry_init.c
+++ b/registry/registry_init.c
@@ -3,6 +3,65 @@
#include "daemon/common.h"
#include "registry_internals.h"
+void registry_db_stats(void) {
+ size_t persons = 0;
+ size_t persons_urls = 0;
+ size_t max_urls_per_person = 0;
+
+ REGISTRY_PERSON *p;
+ dfe_start_read(registry.persons, p) {
+ persons++;
+ size_t urls = 0;
+ for(REGISTRY_PERSON_URL *pu = p->person_urls ; pu ;pu = pu->next)
+ urls++;
+
+ if(urls > max_urls_per_person)
+ max_urls_per_person = urls;
+
+ persons_urls += urls;
+ }
+ dfe_done(p);
+
+ size_t machines = 0;
+ size_t machines_urls = 0;
+ size_t max_urls_per_machine = 0;
+
+ REGISTRY_MACHINE *m;
+ dfe_start_read(registry.machines, m) {
+ machines++;
+ size_t urls = 0;
+ for(REGISTRY_MACHINE_URL *mu = m->machine_urls ; mu ;mu = mu->next)
+ urls++;
+
+ if(urls > max_urls_per_machine)
+ max_urls_per_machine = urls;
+
+ machines_urls += urls;
+ }
+ dfe_done(m);
+
+ netdata_log_info("REGISTRY: persons %zu, person_urls %zu, max_urls_per_person %zu, "
+ "machines %zu, machine_urls %zu, max_urls_per_machine %zu",
+ persons, persons_urls, max_urls_per_person,
+ machines, machines_urls, max_urls_per_machine);
+}
+
+void registry_generate_curl_urls(void) {
+ FILE *fp = fopen("/tmp/registry.curl", "w+");
+ if (unlikely(!fp))
+ return;
+
+ REGISTRY_PERSON *p;
+ dfe_start_read(registry.persons, p) {
+ for(REGISTRY_PERSON_URL *pu = p->person_urls ; pu ;pu = pu->next) {
+ fprintf(fp, "do_curl '%s' '%s' '%s'\n", p->guid, pu->machine->guid, string2str(pu->url));
+ }
+ }
+ dfe_done(p);
+
+ fclose(fp);
+}
+
int registry_init(void) {
char filename[FILENAME_MAX + 1];
@@ -11,12 +70,12 @@ int registry_init(void) {
registry.enabled = config_get_boolean(CONFIG_SECTION_REGISTRY, "enabled", 0);
}
else {
- info("Registry is disabled - use the central netdata");
+ netdata_log_info("Registry is disabled - use the central netdata");
config_set_boolean(CONFIG_SECTION_REGISTRY, "enabled", 0);
registry.enabled = 0;
}
- // pathnames
+ // path names
snprintfz(filename, FILENAME_MAX, "%s/registry", netdata_configured_varlib_dir);
registry.pathname = config_get(CONFIG_SECTION_DIRECTORIES, "registry", filename);
if(mkdir(registry.pathname, 0770) == -1 && errno != EEXIST)
@@ -57,91 +116,134 @@ int registry_init(void) {
config_set_number(CONFIG_SECTION_REGISTRY, "max URL name length", (long long)registry.max_name_length);
}
+ bool use_mmap = config_get_boolean(CONFIG_SECTION_REGISTRY, "use mmap", false);
+
// initialize entries counters
registry.persons_count = 0;
registry.machines_count = 0;
registry.usages_count = 0;
- registry.urls_count = 0;
registry.persons_urls_count = 0;
registry.machines_urls_count = 0;
- // initialize memory counters
- registry.persons_memory = 0;
- registry.machines_memory = 0;
- registry.urls_memory = 0;
- registry.persons_urls_memory = 0;
- registry.machines_urls_memory = 0;
-
// initialize locks
netdata_mutex_init(&registry.lock);
- // create dictionaries
- registry.persons = dictionary_create(REGISTRY_DICTIONARY_OPTIONS);
- registry.machines = dictionary_create(REGISTRY_DICTIONARY_OPTIONS);
- avl_init(&registry.registry_urls_root_index, registry_url_compare);
-
// load the registry database
if(registry.enabled) {
+ // create dictionaries
+ registry.persons = dictionary_create(REGISTRY_DICTIONARY_OPTIONS);
+ registry.machines = dictionary_create(REGISTRY_DICTIONARY_OPTIONS);
+
+ // initialize the allocators
+
+ size_t min_page_size = 4 * 1024;
+ size_t max_page_size = 1024 * 1024;
+
+ if(use_mmap) {
+ min_page_size = 100 * 1024 * 1024;
+ max_page_size = 512 * 1024 * 1024;
+ }
+
+ registry.persons_aral = aral_create("registry_persons", sizeof(REGISTRY_PERSON),
+ min_page_size / sizeof(REGISTRY_PERSON), max_page_size,
+ &registry.aral_stats,
+ "registry_persons",
+ &netdata_configured_cache_dir,
+ use_mmap, true);
+
+ registry.machines_aral = aral_create("registry_machines", sizeof(REGISTRY_MACHINE),
+ min_page_size / sizeof(REGISTRY_MACHINE), max_page_size,
+ &registry.aral_stats,
+ "registry_machines",
+ &netdata_configured_cache_dir,
+ use_mmap, true);
+
+ registry.person_urls_aral = aral_create("registry_person_urls", sizeof(REGISTRY_PERSON_URL),
+ min_page_size / sizeof(REGISTRY_PERSON_URL), max_page_size,
+ &registry.aral_stats,
+ "registry_person_urls",
+ &netdata_configured_cache_dir,
+ use_mmap, true);
+
+ registry.machine_urls_aral = aral_create("registry_machine_urls", sizeof(REGISTRY_MACHINE_URL),
+ min_page_size / sizeof(REGISTRY_MACHINE_URL), max_page_size,
+ &registry.aral_stats,
+ "registry_machine_urls",
+ &netdata_configured_cache_dir,
+ use_mmap, true);
+
+ // disable cancelability to avoid enable/disable per item in the dictionary locks
+ netdata_thread_disable_cancelability();
+
registry_log_open();
registry_db_load();
registry_log_load();
if(unlikely(registry_db_should_be_saved()))
registry_db_save();
+
+// registry_db_stats();
+// registry_generate_curl_urls();
+// exit(0);
+
+ netdata_thread_enable_cancelability();
}
return 0;
}
-static int machine_urls_delete_callback(const DICTIONARY_ITEM *item __maybe_unused, void *entry, void *data) {
- REGISTRY_MACHINE *m = (REGISTRY_MACHINE *)data;
- (void)m;
+static int machine_delete_callback(const DICTIONARY_ITEM *item __maybe_unused, void *entry, void *data __maybe_unused) {
+ REGISTRY_MACHINE *m = (REGISTRY_MACHINE *)entry;
- REGISTRY_MACHINE_URL *mu = (REGISTRY_MACHINE_URL *)entry;
+ int count = 0;
- debug(D_REGISTRY, "Registry: unlinking url '%s' from machine", mu->url->url);
- registry_url_unlink(mu->url);
+ while(m->machine_urls) {
+ registry_machine_url_unlink_from_machine_and_free(m, m->machine_urls);
+ count++;
+ }
- debug(D_REGISTRY, "Registry: freeing machine url");
- freez(mu);
+ aral_freez(registry.machines_aral, m);
- return 1;
+ return count + 1;
}
-static int machine_delete_callback(const DICTIONARY_ITEM *item __maybe_unused, void *entry, void *data __maybe_unused) {
- REGISTRY_MACHINE *m = (REGISTRY_MACHINE *)entry;
- int ret = dictionary_walkthrough_read(m->machine_urls, machine_urls_delete_callback, m);
-
- dictionary_destroy(m->machine_urls);
- freez(m);
-
- return ret + 1;
-}
static int registry_person_del_callback(const DICTIONARY_ITEM *item __maybe_unused, void *entry, void *d __maybe_unused) {
REGISTRY_PERSON *p = (REGISTRY_PERSON *)entry;
- debug(D_REGISTRY, "Registry: registry_person_del('%s'): deleting person", p->guid);
+ netdata_log_debug(D_REGISTRY, "Registry: registry_person_del('%s'): deleting person", p->guid);
- while(p->person_urls.root)
- registry_person_unlink_from_url(p, (REGISTRY_PERSON_URL *)p->person_urls.root);
+ while(p->person_urls)
+ registry_person_unlink_from_url(p, (REGISTRY_PERSON_URL *)p->person_urls);
//debug(D_REGISTRY, "Registry: deleting person '%s' from persons registry", p->guid);
//dictionary_del(registry.persons, p->guid);
- debug(D_REGISTRY, "Registry: freeing person '%s'", p->guid);
- freez(p);
+ netdata_log_debug(D_REGISTRY, "Registry: freeing person '%s'", p->guid);
+ aral_freez(registry.persons_aral, p);
return 1;
}
void registry_free(void) {
if(!registry.enabled) return;
+ registry.enabled = false;
- debug(D_REGISTRY, "Registry: destroying persons dictionary");
+ netdata_log_debug(D_REGISTRY, "Registry: destroying persons dictionary");
dictionary_walkthrough_read(registry.persons, registry_person_del_callback, NULL);
dictionary_destroy(registry.persons);
+ registry.persons = NULL;
- debug(D_REGISTRY, "Registry: destroying machines dictionary");
+ netdata_log_debug(D_REGISTRY, "Registry: destroying machines dictionary");
dictionary_walkthrough_read(registry.machines, machine_delete_callback, NULL);
dictionary_destroy(registry.machines);
+ registry.machines = NULL;
+
+ aral_destroy(registry.persons_aral);
+ aral_destroy(registry.machines_aral);
+ aral_destroy(registry.person_urls_aral);
+ aral_destroy(registry.machine_urls_aral);
+ registry.persons_aral = NULL;
+ registry.machines_aral = NULL;
+ registry.person_urls_aral = NULL;
+ registry.machine_urls_aral = NULL;
}
diff --git a/registry/registry_internals.c b/registry/registry_internals.c
index fe4d2dac5..74f12b558 100644
--- a/registry/registry_internals.c
+++ b/registry/registry_internals.c
@@ -13,7 +13,7 @@ struct registry registry;
int regenerate_guid(const char *guid, char *result) {
uuid_t uuid;
if(unlikely(uuid_parse(guid, uuid) == -1)) {
- info("Registry: GUID '%s' is not a valid GUID.", guid);
+ netdata_log_info("Registry: GUID '%s' is not a valid GUID.", guid);
return -1;
}
else {
@@ -21,7 +21,7 @@ int regenerate_guid(const char *guid, char *result) {
#ifdef NETDATA_INTERNAL_CHECKS
if(strcmp(guid, result) != 0)
- info("GUID '%s' and re-generated GUID '%s' differ!", guid, result);
+ netdata_log_info("GUID '%s' and re-generated GUID '%s' differ!", guid, result);
#endif /* NETDATA_INTERNAL_CHECKS */
}
@@ -80,11 +80,11 @@ static inline char *registry_fix_url(char *url, size_t *len) {
// HELPERS
// verify the person, the machine and the URL exist in our DB
-REGISTRY_PERSON_URL *registry_verify_request(char *person_guid, char *machine_guid, char *url, REGISTRY_PERSON **pp, REGISTRY_MACHINE **mm) {
+REGISTRY_PERSON_URL *registry_verify_request(const char *person_guid, char *machine_guid, char *url, REGISTRY_PERSON **pp, REGISTRY_MACHINE **mm) {
char pbuf[GUID_LEN + 1], mbuf[GUID_LEN + 1];
if(!person_guid || !*person_guid || !machine_guid || !*machine_guid || !url || !*url) {
- info("Registry Request Verification: invalid request! person: '%s', machine '%s', url '%s'", person_guid?person_guid:"UNSET", machine_guid?machine_guid:"UNSET", url?url:"UNSET");
+ netdata_log_info("Registry Request Verification: invalid request! person: '%s', machine '%s', url '%s'", person_guid?person_guid:"UNSET", machine_guid?machine_guid:"UNSET", url?url:"UNSET");
return NULL;
}
@@ -93,14 +93,14 @@ REGISTRY_PERSON_URL *registry_verify_request(char *person_guid, char *machine_gu
// make sure the person GUID is valid
if(regenerate_guid(person_guid, pbuf) == -1) {
- info("Registry Request Verification: invalid person GUID, person: '%s', machine '%s', url '%s'", person_guid, machine_guid, url);
+ netdata_log_info("Registry Request Verification: invalid person GUID, person: '%s', machine '%s', url '%s'", person_guid, machine_guid, url);
return NULL;
}
person_guid = pbuf;
// make sure the machine GUID is valid
if(regenerate_guid(machine_guid, mbuf) == -1) {
- info("Registry Request Verification: invalid machine GUID, person: '%s', machine '%s', url '%s'", person_guid, machine_guid, url);
+ netdata_log_info("Registry Request Verification: invalid machine GUID, person: '%s', machine '%s', url '%s'", person_guid, machine_guid, url);
return NULL;
}
machine_guid = mbuf;
@@ -108,7 +108,7 @@ REGISTRY_PERSON_URL *registry_verify_request(char *person_guid, char *machine_gu
// make sure the machine exists
REGISTRY_MACHINE *m = registry_machine_find(machine_guid);
if(!m) {
- info("Registry Request Verification: machine not found, person: '%s', machine '%s', url '%s'", person_guid, machine_guid, url);
+ netdata_log_info("Registry Request Verification: machine not found, person: '%s', machine '%s', url '%s'", person_guid, machine_guid, url);
return NULL;
}
if(mm) *mm = m;
@@ -116,18 +116,21 @@ REGISTRY_PERSON_URL *registry_verify_request(char *person_guid, char *machine_gu
// make sure the person exist
REGISTRY_PERSON *p = registry_person_find(person_guid);
if(!p) {
- info("Registry Request Verification: person not found, person: '%s', machine '%s', url '%s'", person_guid, machine_guid, url);
+ netdata_log_info("Registry Request Verification: person not found, person: '%s', machine '%s', url '%s'", person_guid, machine_guid, url);
return NULL;
}
if(pp) *pp = p;
- REGISTRY_PERSON_URL *pu = registry_person_url_index_find(p, url);
+ STRING *u = string_strdupz(url);
+ REGISTRY_PERSON_URL *pu = registry_person_url_index_find(p, u);
+ string_freez(u);
+
if(!pu) {
- info("Registry Request Verification: URL not found for person, person: '%s', machine '%s', url '%s'", person_guid, machine_guid, url);
+ netdata_log_info("Registry Request Verification: URL not found for person, person: '%s', machine '%s', url '%s'", person_guid, machine_guid, url);
return NULL;
}
//else if (pu->machine != m) {
- // info("Registry Request Verification: Machine mismatch: person: '%s', machine requested='%s' <> loaded='%s', url '%s'", person_guid, machine_guid, pu->machine->guid, url);
+ // netdata_log_info("Registry Request Verification: Machine mismatch: person: '%s', machine requested='%s' <> loaded='%s', url '%s'", person_guid, machine_guid, pu->machine->guid, url);
// return NULL;
//}
@@ -138,23 +141,28 @@ REGISTRY_PERSON_URL *registry_verify_request(char *person_guid, char *machine_gu
// ----------------------------------------------------------------------------
// REGISTRY REQUESTS
-REGISTRY_PERSON *registry_request_access(char *person_guid, char *machine_guid, char *url, char *name, time_t when) {
- debug(D_REGISTRY, "registry_request_access('%s', '%s', '%s'): NEW REQUEST", (person_guid)?person_guid:"", machine_guid, url);
+REGISTRY_PERSON *registry_request_access(const char *person_guid, char *machine_guid, char *url, char *name, time_t when) {
+ netdata_log_debug(D_REGISTRY, "registry_request_access('%s', '%s', '%s'): NEW REQUEST", (person_guid)?person_guid:"", machine_guid, url);
+
+ bool is_dummy = is_dummy_person(person_guid);
- REGISTRY_MACHINE *m = registry_machine_get(machine_guid, when);
+ REGISTRY_MACHINE *m = registry_machine_find_or_create(machine_guid, when, is_dummy);
if(!m) return NULL;
+ REGISTRY_PERSON *p = registry_person_find_or_create(person_guid, when, is_dummy);
+
// make sure the name is valid
- size_t namelen;
- name = registry_fix_machine_name(name, &namelen);
+ size_t name_len;
+ name = registry_fix_machine_name(name, &name_len);
- size_t urllen;
- url = registry_fix_url(url, &urllen);
+ size_t url_len;
+ url = registry_fix_url(url, &url_len);
- REGISTRY_PERSON *p = registry_person_get(person_guid, when);
+ STRING *u = string_strdupz(url);
+
+ if(!is_dummy)
+ registry_person_link_to_url(p, m, u, name, name_len, when);
- REGISTRY_URL *u = registry_url_get(url, urllen);
- registry_person_link_to_url(p, m, u, name, namelen, when);
registry_machine_link_to_url(m, u, when);
registry_log('A', p, m, u, name);
@@ -164,7 +172,7 @@ REGISTRY_PERSON *registry_request_access(char *person_guid, char *machine_guid,
return p;
}
-REGISTRY_PERSON *registry_request_delete(char *person_guid, char *machine_guid, char *url, char *delete_url, time_t when) {
+REGISTRY_PERSON *registry_request_delete(const char *person_guid, char *machine_guid, char *url, char *delete_url, time_t when) {
(void) when;
REGISTRY_PERSON *p = NULL;
@@ -178,82 +186,63 @@ REGISTRY_PERSON *registry_request_delete(char *person_guid, char *machine_guid,
// make sure the user is not deleting the url it uses
/*
if(!strcmp(delete_url, pu->url->url)) {
- info("Registry Delete Request: delete URL is the one currently accessed, person: '%s', machine '%s', url '%s', delete url '%s'"
+ netdata_log_info("Registry Delete Request: delete URL is the one currently accessed, person: '%s', machine '%s', url '%s', delete url '%s'"
, p->guid, m->guid, pu->url->url, delete_url);
return NULL;
}
*/
- REGISTRY_PERSON_URL *dpu = registry_person_url_index_find(p, delete_url);
+ STRING *d_url = string_strdupz(delete_url);
+ REGISTRY_PERSON_URL *dpu = registry_person_url_index_find(p, d_url);
+ string_freez(d_url);
+
if(!dpu) {
- info("Registry Delete Request: URL not found for person: '%s', machine '%s', url '%s', delete url '%s'", p->guid
- , m->guid, pu->url->url, delete_url);
+ netdata_log_info("Registry Delete Request: URL not found for person: '%s', machine '%s', url '%s', delete url '%s'", p->guid
+ , m->guid, string2str(pu->url), delete_url);
return NULL;
}
- registry_log('D', p, m, pu->url, dpu->url->url);
+ registry_log('D', p, m, pu->url, string2str(dpu->url));
registry_person_unlink_from_url(p, dpu);
return p;
}
-// a structure to pass to the dictionary_walkthrough_read() callback handler
-struct machine_request_callback_data {
- REGISTRY_MACHINE *find_this_machine;
- REGISTRY_PERSON_URL *result;
-};
-
-// the callback function
-// this will be run for every PERSON_URL of this PERSON
-static int machine_request_callback(void *entry, void *data) {
- REGISTRY_PERSON_URL *mypu = (REGISTRY_PERSON_URL *)entry;
- struct machine_request_callback_data *myrdata = (struct machine_request_callback_data *)data;
-
- if(mypu->machine == myrdata->find_this_machine) {
- myrdata->result = mypu;
- return -1; // this will also stop the walk through
- }
-
- return 0; // continue
-}
-
-REGISTRY_MACHINE *registry_request_machine(char *person_guid, char *machine_guid, char *url, char *request_machine, time_t when) {
- (void)when;
-
+REGISTRY_MACHINE *registry_request_machine(const char *person_guid, char *request_machine, STRING **hostname) {
+ char pbuf[GUID_LEN + 1];
char mbuf[GUID_LEN + 1];
- REGISTRY_PERSON *p = NULL;
- REGISTRY_MACHINE *m = NULL;
- REGISTRY_PERSON_URL *pu = registry_verify_request(person_guid, machine_guid, url, &p, &m);
- if(!pu || !p || !m) return NULL;
+ // make sure the person GUID is valid
+ if(regenerate_guid(person_guid, pbuf) == -1) {
+ netdata_log_info("REGISTRY: %s(): invalid person GUID '%s'", __FUNCTION__ , person_guid);
+ return NULL;
+ }
+ person_guid = pbuf;
- // make sure the machine GUID is valid
+ // make sure the person GUID is valid
if(regenerate_guid(request_machine, mbuf) == -1) {
- info("Registry Machine URLs request: invalid machine GUID, person: '%s', machine '%s', url '%s', request machine '%s'", p->guid, m->guid, pu->url->url, request_machine);
+ netdata_log_info("REGISTRY: %s(): invalid search machine GUID '%s'", __FUNCTION__ , request_machine);
return NULL;
}
request_machine = mbuf;
- // make sure the machine exists
- m = registry_machine_find(request_machine);
- if(!m) {
- info("Registry Machine URLs request: machine not found, person: '%s', machine '%s', url '%s', request machine '%s'", p->guid, machine_guid, pu->url->url, request_machine);
- return NULL;
- }
+ REGISTRY_PERSON *p = registry_person_find(person_guid);
+ if(!p) return NULL;
+
+ REGISTRY_MACHINE *m = registry_machine_find(request_machine);
+ if(!m) return NULL;
// Verify the user has in the past accessed this machine
// We will walk through the PERSON_URLs to find the machine
// linking to our machine
- // a structure to pass to the dictionary_walkthrough_read() callback handler
- struct machine_request_callback_data rdata = { m, NULL };
-
- // request a walk through on the dictionary
- avl_traverse(&p->person_urls, machine_request_callback, &rdata);
-
- if(rdata.result)
- return m;
+ // make sure the user has access
+ for(REGISTRY_PERSON_URL *pu = p->person_urls; pu ;pu = pu->next)
+ if(pu->machine == m) {
+ *hostname = string_dup(pu->machine_name);
+ return m;
+ }
return NULL;
}
@@ -270,7 +259,7 @@ static inline int is_machine_guid_blacklisted(const char *guid) {
if(!strcmp(guid, "8a795b0c-2311-11e6-8563-000c295076a6")
|| !strcmp(guid, "4aed1458-1c3e-11e6-a53f-000c290fc8f5")
) {
- error("Blacklisted machine GUID '%s' found.", guid);
+ netdata_log_error("Blacklisted machine GUID '%s' found.", guid);
return 1;
}
@@ -292,11 +281,11 @@ char *registry_get_this_machine_guid(void) {
if(fd != -1) {
char buf[GUID_LEN + 1];
if(read(fd, buf, GUID_LEN) != GUID_LEN)
- error("Failed to read machine GUID from '%s'", registry.machine_guid_filename);
+ netdata_log_error("Failed to read machine GUID from '%s'", registry.machine_guid_filename);
else {
buf[GUID_LEN] = '\0';
if(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.",
+ netdata_log_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);
guid[0] = '\0';
diff --git a/registry/registry_internals.h b/registry/registry_internals.h
index 3456d788d..c7f8f43dd 100644
--- a/registry/registry_internals.h
+++ b/registry/registry_internals.h
@@ -10,28 +10,24 @@
#define REGISTRY_DICTIONARY_OPTIONS (DICT_OPTION_VALUE_LINK_DONT_CLONE | DICT_OPTION_NAME_LINK_DONT_CLONE | DICT_OPTION_SINGLE_THREADED)
+#define REGISTRY_VERIFY_COOKIES_GUID "11111111-2222-3333-4444-555555555555"
+#define is_dummy_person(person_guid) (strcmp(person_guid, REGISTRY_VERIFY_COOKIES_GUID) == 0)
+
// ----------------------------------------------------------------------------
// COMMON structures
struct registry {
int enabled;
+ netdata_mutex_t lock;
// entries counters / statistics
unsigned long long persons_count;
unsigned long long machines_count;
unsigned long long usages_count;
- unsigned long long urls_count;
unsigned long long persons_urls_count;
unsigned long long machines_urls_count;
unsigned long long log_count;
- // memory counters / statistics
- unsigned long long persons_memory;
- unsigned long long machines_memory;
- unsigned long long urls_memory;
- unsigned long long persons_urls_memory;
- unsigned long long machines_urls_memory;
-
// configuration
unsigned long long save_registry_every_entries;
char *registry_domain;
@@ -58,12 +54,15 @@ struct registry {
DICTIONARY *persons; // dictionary of REGISTRY_PERSON *, with key the REGISTRY_PERSON.guid
DICTIONARY *machines; // dictionary of REGISTRY_MACHINE *, with key the REGISTRY_MACHINE.guid
- avl_tree_type registry_urls_root_index;
+ ARAL *persons_aral;
+ ARAL *machines_aral;
- netdata_mutex_t lock;
+ ARAL *person_urls_aral;
+ ARAL *machine_urls_aral;
+
+ struct aral_statistics aral_stats;
};
-#include "registry_url.h"
#include "registry_machine.h"
#include "registry_person.h"
#include "registry.h"
@@ -71,12 +70,12 @@ struct registry {
extern struct registry registry;
// REGISTRY LOW-LEVEL REQUESTS (in registry-internals.c)
-REGISTRY_PERSON *registry_request_access(char *person_guid, char *machine_guid, char *url, char *name, time_t when);
-REGISTRY_PERSON *registry_request_delete(char *person_guid, char *machine_guid, char *url, char *delete_url, time_t when);
-REGISTRY_MACHINE *registry_request_machine(char *person_guid, char *machine_guid, char *url, char *request_machine, time_t when);
+REGISTRY_PERSON *registry_request_access(const char *person_guid, char *machine_guid, char *url, char *name, time_t when);
+REGISTRY_PERSON *registry_request_delete(const char *person_guid, char *machine_guid, char *url, char *delete_url, time_t when);
+REGISTRY_MACHINE *registry_request_machine(const char *person_guid, char *request_machine, STRING **hostname);
// REGISTRY LOG (in registry_log.c)
-void registry_log(char action, REGISTRY_PERSON *p, REGISTRY_MACHINE *m, REGISTRY_URL *u, char *name);
+void registry_log(char action, REGISTRY_PERSON *p, REGISTRY_MACHINE *m, STRING *u, const char *name);
int registry_log_open(void);
void registry_log_close(void);
void registry_log_recreate(void);
diff --git a/registry/registry_log.c b/registry/registry_log.c
index b048135e6..118d47c15 100644
--- a/registry/registry_log.c
+++ b/registry/registry_log.c
@@ -3,7 +3,7 @@
#include "daemon/common.h"
#include "registry_internals.h"
-void registry_log(char action, REGISTRY_PERSON *p, REGISTRY_MACHINE *m, REGISTRY_URL *u, char *name) {
+void registry_log(char action, REGISTRY_PERSON *p, REGISTRY_MACHINE *m, STRING *u, const char *name) {
if(likely(registry.log_fp)) {
if(unlikely(fprintf(registry.log_fp, "%c\t%08x\t%s\t%s\t%s\t%s\n",
action,
@@ -11,8 +11,8 @@ void registry_log(char action, REGISTRY_PERSON *p, REGISTRY_MACHINE *m, REGISTRY
p->guid,
m->guid,
name,
- u->url) < 0))
- error("Registry: failed to save log. Registry data may be lost in case of abnormal restart.");
+ string2str(u)) < 0))
+ netdata_log_error("Registry: failed to save log. Registry data may be lost in case of abnormal restart.");
// we increase the counter even on failures
// so that the registry will be saved periodically
@@ -33,11 +33,11 @@ int registry_log_open(void) {
registry.log_fp = fopen(registry.log_filename, "a");
if(registry.log_fp) {
if (setvbuf(registry.log_fp, NULL, _IOLBF, 0) != 0)
- error("Cannot set line buffering on registry log file.");
+ netdata_log_error("Cannot set line buffering on registry log file.");
return 0;
}
- error("Cannot open registry log file '%s'. Registry data will be lost in case of netdata or server crash.", registry.log_filename);
+ netdata_log_error("Cannot open registry log file '%s'. Registry data will be lost in case of netdata or server crash.", registry.log_filename);
return -1;
}
@@ -55,7 +55,8 @@ void registry_log_recreate(void) {
// open it with truncate
registry.log_fp = fopen(registry.log_filename, "w");
if(registry.log_fp) fclose(registry.log_fp);
- else error("Cannot truncate registry log '%s'", registry.log_filename);
+ else
+ netdata_log_error("Cannot truncate registry log '%s'", registry.log_filename);
registry.log_fp = NULL;
registry_log_open();
@@ -69,10 +70,10 @@ ssize_t registry_log_load(void) {
// otherwise we will append to it the values we read
registry_log_close();
- debug(D_REGISTRY, "Registry: loading active db from: %s", registry.log_filename);
+ netdata_log_debug(D_REGISTRY, "Registry: loading active db from: %s", registry.log_filename);
FILE *fp = fopen(registry.log_filename, "r");
if(!fp)
- error("Registry: cannot open registry file: %s", registry.log_filename);
+ netdata_log_error("Registry: cannot open registry file: %s", registry.log_filename);
else {
char *s, buf[4096 + 1];
line = 0;
@@ -87,13 +88,13 @@ ssize_t registry_log_load(void) {
// verify it is valid
if (unlikely(len < 85 || s[1] != '\t' || s[10] != '\t' || s[47] != '\t' || s[84] != '\t')) {
- error("Registry: log line %zd is wrong (len = %zu).", line, len);
+ netdata_log_error("Registry: log line %zd is wrong (len = %zu).", line, len);
continue;
}
s[1] = s[10] = s[47] = s[84] = '\0';
// get the variables
- time_t when = strtoul(&s[2], NULL, 16);
+ time_t when = (time_t)strtoul(&s[2], NULL, 16);
char *person_guid = &s[11];
char *machine_guid = &s[48];
char *name = &s[85];
@@ -102,7 +103,7 @@ ssize_t registry_log_load(void) {
char *url = name;
while(*url && *url != '\t') url++;
if(!*url) {
- error("Registry: log line %zd does not have a url.", line);
+ netdata_log_error("Registry: log line %zd does not have a url.", line);
continue;
}
*url++ = '\0';
@@ -121,7 +122,7 @@ ssize_t registry_log_load(void) {
break;
default:
- error("Registry: ignoring line %zd of filename '%s': %s.", line, registry.log_filename, s);
+ netdata_log_error("Registry: ignoring line %zd of filename '%s': %s.", line, registry.log_filename, s);
break;
}
}
diff --git a/registry/registry_machine.c b/registry/registry_machine.c
index 414cd16d9..a94fb8ea4 100644
--- a/registry/registry_machine.c
+++ b/registry/registry_machine.c
@@ -7,52 +7,59 @@
// MACHINE
REGISTRY_MACHINE *registry_machine_find(const char *machine_guid) {
- debug(D_REGISTRY, "Registry: registry_machine_find('%s')", machine_guid);
+ netdata_log_debug(D_REGISTRY, "REGISTRY: registry_machine_find('%s')", machine_guid);
return dictionary_get(registry.machines, machine_guid);
}
-REGISTRY_MACHINE_URL *registry_machine_url_allocate(REGISTRY_MACHINE *m, REGISTRY_URL *u, time_t when) {
- debug(D_REGISTRY, "registry_machine_url_allocate('%s', '%s'): allocating %zu bytes", m->guid, u->url, sizeof(REGISTRY_MACHINE_URL));
+REGISTRY_MACHINE_URL *registry_machine_url_find(REGISTRY_MACHINE *m, STRING *url) {
+ REGISTRY_MACHINE_URL *mu;
- REGISTRY_MACHINE_URL *mu = mallocz(sizeof(REGISTRY_MACHINE_URL));
+ for(mu = m->machine_urls; mu ;mu = mu->next)
+ if(mu->url == url)
+ break;
+
+ return mu;
+}
+
+void registry_machine_url_unlink_from_machine_and_free(REGISTRY_MACHINE *m, REGISTRY_MACHINE_URL *mu) {
+ DOUBLE_LINKED_LIST_REMOVE_ITEM_UNSAFE(m->machine_urls, mu, prev, next);
+ string_freez(mu->url);
+ aral_freez(registry.machine_urls_aral, mu);
+}
+
+REGISTRY_MACHINE_URL *registry_machine_url_allocate(REGISTRY_MACHINE *m, STRING *u, time_t when) {
+ netdata_log_debug(D_REGISTRY, "REGISTRY: registry_machine_url_allocate('%s', '%s'): allocating %zu bytes", m->guid, string2str(u), sizeof(REGISTRY_MACHINE_URL));
+
+ REGISTRY_MACHINE_URL *mu = aral_mallocz(registry.machine_urls_aral);
mu->first_t = mu->last_t = (uint32_t)when;
mu->usages = 1;
- mu->url = u;
+ mu->url = string_dup(u);
mu->flags = REGISTRY_URL_FLAGS_DEFAULT;
- registry.machines_urls_memory += sizeof(REGISTRY_MACHINE_URL);
-
- debug(D_REGISTRY, "registry_machine_url_allocate('%s', '%s'): indexing URL in machine", m->guid, u->url);
-
- registry.machines_urls_memory -= dictionary_stats_for_registry(m->machine_urls);
- dictionary_set(m->machine_urls, u->url, mu, sizeof(REGISTRY_MACHINE_URL));
- registry.machines_urls_memory += dictionary_stats_for_registry(m->machine_urls);
+ netdata_log_debug(D_REGISTRY, "REGISTRY: registry_machine_url_allocate('%s', '%s'): indexing URL in machine", m->guid, string2str(u));
- registry_url_link(u);
+ DOUBLE_LINKED_LIST_PREPEND_ITEM_UNSAFE(m->machine_urls, mu, prev, next);
return mu;
}
REGISTRY_MACHINE *registry_machine_allocate(const char *machine_guid, time_t when) {
- debug(D_REGISTRY, "Registry: registry_machine_allocate('%s'): creating new machine, sizeof(MACHINE)=%zu", machine_guid, sizeof(REGISTRY_MACHINE));
+ netdata_log_debug(D_REGISTRY, "REGISTRY: registry_machine_allocate('%s'): creating new machine, sizeof(MACHINE)=%zu", machine_guid, sizeof(REGISTRY_MACHINE));
- REGISTRY_MACHINE *m = mallocz(sizeof(REGISTRY_MACHINE));
+ REGISTRY_MACHINE *m = aral_mallocz(registry.machines_aral);
strncpyz(m->guid, machine_guid, GUID_LEN);
- debug(D_REGISTRY, "Registry: registry_machine_allocate('%s'): creating dictionary of urls", machine_guid);
- m->machine_urls = dictionary_create(REGISTRY_DICTIONARY_OPTIONS);
+ m->machine_urls = NULL;
m->first_t = m->last_t = (uint32_t)when;
m->usages = 0;
+ m->links = 0;
- registry.machines_memory += sizeof(REGISTRY_MACHINE);
registry.machines_count++;
- registry.machines_urls_memory -= dictionary_stats_for_registry(m->machine_urls);
dictionary_set(registry.machines, m->guid, m, sizeof(REGISTRY_MACHINE));
- registry.machines_urls_memory += dictionary_stats_for_registry(m->machine_urls);
return m;
}
@@ -60,14 +67,14 @@ REGISTRY_MACHINE *registry_machine_allocate(const char *machine_guid, time_t whe
// 1. validate machine GUID
// 2. if it is valid, find it or create it and return it
// 3. if it is not valid, return NULL
-REGISTRY_MACHINE *registry_machine_get(const char *machine_guid, time_t when) {
+REGISTRY_MACHINE *registry_machine_find_or_create(const char *machine_guid, time_t when, bool is_dummy __maybe_unused) {
REGISTRY_MACHINE *m = NULL;
if(likely(machine_guid && *machine_guid)) {
// validate it is a GUID
char buf[GUID_LEN + 1];
if(unlikely(regenerate_guid(machine_guid, buf) == -1))
- info("Registry: machine guid '%s' is not a valid guid. Ignoring it.", machine_guid);
+ netdata_log_info("REGISTRY: machine guid '%s' is not a valid guid. Ignoring it.", machine_guid);
else {
machine_guid = buf;
m = registry_machine_find(machine_guid);
@@ -82,17 +89,17 @@ REGISTRY_MACHINE *registry_machine_get(const char *machine_guid, time_t when) {
// ----------------------------------------------------------------------------
// LINKING OF OBJECTS
-REGISTRY_MACHINE_URL *registry_machine_link_to_url(REGISTRY_MACHINE *m, REGISTRY_URL *u, time_t when) {
- debug(D_REGISTRY, "registry_machine_link_to_url('%s', '%s'): searching for URL in machine", m->guid, u->url);
+REGISTRY_MACHINE_URL *registry_machine_link_to_url(REGISTRY_MACHINE *m, STRING *url, time_t when) {
+ netdata_log_debug(D_REGISTRY, "REGISTRY: registry_machine_link_to_url('%s', '%s'): searching for URL in machine", m->guid, string2str(url));
- REGISTRY_MACHINE_URL *mu = dictionary_get(m->machine_urls, u->url);
+ REGISTRY_MACHINE_URL *mu = registry_machine_url_find(m, url);
if(!mu) {
- debug(D_REGISTRY, "registry_machine_link_to_url('%s', '%s'): not found", m->guid, u->url);
- mu = registry_machine_url_allocate(m, u, when);
+ netdata_log_debug(D_REGISTRY, "REGISTRY: registry_machine_link_to_url('%s', '%s'): not found", m->guid, string2str(url));
+ mu = registry_machine_url_allocate(m, url, when);
registry.machines_urls_count++;
}
else {
- debug(D_REGISTRY, "registry_machine_link_to_url('%s', '%s'): found", m->guid, u->url);
+ netdata_log_debug(D_REGISTRY, "REGISTRY: registry_machine_link_to_url('%s', '%s'): found", m->guid, string2str(url));
mu->usages++;
if(likely(mu->last_t < (uint32_t)when)) mu->last_t = (uint32_t)when;
}
@@ -101,7 +108,7 @@ REGISTRY_MACHINE_URL *registry_machine_link_to_url(REGISTRY_MACHINE *m, REGISTRY
if(likely(m->last_t < (uint32_t)when)) m->last_t = (uint32_t)when;
if(mu->flags & REGISTRY_URL_FLAGS_EXPIRED) {
- debug(D_REGISTRY, "registry_machine_link_to_url('%s', '%s'): accessing an expired URL.", m->guid, u->url);
+ netdata_log_debug(D_REGISTRY, "REGISTRY: registry_machine_link_to_url('%s', '%s'): accessing an expired URL.", m->guid, string2str(url));
mu->flags &= ~REGISTRY_URL_FLAGS_EXPIRED;
}
diff --git a/registry/registry_machine.h b/registry/registry_machine.h
index bc95ecf69..4e8a407fe 100644
--- a/registry/registry_machine.h
+++ b/registry/registry_machine.h
@@ -10,13 +10,15 @@
// For each MACHINE-URL pair we keep this
struct registry_machine_url {
- REGISTRY_URL *url; // de-duplicated URL
+ STRING *url; // de-duplicated URL
uint8_t flags;
uint32_t first_t; // the first time we saw this
uint32_t last_t; // the last time we saw this
uint32_t usages; // how many times this has been accessed
+
+ struct registry_machine_url *prev, *next;
};
typedef struct registry_machine_url REGISTRY_MACHINE_URL;
@@ -26,7 +28,7 @@ struct registry_machine {
uint32_t links; // the number of REGISTRY_PERSON_URL linked to this machine
- DICTIONARY *machine_urls; // MACHINE_URL *
+ REGISTRY_MACHINE_URL *machine_urls; // MACHINE_URL *
uint32_t first_t; // the first time we saw this
uint32_t last_t; // the last time we saw this
@@ -35,9 +37,12 @@ struct registry_machine {
typedef struct registry_machine REGISTRY_MACHINE;
REGISTRY_MACHINE *registry_machine_find(const char *machine_guid);
-REGISTRY_MACHINE_URL *registry_machine_url_allocate(REGISTRY_MACHINE *m, REGISTRY_URL *u, time_t when);
+REGISTRY_MACHINE_URL *registry_machine_url_allocate(REGISTRY_MACHINE *m, STRING *u, time_t when);
REGISTRY_MACHINE *registry_machine_allocate(const char *machine_guid, time_t when);
-REGISTRY_MACHINE *registry_machine_get(const char *machine_guid, time_t when);
-REGISTRY_MACHINE_URL *registry_machine_link_to_url(REGISTRY_MACHINE *m, REGISTRY_URL *u, time_t when);
+REGISTRY_MACHINE *registry_machine_find_or_create(const char *machine_guid, time_t when, bool is_dummy);
+REGISTRY_MACHINE_URL *registry_machine_link_to_url(REGISTRY_MACHINE *m, STRING *url, time_t when);
+
+REGISTRY_MACHINE_URL *registry_machine_url_find(REGISTRY_MACHINE *m, STRING *url);
+void registry_machine_url_unlink_from_machine_and_free(REGISTRY_MACHINE *m, REGISTRY_MACHINE_URL *mu);
#endif //NETDATA_REGISTRY_MACHINE_H
diff --git a/registry/registry_person.c b/registry/registry_person.c
index 2f55e99d3..4fd40fd75 100644
--- a/registry/registry_person.c
+++ b/registry/registry_person.c
@@ -6,103 +6,78 @@
// ----------------------------------------------------------------------------
// PERSON_URL INDEX
-int person_url_compare(void *a, void *b) {
- register uint32_t hash1 = ((REGISTRY_PERSON_URL *)a)->url->hash;
- register uint32_t hash2 = ((REGISTRY_PERSON_URL *)b)->url->hash;
+inline REGISTRY_PERSON_URL *registry_person_url_index_find(REGISTRY_PERSON *p, STRING *url) {
+ netdata_log_debug(D_REGISTRY, "Registry: registry_person_url_index_find('%s', '%s')", p->guid, string2str(url));
- if(hash1 < hash2) return -1;
- else if(hash1 > hash2) return 1;
- else return strcmp(((REGISTRY_PERSON_URL *)a)->url->url, ((REGISTRY_PERSON_URL *)b)->url->url);
-}
-
-inline REGISTRY_PERSON_URL *registry_person_url_index_find(REGISTRY_PERSON *p, const char *url) {
- debug(D_REGISTRY, "Registry: registry_person_url_index_find('%s', '%s')", p->guid, url);
-
- char buf[sizeof(REGISTRY_URL) + strlen(url)];
-
- REGISTRY_URL *u = (REGISTRY_URL *)&buf;
- strcpy(u->url, url);
- u->hash = simple_hash(u->url);
+ REGISTRY_PERSON_URL *pu;
+ for(pu = p->person_urls ; pu ;pu = pu->next)
+ if(pu->url == url)
+ break;
- REGISTRY_PERSON_URL tpu = { .url = u };
-
- REGISTRY_PERSON_URL *pu = (REGISTRY_PERSON_URL *)avl_search(&p->person_urls, (void *)&tpu);
return pu;
}
inline REGISTRY_PERSON_URL *registry_person_url_index_add(REGISTRY_PERSON *p, REGISTRY_PERSON_URL *pu) {
- debug(D_REGISTRY, "Registry: registry_person_url_index_add('%s', '%s')", p->guid, pu->url->url);
- REGISTRY_PERSON_URL *tpu = (REGISTRY_PERSON_URL *)avl_insert(&(p->person_urls), (avl_t *)(pu));
- if(tpu != pu)
- error("Registry: registry_person_url_index_add('%s', '%s') already exists as '%s'", p->guid, pu->url->url, tpu->url->url);
-
- return tpu;
+ DOUBLE_LINKED_LIST_PREPEND_ITEM_UNSAFE(p->person_urls, pu, prev, next);
+ return pu;
}
inline REGISTRY_PERSON_URL *registry_person_url_index_del(REGISTRY_PERSON *p, REGISTRY_PERSON_URL *pu) {
- debug(D_REGISTRY, "Registry: registry_person_url_index_del('%s', '%s')", p->guid, pu->url->url);
- REGISTRY_PERSON_URL *tpu = (REGISTRY_PERSON_URL *)avl_remove(&(p->person_urls), (avl_t *)(pu));
- if(!tpu)
- error("Registry: registry_person_url_index_del('%s', '%s') deleted nothing", p->guid, pu->url->url);
- else if(tpu != pu)
- error("Registry: registry_person_url_index_del('%s', '%s') deleted wrong URL '%s'", p->guid, pu->url->url, tpu->url->url);
-
- return tpu;
+ DOUBLE_LINKED_LIST_REMOVE_ITEM_UNSAFE(p->person_urls, pu, prev, next);
+ return pu;
}
// ----------------------------------------------------------------------------
// PERSON_URL
-REGISTRY_PERSON_URL *registry_person_url_allocate(REGISTRY_PERSON *p, REGISTRY_MACHINE *m, REGISTRY_URL *u, char *name, size_t namelen, time_t when) {
- debug(D_REGISTRY, "registry_person_url_allocate('%s', '%s', '%s'): allocating %zu bytes", p->guid, m->guid, u->url, sizeof(REGISTRY_PERSON_URL) + namelen);
+REGISTRY_PERSON_URL *registry_person_url_allocate(REGISTRY_PERSON *p, REGISTRY_MACHINE *m, STRING *url, char *machine_name, size_t machine_name_len, time_t when) {
+ netdata_log_debug(D_REGISTRY, "registry_person_url_allocate('%s', '%s', '%s'): allocating %zu bytes", p->guid, m->guid, string2str(url), sizeof(REGISTRY_PERSON_URL) + machine_name_len);
// protection from too big names
- if(namelen > registry.max_name_length)
- namelen = registry.max_name_length;
+ if(machine_name_len > registry.max_name_length)
+ machine_name_len = registry.max_name_length;
- REGISTRY_PERSON_URL *pu = mallocz(sizeof(REGISTRY_PERSON_URL) + namelen);
+ REGISTRY_PERSON_URL *pu = aral_mallocz(registry.person_urls_aral);
- // a simple strcpy() should do the job
- // but I prefer to be safe, since the caller specified urllen
- strncpyz(pu->machine_name, name, namelen);
+ // a simple strcpy() should do the job,
+ // but I prefer to be safe, since the caller specified name_len
+ pu->machine_name = string_strdupz(machine_name);
pu->machine = m;
pu->first_t = pu->last_t = (uint32_t)when;
pu->usages = 1;
- pu->url = u;
+ pu->url = string_dup(url);
pu->flags = REGISTRY_URL_FLAGS_DEFAULT;
m->links++;
- registry.persons_urls_memory += sizeof(REGISTRY_PERSON_URL) + namelen;
-
- debug(D_REGISTRY, "registry_person_url_allocate('%s', '%s', '%s'): indexing URL in person", p->guid, m->guid, u->url);
+ netdata_log_debug(D_REGISTRY, "registry_person_url_allocate('%s', '%s', '%s'): indexing URL in person", p->guid, m->guid, string2str(url));
REGISTRY_PERSON_URL *tpu = registry_person_url_index_add(p, pu);
if(tpu != pu) {
- error("Registry: Attempted to add duplicate person url '%s' with name '%s' to person '%s'", u->url, name, p->guid);
- freez(pu);
+ netdata_log_error("Registry: Attempted to add duplicate person url '%s' with name '%s' to person '%s'", string2str(url), machine_name, p->guid);
+ string_freez(pu->machine_name);
+ string_freez(pu->url);
+ aral_freez(registry.person_urls_aral, pu);
pu = tpu;
}
- else
- registry_url_link(u);
return pu;
}
-void registry_person_url_free(REGISTRY_PERSON *p, REGISTRY_PERSON_URL *pu) {
- debug(D_REGISTRY, "registry_person_url_free('%s', '%s')", p->guid, pu->url->url);
+void registry_person_url_deindex_and_free(REGISTRY_PERSON *p, REGISTRY_PERSON_URL *pu) {
+ netdata_log_debug(D_REGISTRY, "registry_person_url_deindex_and_free('%s', '%s')", p->guid, string2str(pu->url));
REGISTRY_PERSON_URL *tpu = registry_person_url_index_del(p, pu);
if(tpu) {
- registry_url_unlink(tpu->url);
+ string_freez(tpu->machine_name);
+ string_freez(tpu->url);
tpu->machine->links--;
- registry.persons_urls_memory -= sizeof(REGISTRY_PERSON_URL) + strlen(tpu->machine_name);
- freez(tpu);
+ aral_freez(registry.person_urls_aral, tpu);
}
}
// this function is needed to change the name of a PERSON_URL
-REGISTRY_PERSON_URL *registry_person_url_reallocate(REGISTRY_PERSON *p, REGISTRY_MACHINE *m, REGISTRY_URL *u, char *name, size_t namelen, time_t when, REGISTRY_PERSON_URL *pu) {
- debug(D_REGISTRY, "registry_person_url_reallocate('%s', '%s', '%s'): allocating %zu bytes", p->guid, m->guid, u->url, sizeof(REGISTRY_PERSON_URL) + namelen);
+REGISTRY_PERSON_URL *registry_person_url_reallocate(REGISTRY_PERSON *p, REGISTRY_MACHINE *m, STRING *url, char *machine_name, size_t machine_name_len, time_t when, REGISTRY_PERSON_URL *pu) {
+ netdata_log_debug(D_REGISTRY, "registry_person_url_reallocate('%s', '%s', '%s'): allocating %zu bytes", p->guid, m->guid, string2str(url), sizeof(REGISTRY_PERSON_URL) + machine_name_len);
// keep a backup
REGISTRY_PERSON_URL pu2 = {
@@ -111,15 +86,15 @@ REGISTRY_PERSON_URL *registry_person_url_reallocate(REGISTRY_PERSON *p, REGISTRY
.usages = pu->usages,
.flags = pu->flags,
.machine = pu->machine,
- .machine_name = ""
+ .machine_name = NULL
};
// remove the existing one from the index
- registry_person_url_free(p, pu);
+ registry_person_url_deindex_and_free(p, pu);
pu = &pu2;
// allocate a new one
- REGISTRY_PERSON_URL *tpu = registry_person_url_allocate(p, m, u, name, namelen, when);
+ REGISTRY_PERSON_URL *tpu = registry_person_url_allocate(p, m, url, machine_name, machine_name_len, when);
tpu->first_t = pu->first_t;
tpu->last_t = pu->last_t;
tpu->usages = pu->usages;
@@ -133,40 +108,37 @@ REGISTRY_PERSON_URL *registry_person_url_reallocate(REGISTRY_PERSON *p, REGISTRY
// PERSON
REGISTRY_PERSON *registry_person_find(const char *person_guid) {
- debug(D_REGISTRY, "Registry: registry_person_find('%s')", person_guid);
+ netdata_log_debug(D_REGISTRY, "Registry: registry_person_find('%s')", person_guid);
return dictionary_get(registry.persons, person_guid);
}
REGISTRY_PERSON *registry_person_allocate(const char *person_guid, time_t when) {
- debug(D_REGISTRY, "Registry: registry_person_allocate('%s'): allocating new person, sizeof(PERSON)=%zu", (person_guid)?person_guid:"", sizeof(REGISTRY_PERSON));
+ netdata_log_debug(D_REGISTRY, "Registry: registry_person_allocate('%s'): allocating new person, sizeof(PERSON)=%zu", (person_guid)?person_guid:"", sizeof(REGISTRY_PERSON));
- REGISTRY_PERSON *p = mallocz(sizeof(REGISTRY_PERSON));
+ REGISTRY_PERSON *p = aral_mallocz(registry.persons_aral);
if(!person_guid) {
for(;;) {
uuid_t uuid;
uuid_generate(uuid);
uuid_unparse_lower(uuid, p->guid);
- debug(D_REGISTRY, "Registry: Checking if the generated person guid '%s' is unique", p->guid);
+ netdata_log_debug(D_REGISTRY, "Registry: Checking if the generated person guid '%s' is unique", p->guid);
if (!dictionary_get(registry.persons, p->guid)) {
- debug(D_REGISTRY, "Registry: generated person guid '%s' is unique", p->guid);
+ netdata_log_debug(D_REGISTRY, "Registry: generated person guid '%s' is unique", p->guid);
break;
}
else
- info("Registry: generated person guid '%s' found in the registry. Retrying...", p->guid);
+ netdata_log_info("Registry: generated person guid '%s' found in the registry. Retrying...", p->guid);
}
}
else
strncpyz(p->guid, person_guid, GUID_LEN);
- debug(D_REGISTRY, "Registry: registry_person_allocate('%s'): creating dictionary of urls", p->guid);
- avl_init(&p->person_urls, person_url_compare);
+ p->person_urls = NULL;
p->first_t = p->last_t = (uint32_t)when;
p->usages = 0;
- registry.persons_memory += sizeof(REGISTRY_PERSON);
-
registry.persons_count++;
dictionary_set(registry.persons, p->guid, p, sizeof(REGISTRY_PERSON));
@@ -178,23 +150,29 @@ REGISTRY_PERSON *registry_person_allocate(const char *person_guid, time_t when)
// 2. if it is valid, find it
// 3. if it is not valid, create a new one
// 4. return it
-REGISTRY_PERSON *registry_person_get(const char *person_guid, time_t when) {
- debug(D_REGISTRY, "Registry: registry_person_get('%s'): creating dictionary of urls", person_guid);
+REGISTRY_PERSON *registry_person_find_or_create(const char *person_guid, time_t when, bool is_dummy) {
+ netdata_log_debug(D_REGISTRY, "Registry: registry_person_find_or_create('%s'): creating dictionary of urls", person_guid);
+ char buf[GUID_LEN + 1];
REGISTRY_PERSON *p = NULL;
if(person_guid && *person_guid) {
- char buf[GUID_LEN + 1];
// validate it is a GUID
- if(unlikely(regenerate_guid(person_guid, buf) == -1))
- info("Registry: person guid '%s' is not a valid guid. Ignoring it.", person_guid);
+ if(unlikely(regenerate_guid(person_guid, buf) == -1)) {
+ netdata_log_info("Registry: person guid '%s' is not a valid guid. Ignoring it.", person_guid);
+ person_guid = NULL;
+ }
else {
person_guid = buf;
p = registry_person_find(person_guid);
+ if(!p && !is_dummy)
+ person_guid = NULL;
}
}
+ else
+ person_guid = NULL;
- if(!p) p = registry_person_allocate(NULL, when);
+ if(!p) p = registry_person_allocate(person_guid, when);
return p;
}
@@ -202,39 +180,39 @@ REGISTRY_PERSON *registry_person_get(const char *person_guid, time_t when) {
// ----------------------------------------------------------------------------
// LINKING OF OBJECTS
-REGISTRY_PERSON_URL *registry_person_link_to_url(REGISTRY_PERSON *p, REGISTRY_MACHINE *m, REGISTRY_URL *u, char *name, size_t namelen, time_t when) {
- debug(D_REGISTRY, "registry_person_link_to_url('%s', '%s', '%s'): searching for URL in person", p->guid, m->guid, u->url);
+REGISTRY_PERSON_URL *registry_person_link_to_url(REGISTRY_PERSON *p, REGISTRY_MACHINE *m, STRING *url, char *machine_name, size_t machine_name_len, time_t when) {
+ netdata_log_debug(D_REGISTRY, "registry_person_link_to_url('%s', '%s', '%s'): searching for URL in person", p->guid, m->guid, string2str(url));
- REGISTRY_PERSON_URL *pu = registry_person_url_index_find(p, u->url);
+ REGISTRY_PERSON_URL *pu = registry_person_url_index_find(p, url);
if(!pu) {
- debug(D_REGISTRY, "registry_person_link_to_url('%s', '%s', '%s'): not found", p->guid, m->guid, u->url);
- pu = registry_person_url_allocate(p, m, u, name, namelen, when);
+ netdata_log_debug(D_REGISTRY, "registry_person_link_to_url('%s', '%s', '%s'): not found", p->guid, m->guid, string2str(url));
+ pu = registry_person_url_allocate(p, m, url, machine_name, machine_name_len, when);
registry.persons_urls_count++;
}
else {
- debug(D_REGISTRY, "registry_person_link_to_url('%s', '%s', '%s'): found", p->guid, m->guid, u->url);
+ netdata_log_debug(D_REGISTRY, "registry_person_link_to_url('%s', '%s', '%s'): found", p->guid, m->guid, string2str(url));
pu->usages++;
if(likely(pu->last_t < (uint32_t)when)) pu->last_t = (uint32_t)when;
if(pu->machine != m) {
- REGISTRY_MACHINE_URL *mu = dictionary_get(pu->machine->machine_urls, u->url);
+ REGISTRY_MACHINE_URL *mu = registry_machine_url_find(pu->machine, url);
if(mu) {
- debug(D_REGISTRY, "registry_person_link_to_url('%s', '%s', '%s'): URL switched machines (old was '%s') - expiring it from previous machine.",
- p->guid, m->guid, u->url, pu->machine->guid);
+ netdata_log_debug(D_REGISTRY, "registry_person_link_to_url('%s', '%s', '%s'): URL switched machines (old was '%s') - expiring it from previous machine.",
+ p->guid, m->guid, string2str(url), pu->machine->guid);
mu->flags |= REGISTRY_URL_FLAGS_EXPIRED;
}
else {
- debug(D_REGISTRY, "registry_person_link_to_url('%s', '%s', '%s'): URL switched machines (old was '%s') - but the URL is not linked to the old machine.",
- p->guid, m->guid, u->url, pu->machine->guid);
+ netdata_log_debug(D_REGISTRY, "registry_person_link_to_url('%s', '%s', '%s'): URL switched machines (old was '%s') - but the URL is not linked to the old machine.",
+ p->guid, m->guid, string2str(url), pu->machine->guid);
}
pu->machine->links--;
pu->machine = m;
}
- if(strcmp(pu->machine_name, name) != 0) {
+ if(strcmp(string2str(pu->machine_name), machine_name) != 0) {
// the name of the PERSON_URL has changed !
- pu = registry_person_url_reallocate(p, m, u, name, namelen, when, pu);
+ pu = registry_person_url_reallocate(p, m, url, machine_name, machine_name_len, when, pu);
}
}
@@ -242,7 +220,7 @@ REGISTRY_PERSON_URL *registry_person_link_to_url(REGISTRY_PERSON *p, REGISTRY_MA
if(likely(p->last_t < (uint32_t)when)) p->last_t = (uint32_t)when;
if(pu->flags & REGISTRY_URL_FLAGS_EXPIRED) {
- debug(D_REGISTRY, "registry_person_link_to_url('%s', '%s', '%s'): accessing an expired URL. Re-enabling URL.", p->guid, m->guid, u->url);
+ netdata_log_debug(D_REGISTRY, "registry_person_link_to_url('%s', '%s', '%s'): accessing an expired URL. Re-enabling URL.", p->guid, m->guid, string2str(url));
pu->flags &= ~REGISTRY_URL_FLAGS_EXPIRED;
}
@@ -250,5 +228,5 @@ REGISTRY_PERSON_URL *registry_person_link_to_url(REGISTRY_PERSON *p, REGISTRY_MA
}
void registry_person_unlink_from_url(REGISTRY_PERSON *p, REGISTRY_PERSON_URL *pu) {
- registry_person_url_free(p, pu);
+ registry_person_url_deindex_and_free(p, pu);
}
diff --git a/registry/registry_person.h b/registry/registry_person.h
index 674596be6..4c2ca710f 100644
--- a/registry/registry_person.h
+++ b/registry/registry_person.h
@@ -10,19 +10,18 @@
// for each PERSON-URL pair we keep this
struct registry_person_url {
- avl_t avl; // binary tree node
-
- REGISTRY_URL *url; // de-duplicated URL
- REGISTRY_MACHINE *machine; // link the MACHINE of this URL
-
uint8_t flags;
+ uint32_t usages; // how many times this has been accessed
+
uint32_t first_t; // the first time we saw this
uint32_t last_t; // the last time we saw this
- uint32_t usages; // how many times this has been accessed
- char machine_name[1]; // the name of the machine, as known by the user
- // dynamically allocated to fit properly
+ REGISTRY_MACHINE *machine; // link the MACHINE of this URL
+ STRING *machine_name; // the hostname of the machine
+ STRING *url; // de-duplicated URL
+
+ struct registry_person_url *prev, *next;
};
typedef struct registry_person_url REGISTRY_PERSON_URL;
@@ -30,32 +29,29 @@ typedef struct registry_person_url REGISTRY_PERSON_URL;
struct registry_person {
char guid[GUID_LEN + 1]; // the person GUID
- avl_tree_type person_urls; // dictionary of PERSON_URLs
+ REGISTRY_PERSON_URL *person_urls; // dictionary of PERSON_URLs
uint32_t first_t; // the first time we saw this
uint32_t last_t; // the last time we saw this
uint32_t usages; // how many times this has been accessed
-
- //uint32_t flags;
- //char *email;
};
typedef struct registry_person REGISTRY_PERSON;
// PERSON_URL
-REGISTRY_PERSON_URL *registry_person_url_index_find(REGISTRY_PERSON *p, const char *url);
+REGISTRY_PERSON_URL *registry_person_url_index_find(REGISTRY_PERSON *p, STRING *url);
REGISTRY_PERSON_URL *registry_person_url_index_add(REGISTRY_PERSON *p, REGISTRY_PERSON_URL *pu) NEVERNULL WARNUNUSED;
REGISTRY_PERSON_URL *registry_person_url_index_del(REGISTRY_PERSON *p, REGISTRY_PERSON_URL *pu) WARNUNUSED;
-REGISTRY_PERSON_URL *registry_person_url_allocate(REGISTRY_PERSON *p, REGISTRY_MACHINE *m, REGISTRY_URL *u, char *name, size_t namelen, time_t when);
-REGISTRY_PERSON_URL *registry_person_url_reallocate(REGISTRY_PERSON *p, REGISTRY_MACHINE *m, REGISTRY_URL *u, char *name, size_t namelen, time_t when, REGISTRY_PERSON_URL *pu);
+REGISTRY_PERSON_URL *registry_person_url_allocate(REGISTRY_PERSON *p, REGISTRY_MACHINE *m, STRING *url, char *machine_name, size_t machine_name_len, time_t when);
+REGISTRY_PERSON_URL *registry_person_url_reallocate(REGISTRY_PERSON *p, REGISTRY_MACHINE *m, STRING *url, char *machine_name, size_t machine_name_len, time_t when, REGISTRY_PERSON_URL *pu);
// PERSON
REGISTRY_PERSON *registry_person_find(const char *person_guid);
REGISTRY_PERSON *registry_person_allocate(const char *person_guid, time_t when);
-REGISTRY_PERSON *registry_person_get(const char *person_guid, time_t when);
+REGISTRY_PERSON *registry_person_find_or_create(const char *person_guid, time_t when, bool is_dummy);
// LINKING PERSON -> PERSON_URL
-REGISTRY_PERSON_URL *registry_person_link_to_url(REGISTRY_PERSON *p, REGISTRY_MACHINE *m, REGISTRY_URL *u, char *name, size_t namelen, time_t when);
+REGISTRY_PERSON_URL *registry_person_link_to_url(REGISTRY_PERSON *p, REGISTRY_MACHINE *m, STRING *url, char *machine_name, size_t machine_name_len, time_t when);
void registry_person_unlink_from_url(REGISTRY_PERSON *p, REGISTRY_PERSON_URL *pu);
#endif //NETDATA_REGISTRY_PERSON_H
diff --git a/registry/registry_url.c b/registry/registry_url.c
deleted file mode 100644
index 699e5e680..000000000
--- a/registry/registry_url.c
+++ /dev/null
@@ -1,88 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#include "daemon/common.h"
-#include "registry_internals.h"
-
-// ----------------------------------------------------------------------------
-// REGISTRY_URL
-
-int registry_url_compare(void *a, void *b) {
- if(((REGISTRY_URL *)a)->hash < ((REGISTRY_URL *)b)->hash) return -1;
- else if(((REGISTRY_URL *)a)->hash > ((REGISTRY_URL *)b)->hash) return 1;
- else return strcmp(((REGISTRY_URL *)a)->url, ((REGISTRY_URL *)b)->url);
-}
-
-inline REGISTRY_URL *registry_url_index_add(REGISTRY_URL *u) {
- return (REGISTRY_URL *)avl_insert(&(registry.registry_urls_root_index), (avl_t *)(u));
-}
-
-inline REGISTRY_URL *registry_url_index_del(REGISTRY_URL *u) {
- return (REGISTRY_URL *)avl_remove(&(registry.registry_urls_root_index), (avl_t *)(u));
-}
-
-REGISTRY_URL *registry_url_get(const char *url, size_t urllen) {
- // protection from too big URLs
- if(urllen > registry.max_url_length)
- urllen = registry.max_url_length;
-
- debug(D_REGISTRY, "Registry: registry_url_get('%s', %zu)", url, urllen);
-
- char buf[sizeof(REGISTRY_URL) + urllen]; // no need for +1, 1 is already in REGISTRY_URL
- REGISTRY_URL *n = (REGISTRY_URL *)&buf[0];
- n->len = (uint16_t)urllen;
- strncpyz(n->url, url, n->len);
- n->hash = simple_hash(n->url);
-
- REGISTRY_URL *u = (REGISTRY_URL *)avl_search(&(registry.registry_urls_root_index), (avl_t *)n);
- if(!u) {
- debug(D_REGISTRY, "Registry: registry_url_get('%s', %zu): allocating %zu bytes", url, urllen, sizeof(REGISTRY_URL) + urllen);
- u = callocz(1, sizeof(REGISTRY_URL) + urllen); // no need for +1, 1 is already in REGISTRY_URL
-
- // a simple strcpy() should do the job
- // but I prefer to be safe, since the caller specified urllen
- u->len = (uint16_t)urllen;
- strncpyz(u->url, url, u->len);
- u->links = 0;
- u->hash = simple_hash(u->url);
-
- registry.urls_memory += sizeof(REGISTRY_URL) + urllen; // no need for +1, 1 is already in REGISTRY_URL
-
- debug(D_REGISTRY, "Registry: registry_url_get('%s'): indexing it", url);
- n = registry_url_index_add(u);
- if(n != u) {
- error("INTERNAL ERROR: registry_url_get(): url '%s' already exists in the registry as '%s'", u->url, n->url);
- freez(u);
- u = n;
- }
- else
- registry.urls_count++;
- }
-
- return u;
-}
-
-void registry_url_link(REGISTRY_URL *u) {
- u->links++;
- debug(D_REGISTRY, "Registry: registry_url_link('%s'): URL has now %u links", u->url, u->links);
-}
-
-void registry_url_unlink(REGISTRY_URL *u) {
- u->links--;
- if(!u->links) {
- debug(D_REGISTRY, "Registry: registry_url_unlink('%s'): No more links for this URL", u->url);
- REGISTRY_URL *n = registry_url_index_del(u);
- if(!n) {
- error("INTERNAL ERROR: registry_url_unlink('%s'): cannot find url in index", u->url);
- }
- else {
- if(n != u) {
- error("INTERNAL ERROR: registry_url_unlink('%s'): deleted different url '%s'", u->url, n->url);
- }
-
- registry.urls_memory -= sizeof(REGISTRY_URL) + n->len; // no need for +1, 1 is already in REGISTRY_URL
- freez(n);
- }
- }
- else
- debug(D_REGISTRY, "Registry: registry_url_unlink('%s'): URL has %u links left", u->url, u->links);
-}
diff --git a/registry/registry_url.h b/registry/registry_url.h
deleted file mode 100644
index 8ba0391bc..000000000
--- a/registry/registry_url.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#ifndef NETDATA_REGISTRY_URL_H
-#define NETDATA_REGISTRY_URL_H 1
-
-#include "registry_internals.h"
-
-// ----------------------------------------------------------------------------
-// URL structures
-// Save memory by de-duplicating URLs
-// so instead of storing URLs all over the place
-// we store them here and we keep pointers elsewhere
-
-struct registry_url {
- avl_t avl;
- uint32_t hash; // the index hash
-
- uint32_t links; // the number of links to this URL - when none is left, we free it
-
- uint16_t len; // the length of the URL in bytes
- char url[1]; // the URL - dynamically allocated to more size
-};
-typedef struct registry_url REGISTRY_URL;
-
-// REGISTRY_URL INDEX
-int registry_url_compare(void *a, void *b);
-REGISTRY_URL *registry_url_index_del(REGISTRY_URL *u) WARNUNUSED;
-REGISTRY_URL *registry_url_index_add(REGISTRY_URL *u) NEVERNULL WARNUNUSED;
-
-// REGISTRY_URL MANAGEMENT
-REGISTRY_URL *registry_url_get(const char *url, size_t urllen) NEVERNULL;
-void registry_url_link(REGISTRY_URL *u);
-void registry_url_unlink(REGISTRY_URL *u);
-
-#endif //NETDATA_REGISTRY_URL_H