@cryptotaxi247 / netdata-1 / commits / 90f94eba4

store status file in /var/lib/netdata, not in /var/cache/netdata (#19831)

* store status file in /var/lib/netdata, not in /var/cache/netdata * add db mode and db tiers to the status file * fix compilation * remove old status files * clear errno after deletions * save kubernetes status * do not cleanup old status files on every save

Costa Tsaousis committed Mar 12, 2025 at 12:47 UTC 90f94eba470905c9db527b035640467004208aad
3 files changed +63 -4
src/daemon/daemon-status-file.c
+52 -4
@@ -9,7 +9,7 @@
9 #include <openssl/pem.h>
10 #include <openssl/err.h>
11
12 -#define STATUS_FILE_VERSION 13
12 +#define STATUS_FILE_VERSION 14
13
14 #define STATUS_FILENAME "status-netdata.json"
15
@@ -118,6 +118,12 @@ static void daemon_status_file_to_json(BUFFER *wb, DAEMON_STATUS_FILE *ds) {
118
119 buffer_json_member_add_string_or_empty(wb, "ND_install_type", ds->install_type); // custom
120
121 + if(ds->v >= 14) {
122 + buffer_json_member_add_string(wb, "ND_db_mode", rrd_memory_mode_name(ds->db_mode)); // custom
123 + buffer_json_member_add_uint64(wb, "ND_db_tiers", ds->db_tiers); // custom
124 + buffer_json_member_add_boolean(wb, "ND_kubernetes", ds->kubernetes); // custom
125 + }
126 +
127 buffer_json_member_add_object(wb, "ND_timings"); // custom
128 {
129 buffer_json_member_add_time_t(wb, "init", ds->timings.init);
@@ -226,6 +232,7 @@ static bool daemon_status_file_from_json(json_object *jobj, void *data, BUFFER *
232 bool required_v4 = version >= 4 ? strict : false;
233 bool required_v5 = version >= 5 ? strict : false;
234 bool required_v10 = version >= 10 ? strict : false;
235 + bool required_v14 = version >= 14 ? strict : false;
236
237 // Parse timestamp
238 JSONC_PARSE_TXT2CHAR_OR_ERROR_AND_RETURN(jobj, path, "@timestamp", datetime, error, required_v1);
@@ -252,6 +259,17 @@ static bool daemon_status_file_from_json(json_object *jobj, void *data, BUFFER *
259
260 if(version >= 4)
261 JSONC_PARSE_UINT64_OR_ERROR_AND_RETURN(jobj, path, "ND_restarts", ds->restarts, error, required_v4);
262 +
263 + if(version >= 14) {
264 + JSONC_PARSE_TXT2ENUM_OR_ERROR_AND_RETURN(jobj, path, "ND_db_mode", rrd_memory_mode_id, ds->db_mode, error, required_v14);
265 + JSONC_PARSE_UINT64_OR_ERROR_AND_RETURN(jobj, path, "ND_db_tiers", ds->db_tiers, error, required_v14);
266 + JSONC_PARSE_BOOL_OR_ERROR_AND_RETURN(jobj, path, "ND_kubernetes", ds->kubernetes, error, required_v14);
267 + }
268 + else {
269 + ds->db_mode = default_rrd_memory_mode;
270 + ds->db_tiers = nd_profile.storage_tiers;
271 + ds->kubernetes = false;
272 + }
273 });
274
275 // Parse host object
@@ -383,6 +401,8 @@ static void daemon_status_file_refresh(DAEMON_STATUS status) {
401 session_status.uptime = now_realtime_sec() - netdata_start_time;
402 session_status.timestamp_ut = now_ut;
403 session_status.invocation = nd_log_get_invocation_id();
404 + session_status.db_mode = default_rrd_memory_mode;
405 + session_status.db_tiers = nd_profile.storage_tiers;
406
407 session_status.claim_id = claim_id_get_uuid();
408
@@ -470,11 +490,17 @@ static void daemon_status_file_refresh(DAEMON_STATUS status) {
490
491 // List of fallback directories to try
492 static const char *status_file_fallbacks[] = {
493 + CACHE_DIR,
494 "/tmp",
495 "/run",
496 "/var/run",
497 + ".",
498 };
499
500 +static void set_dynamic_fallbacks(void) {
501 + status_file_fallbacks[0] = netdata_configured_cache_dir;
502 +}
503 +
504 static bool check_status_file(const char *directory, char *filename, size_t filename_size, time_t *mtime) {
505 if(!directory || !*directory)
506 return false;
@@ -529,12 +555,13 @@ void daemon_status_file_load(DAEMON_STATUS_FILE *ds) {
555 time_t newest_mtime = 0, current_mtime;
556
557 // Check the primary directory first
532 - if(check_status_file(netdata_configured_cache_dir, current_filename, sizeof(current_filename), &current_mtime)) {
558 + if(check_status_file(netdata_configured_varlib_dir, current_filename, sizeof(current_filename), &current_mtime)) {
559 strncpyz(newest_filename, current_filename, sizeof(newest_filename) - 1);
560 newest_mtime = current_mtime;
561 }
562
563 // Check each fallback location
564 + set_dynamic_fallbacks();
565 for(size_t i = 0; i < _countof(status_file_fallbacks); i++) {
566 if(check_status_file(status_file_fallbacks[i], current_filename, sizeof(current_filename), &current_mtime) &&
567 (!*newest_filename || current_mtime > newest_mtime)) {
@@ -655,6 +682,23 @@ static void static_save_buffer_init(void) {
682 buffer_flush(static_save_buffer);
683 }
684
685 +static void remove_old_status_files(const char *protected_dir) {
686 + FUNCTION_RUN_ONCE();
687 +
688 + char filename[FILENAME_MAX];
689 +
690 + set_dynamic_fallbacks();
691 + for(size_t i = 0; i < _countof(status_file_fallbacks); i++) {
692 + if(strcmp(status_file_fallbacks[i], protected_dir) == 0)
693 + continue;
694 +
695 + snprintfz(filename, sizeof(filename), "%s/%s", status_file_fallbacks[i], STATUS_FILENAME);
696 + unlink(filename);
697 + }
698 +
699 + errno_clear();
700 +}
701 +
702 static void daemon_status_file_save(BUFFER *wb, DAEMON_STATUS_FILE *ds, bool log) {
703 buffer_flush(wb);
704 buffer_json_initialize(wb, "\"", "\"", 0, true, BUFFER_JSON_OPTIONS_DEFAULT);
@@ -666,18 +710,22 @@ static void daemon_status_file_save(BUFFER *wb, DAEMON_STATUS_FILE *ds, bool log
710
711 // Try primary directory first
712 bool saved = false;
669 - if (save_status_file(netdata_configured_cache_dir, content, content_size))
713 + if (save_status_file(netdata_configured_varlib_dir, content, content_size)) {
714 + remove_old_status_files(netdata_configured_varlib_dir);
715 saved = true;
716 + }
717 else {
718 if(log)
719 nd_log(NDLS_DAEMON, NDLP_DEBUG, "Failed to save status file in primary directory %s",
674 - netdata_configured_cache_dir);
720 + netdata_configured_varlib_dir);
721
722 // Try each fallback directory until successful
723 + set_dynamic_fallbacks();
724 for(size_t i = 0; i < _countof(status_file_fallbacks); i++) {
725 if (save_status_file(status_file_fallbacks[i], content, content_size)) {
726 if(log)
727 nd_log(NDLS_DAEMON, NDLP_DEBUG, "Saved status file in fallback %s", status_file_fallbacks[i]);
728 +
729 saved = true;
730 break;
731 }
src/daemon/daemon-status-file.h
+4
@@ -5,6 +5,7 @@
5
6 #include "libnetdata/libnetdata.h"
7 #include "daemon/config/netdata-conf-profile.h"
8 +#include "database/rrd-database-mode.h"
9
10 typedef enum {
11 DAEMON_STATUS_NONE,
@@ -33,6 +34,9 @@ typedef struct daemon_status_file {
34 EXIT_REASON exit_reason; // the exit reason (maybe empty)
35 ND_PROFILE profile; // the profile of the agent
36 DAEMON_OS_TYPE os_type;
37 + RRD_DB_MODE db_mode;
38 + uint8_t db_tiers;
39 + bool kubernetes;
40
41 time_t boottime; // system boottime
42 time_t uptime; // netdata uptime
src/database/rrdhost-system-info.c
+7
@@ -652,5 +652,12 @@ void get_daemon_status_fields_from_system_info(DAEMON_STATUS_FILE *ds) {
652 if(ri->host_os_id_like)
653 strncpyz(ds->os_id_like, ri->host_os_id_like, sizeof(ds->os_id_like) - 1);
654
655 + if(ri->is_k8s_node) {
656 + if (strcmp(ri->is_k8s_node, "true") == 0)
657 + ds->kubernetes = true;
658 + else
659 + ds->kubernetes = false;
660 + }
661 +
662 ds->read_system_info = true;
663 }