@cryptotaxi247 / netdata-1 / commits / 97dc47efa

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);