Add functionality to store node_id for a host (#11059)
Stelios Fragkakis committed
Apr 29, 2021 at 23:02 UTC
ece7c8df644ae897052f00b60241b0f20b30cd4d
5 files changed
+268
claim/claim.c
+1
@@ -165,6 +165,7 @@ void load_claiming_state(void)
165
}
166
localhost->aclk_state.claimed_id = claimed_id;
167
168
+ invalidate_node_instances(&localhost->host_uuid, claimed_id ? &uuid : NULL);
169
store_claim_id(&localhost->host_uuid, claimed_id ? &uuid : NULL);
170
171
rrdhost_aclk_state_unlock(localhost);
database/rrd.h
+1
@@ -879,6 +879,7 @@ struct rrdhost {
879
struct rrdengine_instance *rrdeng_ctx; // DB engine instance for this host
880
#endif
881
uuid_t host_uuid; // Global GUID for this host
882
+ uuid_t *node_id; // Cloud node_id
883
884
#ifdef ENABLE_HTTPS
885
struct netdata_ssl ssl; //Structure used to encrypt the connection
database/rrdhost.c
+2
@@ -302,6 +302,7 @@ RRDHOST *rrdhost_create(const char *hostname,
302
int rc = sql_store_host(&host->host_uuid, hostname, registry_hostname, update_every, os, timezone, tags);
303
if (unlikely(rc))
304
error_report("Failed to store machine GUID to the database");
305
+ sql_load_node_id(host);
306
}
307
else
308
error_report("Host machine GUID %s is not valid", host->machine_guid);
@@ -899,6 +900,7 @@ void rrdhost_free(RRDHOST *host) {
900
netdata_rwlock_destroy(&host->labels.labels_rwlock);
901
netdata_rwlock_destroy(&host->health_log.alarm_log_rwlock);
902
netdata_rwlock_destroy(&host->rrdhost_rwlock);
903
+ freez(host->node_id);
904
905
freez(host);
906
database/sqlite/sqlite_functions.c
+248
@@ -1385,3 +1385,251 @@ failed:
1385
1386
return;
1387
}
1388
+
1389
+static inline void set_host_node_id(RRDHOST *host, uuid_t *node_id)
1390
+{
1391
+ if (unlikely(!host))
1392
+ return;
1393
+
1394
+ if (unlikely(!node_id)) {
1395
+ freez(host->node_id);
1396
+ host->node_id = NULL;
1397
+ return;
1398
+ }
1399
+
1400
+ if (unlikely(!host->node_id))
1401
+ host->node_id = mallocz(sizeof(*host->node_id));
1402
+ uuid_copy(*(host->node_id), *node_id);
1403
+ return;
1404
+}
1405
+
1406
+#define SQL_UPDATE_NODE_ID "update node_instance set node_id = @node_id where host_id = @host_id;"
1407
+
1408
+int update_node_id(uuid_t *host_id, uuid_t *node_id)
1409
+{
1410
+ sqlite3_stmt *res = NULL;
1411
+ RRDHOST *host = NULL;
1412
+ int rc = 2;
1413
+
1414
+ if (unlikely(!db_meta)) {
1415
+ if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)
1416
+ error_report("Database has not been initialized");
1417
+ return 1;
1418
+ }
1419
+
1420
+ rc = sqlite3_prepare_v2(db_meta, SQL_UPDATE_NODE_ID, -1, &res, 0);
1421
+ if (unlikely(rc != SQLITE_OK)) {
1422
+ error_report("Failed to prepare statement to store node instance information");
1423
+ return 1;
1424
+ }
1425
+
1426
+ rc = sqlite3_bind_blob(res, 1, node_id, sizeof(*node_id), SQLITE_STATIC);
1427
+ if (unlikely(rc != SQLITE_OK)) {
1428
+ error_report("Failed to bind host_id parameter to store node instance information");
1429
+ goto failed;
1430
+ }
1431
+
1432
+ rc = sqlite3_bind_blob(res, 2, host_id, sizeof(*host_id), SQLITE_STATIC);
1433
+ if (unlikely(rc != SQLITE_OK)) {
1434
+ error_report("Failed to bind host_id parameter to store node instance information");
1435
+ goto failed;
1436
+ }
1437
+
1438
+ rc = execute_insert(res);
1439
+ if (unlikely(rc != SQLITE_DONE))
1440
+ error_report("Failed to store node instance information, rc = %d", rc);
1441
+ rc = sqlite3_changes(db_meta);
1442
+
1443
+ char host_guid[GUID_LEN + 1];
1444
+ uuid_unparse_lower(*host_id, host_guid);
1445
+ rrd_wrlock();
1446
+ host = rrdhost_find_by_guid(host_guid, 0);
1447
+ if (likely(host))
1448
+ set_host_node_id(host, node_id);
1449
+ rrd_unlock();
1450
+
1451
+failed:
1452
+ if (unlikely(sqlite3_finalize(res) != SQLITE_OK))
1453
+ error_report("Failed to finalize the prepared statement when storing node instance information");
1454
+
1455
+ return rc - 1;
1456
+}
1457
+
1458
+#define SQL_SELECT_NODE_ID "select node_id from node_instance where host_id = @host_id and node_id not null;"
1459
+
1460
+int get_node_id(uuid_t *host_id, uuid_t *node_id)
1461
+{
1462
+ sqlite3_stmt *res = NULL;
1463
+ int rc;
1464
+
1465
+ if (unlikely(!db_meta)) {
1466
+ if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)
1467
+ error_report("Database has not been initialized");
1468
+ return 1;
1469
+ }
1470
+
1471
+ rc = sqlite3_prepare_v2(db_meta, SQL_SELECT_NODE_ID, -1, &res, 0);
1472
+ if (unlikely(rc != SQLITE_OK)) {
1473
+ error_report("Failed to prepare statement to select node instance information for a host");
1474
+ return 1;
1475
+ }
1476
+
1477
+ rc = sqlite3_bind_blob(res, 1, host_id, sizeof(*host_id), SQLITE_STATIC);
1478
+ if (unlikely(rc != SQLITE_OK)) {
1479
+ error_report("Failed to bind host_id parameter to select node instance information");
1480
+ goto failed;
1481
+ }
1482
+
1483
+ rc = sqlite3_step(res);
1484
+ if (likely(rc == SQLITE_ROW && node_id))
1485
+ uuid_copy(*node_id, *((uuid_t *) sqlite3_column_blob(res, 0)));
1486
+
1487
+failed:
1488
+ if (unlikely(sqlite3_finalize(res) != SQLITE_OK))
1489
+ error_report("Failed to finalize the prepared statement when selecting node instance information");
1490
+
1491
+ return (rc == SQLITE_ROW) ? 0 : -1;
1492
+}
1493
+
1494
+#define SQL_INVALIDATE_NODE_INSTANCES "update node_instance set node_id = NULL where exists " \
1495
+ "(select host_id from node_instance where host_id = @host_id and (@claim_id is null or claim_id <> @claim_id));"
1496
+
1497
+void invalidate_node_instances(uuid_t *host_id, uuid_t *claim_id)
1498
+{
1499
+ sqlite3_stmt *res = NULL;
1500
+ int rc;
1501
+
1502
+ if (unlikely(!db_meta)) {
1503
+ if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)
1504
+ error_report("Database has not been initialized");
1505
+ return;
1506
+ }
1507
+
1508
+ rc = sqlite3_prepare_v2(db_meta, SQL_INVALIDATE_NODE_INSTANCES, -1, &res, 0);
1509
+ if (unlikely(rc != SQLITE_OK)) {
1510
+ error_report("Failed to prepare statement to invalidate node instance ids");
1511
+ return;
1512
+ }
1513
+
1514
+ rc = sqlite3_bind_blob(res, 1, host_id, sizeof(*host_id), SQLITE_STATIC);
1515
+ if (unlikely(rc != SQLITE_OK)) {
1516
+ error_report("Failed to bind host_id parameter to invalidate node instance information");
1517
+ goto failed;
1518
+ }
1519
+
1520
+ if (claim_id)
1521
+ rc = sqlite3_bind_blob(res, 2, claim_id, sizeof(*claim_id), SQLITE_STATIC);
1522
+ else
1523
+ rc = sqlite3_bind_null(res, 2);
1524
+
1525
+ if (unlikely(rc != SQLITE_OK)) {
1526
+ error_report("Failed to bind claim_id parameter to invalidate node instance information");
1527
+ goto failed;
1528
+ }
1529
+
1530
+ rc = execute_insert(res);
1531
+ if (unlikely(rc != SQLITE_DONE))
1532
+ error_report("Failed to invalidate node instance information, rc = %d", rc);
1533
+
1534
+failed:
1535
+ if (unlikely(sqlite3_finalize(res) != SQLITE_OK))
1536
+ error_report("Failed to finalize the prepared statement when invalidating node instance information");
1537
+}
1538
+
1539
+#define SQL_GET_NODE_INSTANCE_LIST "select ni.node_id, ni.host_id, h.hostname " \
1540
+ "from node_instance ni, host h where ni.host_id = h.host_id;"
1541
+
1542
+struct node_instance_list *get_node_list(void)
1543
+{
1544
+ struct node_instance_list *node_list = NULL;
1545
+ sqlite3_stmt *res = NULL;
1546
+ int rc;
1547
+
1548
+ if (unlikely(!db_meta)) {
1549
+ if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)
1550
+ error_report("Database has not been initialized");
1551
+ return NULL;
1552
+ }
1553
+
1554
+ rc = sqlite3_prepare_v2(db_meta, SQL_GET_NODE_INSTANCE_LIST, -1, &res, 0);
1555
+ if (unlikely(rc != SQLITE_OK)) {
1556
+ error_report("Failed to prepare statement store chart labels");
1557
+ return NULL;
1558
+ };
1559
+
1560
+ int row = 0;
1561
+ char host_guid[37];
1562
+ while (sqlite3_step(res) == SQLITE_ROW)
1563
+ row++;
1564
+
1565
+ if (sqlite3_reset(res) != SQLITE_OK) {
1566
+ error_report("Failed to reset the prepared statement fetching storing node instance information");
1567
+ goto failed;
1568
+ }
1569
+ node_list = callocz(row + 1, sizeof(*node_list));
1570
+ int max_rows = row;
1571
+ row = 0;
1572
+ while (sqlite3_step(res) == SQLITE_ROW) {
1573
+ if (sqlite3_column_bytes(res, 0) == sizeof(uuid_t))
1574
+ uuid_copy(node_list[row].node_id, *((uuid_t *)sqlite3_column_blob(res, 0)));
1575
+ if (sqlite3_column_bytes(res, 1) == sizeof(uuid_t)) {
1576
+ uuid_t *host_id = (uuid_t *)sqlite3_column_blob(res, 1);
1577
+ uuid_copy(node_list[row].host_id, *host_id);
1578
+ node_list[row].querable = 1;
1579
+ uuid_unparse_lower(*host_id, host_guid);
1580
+ node_list[row].live = rrdhost_find_by_guid(host_guid, 0) ? 1 : 0;
1581
+ node_list[row].hops = uuid_compare(*host_id, localhost->host_uuid) ? 1 : 0;
1582
+ node_list[row].hostname =
1583
+ sqlite3_column_bytes(res, 2) ? strdupz((char *)sqlite3_column_text(res, 2)) : NULL;
1584
+ }
1585
+ row++;
1586
+ if (row == max_rows)
1587
+ break;
1588
+ }
1589
+
1590
+failed:
1591
+ if (unlikely(sqlite3_finalize(res) != SQLITE_OK))
1592
+ error_report("Failed to finalize the prepared statement when storing node instance information");
1593
+
1594
+ return node_list;
1595
+};
1596
+
1597
+#define SQL_GET_HOST_NODE_ID "select node_id from node_instance where host_id = @host_id;"
1598
+
1599
+void sql_load_node_id(RRDHOST *host)
1600
+{
1601
+ sqlite3_stmt *res = NULL;
1602
+ int rc;
1603
+
1604
+ if (unlikely(!db_meta)) {
1605
+ if (default_rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE)
1606
+ error_report("Database has not been initialized");
1607
+ return;
1608
+ }
1609
+
1610
+ rc = sqlite3_prepare_v2(db_meta, SQL_GET_HOST_NODE_ID, -1, &res, 0);
1611
+ if (unlikely(rc != SQLITE_OK)) {
1612
+ error_report("Failed to prepare statement store chart labels");
1613
+ return;
1614
+ };
1615
+
1616
+ rc = sqlite3_bind_blob(res, 1, &host->host_uuid, sizeof(host->host_uuid), SQLITE_STATIC);
1617
+ if (unlikely(rc != SQLITE_OK)) {
1618
+ error_report("Failed to bind host_id parameter to store node instance information");
1619
+ goto failed;
1620
+ }
1621
+
1622
+ rc = sqlite3_step(res);
1623
+ if (likely(rc == SQLITE_ROW)) {
1624
+ if (likely(sqlite3_column_bytes(res, 0) == sizeof(uuid_t)))
1625
+ set_host_node_id(host, (uuid_t *)sqlite3_column_blob(res, 0));
1626
+ else
1627
+ set_host_node_id(host, NULL);
1628
+ }
1629
+
1630
+failed:
1631
+ if (unlikely(sqlite3_finalize(res) != SQLITE_OK))
1632
+ error_report("Failed to finalize the prepared statement when storing node instance information");
1633
+
1634
+ return;
1635
+};
database/sqlite/sqlite_functions.h
+16
@@ -6,6 +6,17 @@
6
#include "../../daemon/common.h"
7
#include "sqlite3.h"
8
9
+// return a node list
10
+struct node_instance_list {
11
+ uuid_t node_id;
12
+ uuid_t host_id;
13
+ char *hostname;
14
+ int live;
15
+ int querable;
16
+ int hops;
17
+};
18
+
19
+
20
#define SQLITE_INSERT_DELAY (50) // Insert delay in case of lock
21
22
#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);"
@@ -61,4 +72,9 @@ extern void delete_dimension_uuid(uuid_t *dimension_uuid);
72
extern void sql_store_chart_label(uuid_t *chart_uuid, int source_type, char *label, char *value);
73
extern void sql_build_context_param_list(struct context_param **param_list, RRDHOST *host, char *context, char *chart);
74
extern void store_claim_id(uuid_t *host_id, uuid_t *claim_id);
75
+extern int update_node_id(uuid_t *host_id, uuid_t *node_id);
76
+extern int get_node_id(uuid_t *host_id, uuid_t *node_id);
77
+extern void invalidate_node_instances(uuid_t *host_id, uuid_t *claim_id);
78
+extern struct node_instance_list *get_node_list(void);
79
+extern void sql_load_node_id(RRDHOST *host);
80
#endif //NETDATA_SQLITE_FUNCTIONS_H