diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2021-05-19 12:33:38 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2021-05-19 12:33:59 +0000 |
commit | 1ee0c09c5742557e037df5421ca62abddb90ae22 (patch) | |
tree | 71c0fa48bb6d31d036c9badd7e038527f90d1a73 /database/sqlite | |
parent | Releasing debian version 1.30.1-1. (diff) | |
download | netdata-1ee0c09c5742557e037df5421ca62abddb90ae22.tar.xz netdata-1ee0c09c5742557e037df5421ca62abddb90ae22.zip |
Merging upstream version 1.31.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'database/sqlite')
-rw-r--r-- | database/sqlite/sqlite_functions.c | 297 | ||||
-rw-r--r-- | database/sqlite/sqlite_functions.h | 17 |
2 files changed, 313 insertions, 1 deletions
diff --git a/database/sqlite/sqlite_functions.c b/database/sqlite/sqlite_functions.c index 694b8633..382ed8b0 100644 --- a/database/sqlite/sqlite_functions.c +++ b/database/sqlite/sqlite_functions.c @@ -19,7 +19,7 @@ const char *database_config[] = { "CREATE INDEX IF NOT EXISTS ind_c1 on chart (host_id, id, type, name);", "CREATE TABLE IF NOT EXISTS chart_label(chart_id blob, source_type int, label_key text, " "label_value text, date_created int, PRIMARY KEY (chart_id, label_key));", - + "CREATE TABLE IF NOT EXISTS node_instance (host_id blob PRIMARY KEY, claim_id, node_id, date_created);", "delete from chart_active;", "delete from dimension_active;", "delete from chart where chart_id not in (select chart_id from dimension);", @@ -1338,3 +1338,298 @@ failed: #endif return; } + +#define SQL_STORE_CLAIM_ID "insert into node_instance " \ + "(host_id, claim_id, date_created) values (@host_id, @claim_id, strftime('%s')) " \ + "on conflict(host_id) do update set claim_id = excluded.claim_id;" + +void store_claim_id(uuid_t *host_id, uuid_t *claim_id) +{ + sqlite3_stmt *res = NULL; + int rc; + + if (unlikely(!db_meta)) { + if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE) + error_report("Database has not been initialized"); + return; + } + + rc = sqlite3_prepare_v2(db_meta, SQL_STORE_CLAIM_ID, -1, &res, 0); + if (unlikely(rc != SQLITE_OK)) { + error_report("Failed to prepare statement store chart labels"); + return; + } + + rc = sqlite3_bind_blob(res, 1, host_id, sizeof(*host_id), SQLITE_STATIC); + if (unlikely(rc != SQLITE_OK)) { + error_report("Failed to bind host_id parameter to store node instance information"); + goto failed; + } + + if (claim_id) + rc = sqlite3_bind_blob(res, 2, claim_id, sizeof(*claim_id), SQLITE_STATIC); + else + rc = sqlite3_bind_null(res, 2); + if (unlikely(rc != SQLITE_OK)) { + error_report("Failed to bind claim_id parameter to store node instance information"); + goto failed; + } + + rc = execute_insert(res); + if (unlikely(rc != SQLITE_DONE)) + error_report("Failed to store node instance information, rc = %d", rc); + +failed: + if (unlikely(sqlite3_finalize(res) != SQLITE_OK)) + error_report("Failed to finalize the prepared statement when storing node instance information"); + + return; +} + +static inline void set_host_node_id(RRDHOST *host, uuid_t *node_id) +{ + if (unlikely(!host)) + return; + + if (unlikely(!node_id)) { + freez(host->node_id); + host->node_id = NULL; + return; + } + + if (unlikely(!host->node_id)) + host->node_id = mallocz(sizeof(*host->node_id)); + uuid_copy(*(host->node_id), *node_id); + return; +} + +#define SQL_UPDATE_NODE_ID "update node_instance set node_id = @node_id where host_id = @host_id;" + +int update_node_id(uuid_t *host_id, uuid_t *node_id) +{ + sqlite3_stmt *res = NULL; + RRDHOST *host = NULL; + int rc = 2; + + if (unlikely(!db_meta)) { + if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE) + error_report("Database has not been initialized"); + return 1; + } + + rc = sqlite3_prepare_v2(db_meta, SQL_UPDATE_NODE_ID, -1, &res, 0); + if (unlikely(rc != SQLITE_OK)) { + error_report("Failed to prepare statement to store node instance information"); + return 1; + } + + rc = sqlite3_bind_blob(res, 1, node_id, sizeof(*node_id), SQLITE_STATIC); + if (unlikely(rc != SQLITE_OK)) { + error_report("Failed to bind host_id parameter to store node instance information"); + goto failed; + } + + rc = sqlite3_bind_blob(res, 2, host_id, sizeof(*host_id), SQLITE_STATIC); + if (unlikely(rc != SQLITE_OK)) { + error_report("Failed to bind host_id parameter to store node instance information"); + goto failed; + } + + rc = execute_insert(res); + if (unlikely(rc != SQLITE_DONE)) + error_report("Failed to store node instance information, rc = %d", rc); + rc = sqlite3_changes(db_meta); + + char host_guid[GUID_LEN + 1]; + uuid_unparse_lower(*host_id, host_guid); + rrd_wrlock(); + host = rrdhost_find_by_guid(host_guid, 0); + if (likely(host)) + set_host_node_id(host, node_id); + rrd_unlock(); + +failed: + if (unlikely(sqlite3_finalize(res) != SQLITE_OK)) + error_report("Failed to finalize the prepared statement when storing node instance information"); + + return rc - 1; +} + +#define SQL_SELECT_NODE_ID "select node_id from node_instance where host_id = @host_id and node_id not null;" + +int get_node_id(uuid_t *host_id, uuid_t *node_id) +{ + sqlite3_stmt *res = NULL; + int rc; + + if (unlikely(!db_meta)) { + if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE) + error_report("Database has not been initialized"); + return 1; + } + + rc = sqlite3_prepare_v2(db_meta, SQL_SELECT_NODE_ID, -1, &res, 0); + if (unlikely(rc != SQLITE_OK)) { + error_report("Failed to prepare statement to select node instance information for a host"); + return 1; + } + + rc = sqlite3_bind_blob(res, 1, host_id, sizeof(*host_id), SQLITE_STATIC); + if (unlikely(rc != SQLITE_OK)) { + error_report("Failed to bind host_id parameter to select node instance information"); + goto failed; + } + + rc = sqlite3_step(res); + if (likely(rc == SQLITE_ROW && node_id)) + uuid_copy(*node_id, *((uuid_t *) sqlite3_column_blob(res, 0))); + +failed: + if (unlikely(sqlite3_finalize(res) != SQLITE_OK)) + error_report("Failed to finalize the prepared statement when selecting node instance information"); + + return (rc == SQLITE_ROW) ? 0 : -1; +} + +#define SQL_INVALIDATE_NODE_INSTANCES "update node_instance set node_id = NULL where exists " \ + "(select host_id from node_instance where host_id = @host_id and (@claim_id is null or claim_id <> @claim_id));" + +void invalidate_node_instances(uuid_t *host_id, uuid_t *claim_id) +{ + sqlite3_stmt *res = NULL; + int rc; + + if (unlikely(!db_meta)) { + if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE) + error_report("Database has not been initialized"); + return; + } + + rc = sqlite3_prepare_v2(db_meta, SQL_INVALIDATE_NODE_INSTANCES, -1, &res, 0); + if (unlikely(rc != SQLITE_OK)) { + error_report("Failed to prepare statement to invalidate node instance ids"); + return; + } + + rc = sqlite3_bind_blob(res, 1, host_id, sizeof(*host_id), SQLITE_STATIC); + if (unlikely(rc != SQLITE_OK)) { + error_report("Failed to bind host_id parameter to invalidate node instance information"); + goto failed; + } + + if (claim_id) + rc = sqlite3_bind_blob(res, 2, claim_id, sizeof(*claim_id), SQLITE_STATIC); + else + rc = sqlite3_bind_null(res, 2); + + if (unlikely(rc != SQLITE_OK)) { + error_report("Failed to bind claim_id parameter to invalidate node instance information"); + goto failed; + } + + rc = execute_insert(res); + if (unlikely(rc != SQLITE_DONE)) + error_report("Failed to invalidate node instance information, rc = %d", rc); + +failed: + if (unlikely(sqlite3_finalize(res) != SQLITE_OK)) + error_report("Failed to finalize the prepared statement when invalidating node instance information"); +} + +#define SQL_GET_NODE_INSTANCE_LIST "select ni.node_id, ni.host_id, h.hostname " \ + "from node_instance ni, host h where ni.host_id = h.host_id;" + +struct node_instance_list *get_node_list(void) +{ + struct node_instance_list *node_list = NULL; + sqlite3_stmt *res = NULL; + int rc; + + if (unlikely(!db_meta)) { + if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE) + error_report("Database has not been initialized"); + return NULL; + } + + rc = sqlite3_prepare_v2(db_meta, SQL_GET_NODE_INSTANCE_LIST, -1, &res, 0); + if (unlikely(rc != SQLITE_OK)) { + error_report("Failed to prepare statement store chart labels"); + return NULL; + }; + + int row = 0; + char host_guid[37]; + while (sqlite3_step(res) == SQLITE_ROW) + row++; + + if (sqlite3_reset(res) != SQLITE_OK) { + error_report("Failed to reset the prepared statement fetching storing node instance information"); + goto failed; + } + node_list = callocz(row + 1, sizeof(*node_list)); + int max_rows = row; + row = 0; + while (sqlite3_step(res) == SQLITE_ROW) { + if (sqlite3_column_bytes(res, 0) == sizeof(uuid_t)) + uuid_copy(node_list[row].node_id, *((uuid_t *)sqlite3_column_blob(res, 0))); + if (sqlite3_column_bytes(res, 1) == sizeof(uuid_t)) { + uuid_t *host_id = (uuid_t *)sqlite3_column_blob(res, 1); + uuid_copy(node_list[row].host_id, *host_id); + node_list[row].querable = 1; + uuid_unparse_lower(*host_id, host_guid); + node_list[row].live = rrdhost_find_by_guid(host_guid, 0) ? 1 : 0; + node_list[row].hops = uuid_compare(*host_id, localhost->host_uuid) ? 1 : 0; + node_list[row].hostname = + sqlite3_column_bytes(res, 2) ? strdupz((char *)sqlite3_column_text(res, 2)) : NULL; + } + row++; + if (row == max_rows) + break; + } + +failed: + if (unlikely(sqlite3_finalize(res) != SQLITE_OK)) + error_report("Failed to finalize the prepared statement when storing node instance information"); + + return node_list; +}; + +#define SQL_GET_HOST_NODE_ID "select node_id from node_instance where host_id = @host_id;" + +void sql_load_node_id(RRDHOST *host) +{ + sqlite3_stmt *res = NULL; + int rc; + + if (unlikely(!db_meta)) { + if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE) + error_report("Database has not been initialized"); + return; + } + + rc = sqlite3_prepare_v2(db_meta, SQL_GET_HOST_NODE_ID, -1, &res, 0); + if (unlikely(rc != SQLITE_OK)) { + error_report("Failed to prepare statement store chart labels"); + return; + }; + + rc = sqlite3_bind_blob(res, 1, &host->host_uuid, sizeof(host->host_uuid), SQLITE_STATIC); + if (unlikely(rc != SQLITE_OK)) { + error_report("Failed to bind host_id parameter to store node instance information"); + goto failed; + } + + rc = sqlite3_step(res); + if (likely(rc == SQLITE_ROW)) { + if (likely(sqlite3_column_bytes(res, 0) == sizeof(uuid_t))) + set_host_node_id(host, (uuid_t *)sqlite3_column_blob(res, 0)); + else + set_host_node_id(host, NULL); + } + +failed: + if (unlikely(sqlite3_finalize(res) != SQLITE_OK)) + error_report("Failed to finalize the prepared statement when storing node instance information"); + + return; +}; diff --git a/database/sqlite/sqlite_functions.h b/database/sqlite/sqlite_functions.h index d2bee75d..30a52bf7 100644 --- a/database/sqlite/sqlite_functions.h +++ b/database/sqlite/sqlite_functions.h @@ -6,6 +6,17 @@ #include "../../daemon/common.h" #include "sqlite3.h" +// return a node list +struct node_instance_list { + uuid_t node_id; + uuid_t host_id; + char *hostname; + int live; + int querable; + int hops; +}; + + #define SQLITE_INSERT_DELAY (50) // Insert delay in case of lock #define SQL_STORE_HOST "insert or replace into host (host_id,hostname,registry_hostname,update_every,os,timezone,tags) values (?1,?2,?3,?4,?5,?6,?7);" @@ -60,4 +71,10 @@ extern void db_lock(void); extern void delete_dimension_uuid(uuid_t *dimension_uuid); extern void sql_store_chart_label(uuid_t *chart_uuid, int source_type, char *label, char *value); extern void sql_build_context_param_list(struct context_param **param_list, RRDHOST *host, char *context, char *chart); +extern void store_claim_id(uuid_t *host_id, uuid_t *claim_id); +extern int update_node_id(uuid_t *host_id, uuid_t *node_id); +extern int get_node_id(uuid_t *host_id, uuid_t *node_id); +extern void invalidate_node_instances(uuid_t *host_id, uuid_t *claim_id); +extern struct node_instance_list *get_node_list(void); +extern void sql_load_node_id(RRDHOST *host); #endif //NETDATA_SQLITE_FUNCTIONS_H |