fixed memory leak in cgroups; cgroups have now simple patterns for excluding cgroups and paths
Costa Tsaousis (ktsaou) committed
Jan 14, 2017 at 22:01 UTC
97dc47efa3c29266bc1a295485fa8b5cc280b31e
4 files changed
+60
-50
src/main.c
+2
-2
@@ -20,9 +20,9 @@ void netdata_cleanup_and_exit(int ret) {
20
21
#ifdef NETDATA_INTERNAL_CHECKS
22
// kill all childs
23
- kill_childs();
23
+ //kill_childs();
24
25
- // free all memory
25
+ // free database
26
rrdset_free_all();
27
#endif
28
src/plugin_proc_diskspace.c
+4
-5
@@ -1,6 +1,6 @@
1
#include "common.h"
2
3
-#define DELAULT_EXLUDED_PATHS "/proc/ /sys/ /var/run/user/ /run/user/"
3
+#define DELAULT_EXLUDED_PATHS "/proc/* /sys/* /var/run/user/* /run/user/*"
4
5
static struct mountinfo *disk_mountinfo_root = NULL;
6
static int check_for_new_mountpoints_every = 15;
@@ -37,19 +37,18 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) {
37
38
if(unlikely(!mount_points)) {
39
const char *s;
40
+ NETDATA_SIMPLE_PREFIX_MODE mode = NETDATA_SIMPLE_PATTERN_MODE_EXACT;
41
42
if(config_exists("plugin:proc:/proc/diskstats", "exclude space metrics on paths") && !config_exists("plugin:proc:diskspace", "exclude space metrics on paths")) {
43
// the config exists in the old section
44
s = config_get("plugin:proc:/proc/diskstats", "exclude space metrics on paths", DELAULT_EXLUDED_PATHS);
44
-
45
- // set it to the new section
46
- config_set("plugin:proc:diskspace", "exclude space metrics on paths", s);
45
+ mode = NETDATA_SIMPLE_PATTERN_MODE_PREFIX;
46
}
47
else
48
s = config_get("plugin:proc:diskspace", "exclude space metrics on paths", DELAULT_EXLUDED_PATHS);
49
50
mount_points = dictionary_create(DICTIONARY_FLAG_SINGLE_THREADED);
52
- excluded_mountpoints = netdata_simple_pattern_list_create(s, NETDATA_SIMPLE_PATTERN_MODE_PREFIX);
51
+ excluded_mountpoints = netdata_simple_pattern_list_create(s, mode);
52
}
53
54
struct mount_point_metadata *m = dictionary_get(mount_points, mi->mount_point);
src/sys_fs_cgroup.c
+52
-43
@@ -19,8 +19,11 @@ static int cgroup_root_count = 0;
19
static int cgroup_root_max = 500;
20
static int cgroup_max_depth = 0;
21
22
+static NETDATA_SIMPLE_PATTERN *disabled_cgroups_patterns = NULL;
23
+static NETDATA_SIMPLE_PATTERN *disabled_cgroup_paths = NULL;
24
+
25
void read_cgroup_plugin_configuration() {
23
- cgroup_check_for_new_every = config_get_number("plugin:cgroups", "check for new cgroups every", cgroup_check_for_new_every);
26
+ cgroup_check_for_new_every = (int)config_get_number("plugin:cgroups", "check for new cgroups every", cgroup_check_for_new_every);
27
28
cgroup_enable_cpuacct_stat = config_get_boolean_ondemand("plugin:cgroups", "enable cpuacct stat", cgroup_enable_cpuacct_stat);
29
cgroup_enable_cpuacct_usage = config_get_boolean_ondemand("plugin:cgroups", "enable cpuacct usage", cgroup_enable_cpuacct_usage);
@@ -70,11 +73,38 @@ void read_cgroup_plugin_configuration() {
73
snprintfz(filename, FILENAME_MAX, "%s%s", global_host_prefix, s);
74
cgroup_devices_base = config_get("plugin:cgroups", "path to /sys/fs/cgroup/devices", filename);
75
73
- cgroup_root_max = config_get_number("plugin:cgroups", "max cgroups to allow", cgroup_root_max);
74
- cgroup_max_depth = config_get_number("plugin:cgroups", "max cgroups depth to monitor", cgroup_max_depth);
76
+ cgroup_root_max = (int)config_get_number("plugin:cgroups", "max cgroups to allow", cgroup_root_max);
77
+ cgroup_max_depth = (int)config_get_number("plugin:cgroups", "max cgroups depth to monitor", cgroup_max_depth);
78
79
cgroup_enable_new_cgroups_detected_at_runtime = config_get_boolean("plugin:cgroups", "enable new cgroups detected at run time", cgroup_enable_new_cgroups_detected_at_runtime);
80
81
+ disabled_cgroups_patterns = netdata_simple_pattern_list_create(
82
+ config_get("plugin:cgroups", "disable by default cgroups matching",
83
+ " lxc docker libvirt qemu systemd "
84
+ " system system.slice "
85
+ " machine machine.slice "
86
+ " user user.slice "
87
+ " init.scope "
88
+ " *.swap "
89
+ " *.slice "
90
+ " *.user "
91
+ " *.mount "
92
+ " *.service "
93
+ " *.partition "
94
+ " */ns " // lxc/*/ns #1397
95
+ ), NETDATA_SIMPLE_PATTERN_MODE_EXACT);
96
+
97
+ disabled_cgroup_paths = netdata_simple_pattern_list_create(
98
+ config_get("plugin:cgroups", "disable by default cgroup paths matching",
99
+ " system.slice "
100
+ " system "
101
+ " systemd "
102
+ " user.slice "
103
+ " user "
104
+ " init.scope "
105
+ " *-qemu "
106
+ ), NETDATA_SIMPLE_PATTERN_MODE_EXACT);
107
+
108
mountinfo_free(root);
109
}
110
@@ -173,6 +203,7 @@ struct cpuacct_usage {
203
};
204
205
#define CGROUP_OPTIONS_DISABLED_DUPLICATE 0x00000001
206
+#define CGROUP_OPTIONS_PART_OF_GROUP 0x00000002
207
208
struct cgroup {
209
uint32_t options;
@@ -659,7 +690,7 @@ void cgroup_get_chart_id(struct cgroup *cg) {
690
}
691
692
struct cgroup *cgroup_add(const char *id) {
662
- debug(D_CGROUP, "adding cgroup '%s'", id);
693
+ debug(D_CGROUP, "adding cgroup with id '%s'", id);
694
695
if(cgroup_root_count >= cgroup_root_max) {
696
info("Maximum number of cgroups reached (%d). Not adding cgroup '%s'", cgroup_root_count, id);
@@ -676,40 +707,11 @@ struct cgroup *cgroup_add(const char *id) {
707
}
708
else {
709
if(*chart_id == '/') chart_id++;
679
-
680
- size_t len = strlen(chart_id);
681
-
682
- // disable by default the parent cgroup
683
- // for known cgroup managers
684
- if(!strcmp(chart_id, "lxc") ||
685
- !strcmp(chart_id, "docker") ||
686
- !strcmp(chart_id, "libvirt") ||
687
- !strcmp(chart_id, "qemu") ||
688
- !strcmp(chart_id, "systemd") ||
689
- !strcmp(chart_id, "system.slice") ||
690
- !strcmp(chart_id, "machine.slice") ||
691
- !strcmp(chart_id, "init.scope") ||
692
- !strcmp(chart_id, "user") ||
693
- !strcmp(chart_id, "system") ||
694
- !strcmp(chart_id, "machine") ||
695
- // starts with them
696
- (len > 5 && !strncmp(chart_id, "user/", 5)) ||
697
- (len > 11 && !strncmp(chart_id, "user.slice/", 11)) ||
698
- // ends with them
699
- (len > 5 && !strncmp(&chart_id[len - 5], ".user", 5)) ||
700
- (len > 5 && !strncmp(&chart_id[len - 5], ".swap", 5)) ||
701
- (len > 6 && !strncmp(&chart_id[len - 6], ".slice", 6)) ||
702
- (len > 6 && !strncmp(&chart_id[len - 6], ".mount", 6)) ||
703
- (len > 8 && !strncmp(&chart_id[len - 8], ".session", 8)) ||
704
- (len > 8 && !strncmp(&chart_id[len - 8], ".service", 8)) ||
705
- (len > 10 && !strncmp(&chart_id[len - 10], ".partition", 10)) ||
706
- // starts and ends with them
707
- (len > 7 && !strncmp(chart_id, "lxc/", 4) && !strncmp(&chart_id[len - 3], "/ns", 3)) // #1397
708
- ) {
710
+ if(netdata_simple_pattern_list_matches(disabled_cgroups_patterns, chart_id))
711
def = 0;
710
- }
712
}
712
- debug(D_CGROUP, "cgroup '%s' (chart_id '%s') is (by default) %s", id, chart_id, (def)?"enabled":"disabled");
713
+
714
+ debug(D_CGROUP, "cgroup with id '%s' (chart_id '%s') is (by default) %s", id, chart_id, (def)?"enabled":"disabled");
715
716
struct cgroup *cg = callocz(1, sizeof(struct cgroup));
717
@@ -736,11 +738,11 @@ struct cgroup *cgroup_add(const char *id) {
738
// fix the name by calling the external script
739
cgroup_get_chart_id(cg);
740
739
- debug(D_CGROUP, "adding cgroup '%s' with chart id '%s'", id, chart_id);
741
+ debug(D_CGROUP, "adding cgroup '%s' ('%s') with chart id '%s' ('%s')", cg->id, id, cg->chart_id, chart_id);
742
743
char option[FILENAME_MAX + 1];
744
snprintfz(option, FILENAME_MAX, "enable cgroup %s", cg->chart_title);
743
- cg->enabled = config_get_boolean("plugin:cgroups", option, def);
745
+ cg->enabled = (char)config_get_boolean("plugin:cgroups", option, def);
746
747
if(cg->enabled) {
748
struct cgroup *t;
@@ -780,17 +782,25 @@ void cgroup_free(struct cgroup *cg) {
782
783
freez(cg->cpuacct_stat.filename);
784
freez(cg->cpuacct_usage.filename);
785
+
786
freez(cg->memory.filename);
787
+ freez(cg->memory.filename_failcnt);
788
+ freez(cg->memory.filename_usage_in_bytes);
789
+ freez(cg->memory.filename_msw_usage_in_bytes);
790
+
791
freez(cg->io_service_bytes.filename);
792
freez(cg->io_serviced.filename);
793
+
794
freez(cg->throttle_io_service_bytes.filename);
795
freez(cg->throttle_io_serviced.filename);
796
+
797
freez(cg->io_merged.filename);
798
freez(cg->io_queued.filename);
799
800
freez(cg->id);
801
freez(cg->chart_id);
802
freez(cg->chart_title);
803
+
804
freez(cg);
805
806
cgroup_root_count--;
@@ -879,8 +889,7 @@ int find_dir_in_subdirs(const char *base, const char *this, void (*callback)(con
889
// do not decent in directories we are not interested
890
// https://github.com/firehol/netdata/issues/345
891
int def = 1;
882
- size_t len = strlen(r);
883
- if(len > 5 && !strncmp(&r[len - 5], "-qemu", 5))
892
+ if(netdata_simple_pattern_list_matches(disabled_cgroup_paths, r))
893
def = 0;
894
895
// we check for this option here
@@ -1133,13 +1142,13 @@ void update_cgroup_charts(int update_every) {
1142
RRDSET *st;
1143
1144
for(cg = cgroup_root; cg ; cg = cg->next) {
1136
- if(!cg->available || !cg->enabled)
1145
+ if(!cg->available || !cg->enabled || cg->options & CGROUP_OPTIONS_PART_OF_GROUP)
1146
continue;
1147
1148
if(cg->id[0] == '\0')
1149
strcpy(type, "cgroup_root");
1141
- else if(cg->id[0] == '/')
1142
- snprintfz(type, RRD_ID_LENGTH_MAX, "cgroup_%s", cg->chart_id);
1150
+ //else if(cg->id[0] == '/')
1151
+ // snprintfz(type, RRD_ID_LENGTH_MAX, "cgroup_%s", cg->chart_id);
1152
else
1153
snprintfz(type, RRD_ID_LENGTH_MAX, "cgroup_%s", cg->chart_id);
1154
src/web_server.c
+2
@@ -470,6 +470,8 @@ void *socket_listen_main_multi_threaded(void *ptr) {
470
debug(D_WEB_CLIENT, "LISTENER: exit!");
471
close_listen_sockets();
472
473
+ freez(fds);
474
+
475
static_thread->enabled = 0;
476
static_thread->thread = NULL;
477
pthread_exit(NULL);