simple_pattern now also supports asterisks in the middle; cgroups cleanup;
Costa Tsaousis (ktsaou) committed
Jan 15, 2017 at 06:03 UTC
83df0e7941994cb3a081af565f4b11f3c436bfe0
7 files changed
+283
-212
CMakeLists.txt
+1
-1
@@ -101,7 +101,7 @@ set(NETDATA_SOURCE_FILES
101
src/registry_person.c
102
src/registry_person.h
103
src/registry_machine.c
104
- src/registry_machine.h src/registry_internals.c src/registry_init.c src/registry_db.c src/registry_log.c src/proc_uptime.c src/sys_devices_system_edac_mc.c src/plugin_proc_diskspace.c src/plugin_proc_diskspace.h)
104
+ src/registry_machine.h src/registry_internals.c src/registry_init.c src/registry_db.c src/registry_log.c src/proc_uptime.c src/sys_devices_system_edac_mc.c src/plugin_proc_diskspace.c src/plugin_proc_diskspace.h src/simple_pattern.c src/simple_pattern.h)
105
106
set(APPS_PLUGIN_SOURCE_FILES
107
src/appconfig.c
src/Makefile.am
+1
@@ -46,6 +46,7 @@ netdata_SOURCES = \
46
plugins_d.c plugins_d.h \
47
popen.c popen.h \
48
socket.c socket.h \
49
+ simple_pattern.c simple_pattern.h \
50
sys_fs_cgroup.c \
51
sys_devices_system_edac_mc.c \
52
procfile.c procfile.h \
src/common.c
-126
@@ -1187,129 +1187,3 @@ int read_single_number_file(const char *filename, unsigned long long *result) {
1187
*result = strtoull(buffer, NULL, 0);
1188
return 0;
1189
}
1190
-
1191
-// ----------------------------------------------------------------------------
1192
-// simple_pattern_match
1193
-
1194
-struct simple_pattern {
1195
- const char *match;
1196
- size_t len;
1197
- NETDATA_SIMPLE_PREFIX_MODE mode;
1198
- struct simple_pattern *next;
1199
-};
1200
-
1201
-NETDATA_SIMPLE_PATTERN *netdata_simple_pattern_list_create(const char *list, NETDATA_SIMPLE_PREFIX_MODE default_mode) {
1202
- struct simple_pattern *root = NULL, *last = NULL;
1203
-
1204
- if(unlikely(!list || !*list)) return root;
1205
-
1206
- char *a = strdupz(list);
1207
- if(a && *a) {
1208
- char *s = a;
1209
-
1210
- while(s && *s) {
1211
- // skip all spaces
1212
- while(isspace(*s)) s++;
1213
-
1214
- // empty string
1215
- if(unlikely(!*s)) break;
1216
-
1217
- // find the next space
1218
- char *c = s;
1219
- while(*c && !isspace(*c)) c++;
1220
-
1221
- // find the next word
1222
- char *n;
1223
- if(likely(*c)) n = c + 1;
1224
- else n = NULL;
1225
-
1226
- // terminate our string
1227
- *c = '\0';
1228
-
1229
- char buf[100 + 1];
1230
- strncpy(buf, s, 100);
1231
- buf[100] = '\0';
1232
- if(likely(n)) *c = ' ';
1233
- s = buf;
1234
-
1235
- NETDATA_SIMPLE_PREFIX_MODE mode;
1236
- size_t len = strlen(s);
1237
- if(len >= 2 && *s == '*' && s[len - 1] == '*') {
1238
- s[len - 1] = '\0';
1239
- s++;
1240
- mode = NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING;
1241
- }
1242
- else if(len >= 1 && *s == '*') {
1243
- s++;
1244
- mode = NETDATA_SIMPLE_PATTERN_MODE_SUFFIX;
1245
- }
1246
- else if(len >= 1 && s[len - 1] == '*') {
1247
- s[len - 1] = '\0';
1248
- mode = NETDATA_SIMPLE_PATTERN_MODE_PREFIX;
1249
- }
1250
- else
1251
- mode = default_mode;
1252
-
1253
- // allocate the structure
1254
- struct simple_pattern *m = callocz(1, sizeof(struct simple_pattern));
1255
- if(*s) {
1256
- m->match = strdup(s);
1257
- m->len = strlen(m->match);
1258
- m->mode = mode;
1259
- }
1260
- else {
1261
- m->mode = NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING;
1262
- }
1263
-
1264
- // link it at the end
1265
- if(unlikely(!root))
1266
- root = last = m;
1267
- else {
1268
- last->next = m;
1269
- last = m;
1270
- }
1271
-
1272
- // prepare for next loop
1273
- s = n;
1274
- }
1275
- }
1276
-
1277
- free(a);
1278
- return (NETDATA_SIMPLE_PATTERN *)root;
1279
-}
1280
-
1281
-int netdata_simple_pattern_list_matches(NETDATA_SIMPLE_PATTERN *list, const char *str) {
1282
- struct simple_pattern *m, *root = (struct simple_pattern *)list;
1283
-
1284
- if(unlikely(!root)) return 0;
1285
-
1286
- size_t len = strlen(str);
1287
- for(m = root; m ; m = m->next) {
1288
- if(m->len <= len) {
1289
- switch(m->mode) {
1290
- case NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING:
1291
- if(unlikely(!m->len || strstr(str, m->match)))
1292
- return 1;
1293
- break;
1294
-
1295
- case NETDATA_SIMPLE_PATTERN_MODE_PREFIX:
1296
- if(unlikely(strncmp(str, m->match, m->len) == 0))
1297
- return 1;
1298
- break;
1299
-
1300
- case NETDATA_SIMPLE_PATTERN_MODE_SUFFIX:
1301
- if(unlikely(strcmp(&str[len - m->len], m->match) == 0))
1302
- return 1;
1303
- break;
1304
-
1305
- case NETDATA_SIMPLE_PATTERN_MODE_EXACT:
1306
- default:
1307
- if(unlikely(strcmp(str, m->match) == 0))
1308
- return 1;
1309
- break;
1310
- }
1311
- }
1312
- }
1313
-
1314
- return 0;
1315
-}
src/common.h
+1
-10
@@ -164,6 +164,7 @@
164
// ----------------------------------------------------------------------------
165
// netdata include files
166
167
+#include "simple_pattern.h"
168
#include "avl.h"
169
#include "clocks.h"
170
#include "log.h"
@@ -278,14 +279,4 @@ extern void get_system_HZ(void);
279
280
extern int read_single_number_file(const char *filename, unsigned long long *result);
281
281
-typedef enum {
282
- NETDATA_SIMPLE_PATTERN_MODE_EXACT,
283
- NETDATA_SIMPLE_PATTERN_MODE_PREFIX,
284
- NETDATA_SIMPLE_PATTERN_MODE_SUFFIX,
285
- NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING
286
-} NETDATA_SIMPLE_PREFIX_MODE;
287
-typedef void NETDATA_SIMPLE_PATTERN;
288
-extern NETDATA_SIMPLE_PATTERN *netdata_simple_pattern_list_create(const char *list, NETDATA_SIMPLE_PREFIX_MODE default_mode);
289
-extern int netdata_simple_pattern_list_matches(NETDATA_SIMPLE_PATTERN *list, const char *str);
290
-
282
#endif /* NETDATA_COMMON_H */
src/simple_pattern.c
new
+204
@@ -0,0 +1,204 @@
1
+#include "common.h"
2
+
3
+struct simple_pattern {
4
+ const char *match;
5
+ size_t len;
6
+ NETDATA_SIMPLE_PREFIX_MODE mode;
7
+
8
+ struct simple_pattern *child;
9
+
10
+ struct simple_pattern *next;
11
+};
12
+
13
+static inline struct simple_pattern *parse_pattern(const char *str, NETDATA_SIMPLE_PREFIX_MODE default_mode) {
14
+ info(">>>> PARSE: '%s'", str);
15
+
16
+ NETDATA_SIMPLE_PREFIX_MODE mode;
17
+ struct simple_pattern *child = NULL;
18
+
19
+ char *buf = strdupz(str);
20
+ char *s = buf, *c = buf;
21
+
22
+ // skip asterisks in front
23
+ while(*c == '*') c++;
24
+
25
+ // find the next asterisk
26
+ while(*c && *c != '*') c++ ;
27
+
28
+ // do we have an asterisk in the middle?
29
+ if(*c == '*' && c[1] != '\0') {
30
+ // yes, we have
31
+ child = parse_pattern(c, default_mode);
32
+ c[1] = '\0';
33
+ }
34
+
35
+ // check what this one matches
36
+
37
+ size_t len = strlen(s);
38
+ if(len >= 2 && *s == '*' && s[len - 1] == '*') {
39
+ s[len - 1] = '\0';
40
+ s++;
41
+ mode = NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING;
42
+ }
43
+ else if(len >= 1 && *s == '*') {
44
+ s++;
45
+ mode = NETDATA_SIMPLE_PATTERN_MODE_SUFFIX;
46
+ }
47
+ else if(len >= 1 && s[len - 1] == '*') {
48
+ s[len - 1] = '\0';
49
+ mode = NETDATA_SIMPLE_PATTERN_MODE_PREFIX;
50
+ }
51
+ else
52
+ mode = default_mode;
53
+
54
+ // allocate the structure
55
+ struct simple_pattern *m = callocz(1, sizeof(struct simple_pattern));
56
+ if(*s) {
57
+ m->match = strdup(s);
58
+ m->len = strlen(m->match);
59
+ m->mode = mode;
60
+ }
61
+ else {
62
+ m->mode = NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING;
63
+ }
64
+
65
+ m->child = child;
66
+
67
+ free(buf);
68
+
69
+ info("PATTERN '%s' is composed by", str);
70
+ struct simple_pattern *p;
71
+ for(p = m; p ; p = p->child)
72
+ info(">>>> COMPONENT: '%s%s%s' (len %zu type %u)",
73
+ (p->mode == NETDATA_SIMPLE_PATTERN_MODE_SUFFIX || p->mode == NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING)?"*":"",
74
+ p->match,
75
+ (p->mode == NETDATA_SIMPLE_PATTERN_MODE_PREFIX || p->mode == NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING)?"*":"",
76
+ p->len,
77
+ p->mode);
78
+
79
+ return m;
80
+}
81
+
82
+NETDATA_SIMPLE_PATTERN *netdata_simple_pattern_list_create(const char *list, NETDATA_SIMPLE_PREFIX_MODE default_mode) {
83
+ struct simple_pattern *root = NULL, *last = NULL;
84
+
85
+ if(unlikely(!list || !*list)) return root;
86
+
87
+ char *buf = strdupz(list);
88
+ if(buf && *buf) {
89
+ char *s = buf;
90
+
91
+ while(s && *s) {
92
+ // skip all spaces
93
+ while(isspace(*s)) s++;
94
+
95
+ // empty string
96
+ if(unlikely(!*s)) break;
97
+
98
+ // find the next space
99
+ char *c = s;
100
+ while(*c && !isspace(*c)) c++;
101
+
102
+ // find the next word
103
+ char *n;
104
+ if(likely(*c)) n = c + 1;
105
+ else n = NULL;
106
+
107
+ // terminate our string
108
+ *c = '\0';
109
+
110
+ struct simple_pattern *m = parse_pattern(s, default_mode);
111
+
112
+ if(likely(n)) *c = ' ';
113
+
114
+ // link it at the end
115
+ if(unlikely(!root))
116
+ root = last = m;
117
+ else {
118
+ last->next = m;
119
+ last = m;
120
+ }
121
+
122
+ // prepare for next loop
123
+ s = n;
124
+ }
125
+ }
126
+
127
+ free(buf);
128
+ return (NETDATA_SIMPLE_PATTERN *)root;
129
+}
130
+
131
+static inline int match_pattern(struct simple_pattern *m, const char *str, size_t len) {
132
+ info("CHECK string '%s' (len %zu) with pattern '%s%s%s' (len %zu type %u)", str, len,
133
+ (m->mode == NETDATA_SIMPLE_PATTERN_MODE_SUFFIX || m->mode == NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING)?"*":"",
134
+ m->match,
135
+ (m->mode == NETDATA_SIMPLE_PATTERN_MODE_PREFIX || m->mode == NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING)?"*":"",
136
+ m->len, m->mode);
137
+
138
+ char *s;
139
+
140
+ if(m->len <= len) {
141
+ switch(m->mode) {
142
+ case NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING:
143
+ if(!m->len) return 1;
144
+ if((s = strstr(str, m->match))) {
145
+ if(!m->child) return 1;
146
+ return match_pattern(m->child, &s[m->len], len - (s - str) - m->len);
147
+ }
148
+ break;
149
+
150
+ case NETDATA_SIMPLE_PATTERN_MODE_PREFIX:
151
+ if(unlikely(strncmp(str, m->match, m->len) == 0)) {
152
+ if(!m->child) return 1;
153
+ return match_pattern(m->child, &str[m->len], len - m->len);
154
+ }
155
+ break;
156
+
157
+ case NETDATA_SIMPLE_PATTERN_MODE_SUFFIX:
158
+ if(unlikely(strcmp(&str[len - m->len], m->match) == 0)) {
159
+ if(!m->child) return 1;
160
+ return 0;
161
+ }
162
+ break;
163
+
164
+ case NETDATA_SIMPLE_PATTERN_MODE_EXACT:
165
+ default:
166
+ if(unlikely(strcmp(str, m->match) == 0)) {
167
+ if(!m->child) return 1;
168
+ return 0;
169
+ }
170
+ break;
171
+ }
172
+ }
173
+
174
+ return 0;
175
+}
176
+
177
+int netdata_simple_pattern_list_matches(NETDATA_SIMPLE_PATTERN *list, const char *str) {
178
+ struct simple_pattern *m, *root = (struct simple_pattern *)list;
179
+
180
+ if(unlikely(!root)) return 0;
181
+
182
+ size_t len = strlen(str);
183
+ for(m = root; m ; m = m->next)
184
+ if(match_pattern(m, str, len)) {
185
+ info("MATCHED string '%s' (len %zu) with pattern '%s%s%s' (len %zu type %u)", str, len,
186
+ (m->mode == NETDATA_SIMPLE_PATTERN_MODE_SUFFIX || m->mode == NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING)?"*":"",
187
+ m->match,
188
+ (m->mode == NETDATA_SIMPLE_PATTERN_MODE_PREFIX || m->mode == NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING)?"*":"",
189
+ m->len, m->mode);
190
+
191
+ struct simple_pattern *p;
192
+ for(p = m; p ; p = p->child)
193
+ info(">>>> MATCHED COMPONENT: '%s%s%s' (len %zu type %u)",
194
+ (p->mode == NETDATA_SIMPLE_PATTERN_MODE_SUFFIX || p->mode == NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING)?"*":"",
195
+ p->match,
196
+ (p->mode == NETDATA_SIMPLE_PATTERN_MODE_PREFIX || p->mode == NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING)?"*":"",
197
+ p->len,
198
+ p->mode);
199
+
200
+ return 1;
201
+ }
202
+
203
+ return 0;
204
+}
src/simple_pattern.h
new
+15
@@ -0,0 +1,15 @@
1
+#ifndef NETDATA_SIMPLE_PATTERN_H
2
+#define NETDATA_SIMPLE_PATTERN_H
3
+
4
+typedef enum {
5
+ NETDATA_SIMPLE_PATTERN_MODE_EXACT,
6
+ NETDATA_SIMPLE_PATTERN_MODE_PREFIX,
7
+ NETDATA_SIMPLE_PATTERN_MODE_SUFFIX,
8
+ NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING
9
+} NETDATA_SIMPLE_PREFIX_MODE;
10
+
11
+typedef void NETDATA_SIMPLE_PATTERN;
12
+extern NETDATA_SIMPLE_PATTERN *netdata_simple_pattern_list_create(const char *list, NETDATA_SIMPLE_PREFIX_MODE default_mode);
13
+extern int netdata_simple_pattern_list_matches(NETDATA_SIMPLE_PATTERN *list, const char *str);
14
+
15
+#endif //NETDATA_SIMPLE_PATTERN_H
src/sys_fs_cgroup.c
+61
-75
@@ -8,8 +8,10 @@ static int cgroup_enable_cpuacct_usage = CONFIG_ONDEMAND_ONDEMAND;
8
static int cgroup_enable_memory = CONFIG_ONDEMAND_ONDEMAND;
9
static int cgroup_enable_devices = CONFIG_ONDEMAND_ONDEMAND;
10
static int cgroup_enable_blkio = CONFIG_ONDEMAND_ONDEMAND;
11
+static int cgroup_enable_systemd_services = CONFIG_ONDEMAND_NO;
12
static int cgroup_enable_new_cgroups_detected_at_runtime = 1;
13
static int cgroup_check_for_new_every = 10;
14
+static int cgroup_update_every = 1;
15
static char *cgroup_cpuacct_base = NULL;
16
static char *cgroup_blkio_base = NULL;
17
static char *cgroup_memory_base = NULL;
@@ -27,13 +29,21 @@ static NETDATA_SIMPLE_PATTERN *systemd_services_cgroups = NULL;
29
static char *cgroups_rename_script = PLUGINS_DIR "/cgroup-name.sh";
30
31
void read_cgroup_plugin_configuration() {
30
- cgroup_check_for_new_every = (int)config_get_number("plugin:cgroups", "check for new cgroups every", cgroup_check_for_new_every);
32
+ cgroup_update_every = (int)config_get_number("plugin:cgroups", "update every", rrd_update_every);
33
+ if(cgroup_update_every < rrd_update_every)
34
+ cgroup_update_every = rrd_update_every;
35
+
36
+ cgroup_check_for_new_every = (int)config_get_number("plugin:cgroups", "check for new cgroups every", cgroup_check_for_new_every * cgroup_update_every);
37
+ if(cgroup_check_for_new_every < cgroup_update_every)
38
+ cgroup_check_for_new_every = cgroup_update_every;
39
40
cgroup_enable_cpuacct_stat = config_get_boolean_ondemand("plugin:cgroups", "enable cpuacct stat", cgroup_enable_cpuacct_stat);
41
cgroup_enable_cpuacct_usage = config_get_boolean_ondemand("plugin:cgroups", "enable cpuacct usage", cgroup_enable_cpuacct_usage);
42
cgroup_enable_memory = config_get_boolean_ondemand("plugin:cgroups", "enable memory", cgroup_enable_memory);
43
cgroup_enable_blkio = config_get_boolean_ondemand("plugin:cgroups", "enable blkio", cgroup_enable_blkio);
44
45
+ cgroup_enable_systemd_services = config_get_boolean_ondemand("plugin:cgroups", "enable systemd services", cgroup_enable_systemd_services);
46
+
47
char filename[FILENAME_MAX + 1], *s;
48
struct mountinfo *mi, *root = mountinfo_read(0);
49
@@ -94,6 +104,7 @@ void read_cgroup_plugin_configuration() {
104
" *.user "
105
" *.mount "
106
" *.partition "
107
+ " *.service "
108
" */ns " // /lxc/*/ns #1397
109
), NETDATA_SIMPLE_PATTERN_MODE_EXACT);
110
@@ -121,10 +132,11 @@ void read_cgroup_plugin_configuration() {
132
" *.user "
133
), NETDATA_SIMPLE_PATTERN_MODE_EXACT);
134
124
- systemd_services_cgroups = netdata_simple_pattern_list_create(
125
- config_get("plugin:cgroups", "cgroups to match as systemd services",
126
- " *.service "
127
- ), NETDATA_SIMPLE_PATTERN_MODE_EXACT);
135
+ if(cgroup_enable_systemd_services)
136
+ systemd_services_cgroups = netdata_simple_pattern_list_create(
137
+ config_get("plugin:cgroups", "cgroups to match as systemd services",
138
+ " /system.slice/*.service "
139
+ ), NETDATA_SIMPLE_PATTERN_MODE_EXACT);
140
141
mountinfo_free(root);
142
}
@@ -749,37 +761,40 @@ void cgroup_get_chart_name(struct cgroup *cg) {
761
debug(D_CGROUP, "cgroup '%s' will not be renamed - it matches the list of disabled cgroup renames (will be shown as '%s')", cg->id, cg->chart_id);
762
763
752
- if(netdata_simple_pattern_list_matches(systemd_services_cgroups, cg->id) ||
753
- netdata_simple_pattern_list_matches(systemd_services_cgroups, cg->chart_id)) {
754
- debug(D_CGROUP, "cgroup '%s' with chart id '%s' (title: '%s') matches systemd services cgroups", cg->id, cg->chart_id, cg->chart_title);
764
+ if(cgroup_enable_systemd_services) {
765
+ if(netdata_simple_pattern_list_matches(systemd_services_cgroups, cg->id) ||
766
+ netdata_simple_pattern_list_matches(systemd_services_cgroups, cg->chart_id)) {
767
+ debug(D_CGROUP, "cgroup '%s' with chart id '%s' (title: '%s') matches systemd services cgroups", cg->id, cg->chart_id, cg->chart_title);
768
756
- char buffer[CGROUP_CHARTID_LINE_MAX + 1];
757
- cg->options |= CGROUP_OPTIONS_SYSTEM_SLICE_SERVICE;
769
+ char buffer[CGROUP_CHARTID_LINE_MAX + 1];
770
+ cg->options |= CGROUP_OPTIONS_SYSTEM_SLICE_SERVICE;
771
759
- strncpy(buffer, cg->id, CGROUP_CHARTID_LINE_MAX);
760
- char *s = buffer;
772
+ strncpy(buffer, cg->id, CGROUP_CHARTID_LINE_MAX);
773
+ char *s = buffer;
774
762
- // skip to the last slash
763
- size_t len = strlen(s);
764
- while(len--) if(unlikely(s[len] == '/')) break;
765
- if(len) s = &s[len+1];
775
+ // skip to the last slash
776
+ size_t len = strlen(s);
777
+ while(len--) if(unlikely(s[len] == '/')) break;
778
+ if(len) s = &s[len + 1];
779
767
- // remove extension
768
- //len = strlen(s);
769
- //while(len--) if(unlikely(s[len] == '.')) break;
770
- //if(len) s[len] = '\0';
780
+ // remove extension
781
+ //len = strlen(s);
782
+ //while(len--) if(unlikely(s[len] == '.')) break;
783
+ //if(len) s[len] = '\0';
784
772
- freez(cg->chart_title);
773
- cg->chart_title = cgroup_title_strdupz(s);
785
+ freez(cg->chart_title);
786
+ cg->chart_title = cgroup_title_strdupz(s);
787
775
- freez(cg->chart_id);
776
- cg->chart_id = cgroup_chart_id_strdupz(s);
777
- cg->hash_chart = simple_hash(cg->chart_id);
788
+ freez(cg->chart_id);
789
+ cg->chart_id = cgroup_chart_id_strdupz(s);
790
+ cg->hash_chart = simple_hash(cg->chart_id);
791
+ cg->enabled = 1;
792
779
- debug(D_CGROUP, "cgroup '%s' renamed to '%s' (title: '%s')", cg->id, cg->chart_id, cg->chart_title);
793
+ debug(D_CGROUP, "cgroup '%s' renamed to '%s' (title: '%s')", cg->id, cg->chart_id, cg->chart_title);
794
+ }
795
+ else
796
+ debug(D_CGROUP, "cgroup '%s' with chart id '%s' (title: '%s') does not match systemd services groups", cg->id, cg->chart_id, cg->chart_title);
797
}
781
- else
782
- debug(D_CGROUP, "cgroup '%s' with chart id '%s' (title: '%s') does not match systemd services groups", cg->id, cg->chart_id, cg->chart_title);
798
}
799
800
struct cgroup *cgroup_add(const char *id) {
@@ -1509,29 +1524,6 @@ void update_cgroup_charts(int update_every) {
1524
// ----------------------------------------------------------------------------
1525
// cgroups main
1526
1512
-int do_sys_fs_cgroup(int update_every, usec_t dt) {
1513
- (void)dt;
1514
-
1515
- static int cgroup_global_config_read = 0;
1516
- static time_t last_run = 0;
1517
- time_t now = now_realtime_sec();
1518
-
1519
- if(unlikely(!cgroup_global_config_read)) {
1520
- read_cgroup_plugin_configuration();
1521
- cgroup_global_config_read = 1;
1522
- }
1523
-
1524
- if(unlikely(cgroup_enable_new_cgroups_detected_at_runtime && now - last_run > cgroup_check_for_new_every)) {
1525
- find_all_cgroups();
1526
- last_run = now;
1527
- }
1528
-
1529
- read_all_cgroups(cgroup_root);
1530
- update_cgroup_charts(update_every);
1531
-
1532
- return 0;
1533
-}
1534
-
1527
void *cgroups_main(void *ptr) {
1528
struct netdata_static_thread *static_thread = (struct netdata_static_thread *)ptr;
1529
@@ -1546,51 +1538,45 @@ void *cgroups_main(void *ptr) {
1538
struct rusage thread;
1539
1540
// when ZERO, attempt to do it
1549
- int vdo_sys_fs_cgroup = 0;
1550
- int vdo_cpu_netdata = !config_get_boolean("plugin:cgroups", "cgroups plugin resources", 1);
1541
+ int vdo_cpu_netdata = config_get_boolean("plugin:cgroups", "cgroups plugin resources", 1);
1542
1552
- // keep track of the time each module was called
1553
- usec_t sutime_sys_fs_cgroup = 0ULL;
1554
-
1555
- // the next time we will run - aligned properly
1556
- usec_t sunext = (now_realtime_sec() - (now_realtime_sec() % rrd_update_every) + rrd_update_every) * USEC_PER_SEC;
1543
+ read_cgroup_plugin_configuration();
1544
1545
RRDSET *stcpu_thread = NULL;
1546
1547
+ usec_t step = cgroup_update_every * USEC_PER_SEC;
1548
+ usec_t find_every = cgroup_check_for_new_every * USEC_PER_SEC, find_next = 0;
1549
for(;;) {
1561
- usec_t sunow;
1562
- if(unlikely(netdata_exit)) break;
1563
-
1564
- // delay until it is our time to run
1565
- while((sunow = now_realtime_usec()) < sunext)
1566
- sleep_usec(sunext - sunow);
1550
+ usec_t now = now_monotonic_usec();
1551
+ usec_t next = now - (now % step) + step;
1552
1568
- // find the next time we need to run
1569
- while(now_realtime_usec() > sunext)
1570
- sunext += rrd_update_every * USEC_PER_SEC;
1553
+ while(now < next) {
1554
+ sleep_usec(next - now);
1555
+ now = now_monotonic_usec();
1556
+ }
1557
1558
if(unlikely(netdata_exit)) break;
1559
1560
// BEGIN -- the job to be done
1561
1576
- if(!vdo_sys_fs_cgroup) {
1577
- debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_sys_fs_cgroup().");
1578
- sunow = now_realtime_usec();
1579
- vdo_sys_fs_cgroup = do_sys_fs_cgroup(rrd_update_every, (sutime_sys_fs_cgroup > 0)?sunow - sutime_sys_fs_cgroup:0ULL);
1580
- sutime_sys_fs_cgroup = sunow;
1562
+ if(unlikely(now >= find_next)) {
1563
+ find_all_cgroups();
1564
+ find_next = now + find_every;
1565
}
1582
- if(unlikely(netdata_exit)) break;
1566
+
1567
+ read_all_cgroups(cgroup_root);
1568
+ update_cgroup_charts(cgroup_update_every);
1569
1570
// END -- the job is done
1571
1572
// --------------------------------------------------------------------
1573
1588
- if(!vdo_cpu_netdata) {
1574
+ if(vdo_cpu_netdata) {
1575
getrusage(RUSAGE_THREAD, &thread);
1576
1577
if(!stcpu_thread) stcpu_thread = rrdset_find("netdata.plugin_cgroups_cpu");
1578
if(!stcpu_thread) {
1593
- stcpu_thread = rrdset_create("netdata", "plugin_cgroups_cpu", NULL, "cgroups", NULL, "NetData CGroups Plugin CPU usage", "milliseconds/s", 132000, rrd_update_every, RRDSET_TYPE_STACKED);
1579
+ stcpu_thread = rrdset_create("netdata", "plugin_cgroups_cpu", NULL, "cgroups", NULL, "NetData CGroups Plugin CPU usage", "milliseconds/s", 132000, cgroup_update_every, RRDSET_TYPE_STACKED);
1580
1581
rrddim_add(stcpu_thread, "user", NULL, 1, 1000, RRDDIM_INCREMENTAL);
1582
rrddim_add(stcpu_thread, "system", NULL, 1, 1000, RRDDIM_INCREMENTAL);