128
) {
129
debug(D_RRDHOST, "Host '%s': adding with guid '%s'", hostname, guid);
130
131
+#ifdef ENABLE_DBENGINE
132
+ int is_legacy = is_archived ? 0 : (memory_mode == RRD_MEMORY_MODE_DBENGINE) && is_legacy_child(guid);
133
+#else
134
+ int is_legacy = 1;
135
+#endif
136
rrd_check_wrlock();
137
138
+ int is_in_multihost = (memory_mode == RRD_MEMORY_MODE_DBENGINE && !is_legacy);
139
RRDHOST *host = callocz(1, sizeof(RRDHOST));
140
141
host->rrd_update_every = (update_every > 0)?update_every:1;
142
host->rrd_history_entries = align_entries_to_pagesize(memory_mode, entries);
143
host->rrd_memory_mode = memory_mode;
138
-#ifdef ENABLE_DBENGINE
139
- host->page_cache_mb = default_rrdeng_page_cache_mb;
140
- host->disk_space_mb = default_rrdeng_disk_quota_mb;
141
-#endif
142
- host->health_enabled = (memory_mode == RRD_MEMORY_MODE_NONE)? 0 : health_enabled;
144
+ host->health_enabled = ((memory_mode == RRD_MEMORY_MODE_NONE) || is_archived) ? 0 : health_enabled;
145
146
host->sender = mallocz(sizeof(*host->sender));
147
sender_init(host->sender, host);
229
}
230
else {
231
// this is not localhost - append our GUID to localhost path
232
+ if (is_in_multihost) { // don't append to cache dir in multihost
233
+ host->cache_dir = strdupz(netdata_configured_cache_dir);
234
+ } else {
235
+ snprintfz(filename, FILENAME_MAX, "%s/%s", netdata_configured_cache_dir, host->machine_guid);
236
+ host->cache_dir = strdupz(filename);
237
+ }
238
231
- snprintfz(filename, FILENAME_MAX, "%s/%s", netdata_configured_cache_dir, host->machine_guid);
232
- host->cache_dir = strdupz(filename);
233
-
234
- if(host->rrd_memory_mode == RRD_MEMORY_MODE_MAP || host->rrd_memory_mode == RRD_MEMORY_MODE_SAVE ||
235
- host->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE) {
239
+ if((host->rrd_memory_mode == RRD_MEMORY_MODE_MAP || host->rrd_memory_mode == RRD_MEMORY_MODE_SAVE || (
240
+ host->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE && is_legacy))) {
241
int r = mkdir(host->cache_dir, 0775);
242
if(r != 0 && errno != EEXIST)
243
error("Host '%s': cannot create directory '%s'", host->hostname, host->cache_dir);
246
snprintfz(filename, FILENAME_MAX, "%s/%s", netdata_configured_varlib_dir, host->machine_guid);
247
host->varlib_dir = strdupz(filename);
248
244
- if(host->health_enabled) {
249
+ if(!is_archived && host->health_enabled) {
250
int r = mkdir(host->varlib_dir, 0775);
251
if(r != 0 && errno != EEXIST)
252
error("Host '%s': cannot create directory '%s'", host->hostname, host->varlib_dir);
254
255
}
256
252
- if(host->health_enabled) {
257
+ if(!is_archived && host->health_enabled) {
258
snprintfz(filename, FILENAME_MAX, "%s/health", host->varlib_dir);
259
int r = mkdir(filename, 0775);
260
if(r != 0 && errno != EEXIST)
272
// ------------------------------------------------------------------------
273
// load health configuration
274
270
- if(host->health_enabled) {
275
+ if(!is_archived && host->health_enabled) {
276
rrdhost_wrlock(host);
277
health_readdir(host, health_user_config_dir(), health_stock_config_dir(), NULL);
278
rrdhost_unlock(host);
281
health_alarm_log_open(host);
282
}
283
284
+ RRDHOST *t = rrdhost_index_add(host);
285
+
286
+ if(t != host) {
287
+ error("Host '%s': cannot add host with machine guid '%s' to index. It already exists as host '%s' with machine guid '%s'.", host->hostname, host->machine_guid, t->hostname, t->machine_guid);
288
+ rrdhost_free(host);
289
+ return NULL;
290
+ }
291
+
292
if (host->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE) {
293
#ifdef ENABLE_DBENGINE
294
if (unlikely(-1 == uuid_parse(host->machine_guid, host->host_uuid))) {
298
error("Failed to store machine GUID to global map");
299
else
300
info("Added %s to global map for host %s", host->machine_guid, host->hostname);
288
- host->objects_nr = 1;
301
host->compaction_id = 0;
302
char dbenginepath[FILENAME_MAX + 1];
303
int ret;
304
305
snprintfz(dbenginepath, FILENAME_MAX, "%s/dbengine", host->cache_dir);
306
ret = mkdir(dbenginepath, 0775);
295
- if(ret != 0 && errno != EEXIST)
307
+ if (ret != 0 && errno != EEXIST)
308
error("Host '%s': cannot create directory '%s'", host->hostname, dbenginepath);
309
+ else ret = 0; // succeed
310
+ if (is_legacy) // initialize legacy dbengine instance as needed
311
+ ret = rrdeng_init(host, &host->rrdeng_ctx, dbenginepath, default_rrdeng_page_cache_mb,
312
+ default_rrdeng_disk_quota_mb); // may fail here for legacy dbengine initialization
313
else
298
- ret = rrdeng_init(host, &host->rrdeng_ctx, dbenginepath, host->page_cache_mb, host->disk_space_mb);
299
- if(ret) {
300
- error("Host '%s': cannot initialize host with machine guid '%s'. Failed to initialize DB engine at '%s'.",
301
- host->hostname, host->machine_guid, host->cache_dir);
314
+ host->rrdeng_ctx = &multidb_ctx;
315
+ if (ret) { // check legacy or multihost initialization success
316
+ error(
317
+ "Host '%s': cannot initialize host with machine guid '%s'. Failed to initialize DB engine at '%s'.",
318
+ host->hostname, host->machine_guid, host->cache_dir);
319
rrdhost_free(host);
320
host = NULL;
321
//rrd_hosts_available++; //TODO: maybe we want this?
322
323
return host;
324
}
325
+
326
+ metalog_upd_objcount(host, 1);
327
#else
328
fatal("RRD_MEMORY_MODE_DBENGINE is not supported in this platform.");
329
#endif
344
else localhost = host;
345
}
346
328
- RRDHOST *t = rrdhost_index_add(host);
329
-
330
- if(t != host) {
331
- error("Host '%s': cannot add host with machine guid '%s' to index. It already exists as host '%s' with machine guid '%s'.", host->hostname, host->machine_guid, t->hostname, t->machine_guid);
332
- rrdhost_free(host);
333
- host = NULL;
334
- }
335
- else {
336
- info("Host '%s' (at registry as '%s') with guid '%s' initialized"
337
- ", os '%s'"
338
- ", timezone '%s'"
339
- ", tags '%s'"
340
- ", program_name '%s'"
341
- ", program_version '%s'"
342
- ", update every %d"
343
- ", memory mode %s"
344
- ", history entries %ld"
345
- ", streaming %s"
346
- " (to '%s' with api key '%s')"
347
- ", health %s"
348
- ", cache_dir '%s'"
349
- ", varlib_dir '%s'"
350
- ", health_log '%s'"
351
- ", alarms default handler '%s'"
352
- ", alarms default recipient '%s'"
353
- , host->hostname
354
- , host->registry_hostname
355
- , host->machine_guid
356
- , host->os
357
- , host->timezone
358
- , (host->tags)?host->tags:""
359
- , host->program_name
360
- , host->program_version
361
- , host->rrd_update_every
362
- , rrd_memory_mode_name(host->rrd_memory_mode)
363
- , host->rrd_history_entries
364
- , host->rrdpush_send_enabled?"enabled":"disabled"
365
- , host->rrdpush_send_destination?host->rrdpush_send_destination:""
366
- , host->rrdpush_send_api_key?host->rrdpush_send_api_key:""
367
- , host->health_enabled?"enabled":"disabled"
368
- , host->cache_dir
369
- , host->varlib_dir
370
- , host->health_log_filename
371
- , host->health_default_exec
372
- , host->health_default_recipient
373
- );
374
- }
347
+ info("Host '%s' (at registry as '%s') with guid '%s' initialized"
348
+ ", os '%s'"
349
+ ", timezone '%s'"
350
+ ", tags '%s'"
351
+ ", program_name '%s'"
352
+ ", program_version '%s'"
353
+ ", update every %d"
354
+ ", memory mode %s"
355
+ ", history entries %ld"
356
+ ", streaming %s"
357
+ " (to '%s' with api key '%s')"
358
+ ", health %s"
359
+ ", cache_dir '%s'"
360
+ ", varlib_dir '%s'"
361
+ ", health_log '%s'"
362
+ ", alarms default handler '%s'"
363
+ ", alarms default recipient '%s'"
364
+ , host->hostname
365
+ , host->registry_hostname
366
+ , host->machine_guid
367
+ , host->os
368
+ , host->timezone
369
+ , (host->tags)?host->tags:""
370
+ , host->program_name
371
+ , host->program_version
372
+ , host->rrd_update_every
373
+ , rrd_memory_mode_name(host->rrd_memory_mode)
374
+ , host->rrd_history_entries
375
+ , host->rrdpush_send_enabled?"enabled":"disabled"
376
+ , host->rrdpush_send_destination?host->rrdpush_send_destination:""
377
+ , host->rrdpush_send_api_key?host->rrdpush_send_api_key:""
378
+ , host->health_enabled?"enabled":"disabled"
379
+ , host->cache_dir
380
+ , host->varlib_dir
381
+ , host->health_log_filename
382
+ , host->health_default_exec
383
+ , host->health_default_recipient
384
+ );
385
376
- rrd_hosts_available++;
386
+ if (!is_archived)
387
+ rrd_hosts_available++;
388
389
#ifdef ENABLE_DBENGINE
390
if (likely(!is_localhost && !is_archived && host && host->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE))
419
UNUSED(rrdpush_api_key);
420
UNUSED(rrdpush_send_charts_matching);
421
411
- host->health_enabled = health_enabled;
422
+ host->health_enabled = (mode == RRD_MEMORY_MODE_NONE) ? 0 : health_enabled;
423
//host->stream_version = STREAMING_PROTOCOL_CURRENT_VERSION; Unused?
424
425
rrdhost_system_info_free(host->system_info);
464
465
// update host tags
466
rrdhost_init_tags(host, tags);
467
+
468
+ if (rrdhost_flag_check(host, RRDHOST_FLAG_ARCHIVED)) {
469
+ rrdhost_flag_clear(host, RRDHOST_FLAG_ARCHIVED);
470
+ if(host->health_enabled) {
471
+ int r;
472
+ char filename[FILENAME_MAX + 1];
473
+
474
+ if (host != localhost) {
475
+ r = mkdir(host->varlib_dir, 0775);
476
+ if (r != 0 && errno != EEXIST)
477
+ error("Host '%s': cannot create directory '%s'", host->hostname, host->varlib_dir);
478
+ }
479
+ snprintfz(filename, FILENAME_MAX, "%s/health", host->varlib_dir);
480
+ r = mkdir(filename, 0775);
481
+ if(r != 0 && errno != EEXIST)
482
+ error("Host '%s': cannot create directory '%s'", host->hostname, filename);
483
+
484
+ rrdhost_wrlock(host);
485
+ health_readdir(host, health_user_config_dir(), health_stock_config_dir(), NULL);
486
+ rrdhost_unlock(host);
487
+
488
+ health_alarm_log_load(host);
489
+ health_alarm_log_open(host);
490
+ }
491
+ rrd_hosts_available++;
492
+ info("Host %s is not in archived mode anymore", host->hostname);
493
+ }
494
#ifdef ENABLE_DBENGINE
495
if (likely(host->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE))
496
metalog_commit_update_host(host);
521
522
rrd_wrlock();
523
RRDHOST *host = rrdhost_find_by_guid(guid, 0);
524
+ if (unlikely(host && RRD_MEMORY_MODE_DBENGINE != mode && rrdhost_flag_check(host, RRDHOST_FLAG_ARCHIVED))) {
525
+ /* If a legacy memory mode instantiates all dbengine state must be discarded to avoid inconsistencies */
526
+ error("Archived host '%s' has memory mode '%s', but the wanted one is '%s'. Discarding archived state.",
527
+ host->hostname, rrd_memory_mode_name(host->rrd_memory_mode), rrd_memory_mode_name(mode));
528
+ rrdhost_free(host);
529
+ host = NULL;
530
+ }
531
if(!host) {
532
host = rrdhost_create(
533
hostname
600
if(rrdhost_should_be_removed(host, protected, now)) {
601
info("Host '%s' with machine guid '%s' is obsolete - cleaning up.", host->hostname, host->machine_guid);
602
558
- if(rrdhost_flag_check(host, RRDHOST_FLAG_DELETE_ORPHAN_HOST))
603
+ if (rrdhost_flag_check(host, RRDHOST_FLAG_DELETE_ORPHAN_HOST)
604
+#ifdef ENABLE_DBENGINE
605
+ /* don't delete multi-host DB host files */
606
+ && !(host->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE && host->rrdeng_ctx == &multidb_ctx)
607
+#endif
608
+ )
609
rrdhost_delete_charts(host);
610
else
611
rrdhost_save_charts(host);
652
, 1
653
, 0
654
);
655
+ if (unlikely(!localhost)) {
656
+ rrd_unlock();
657
+ return 1;
658
+ }
659
+
660
+#ifdef ENABLE_DBENGINE
661
+ char dbenginepath[FILENAME_MAX + 1];
662
+ int ret;
663
+ snprintfz(dbenginepath, FILENAME_MAX, "%s/dbengine", localhost->cache_dir);
664
+ ret = mkdir(dbenginepath, 0775);
665
+ if (ret != 0 && errno != EEXIST)
666
+ error("Host '%s': cannot create directory '%s'", localhost->hostname, dbenginepath);
667
+ else // Unconditionally create multihost db to support on demand host creation
668
+ ret = rrdeng_init(NULL, NULL, dbenginepath, default_rrdeng_page_cache_mb, default_multidb_disk_quota_mb);
669
+ if (ret) {
670
+ error(
671
+ "Host '%s' with machine guid '%s' failed to initialize multi-host DB engine instance at '%s'.",
672
+ localhost->hostname, localhost->machine_guid, localhost->cache_dir);
673
+ rrdhost_free(localhost);
674
+ localhost = NULL;
675
+ rrd_unlock();
676
+ return 1;
677
+ }
678
+#endif
679
rrd_unlock();
606
- web_client_api_v1_management_init();
680
+
681
+ web_client_api_v1_management_init();
682
return localhost==NULL;
683
}
684
792
// release its children resources
793
794
#ifdef ENABLE_DBENGINE
720
- rrdeng_prepare_exit(host->rrdeng_ctx);
795
+ if (host->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE && host->rrdeng_ctx != &multidb_ctx)
796
+ rrdeng_prepare_exit(host->rrdeng_ctx);
797
#endif
798
while(host->rrdset_root)
799
rrdset_free(host->rrdset_root);
825
826
health_alarm_log_free(host);
827
752
- if (host->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE) {
828
#ifdef ENABLE_DBENGINE
829
+ if (host->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE && host->rrdeng_ctx != &multidb_ctx)
830
rrdeng_exit(host->rrdeng_ctx);
831
#endif
756
- }
832
833
// ------------------------------------------------------------------------
834
// remove it from the indexes
886
887
void rrdhost_free_all(void) {
888
rrd_wrlock();
814
- while(localhost) rrdhost_free(localhost);
889
+ /* Make sure child-hosts are released before the localhost. */
890
+ while(localhost->next) rrdhost_free(localhost->next);
891
+ rrdhost_free(localhost);
892
rrd_unlock();
893
}
894
1473
1474
RRDHOST *host;
1475
rrdhost_foreach_read(host) {
1399
- if(host != localhost && rrdhost_flag_check(host, RRDHOST_FLAG_DELETE_OBSOLETE_CHARTS) && !host->receiver)
1476
+ if (host != localhost && rrdhost_flag_check(host, RRDHOST_FLAG_DELETE_ORPHAN_HOST) && !host->receiver
1477
+#ifdef ENABLE_DBENGINE
1478
+ /* don't delete multi-host DB host files */
1479
+ && !(host->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE && host->rrdeng_ctx == &multidb_ctx)
1480
+#endif
1481
+ )
1482
rrdhost_delete_charts(host);
1483
else
1484
rrdhost_cleanup_charts(host);