@cryptotaxi247 / netdata-1 / commits / 7d28ae33c

allow certain paths to be excluded from disk space statistics; fixes #1206

Costa Tsaousis (ktsaou) committed Nov 5, 2016 at 03:42 UTC 7d28ae33c4227645b918a9f7829cea9801eb815a
1 file changed +103 -11
src/proc_diskstats.c
+103 -11
@@ -56,10 +56,88 @@ static inline void mountinfo_reload(int force) {
56 }
57 }
58
59 +
60 +// linked list of mount points that are by default disabled
61 +static struct excluded_mount_point {
62 + const char *prefix;
63 + size_t len;
64 + struct excluded_mount_point *next;
65 +} *excluded_mount_points = NULL;
66 +
67 +static inline int is_mount_point_excluded(const char *mount_point) {
68 + static int initialized = 0;
69 +
70 + if(unlikely(!initialized)) {
71 + initialized = 1;
72 +
73 + char *a = config_get("plugin:proc:/proc/diskstats", "exclude space metrics on paths", "/var/run/user/ /run/user/");
74 + if(a && *a) {
75 + char *s = a;
76 +
77 + while(s && *s) {
78 + // skip all spaces
79 + while(isspace(*s)) s++;
80 +
81 + // empty string
82 + if(unlikely(!*s)) break;
83 +
84 + // find the next space
85 + char *c = s;
86 + while(*c && !isspace(*c)) c++;
87 +
88 + char *n;
89 + if(likely(*c)) n = c + 1;
90 + else n = NULL;
91 +
92 + // terminate our string
93 + *c = '\0';
94 +
95 + // allocate the structure
96 + struct excluded_mount_point *m = mallocz(sizeof(struct excluded_mount_point));
97 + m->prefix = strdup(s);
98 + m->len = strlen(m->prefix);
99 + m->next = excluded_mount_points;
100 + excluded_mount_points = m;
101 +
102 + // prepare for next loop
103 + s = n;
104 + if(likely(n)) *c = ' ';
105 + }
106 + }
107 + }
108 +
109 + size_t len = strlen(mount_point);
110 + struct excluded_mount_point *m;
111 + for(m = excluded_mount_points; m ; m = m->next) {
112 + if(m->len <= len) {
113 + // fprintf(stderr, "SPACE: comparing '%s' with '%s'\n", mount_point, m->prefix);
114 + if(strncmp(m->prefix, mount_point, m->len) == 0) {
115 + // fprintf(stderr, "SPACE: excluded '%s'\n", mount_point);
116 + return 1;
117 + }
118 + }
119 + }
120 +
121 + // fprintf(stderr, "SPACE: included '%s'\n", mount_point);
122 + return 0;
123 +}
124 +
125 +// Data to be stored in DICTIONARY mount_points used by do_disk_space_stats().
126 +// This DICTIONARY is used to lookup the settings of the mount point on each iteration.
127 +struct mount_point_metadata {
128 + int do_space;
129 + int do_inodes;
130 +};
131 +
132 static inline void do_disk_space_stats(struct disk *d, const char *mount_point, const char *mount_source, const char *disk, const char *family, int update_every, unsigned long long dt) {
133 + static DICTIONARY *mount_points = NULL;
134 int do_space, do_inodes;
135
62 - if(d) {
136 + if(unlikely(!mount_points)) {
137 + mount_points = dictionary_create(DICTIONARY_FLAG_SINGLE_THREADED);
138 + }
139 +
140 + if(unlikely(d)) {
141 // verify we collected the metrics for the right disk.
142 // if not the mountpoint has changed.
143
@@ -80,19 +158,33 @@ static inline void do_disk_space_stats(struct disk *d, const char *mount_point,
158 do_inodes = d->do_inodes;
159 }
160 else {
83 - char var_name[4096 + 1];
84 - snprintfz(var_name, 4096, "plugin:proc:/proc/diskstats:%s", mount_point);
161 + struct mount_point_metadata *m = dictionary_get(mount_points, mount_point);
162 + if(!m) {
163 + char var_name[4096 + 1];
164 + snprintfz(var_name, 4096, "plugin:proc:/proc/diskstats:%s", mount_point);
165
86 - int def_space = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "space usage for all disks", CONFIG_ONDEMAND_ONDEMAND);
87 - int def_inodes = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "inodes usage for all disks", CONFIG_ONDEMAND_ONDEMAND);
166 + int def_space = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "space usage for all disks", CONFIG_ONDEMAND_ONDEMAND);
167 + int def_inodes = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "inodes usage for all disks", CONFIG_ONDEMAND_ONDEMAND);
168
89 - if(unlikely(strncmp(mount_point, "/run/user/", 10) == 0)) {
90 - def_space = CONFIG_ONDEMAND_NO;
91 - def_inodes = CONFIG_ONDEMAND_NO;
92 - }
169 + if(is_mount_point_excluded(mount_point)) {
170 + def_space = CONFIG_ONDEMAND_NO;
171 + def_inodes = CONFIG_ONDEMAND_NO;
172 + }
173
94 - do_space = config_get_boolean_ondemand(var_name, "space usage", def_space);
95 - do_inodes = config_get_boolean_ondemand(var_name, "inodes usage", def_inodes);
174 + do_space = config_get_boolean_ondemand(var_name, "space usage", def_space);
175 + do_inodes = config_get_boolean_ondemand(var_name, "inodes usage", def_inodes);
176 +
177 + struct mount_point_metadata mp = {
178 + .do_space = do_space,
179 + .do_inodes = do_inodes
180 + };
181 +
182 + dictionary_set(mount_points, mount_point, &mp, sizeof(struct mount_point_metadata));
183 + }
184 + else {
185 + do_space = m->do_space;
186 + do_inodes = m->do_inodes;
187 + }
188 }
189
190 if(do_space == CONFIG_ONDEMAND_NO && do_inodes == CONFIG_ONDEMAND_NO)