8 char *ce_count_filename;
9 char *ue_count_filename;
14 collected_number ce_count;
15 collected_number ue_count;
22 static struct mc *mc_root = NULL;
24 static void find_all_mc() {
25 char name[FILENAME_MAX + 1];
26 snprintfz(name, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/devices/system/edac/mc");
27 char *dirname = config_get("plugin:proc:/sys/devices/system/edac/mc", "directory to monitor", name);
29 DIR *dir = opendir(dirname);
31 error("Cannot read ECC memory errors directory '%s'", dirname);
35 struct dirent *de = NULL;
36 while((de = readdir(dir))) {
37 if(de->d_type == DT_DIR && de->d_name[0] == 'm' && de->d_name[1] == 'c' && isdigit(de->d_name[2])) {
38 struct mc *m = callocz(1, sizeof(struct mc));
39 m->name = strdupz(de->d_name);
43 snprintfz(name, FILENAME_MAX, "%s/%s/ce_count", dirname, de->d_name);
44 if(stat(name, &st) != -1)
45 m->ce_count_filename = strdupz(name);
47 snprintfz(name, FILENAME_MAX, "%s/%s/ue_count", dirname, de->d_name);
48 if(stat(name, &st) != -1)
49 m->ue_count_filename = strdupz(name);
51 if(!m->ce_count_filename && !m->ue_count_filename) {
65 int do_proc_sys_devices_system_edac_mc(int update_every, usec_t dt) {
68 if(unlikely(mc_root == NULL)) {
70 if(unlikely(mc_root == NULL))
74 static int do_ce = -1, do_ue = -1;
75 calculated_number ce_sum = 0, ue_sum = 0;
78 if(unlikely(do_ce == -1)) {
79 do_ce = config_get_boolean_ondemand("plugin:proc:/sys/devices/system/edac/mc", "enable ECC memory correctable errors", CONFIG_BOOLEAN_AUTO);
80 do_ue = config_get_boolean_ondemand("plugin:proc:/sys/devices/system/edac/mc", "enable ECC memory uncorrectable errors", CONFIG_BOOLEAN_AUTO);
83 if(do_ce != CONFIG_BOOLEAN_NO) {
84 for(m = mc_root; m; m = m->next) {
85 if(m->ce_count_filename) {
88 if(unlikely(!m->ce_ff)) {
89 m->ce_ff = procfile_open(m->ce_count_filename, " \t", PROCFILE_FLAG_DEFAULT);
90 if(unlikely(!m->ce_ff))
94 m->ce_ff = procfile_readall(m->ce_ff);
95 if(unlikely(!m->ce_ff || procfile_lines(m->ce_ff) < 1 || procfile_linewords(m->ce_ff, 0) < 1))
98 m->ce_count = str2ull(procfile_lineword(m->ce_ff, 0, 0));
99 ce_sum += m->ce_count;
105 if(do_ue != CONFIG_BOOLEAN_NO) {
106 for(m = mc_root; m; m = m->next) {
107 if(m->ue_count_filename) {
110 if(unlikely(!m->ue_ff)) {
111 m->ue_ff = procfile_open(m->ue_count_filename, " \t", PROCFILE_FLAG_DEFAULT);
112 if(unlikely(!m->ue_ff))
116 m->ue_ff = procfile_readall(m->ue_ff);
117 if(unlikely(!m->ue_ff || procfile_lines(m->ue_ff) < 1 || procfile_linewords(m->ue_ff, 0) < 1))
120 m->ue_count = str2ull(procfile_lineword(m->ue_ff, 0, 0));
121 ue_sum += m->ue_count;
127 // --------------------------------------------------------------------
129 if(do_ce == CONFIG_BOOLEAN_YES || (do_ce == CONFIG_BOOLEAN_AUTO && ce_sum > 0)) {
130 do_ce = CONFIG_BOOLEAN_YES;
132 static RRDSET *ce_st = NULL;
134 if(unlikely(!ce_st)) {
135 ce_st = rrdset_find_localhost("mem.ecc_ce");
137 ce_st = rrdset_create_localhost("mem", "ecc_ce", NULL, "ecc", NULL, "ECC Memory Correctable Errors"
138 , "errors", 6600, update_every, RRDSET_TYPE_LINE);
140 for(m = mc_root; m; m = m->next)
141 if(m->ce_count_filename)
142 m->ce_rd = rrddim_add(ce_st, m->name, NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
147 for(m = mc_root; m; m = m->next)
148 if(m->ce_count_filename && m->ce_updated)
149 rrddim_set_by_pointer(ce_st, m->ce_rd, m->ce_count);
154 // --------------------------------------------------------------------
156 if(do_ue == CONFIG_BOOLEAN_YES || (do_ue == CONFIG_BOOLEAN_AUTO && ue_sum > 0)) {
157 do_ue = CONFIG_BOOLEAN_YES;
159 static RRDSET *ue_st = NULL;
161 if(unlikely(!ue_st)) {
162 ue_st = rrdset_find_localhost("mem.ecc_ue");
165 ue_st = rrdset_create_localhost("mem", "ecc_ue", NULL, "ecc", NULL, "ECC Memory Uncorrectable Errors"
166 , "errors", 6610, update_every, RRDSET_TYPE_LINE);
168 for(m = mc_root; m; m = m->next)
169 if(m->ue_count_filename)
170 m->ue_rd = rrddim_add(ue_st, m->name, NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
175 for(m = mc_root; m; m = m->next)
176 if(m->ue_count_filename && m->ue_updated)
177 rrddim_set_by_pointer(ue_st, m->ue_rd, m->ue_count);