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