@cryptotaxi247 / netdata-1 / commits / 7b73fd49d

do not monitor disk space on read-only mounts

Costa Tsaousis (ktsaou) committed Dec 11, 2016 at 02:53 UTC 7b73fd49d42e3dba764a3f96a48d49f918c5eb20
3 files changed +61 -88
src/proc_diskstats.c
+39 -88
@@ -129,9 +129,12 @@ struct mount_point_metadata {
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, const char *filesystem, int update_every, unsigned long long dt) {
132 +static inline void do_disk_space_stats(struct mountinfo *mi, int update_every, unsigned long long dt) {
133 (void)dt;
134
135 + const char *family = mi->mount_point;
136 + const char *disk = mi->persistent_id;
137 +
138 static DICTIONARY *mount_points = NULL;
139 int do_space, do_inodes;
140
@@ -139,66 +142,40 @@ static inline void do_disk_space_stats(struct disk *d, const char *mount_point,
142 mount_points = dictionary_create(DICTIONARY_FLAG_SINGLE_THREADED);
143 }
144
142 - if(unlikely(d)) {
143 - // verify we collected the metrics for the right disk.
144 - // if not the mountpoint has changed.
145 -
146 - struct stat buff_stat;
147 - if(unlikely(stat(mount_point, &buff_stat) == -1)) {
148 - error("Failed to stat() for '%s' (disk '%s')", mount_point, disk);
149 - return;
150 - }
151 - else if(unlikely(major(buff_stat.st_dev) != d->major || minor(buff_stat.st_dev) != d->minor)) {
152 - error("Disk '%s' (disk '%s') switched major:minor", mount_point, disk);
153 - freez(d->mount_point);
154 - d->mount_point = NULL;
155 - d->mount_point_hash = 0;
156 - return;
157 - }
158 -
159 - do_space = d->do_space;
160 - do_inodes = d->do_inodes;
161 - }
162 - else {
163 - struct mount_point_metadata *m = dictionary_get(mount_points, mount_point);
164 - if(unlikely(!m)) {
165 - char var_name[4096 + 1];
166 - snprintfz(var_name, 4096, "plugin:proc:/proc/diskstats:%s", mount_point);
145 + struct mount_point_metadata *m = dictionary_get(mount_points, mi->mount_point);
146 + if(unlikely(!m)) {
147 + char var_name[4096 + 1];
148 + snprintfz(var_name, 4096, "plugin:proc:/proc/diskstats:%s", mi->mount_point);
149
168 - int def_space = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "space usage for all disks", CONFIG_ONDEMAND_ONDEMAND);
169 - int def_inodes = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "inodes usage for all disks", CONFIG_ONDEMAND_ONDEMAND);
150 + int def_space = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "space usage for all disks", CONFIG_ONDEMAND_ONDEMAND);
151 + int def_inodes = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "inodes usage for all disks", CONFIG_ONDEMAND_ONDEMAND);
152
171 - if(unlikely(is_mount_point_excluded(mount_point))) {
172 - def_space = CONFIG_ONDEMAND_NO;
173 - def_inodes = CONFIG_ONDEMAND_NO;
174 - }
175 - else if(unlikely(filesystem && !strcmp(filesystem, "iso9660"))) {
176 - def_space = CONFIG_ONDEMAND_NO;
177 - def_inodes = CONFIG_ONDEMAND_NO;
178 - }
153 + if(unlikely(is_mount_point_excluded(mi->mount_point))) {
154 + def_space = CONFIG_ONDEMAND_NO;
155 + def_inodes = CONFIG_ONDEMAND_NO;
156 + }
157
180 - do_space = config_get_boolean_ondemand(var_name, "space usage", def_space);
181 - do_inodes = config_get_boolean_ondemand(var_name, "inodes usage", def_inodes);
158 + do_space = config_get_boolean_ondemand(var_name, "space usage", def_space);
159 + do_inodes = config_get_boolean_ondemand(var_name, "inodes usage", def_inodes);
160
183 - struct mount_point_metadata mp = {
184 - .do_space = do_space,
185 - .do_inodes = do_inodes
186 - };
161 + struct mount_point_metadata mp = {
162 + .do_space = do_space,
163 + .do_inodes = do_inodes
164 + };
165
188 - dictionary_set(mount_points, mount_point, &mp, sizeof(struct mount_point_metadata));
189 - }
190 - else {
191 - do_space = m->do_space;
192 - do_inodes = m->do_inodes;
193 - }
166 + dictionary_set(mount_points, mi->mount_point, &mp, sizeof(struct mount_point_metadata));
167 + }
168 + else {
169 + do_space = m->do_space;
170 + do_inodes = m->do_inodes;
171 }
172
173 if(unlikely(do_space == CONFIG_ONDEMAND_NO && do_inodes == CONFIG_ONDEMAND_NO))
174 return;
175
176 struct statvfs buff_statvfs;
200 - if (statvfs(mount_point, &buff_statvfs) < 0) {
201 - error("Failed statvfs() for '%s' (disk '%s')", mount_point, disk);
177 + if (statvfs(mi->mount_point, &buff_statvfs) < 0) {
178 + error("Failed statvfs() for '%s' (disk '%s')", mi->mount_point, disk);
179 return;
180 }
181
@@ -217,7 +194,7 @@ static inline void do_disk_space_stats(struct disk *d, const char *mount_point,
194
195 #ifdef NETDATA_INTERNAL_CHECKS
196 if(unlikely(btotal != bavail + breserved_root + bused))
220 - error("Disk block statistics for '%s' (disk '%s') do not sum up: total = %llu, available = %llu, reserved = %llu, used = %llu", mount_point, disk, (unsigned long long)btotal, (unsigned long long)bavail, (unsigned long long)breserved_root, (unsigned long long)bused);
197 + error("Disk block statistics for '%s' (disk '%s') do not sum up: total = %llu, available = %llu, reserved = %llu, used = %llu", mi->mount_point, disk, (unsigned long long)btotal, (unsigned long long)bavail, (unsigned long long)breserved_root, (unsigned long long)bused);
198 #endif
199
200 // --------------------------------------------------------------------------
@@ -230,7 +207,7 @@ static inline void do_disk_space_stats(struct disk *d, const char *mount_point,
207
208 #ifdef NETDATA_INTERNAL_CHECKS
209 if(unlikely(btotal != bavail + breserved_root + bused))
233 - error("Disk inode statistics for '%s' (disk '%s') do not sum up: total = %llu, available = %llu, reserved = %llu, used = %llu", mount_point, disk, (unsigned long long)ftotal, (unsigned long long)favail, (unsigned long long)freserved_root, (unsigned long long)fused);
210 + error("Disk inode statistics for '%s' (disk '%s') do not sum up: total = %llu, available = %llu, reserved = %llu, used = %llu", mi->mount_point, disk, (unsigned long long)ftotal, (unsigned long long)favail, (unsigned long long)freserved_root, (unsigned long long)fused);
211 #endif
212
213 // --------------------------------------------------------------------------
@@ -241,7 +218,7 @@ static inline void do_disk_space_stats(struct disk *d, const char *mount_point,
218 st = rrdset_find_bytype("disk_space", disk);
219 if(unlikely(!st)) {
220 char title[4096 + 1];
244 - snprintfz(title, 4096, "Disk Space Usage for %s [%s]", family, mount_source);
221 + snprintfz(title, 4096, "Disk Space Usage for %s [%s]", family, mi->mount_source);
222 st = rrdset_create("disk_space", disk, NULL, family, "disk.space", title, "GB", 2023, update_every, RRDSET_TYPE_STACKED);
223
224 rrddim_add(st, "avail", NULL, bsize, 1024*1024*1024, RRDDIM_ABSOLUTE);
@@ -250,9 +227,9 @@ static inline void do_disk_space_stats(struct disk *d, const char *mount_point,
227 }
228 else rrdset_next(st);
229
253 - rrddim_set(st, "avail", bavail);
254 - rrddim_set(st, "used", bused);
255 - rrddim_set(st, "reserved_for_root", breserved_root);
230 + rrddim_set(st, "avail", (collected_number)bavail);
231 + rrddim_set(st, "used", (collected_number)bused);
232 + rrddim_set(st, "reserved_for_root", (collected_number)breserved_root);
233 rrdset_done(st);
234 }
235
@@ -262,7 +239,7 @@ static inline void do_disk_space_stats(struct disk *d, const char *mount_point,
239 st = rrdset_find_bytype("disk_inodes", disk);
240 if(unlikely(!st)) {
241 char title[4096 + 1];
265 - snprintfz(title, 4096, "Disk Files (inodes) Usage for %s [%s]", family, mount_source);
242 + snprintfz(title, 4096, "Disk Files (inodes) Usage for %s [%s]", family, mi->mount_source);
243 st = rrdset_create("disk_inodes", disk, NULL, family, "disk.inodes", title, "Inodes", 2024, update_every, RRDSET_TYPE_STACKED);
244
245 rrddim_add(st, "avail", NULL, 1, 1, RRDDIM_ABSOLUTE);
@@ -271,9 +248,9 @@ static inline void do_disk_space_stats(struct disk *d, const char *mount_point,
248 }
249 else rrdset_next(st);
250
274 - rrddim_set(st, "avail", favail);
275 - rrddim_set(st, "used", fused);
276 - rrddim_set(st, "reserved_for_root", freserved_root);
251 + rrddim_set(st, "avail", (collected_number)favail);
252 + rrddim_set(st, "used", (collected_number)fused);
253 + rrddim_set(st, "reserved_for_root", (collected_number)freserved_root);
254 rrdset_done(st);
255 }
256 }
@@ -866,15 +843,6 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
843 rrdset_done(st);
844 }
845 }
869 -
870 -/*
871 - // --------------------------------------------------------------------------
872 - // space metrics
873 -
874 - if(unlikely( d->mount_point && (d->do_space || d->do_inodes) )) {
875 - do_disk_space_stats(d, d->mount_point, disk, disk, family, NULL, update_every, dt);
876 - }
877 -*/
846 }
847
848 // --------------------------------------------------------------------------
@@ -882,27 +850,10 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
850
851 struct mountinfo *mi;
852 for(mi = disk_mountinfo_root; mi ;mi = mi->next) {
885 - if(unlikely(mi->flags & (MOUNTINFO_IS_DUMMY|MOUNTINFO_IS_BIND|MOUNTINFO_IS_SAME_DEV|MOUNTINFO_NO_STAT|MOUNTINFO_NO_SIZE)))
886 - continue;
887 -
888 -/*
889 - // skip the ones with block devices
890 - int skip = 0;
891 - struct disk *d;
892 - for(d = disk_root; d ;d = d->next) {
893 - if(unlikely(d->mount_point && mi->mount_point_hash == d->mount_point_hash && strcmp(mi->mount_point, d->mount_point))) {
894 - skip = 1;
895 - break;
896 - }
897 - }
898 -
899 - if(unlikely(skip))
853 + if(unlikely(mi->flags & (MOUNTINFO_IS_DUMMY|MOUNTINFO_IS_BIND|MOUNTINFO_IS_SAME_DEV|MOUNTINFO_NO_STAT|MOUNTINFO_NO_SIZE|MOUNTINFO_READONLY)))
854 continue;
855
902 - // fprintf(stderr, "Will process mount point '%s', source '%s', filesystem '%s'\n", mi->mount_point, mi->mount_source, mi->filesystem);
903 -*/
904 -
905 - do_disk_space_stats(NULL, mi->mount_point, mi->mount_source, mi->persistent_id, mi->mount_point, mi->filesystem, update_every, dt);
856 + do_disk_space_stats(mi, update_every, dt);
857 }
858
859 return 0;
src/proc_self_mountinfo.c
+21
@@ -157,6 +157,21 @@ static char *strdupz_decoding_octal(const char *string) {
157 return buffer;
158 }
159
160 +static inline int is_read_only(const char *s) {
161 + if(!s) return 0;
162 +
163 + size_t len = strlen(s);
164 + if(len < 2) return 0;
165 + if(len == 2) {
166 + if(!strcmp(s, "ro")) return 1;
167 + return 0;
168 + }
169 + if(!strncmp(s, "ro,", 3)) return 1;
170 + if(!strncmp(&s[len - 3], ",ro", 3)) return 1;
171 + if(strstr(s, ",ro,")) return 1;
172 + return 0;
173 +}
174 +
175 // read the whole mountinfo into a linked list
176 struct mountinfo *mountinfo_read() {
177 char filename[FILENAME_MAX + 1];
@@ -214,6 +229,9 @@ struct mountinfo *mountinfo_read() {
229
230 mi->mount_options = strdupz(procfile_lineword(ff, l, w)); w++;
231
232 + if(unlikely(is_read_only(mi->mount_options)))
233 + mi->flags |= MOUNTINFO_READONLY;
234 +
235 // count the optional fields
236 /*
237 unsigned long wo = w;
@@ -254,6 +272,9 @@ struct mountinfo *mountinfo_read() {
272
273 mi->super_options = strdupz(procfile_lineword(ff, l, w)); w++;
274
275 + if(unlikely(is_read_only(mi->super_options)))
276 + mi->flags |= MOUNTINFO_READONLY;
277 +
278 if(unlikely(ME_DUMMY(mi->mount_source, mi->filesystem)))
279 mi->flags |= MOUNTINFO_IS_DUMMY;
280
src/proc_self_mountinfo.h
+1
@@ -7,6 +7,7 @@
7 #define MOUNTINFO_IS_SAME_DEV 0x00000008
8 #define MOUNTINFO_NO_STAT 0x00000010
9 #define MOUNTINFO_NO_SIZE 0x00000020
10 +#define MOUNTINFO_READONLY 0x00000040
11
12 struct mountinfo {
13 long id; // mount ID: unique identifier of the mount (may be reused after umount(2)).