@cryptotaxi247 / netdata-1 / commits / 7780e7311

refactored the code to eliminate several config_get() per disk on every iteration; renamed several variables to make it more clear; moved code to the proper place, etc

Costa Tsaousis (ktsaou) committed May 21, 2016 at 17:30 UTC 7780e7311f3740f314fe664703d9830bfbaa07e1
1 file changed +439 -291
src/proc_diskstats.c
+439 -291
@@ -27,17 +27,35 @@
27 #define DISK_TYPE_PARTITION 2
28 #define DISK_TYPE_CONTAINER 3
29
30 -struct disk {
30 +static struct disk {
31 + char *disk; // the name of the disk (sda, sdb, etc)
32 unsigned long major;
33 unsigned long minor;
34 + int sector_size;
35 int type;
36 char *mount_point;
37 +
38 + // disk options caching
39 + int configured;
40 + int do_io;
41 + int do_ops;
42 + int do_mops;
43 + int do_iotime;
44 + int do_qops;
45 + int do_util;
46 + int do_backlog;
47 + int do_space;
48 + int do_inodes;
49 +
50 struct disk *next;
51 } *disk_root = NULL;
52
38 -struct disk *get_disk(unsigned long major, unsigned long minor) {
53 +static struct mountinfo *disk_mountinfo_root = NULL;
54 +
55 +static struct disk *get_disk(unsigned long major, unsigned long minor, char *disk) {
56 + static char path_to_get_hw_sector_size[FILENAME_MAX + 1] = "";
57 + static char path_to_get_hw_sector_size_partitions[FILENAME_MAX + 1] = "";
58 static char path_find_block_device[FILENAME_MAX + 1] = "";
40 - static struct mountinfo *mountinfo_root = NULL;
59 struct disk *d;
60
61 // search for it in our RAM list.
@@ -52,20 +70,17 @@ struct disk *get_disk(unsigned long major, unsigned long minor) {
70 if(likely(d))
71 return d;
72
55 - if(unlikely(!path_find_block_device[0])) {
56 - char dirname[FILENAME_MAX + 1];
57 - snprintfz(dirname, FILENAME_MAX, "%s%s", global_host_prefix, "/sys/dev/block/%lu:%lu/%s");
58 - snprintfz(path_find_block_device, FILENAME_MAX, "%s", config_get("plugin:proc:/proc/diskstats", "path to get block device infos", dirname));
59 - }
60 -
73 // not found
74 // create a new disk structure
75 d = (struct disk *)malloc(sizeof(struct disk));
76 if(!d) fatal("Cannot allocate memory for struct disk in proc_diskstats.");
77
78 + d->disk = strdup(disk);
79 d->major = major;
80 d->minor = minor;
81 d->type = DISK_TYPE_PHYSICAL; // Default type. Changed later if not correct.
82 + d->configured = 0;
83 + d->sector_size = 512; // the default, will be changed below
84 d->next = NULL;
85
86 // append it to the list
@@ -80,9 +95,16 @@ struct disk *get_disk(unsigned long major, unsigned long minor) {
95 // ------------------------------------------------------------------------
96 // find the type of the device
97
98 + char buffer[FILENAME_MAX + 1];
99 +
100 + // get the default path for finding info about the block device
101 + if(unlikely(!path_find_block_device[0])) {
102 + snprintfz(buffer, FILENAME_MAX, "%s%s", global_host_prefix, "/sys/dev/block/%lu:%lu/%s");
103 + snprintfz(path_find_block_device, FILENAME_MAX, "%s", config_get("plugin:proc:/proc/diskstats", "path to get block device infos", buffer));
104 + }
105 +
106 // find if it is a partition
107 // by checking if /sys/dev/block/MAJOR:MINOR/partition is readable.
85 - char buffer[FILENAME_MAX + 1];
108 snprintfz(buffer, FILENAME_MAX, path_find_block_device, major, minor, "partition");
109 if(access(buffer, R_OK) == 0) {
110 d->type = DISK_TYPE_PARTITION;
@@ -92,13 +114,15 @@ struct disk *get_disk(unsigned long major, unsigned long minor) {
114 snprintfz(buffer, FILENAME_MAX, path_find_block_device, major, minor, "slaves/");
115 DIR *dirp = opendir(buffer);
116 if (dirp != NULL) {
95 - struct dirent *dp;
117 + struct dirent *dp;
118 while( (dp = readdir(dirp)) ) {
119 // . and .. are also files in empty folders.
120 if(strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) {
121 continue;
122 }
123 +
124 d->type = DISK_TYPE_CONTAINER;
125 +
126 // Stop the loop after we found one file.
127 break;
128 }
@@ -110,17 +134,17 @@ struct disk *get_disk(unsigned long major, unsigned long minor) {
134 // ------------------------------------------------------------------------
135 // check if we can find its mount point
136
113 - // mountinfo_find() can be called with NULL mountinfo_root
114 - struct mountinfo *mi = mountinfo_find(mountinfo_root, d->major, d->minor);
137 + // mountinfo_find() can be called with NULL disk_mountinfo_root
138 + struct mountinfo *mi = mountinfo_find(disk_mountinfo_root, d->major, d->minor);
139 if(unlikely(!mi)) {
116 - // mountinfo_free() can be called with NULL mountinfo_root
117 - mountinfo_free(mountinfo_root);
140 + // mountinfo_free() can be called with NULL disk_mountinfo_root
141 + mountinfo_free(disk_mountinfo_root);
142
143 // re-read mountinfo in case something changed
120 - mountinfo_root = mountinfo_read();
144 + disk_mountinfo_root = mountinfo_read();
145
146 // search again for this disk
123 - mi = mountinfo_find(mountinfo_root, d->major, d->minor);
147 + mi = mountinfo_find(disk_mountinfo_root, d->major, d->minor);
148 }
149
150 if(mi)
@@ -129,36 +153,106 @@ struct disk *get_disk(unsigned long major, unsigned long minor) {
153 else
154 d->mount_point = NULL;
155
156 + // ------------------------------------------------------------------------
157 + // find the disk sector size
158 +
159 + if(!path_to_get_hw_sector_size[0]) {
160 + snprintfz(buffer, FILENAME_MAX, "%s%s", global_host_prefix, "/sys/block/%s/queue/hw_sector_size");
161 + snprintfz(path_to_get_hw_sector_size, FILENAME_MAX, "%s", config_get("plugin:proc:/proc/diskstats", "path to get h/w sector size", buffer));
162 + }
163 + if(!path_to_get_hw_sector_size_partitions[0]) {
164 + snprintfz(buffer, FILENAME_MAX, "%s%s", global_host_prefix, "/sys/dev/block/%lu:%lu/subsystem/%s/../queue/hw_sector_size");
165 + snprintfz(path_to_get_hw_sector_size_partitions, FILENAME_MAX, "%s", config_get("plugin:proc:/proc/diskstats", "path to get h/w sector size for partitions", buffer));
166 + }
167 +
168 + {
169 + char tf[FILENAME_MAX + 1], *t;
170 + strncpyz(tf, d->disk, FILENAME_MAX);
171 +
172 + // replace all / with !
173 + for(t = tf; *t ;t++)
174 + if(*t == '/') *t = '!';
175 +
176 + if(d->type == DISK_TYPE_PARTITION)
177 + snprintfz(buffer, FILENAME_MAX, path_to_get_hw_sector_size_partitions, d->major, d->minor, tf);
178 + else
179 + snprintfz(buffer, FILENAME_MAX, path_to_get_hw_sector_size, tf);
180 +
181 + FILE *fpss = fopen(buffer, "r");
182 + if(fpss) {
183 + char buffer2[1024 + 1];
184 + char *tmp = fgets(buffer2, 1024, fpss);
185 +
186 + if(tmp) {
187 + d->sector_size = atoi(tmp);
188 + if(d->sector_size <= 0) {
189 + error("Invalid sector size %d for device %s in %s. Assuming 512.", d->sector_size, d->disk, buffer);
190 + d->sector_size = 512;
191 + }
192 + }
193 + else error("Cannot read data for sector size for device %s from %s. Assuming 512.", d->disk, buffer);
194 +
195 + fclose(fpss);
196 + }
197 + else error("Cannot read sector size for device %s from %s. Assuming 512.", d->disk, buffer);
198 + }
199 +
200 return d;
201 }
202
203 +static inline int select_positive_option(int option1, int option2) {
204 + if(option1 == CONFIG_ONDEMAND_YES || option2 == CONFIG_ONDEMAND_YES)
205 + return CONFIG_ONDEMAND_YES;
206 + else if(option1 == CONFIG_ONDEMAND_ONDEMAND || option2 == CONFIG_ONDEMAND_ONDEMAND)
207 + return CONFIG_ONDEMAND_ONDEMAND;
208 +
209 + return CONFIG_ONDEMAND_NO;
210 +}
211 +
212 int do_proc_diskstats(int update_every, unsigned long long dt) {
213 static procfile *ff = NULL;
137 - static char path_to_get_hw_sector_size[FILENAME_MAX + 1] = "";
138 - static int enable_autodetection;
139 - static int enable_physical_disks, enable_virtual_disks, enable_partitions, enable_mountpoints, enable_virtual_mountpoints, enable_space_metrics;
140 - static int do_io, do_ops, do_mops, do_iotime, do_qops, do_util, do_backlog, do_space, do_inodes;
214 static struct statvfs buff_statvfs;
215 static struct stat buff_stat;
143 -
144 - enable_autodetection = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "enable new disks detected at runtime", CONFIG_ONDEMAND_ONDEMAND);
145 -
146 - enable_physical_disks = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "performance metrics for physical disks", CONFIG_ONDEMAND_ONDEMAND);
147 - enable_virtual_disks = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "performance metrics for virtual disks", CONFIG_ONDEMAND_NO);
148 - enable_partitions = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "performance metrics for partitions", CONFIG_ONDEMAND_NO);
149 - enable_mountpoints = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "performance metrics for mounted filesystems", CONFIG_ONDEMAND_NO);
150 - enable_virtual_mountpoints = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "performance metrics for mounted virtual disks", CONFIG_ONDEMAND_ONDEMAND);
151 - enable_space_metrics = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "space metrics for mounted filesystems", CONFIG_ONDEMAND_ONDEMAND);
152 -
153 - do_io = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "bandwidth for all disks", CONFIG_ONDEMAND_ONDEMAND);
154 - do_ops = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "operations for all disks", CONFIG_ONDEMAND_ONDEMAND);
155 - do_mops = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "merged operations for all disks", CONFIG_ONDEMAND_ONDEMAND);
156 - do_iotime = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "i/o time for all disks", CONFIG_ONDEMAND_ONDEMAND);
157 - do_qops = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "queued operations for all disks", CONFIG_ONDEMAND_ONDEMAND);
158 - do_util = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "utilization percentage for all disks", CONFIG_ONDEMAND_ONDEMAND);
159 - do_backlog = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "backlog for all disks", CONFIG_ONDEMAND_ONDEMAND);
160 - do_space = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "space usage for all disks", CONFIG_ONDEMAND_ONDEMAND);
161 - do_inodes = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "inodes usage for all disks", CONFIG_ONDEMAND_ONDEMAND);
216 + static int global_enable_new_disks_detected_at_runtime = CONFIG_ONDEMAND_YES,
217 + global_enable_performance_for_physical_disks = CONFIG_ONDEMAND_ONDEMAND,
218 + global_enable_performance_for_virtual_disks = CONFIG_ONDEMAND_NO,
219 + global_enable_performance_for_partitions = CONFIG_ONDEMAND_NO,
220 + global_enable_performance_for_mountpoints = CONFIG_ONDEMAND_NO,
221 + global_enable_performance_for_virtual_mountpoints = CONFIG_ONDEMAND_ONDEMAND,
222 + global_enable_space_for_mountpoints = CONFIG_ONDEMAND_ONDEMAND,
223 + global_do_io = CONFIG_ONDEMAND_ONDEMAND,
224 + global_do_ops = CONFIG_ONDEMAND_ONDEMAND,
225 + global_do_mops = CONFIG_ONDEMAND_ONDEMAND,
226 + global_do_iotime = CONFIG_ONDEMAND_ONDEMAND,
227 + global_do_qops = CONFIG_ONDEMAND_ONDEMAND,
228 + global_do_util = CONFIG_ONDEMAND_ONDEMAND,
229 + global_do_backlog = CONFIG_ONDEMAND_ONDEMAND,
230 + global_do_space = CONFIG_ONDEMAND_ONDEMAND,
231 + global_do_inodes = CONFIG_ONDEMAND_ONDEMAND,
232 + globals_initialized = 0;
233 +
234 + if(unlikely(!globals_initialized)) {
235 + global_enable_new_disks_detected_at_runtime = config_get_boolean("plugin:proc:/proc/diskstats", "enable new disks detected at runtime", global_enable_new_disks_detected_at_runtime);
236 +
237 + global_enable_performance_for_physical_disks = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "performance metrics for physical disks", global_enable_performance_for_physical_disks);
238 + global_enable_performance_for_virtual_disks = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "performance metrics for virtual disks", global_enable_performance_for_virtual_disks);
239 + global_enable_performance_for_partitions = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "performance metrics for partitions", global_enable_performance_for_partitions);
240 + global_enable_performance_for_mountpoints = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "performance metrics for mounted filesystems", global_enable_performance_for_mountpoints);
241 + global_enable_performance_for_virtual_mountpoints = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "performance metrics for mounted virtual disks", global_enable_performance_for_virtual_mountpoints);
242 + global_enable_space_for_mountpoints = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "space metrics for mounted filesystems", global_enable_space_for_mountpoints);
243 +
244 + global_do_io = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "bandwidth for all disks", global_do_io);
245 + global_do_ops = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "operations for all disks", global_do_ops);
246 + global_do_mops = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "merged operations for all disks", global_do_mops);
247 + global_do_iotime = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "i/o time for all disks", global_do_iotime);
248 + global_do_qops = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "queued operations for all disks", global_do_qops);
249 + global_do_util = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "utilization percentage for all disks", global_do_util);
250 + global_do_backlog = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "backlog for all disks", global_do_backlog);
251 + global_do_space = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "space usage for all disks", global_do_space);
252 + global_do_inodes = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "inodes usage for all disks", global_do_inodes);
253 +
254 + globals_initialized = 1;
255 + }
256
257 if(!ff) {
258 char filename[FILENAME_MAX + 1];
@@ -167,12 +261,6 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
261 }
262 if(!ff) return 1;
263
170 - if(!path_to_get_hw_sector_size[0]) {
171 - char filename[FILENAME_MAX + 1];
172 - snprintfz(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/sys/block/%s/queue/hw_sector_size");
173 - snprintfz(path_to_get_hw_sector_size, FILENAME_MAX, "%s", config_get("plugin:proc:/proc/diskstats", "path to get h/w sector size", filename));
174 - }
175 -
264 ff = procfile_readall(ff);
265 if(!ff) return 0; // we return 0, so that we will retry to open it next time
266
@@ -182,6 +270,7 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
270 for(l = 0; l < lines ;l++) {
271 // --------------------------------------------------------------------------
272 // Read parameters
273 +
274 char *disk;
275 unsigned long long major = 0, minor = 0,
276 reads = 0, mreads = 0, readsectors = 0, readms = 0,
@@ -241,331 +330,390 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
330 // I/O completion time and the backlog that may be accumulating.
331 backlog_ms = strtoull(procfile_lineword(ff, l, 13), NULL, 10); // rq_ticks
332
333 +
334 // --------------------------------------------------------------------------
335 // remove slashes from disk names
336 char *s;
247 - for(s = disk; *s ;s++) if(*s == '/') *s = '_';
248 - struct disk *d = get_disk(major, minor);
249 - // Find mount point and family
250 - char *mount_point = d->mount_point;
337 + for(s = disk; *s ;s++)
338 + if(*s == '/') *s = '_';
339 +
340 + // --------------------------------------------------------------------------
341 + // get a disk structure for the disk
342 +
343 + struct disk *d = get_disk(major, minor, disk);
344 +
345 +
346 + // --------------------------------------------------------------------------
347 + // Set its family based on mount point
348 +
349 char *family = d->mount_point;
350 if(!family) family = disk;
351
352 +
353 // --------------------------------------------------------------------------
255 - // Check if device is enabled by autodetection or config
256 - int def_enable = -1;
257 - char var_name[4096 + 1];
258 - snprintfz(var_name, 4096, "plugin:proc:/proc/diskstats:%s", disk);
259 -
260 - if(def_enable == -1) def_enable = config_get_boolean_ondemand(var_name, "enable", CONFIG_ONDEMAND_ONDEMAND);
261 - if(def_enable == CONFIG_ONDEMAND_NO) continue;
262 -
263 - int def_performance = CONFIG_ONDEMAND_NO, def_space = CONFIG_ONDEMAND_NO;
264 - if(enable_autodetection) {
265 - if(enable_physical_disks && (d->type == DISK_TYPE_PHYSICAL)) {
266 - def_performance = enable_physical_disks;
267 - } else if(enable_virtual_disks && (d->type == DISK_TYPE_CONTAINER)) {
268 - def_performance = enable_virtual_disks;
269 - } else if(enable_partitions && (d->type == DISK_TYPE_PARTITION)) {
270 - def_performance = enable_partitions;
271 - } else if(enable_virtual_mountpoints && (d->type == DISK_TYPE_CONTAINER) && (d->mount_point != NULL)) {
272 - def_performance = enable_virtual_mountpoints;
273 - } else if(enable_mountpoints && (d->mount_point != NULL)) {
274 - def_performance = enable_mountpoints;
354 + // Check the configuration for the device
355 +
356 + if(unlikely(!d->configured)) {
357 + char var_name[4096 + 1];
358 + snprintfz(var_name, 4096, "plugin:proc:/proc/diskstats:%s", disk);
359 +
360 + int def_enable = config_get_boolean_ondemand(var_name, "enable", global_enable_new_disks_detected_at_runtime);
361 + if(def_enable == CONFIG_ONDEMAND_NO) {
362 + // the user does not want any metrics for this disk
363 + d->do_io = CONFIG_ONDEMAND_NO;
364 + d->do_ops = CONFIG_ONDEMAND_NO;
365 + d->do_mops = CONFIG_ONDEMAND_NO;
366 + d->do_iotime = CONFIG_ONDEMAND_NO;
367 + d->do_qops = CONFIG_ONDEMAND_NO;
368 + d->do_util = CONFIG_ONDEMAND_NO;
369 + d->do_backlog = CONFIG_ONDEMAND_NO;
370 + d->do_space = CONFIG_ONDEMAND_NO;
371 + d->do_inodes = CONFIG_ONDEMAND_NO;
372 }
373 + else {
374 + // this disk is enabled
375 + // check its direct settings
376 +
377 + int def_performance = CONFIG_ONDEMAND_ONDEMAND;
378 + int def_space = (d->mount_point)?CONFIG_ONDEMAND_ONDEMAND:CONFIG_ONDEMAND_NO;
379 +
380 + // since this is 'on demand' we can figure the performance settings
381 + // based on the type of disk
382 +
383 + switch(d->type) {
384 + case DISK_TYPE_PHYSICAL:
385 + def_performance = global_enable_performance_for_physical_disks;
386 + break;
387
277 - if(enable_space_metrics && (d->mount_point != NULL)) {
278 - def_space = enable_space_metrics;
388 + case DISK_TYPE_PARTITION:
389 + def_performance = global_enable_performance_for_partitions;
390 + break;
391 +
392 + case DISK_TYPE_CONTAINER:
393 + def_performance = global_enable_performance_for_virtual_disks;
394 +
395 + if(d->mount_point)
396 + def_performance = select_positive_option(def_performance, global_enable_performance_for_virtual_mountpoints);
397 +
398 + break;
399 + }
400 +
401 + if(d->mount_point)
402 + def_performance = select_positive_option(def_performance, global_enable_performance_for_mountpoints);
403 +
404 + // ------------------------------------------------------------
405 + // now we have def_performance and def_space
406 + // to work further
407 +
408 + // def_performance
409 + // check the user configuration (this will also show our 'on demand' decision)
410 + def_performance = config_get_boolean_ondemand(var_name, "enable performance metrics", def_performance);
411 +
412 + int ddo_io = CONFIG_ONDEMAND_NO,
413 + ddo_ops = CONFIG_ONDEMAND_NO,
414 + ddo_mops = CONFIG_ONDEMAND_NO,
415 + ddo_iotime = CONFIG_ONDEMAND_NO,
416 + ddo_qops = CONFIG_ONDEMAND_NO,
417 + ddo_util = CONFIG_ONDEMAND_NO,
418 + ddo_backlog = CONFIG_ONDEMAND_NO;
419 +
420 + // we enable individual performance charts only when def_performance is not disabled
421 + if(def_performance != CONFIG_ONDEMAND_NO) {
422 + ddo_io = global_do_io,
423 + ddo_ops = global_do_ops,
424 + ddo_mops = global_do_mops,
425 + ddo_iotime = global_do_iotime,
426 + ddo_qops = global_do_qops,
427 + ddo_util = global_do_util,
428 + ddo_backlog = global_do_backlog;
429 + }
430 +
431 + d->do_io = config_get_boolean_ondemand(var_name, "bandwidth", ddo_io);
432 + d->do_ops = config_get_boolean_ondemand(var_name, "operations", ddo_ops);
433 + d->do_mops = config_get_boolean_ondemand(var_name, "merged operations", ddo_mops);
434 + d->do_iotime = config_get_boolean_ondemand(var_name, "i/o time", ddo_iotime);
435 + d->do_qops = config_get_boolean_ondemand(var_name, "queued operations", ddo_qops);
436 + d->do_util = config_get_boolean_ondemand(var_name, "utilization percentage", ddo_util);
437 + d->do_backlog = config_get_boolean_ondemand(var_name, "backlog", ddo_backlog);
438 +
439 + // def_space
440 + if(d->mount_point) {
441 + // check the user configuration (this will also show our 'on demand' decision)
442 + def_space = config_get_boolean_ondemand(var_name, "enable space metrics", def_space);
443 +
444 + int ddo_space = def_space,
445 + ddo_inodes = def_space;
446 +
447 + d->do_space = config_get_boolean_ondemand(var_name, "space usage", ddo_space);
448 + d->do_inodes = config_get_boolean_ondemand(var_name, "inodes usage", ddo_inodes);
449 + }
450 + else {
451 + // don't show settings for this disk
452 + d->do_space = CONFIG_ONDEMAND_NO;
453 + d->do_inodes = CONFIG_ONDEMAND_NO;
454 + }
455 }
456 +
457 + d->configured = 1;
458 }
459
460 RRDSET *st;
461
462 // --------------------------------------------------------------------------
463 // Do performance metrics
286 - def_performance = config_get_boolean_ondemand(var_name, "enable performance metrics", def_performance);
287 - if( (def_performance == CONFIG_ONDEMAND_YES) || (def_performance == CONFIG_ONDEMAND_ONDEMAND && reads && writes) ) {
288 - int ddo_io = do_io, ddo_ops = do_ops, ddo_mops = do_mops, ddo_iotime = do_iotime, ddo_qops = do_qops, ddo_util = do_util, ddo_backlog = do_backlog;
289 -
290 - ddo_io = config_get_boolean_ondemand(var_name, "bandwidth", ddo_io);
291 - ddo_ops = config_get_boolean_ondemand(var_name, "operations", ddo_ops);
292 - ddo_mops = config_get_boolean_ondemand(var_name, "merged operations", ddo_mops);
293 - ddo_iotime = config_get_boolean_ondemand(var_name, "i/o time", ddo_iotime);
294 - ddo_qops = config_get_boolean_ondemand(var_name, "queued operations", ddo_qops);
295 - ddo_util = config_get_boolean_ondemand(var_name, "utilization percentage", ddo_util);
296 - ddo_backlog = config_get_boolean_ondemand(var_name, "backlog", ddo_backlog);
297 -
298 - // by default, do not add charts that do not have values
299 - if(ddo_io == CONFIG_ONDEMAND_ONDEMAND && !reads && !writes) ddo_io = 0;
300 - if(ddo_mops == CONFIG_ONDEMAND_ONDEMAND && mreads == 0 && mwrites == 0) ddo_mops = 0;
301 - if(ddo_iotime == CONFIG_ONDEMAND_ONDEMAND && readms == 0 && writems == 0) ddo_iotime = 0;
302 - if(ddo_util == CONFIG_ONDEMAND_ONDEMAND && busy_ms == 0) ddo_util = 0;
303 - if(ddo_backlog == CONFIG_ONDEMAND_ONDEMAND && backlog_ms == 0) ddo_backlog = 0;
304 - if(ddo_qops == CONFIG_ONDEMAND_ONDEMAND && backlog_ms == 0) ddo_qops = 0;
305 -
306 - // for absolute values, we need to switch the setting to 'yes'
307 - // to allow it refresh from now on
308 - if(ddo_qops == CONFIG_ONDEMAND_ONDEMAND) config_set(var_name, "queued operations", "yes");
309 -
310 - // --------------------------------------------------------------------
311 - int sector_size = 512;
312 - if(ddo_io) {
313 - st = rrdset_find_bytype(RRD_TYPE_DISK, disk);
314 - if(!st) {
315 - char tf[FILENAME_MAX + 1], *t;
316 - char ssfilename[FILENAME_MAX + 1];
464
318 - strncpyz(tf, disk, FILENAME_MAX);
465 + if(d->do_io == CONFIG_ONDEMAND_YES || (d->do_io == CONFIG_ONDEMAND_ONDEMAND && (readsectors || writesectors))) {
466 + d->do_io = CONFIG_ONDEMAND_YES;
467
320 - // replace all / with !
321 - while((t = strchr(tf, '/'))) *t = '!';
468 + st = rrdset_find_bytype(RRD_TYPE_DISK, disk);
469 + if(!st) {
470 + st = rrdset_create(RRD_TYPE_DISK, disk, NULL, family, "disk.io", "Disk I/O Bandwidth", "kilobytes/s", 2000, update_every, RRDSET_TYPE_AREA);
471
323 - snprintfz(ssfilename, FILENAME_MAX, path_to_get_hw_sector_size, tf);
324 - FILE *fpss = fopen(ssfilename, "r");
325 - if(fpss) {
326 - char ssbuffer[1025];
327 - char *tmp = fgets(ssbuffer, 1024, fpss);
472 + rrddim_add(st, "reads", NULL, d->sector_size, 1024, RRDDIM_INCREMENTAL);
473 + rrddim_add(st, "writes", NULL, d->sector_size * -1, 1024, RRDDIM_INCREMENTAL);
474 + }
475 + else rrdset_next_usec(st, dt);
476
329 - if(tmp) {
330 - sector_size = atoi(tmp);
331 - if(sector_size <= 0) {
332 - error("Invalid sector size %d for device %s in %s. Assuming 512.", sector_size, disk, ssfilename);
333 - sector_size = 512;
334 - }
335 - }
336 - else error("Cannot read data for sector size for device %s from %s. Assuming 512.", disk, ssfilename);
477 + last_readsectors = rrddim_set(st, "reads", readsectors);
478 + last_writesectors = rrddim_set(st, "writes", writesectors);
479 + rrdset_done(st);
480 + }
481
338 - fclose(fpss);
339 - }
340 - else error("Cannot read sector size for device %s from %s. Assuming 512.", disk, ssfilename);
482 + // --------------------------------------------------------------------
483
342 - st = rrdset_create(RRD_TYPE_DISK, disk, NULL, family, "disk.io", "Disk I/O Bandwidth", "kilobytes/s", 2000, update_every, RRDSET_TYPE_AREA);
484 + if(d->do_ops == CONFIG_ONDEMAND_YES || (d->do_ops == CONFIG_ONDEMAND_ONDEMAND && (reads || writes))) {
485 + d->do_ops = CONFIG_ONDEMAND_YES;
486
344 - rrddim_add(st, "reads", NULL, sector_size, 1024, RRDDIM_INCREMENTAL);
345 - rrddim_add(st, "writes", NULL, sector_size * -1, 1024, RRDDIM_INCREMENTAL);
346 - }
347 - else rrdset_next_usec(st, dt);
487 + st = rrdset_find_bytype("disk_ops", disk);
488 + if(!st) {
489 + st = rrdset_create("disk_ops", disk, NULL, family, "disk.ops", "Disk Completed I/O Operations", "operations/s", 2001, update_every, RRDSET_TYPE_LINE);
490 + st->isdetail = 1;
491
349 - last_readsectors = rrddim_set(st, "reads", readsectors);
350 - last_writesectors = rrddim_set(st, "writes", writesectors);
351 - rrdset_done(st);
492 + rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_INCREMENTAL);
493 + rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_INCREMENTAL);
494 }
495 + else rrdset_next_usec(st, dt);
496
354 - // --------------------------------------------------------------------
355 - if(ddo_ops) {
356 - st = rrdset_find_bytype("disk_ops", disk);
357 - if(!st) {
358 - st = rrdset_create("disk_ops", disk, NULL, family, "disk.ops", "Disk Completed I/O Operations", "operations/s", 2001, update_every, RRDSET_TYPE_LINE);
359 - st->isdetail = 1;
497 + last_reads = rrddim_set(st, "reads", reads);
498 + last_writes = rrddim_set(st, "writes", writes);
499 + rrdset_done(st);
500 + }
501
361 - rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_INCREMENTAL);
362 - rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_INCREMENTAL);
363 - }
364 - else rrdset_next_usec(st, dt);
502 + // --------------------------------------------------------------------
503
366 - last_reads = rrddim_set(st, "reads", reads);
367 - last_writes = rrddim_set(st, "writes", writes);
368 - rrdset_done(st);
504 + if(d->do_qops == CONFIG_ONDEMAND_YES || (d->do_qops == CONFIG_ONDEMAND_ONDEMAND && queued_ios)) {
505 + d->do_qops = CONFIG_ONDEMAND_YES;
506 +
507 + st = rrdset_find_bytype("disk_qops", disk);
508 + if(!st) {
509 + st = rrdset_create("disk_qops", disk, NULL, family, "disk.qops", "Disk Current I/O Operations", "operations", 2002, update_every, RRDSET_TYPE_LINE);
510 + st->isdetail = 1;
511 +
512 + rrddim_add(st, "operations", NULL, 1, 1, RRDDIM_ABSOLUTE);
513 }
514 + else rrdset_next_usec(st, dt);
515
371 - // --------------------------------------------------------------------
372 - if(ddo_qops) {
373 - st = rrdset_find_bytype("disk_qops", disk);
374 - if(!st) {
375 - st = rrdset_create("disk_qops", disk, NULL, family, "disk.qops", "Disk Current I/O Operations", "operations", 2002, update_every, RRDSET_TYPE_LINE);
376 - st->isdetail = 1;
516 + rrddim_set(st, "operations", queued_ios);
517 + rrdset_done(st);
518 + }
519
378 - rrddim_add(st, "operations", NULL, 1, 1, RRDDIM_ABSOLUTE);
379 - }
380 - else rrdset_next_usec(st, dt);
520 + // --------------------------------------------------------------------
521
382 - rrddim_set(st, "operations", queued_ios);
383 - rrdset_done(st);
522 + if(d->do_backlog == CONFIG_ONDEMAND_YES || (d->do_backlog == CONFIG_ONDEMAND_ONDEMAND && backlog_ms)) {
523 + d->do_backlog = CONFIG_ONDEMAND_YES;
524 +
525 + st = rrdset_find_bytype("disk_backlog", disk);
526 + if(!st) {
527 + st = rrdset_create("disk_backlog", disk, NULL, family, "disk.backlog", "Disk Backlog", "backlog (ms)", 2003, update_every, RRDSET_TYPE_AREA);
528 + st->isdetail = 1;
529 +
530 + rrddim_add(st, "backlog", NULL, 1, 10, RRDDIM_INCREMENTAL);
531 }
532 + else rrdset_next_usec(st, dt);
533
386 - // --------------------------------------------------------------------
387 - if(ddo_backlog) {
388 - st = rrdset_find_bytype("disk_backlog", disk);
389 - if(!st) {
390 - st = rrdset_create("disk_backlog", disk, NULL, family, "disk.backlog", "Disk Backlog", "backlog (ms)", 2003, update_every, RRDSET_TYPE_AREA);
391 - st->isdetail = 1;
534 + rrddim_set(st, "backlog", backlog_ms);
535 + rrdset_done(st);
536 + }
537
393 - rrddim_add(st, "backlog", NULL, 1, 10, RRDDIM_INCREMENTAL);
394 - }
395 - else rrdset_next_usec(st, dt);
538 + // --------------------------------------------------------------------
539
397 - rrddim_set(st, "backlog", backlog_ms);
398 - rrdset_done(st);
540 + if(d->do_util == CONFIG_ONDEMAND_YES || (d->do_util == CONFIG_ONDEMAND_ONDEMAND && busy_ms)) {
541 + d->do_util = CONFIG_ONDEMAND_YES;
542 +
543 + st = rrdset_find_bytype("disk_util", disk);
544 + if(!st) {
545 + st = rrdset_create("disk_util", disk, NULL, family, "disk.util", "Disk Utilization Time", "% of time working", 2004, update_every, RRDSET_TYPE_AREA);
546 + st->isdetail = 1;
547 +
548 + rrddim_add(st, "utilization", NULL, 1, 10, RRDDIM_INCREMENTAL);
549 }
550 + else rrdset_next_usec(st, dt);
551 +
552 + last_busy_ms = rrddim_set(st, "utilization", busy_ms);
553 + rrdset_done(st);
554 + }
555 +
556 + // --------------------------------------------------------------------
557
401 - // --------------------------------------------------------------------
402 - if(ddo_util) {
403 - st = rrdset_find_bytype("disk_util", disk);
558 + if(d->do_mops == CONFIG_ONDEMAND_YES || (d->do_mops == CONFIG_ONDEMAND_ONDEMAND && (mreads || mwrites))) {
559 + d->do_mops = CONFIG_ONDEMAND_YES;
560 +
561 + st = rrdset_find_bytype("disk_mops", disk);
562 + if(!st) {
563 + st = rrdset_create("disk_mops", disk, NULL, family, "disk.mops", "Disk Merged Operations", "merged operations/s", 2021, update_every, RRDSET_TYPE_LINE);
564 + st->isdetail = 1;
565 +
566 + rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_INCREMENTAL);
567 + rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_INCREMENTAL);
568 + }
569 + else rrdset_next_usec(st, dt);
570 +
571 + rrddim_set(st, "reads", mreads);
572 + rrddim_set(st, "writes", mwrites);
573 + rrdset_done(st);
574 + }
575 +
576 + // --------------------------------------------------------------------
577 +
578 + if(d->do_iotime == CONFIG_ONDEMAND_YES || (d->do_iotime == CONFIG_ONDEMAND_ONDEMAND && (readms || writems))) {
579 + d->do_iotime = CONFIG_ONDEMAND_YES;
580 +
581 + st = rrdset_find_bytype("disk_iotime", disk);
582 + if(!st) {
583 + st = rrdset_create("disk_iotime", disk, NULL, family, "disk.iotime", "Disk Total I/O Time", "milliseconds/s", 2022, update_every, RRDSET_TYPE_LINE);
584 + st->isdetail = 1;
585 +
586 + rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_INCREMENTAL);
587 + rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_INCREMENTAL);
588 + }
589 + else rrdset_next_usec(st, dt);
590 +
591 + last_readms = rrddim_set(st, "reads", readms);
592 + last_writems = rrddim_set(st, "writes", writems);
593 + rrdset_done(st);
594 + }
595 +
596 + // --------------------------------------------------------------------
597 + // calculate differential charts
598 + // only if this is not the first time we run
599 +
600 + if(dt) {
601 + if(d->do_iotime && d->do_ops) {
602 + st = rrdset_find_bytype("disk_await", disk);
603 if(!st) {
405 - st = rrdset_create("disk_util", disk, NULL, family, "disk.util", "Disk Utilization Time", "% of time working", 2004, update_every, RRDSET_TYPE_AREA);
604 + st = rrdset_create("disk_await", disk, NULL, family, "disk.await", "Average Completed I/O Operation Time", "ms per operation", 2005, update_every, RRDSET_TYPE_LINE);
605 st->isdetail = 1;
606
408 - rrddim_add(st, "utilization", NULL, 1, 10, RRDDIM_INCREMENTAL);
607 + rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_ABSOLUTE);
608 + rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_ABSOLUTE);
609 }
610 else rrdset_next_usec(st, dt);
611
412 - last_busy_ms = rrddim_set(st, "utilization", busy_ms);
612 + rrddim_set(st, "reads", (reads - last_reads) ? (readms - last_readms) / (reads - last_reads) : 0);
613 + rrddim_set(st, "writes", (writes - last_writes) ? (writems - last_writems) / (writes - last_writes) : 0);
614 rrdset_done(st);
615 }
616
416 - // --------------------------------------------------------------------
417 - if(ddo_mops) {
418 - st = rrdset_find_bytype("disk_mops", disk);
617 + if(d->do_io && d->do_ops) {
618 + st = rrdset_find_bytype("disk_avgsz", disk);
619 if(!st) {
420 - st = rrdset_create("disk_mops", disk, NULL, family, "disk.mops", "Disk Merged Operations", "merged operations/s", 2021, update_every, RRDSET_TYPE_LINE);
620 + st = rrdset_create("disk_avgsz", disk, NULL, family, "disk.avgsz", "Average Completed I/O Operation Bandwidth", "kilobytes per operation", 2006, update_every, RRDSET_TYPE_AREA);
621 st->isdetail = 1;
622
423 - rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_INCREMENTAL);
424 - rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_INCREMENTAL);
623 + rrddim_add(st, "reads", NULL, d->sector_size, 1024, RRDDIM_ABSOLUTE);
624 + rrddim_add(st, "writes", NULL, d->sector_size * -1, 1024, RRDDIM_ABSOLUTE);
625 }
626 else rrdset_next_usec(st, dt);
627
428 - rrddim_set(st, "reads", mreads);
429 - rrddim_set(st, "writes", mwrites);
628 + rrddim_set(st, "reads", (reads - last_reads) ? (readsectors - last_readsectors) / (reads - last_reads) : 0);
629 + rrddim_set(st, "writes", (writes - last_writes) ? (writesectors - last_writesectors) / (writes - last_writes) : 0);
630 rrdset_done(st);
631 }
632
433 - // --------------------------------------------------------------------
434 - if(ddo_iotime) {
435 - st = rrdset_find_bytype("disk_iotime", disk);
633 + if(d->do_util && d->do_ops) {
634 + st = rrdset_find_bytype("disk_svctm", disk);
635 if(!st) {
437 - st = rrdset_create("disk_iotime", disk, NULL, family, "disk.iotime", "Disk Total I/O Time", "milliseconds/s", 2022, update_every, RRDSET_TYPE_LINE);
636 + st = rrdset_create("disk_svctm", disk, NULL, family, "disk.svctm", "Average Service Time", "ms per operation", 2007, update_every, RRDSET_TYPE_LINE);
637 st->isdetail = 1;
638
440 - rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_INCREMENTAL);
441 - rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_INCREMENTAL);
639 + rrddim_add(st, "svctm", NULL, 1, 1, RRDDIM_ABSOLUTE);
640 }
641 else rrdset_next_usec(st, dt);
642
445 - last_readms = rrddim_set(st, "reads", readms);
446 - last_writems = rrddim_set(st, "writes", writems);
643 + rrddim_set(st, "svctm", ((reads - last_reads) + (writes - last_writes)) ? (busy_ms - last_busy_ms) / ((reads - last_reads) + (writes - last_writes)) : 0);
644 rrdset_done(st);
645 }
646 + }
647
450 - // --------------------------------------------------------------------
451 - // calculate differential charts
452 - // only if this is not the first time we run
453 - if(dt) {
454 - if(ddo_iotime && ddo_ops) {
455 - st = rrdset_find_bytype("disk_await", disk);
456 - if(!st) {
457 - st = rrdset_create("disk_await", disk, NULL, family, "disk.await", "Average Completed I/O Operation Time", "ms per operation", 2005, update_every, RRDSET_TYPE_LINE);
458 - st->isdetail = 1;
459 -
460 - rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_ABSOLUTE);
461 - rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_ABSOLUTE);
462 - }
463 - else rrdset_next_usec(st, dt);
648 + // --------------------------------------------------------------------------
649 + // space metrics
650
465 - rrddim_set(st, "reads", (reads - last_reads) ? (readms - last_readms) / (reads - last_reads) : 0);
466 - rrddim_set(st, "writes", (writes - last_writes) ? (writems - last_writems) / (writes - last_writes) : 0);
467 - rrdset_done(st);
468 - }
651 + if(d->mount_point && (d->do_space || d->do_inodes) ) {
652 + // collect space metrics using statvfs
653
470 - if(ddo_io && ddo_ops) {
471 - st = rrdset_find_bytype("disk_avgsz", disk);
472 - if(!st) {
473 - st = rrdset_create("disk_avgsz", disk, NULL, family, "disk.avgsz", "Average Completed I/O Operation Bandwidth", "kilobytes per operation", 2006, update_every, RRDSET_TYPE_AREA);
474 - st->isdetail = 1;
654 + if (statvfs(d->mount_point, &buff_statvfs) < 0)
655 + error("Failed statvfs() for '%s' (disk '%s')", d->mount_point, d->disk);
656 + else {
657 + space_avail = buff_statvfs.f_bavail * buff_statvfs.f_bsize;
658 + space_avail_root = (buff_statvfs.f_bfree - buff_statvfs.f_bavail) * buff_statvfs.f_bsize;
659 + space_used = (buff_statvfs.f_blocks - buff_statvfs.f_bfree) * buff_statvfs.f_bsize;
660
476 - rrddim_add(st, "reads", NULL, sector_size, 1024, RRDDIM_ABSOLUTE);
477 - rrddim_add(st, "writes", NULL, -sector_size, 1024, RRDDIM_ABSOLUTE);
478 - }
479 - else rrdset_next_usec(st, dt);
661 + inodes_avail = buff_statvfs.f_favail;
662 + inodes_avail_root = buff_statvfs.f_ffree - buff_statvfs.f_favail;
663 + inodes_used = buff_statvfs.f_files - buff_statvfs.f_ffree;
664
481 - rrddim_set(st, "reads", (reads - last_reads) ? (readsectors - last_readsectors) / (reads - last_reads) : 0);
482 - rrddim_set(st, "writes", (writes - last_writes) ? (writesectors - last_writesectors) / (writes - last_writes) : 0);
483 - rrdset_done(st);
484 - }
665 + // verify we collected the metrics for the right disk.
666 + // if not the mountpoint has changed.
667
486 - if(ddo_util && ddo_ops) {
487 - st = rrdset_find_bytype("disk_svctm", disk);
488 - if(!st) {
489 - st = rrdset_create("disk_svctm", disk, NULL, family, "disk.svctm", "Average Service Time", "ms per operation", 2007, update_every, RRDSET_TYPE_LINE);
490 - st->isdetail = 1;
668 + if(stat(d->mount_point, &buff_stat) == -1)
669 + error("Failed to stat() for '%s' (disk '%s')", d->mount_point, d->disk);
670 + else {
671 + if(major(buff_stat.st_dev) == major && minor(buff_stat.st_dev) == minor) {
672
492 - rrddim_add(st, "svctm", NULL, 1, 1, RRDDIM_ABSOLUTE);
493 - }
494 - else rrdset_next_usec(st, dt);
673 + // --------------------------------------------------------------------------
674
496 - rrddim_set(st, "svctm", ((reads - last_reads) + (writes - last_writes)) ? (busy_ms - last_busy_ms) / ((reads - last_reads) + (writes - last_writes)) : 0);
497 - rrdset_done(st);
498 - }
499 - }
500 - }
675 + if(d->do_space == CONFIG_ONDEMAND_YES || (d->do_space == CONFIG_ONDEMAND_ONDEMAND && (space_avail || space_avail_root || space_used))) {
676 + st = rrdset_find_bytype("disk_space", disk);
677 + if(!st) {
678 + st = rrdset_create("disk_space", disk, NULL, family, "disk.space", "Disk Space Usage", "GB", 2023, update_every, RRDSET_TYPE_STACKED);
679 + st->isdetail = 1;
680
502 - // --------------------------------------------------------------------------
503 - // Do space metrics
504 - def_space = config_get_boolean_ondemand(var_name, "enable space metrics", def_space);
505 - if(def_space != CONFIG_ONDEMAND_NO) {
506 - int ddo_space = do_space, ddo_inodes = do_inodes;
507 -
508 - ddo_space = config_get_boolean_ondemand(var_name, "space", ddo_space);
509 - ddo_inodes = config_get_boolean_ondemand(var_name, "inodes", ddo_space);
510 - if(mount_point && (ddo_space || ddo_inodes) ) {
511 - // collect space metrics using statvfs
512 - if (statvfs(mount_point, &buff_statvfs) < 0) {
513 - error("Failed checking disk space usage of %s", family);
514 - } else {
515 - // verify we collected the metrics for the right disk.
516 - // if not the mountpoint has changed.
517 - if(stat(mount_point, &buff_stat) == -1) {
518 - error("Failed to call stat for %s", family);
519 - } else {
520 - if(major(buff_stat.st_dev) == major && minor(buff_stat.st_dev) == minor)
521 - {
522 - if(ddo_space) {
523 - space_avail = buff_statvfs.f_bavail * buff_statvfs.f_bsize;
524 - space_avail_root = (buff_statvfs.f_bfree - buff_statvfs.f_bavail) * buff_statvfs.f_bsize;
525 - space_used = (buff_statvfs.f_blocks - buff_statvfs.f_bfree) * buff_statvfs.f_bsize;
526 -
527 - st = rrdset_find_bytype("disk_space", disk);
528 - if(!st) {
529 - st = rrdset_create("disk_space", disk, NULL, family, "disk.space", "Disk Space Usage", "GB", 2023, update_every, RRDSET_TYPE_STACKED);
530 - st->isdetail = 1;
531 -
532 - rrddim_add(st, "avail", NULL, 1, 1000*1000*1000, RRDDIM_ABSOLUTE);
533 - rrddim_add(st, "reserved_for_root", "reserved for root", 1, 1000*1000*1000, RRDDIM_ABSOLUTE);
534 - rrddim_add(st, "used" , NULL, 1, 1000*1000*1000, RRDDIM_ABSOLUTE);
535 - }
536 - else rrdset_next_usec(st, dt);
537 -
538 - rrddim_set(st, "avail", space_avail);
539 - rrddim_set(st, "reserved_for_root", space_avail_root);
540 - rrddim_set(st, "used", space_used);
541 - rrdset_done(st);
681 + rrddim_add(st, "avail", NULL, 1, 1024*1024*1024, RRDDIM_ABSOLUTE);
682 + rrddim_add(st, "reserved_for_root", "reserved for root", 1, 1024*1024*1024, RRDDIM_ABSOLUTE);
683 + rrddim_add(st, "used" , NULL, 1, 1024*1024*1024, RRDDIM_ABSOLUTE);
684 }
543 - if(ddo_inodes) {
544 - inodes_avail = buff_statvfs.f_favail;
545 - inodes_avail_root = buff_statvfs.f_ffree - buff_statvfs.f_favail;
546 - inodes_used = buff_statvfs.f_files - buff_statvfs.f_ffree;
547 -
548 - st = rrdset_find_bytype("disk_inodes", disk);
549 - if(!st) {
550 - st = rrdset_create("disk_inodes", disk, NULL, family, "disk.inodes", "Disk Inodes Usage", "Inodes", 2024, update_every, RRDSET_TYPE_STACKED);
551 - st->isdetail = 1;
552 -
553 - rrddim_add(st, "avail", NULL, 1, 1, RRDDIM_ABSOLUTE);
554 - rrddim_add(st, "reserved_for_root", "reserved for root", 1, 1, RRDDIM_ABSOLUTE);
555 - rrddim_add(st, "used" , NULL, 1, 1, RRDDIM_ABSOLUTE);
556 - }
557 - else rrdset_next_usec(st, dt);
558 -
559 - rrddim_set(st, "avail", inodes_avail);
560 - rrddim_set(st, "reserved_for_root", inodes_avail_root);
561 - rrddim_set(st, "used", inodes_used);
562 - rrdset_done(st);
685 + else rrdset_next_usec(st, dt);
686 +
687 + rrddim_set(st, "avail", space_avail);
688 + rrddim_set(st, "reserved_for_root", space_avail_root);
689 + rrddim_set(st, "used", space_used);
690 + rrdset_done(st);
691 + }
692 +
693 + // --------------------------------------------------------------------------
694 +
695 + if(d->do_inodes == CONFIG_ONDEMAND_YES || (d->do_inodes == CONFIG_ONDEMAND_ONDEMAND && (inodes_avail || inodes_avail_root || inodes_used))) {
696 + st = rrdset_find_bytype("disk_inodes", disk);
697 + if(!st) {
698 + st = rrdset_create("disk_inodes", disk, NULL, family, "disk.inodes", "Disk Inodes Usage", "Inodes", 2024, update_every, RRDSET_TYPE_STACKED);
699 + st->isdetail = 1;
700 +
701 + rrddim_add(st, "avail", NULL, 1, 1, RRDDIM_ABSOLUTE);
702 + rrddim_add(st, "reserved_for_root", "reserved for root", 1, 1, RRDDIM_ABSOLUTE);
703 + rrddim_add(st, "used" , NULL, 1, 1, RRDDIM_ABSOLUTE);
704 }
705 + else rrdset_next_usec(st, dt);
706 +
707 + rrddim_set(st, "avail", inodes_avail);
708 + rrddim_set(st, "reserved_for_root", inodes_avail_root);
709 + rrddim_set(st, "used", inodes_used);
710 + rrdset_done(st);
711 }
712 }
713 }
714 }
715 }
716 }
717 +
718 return 0;
719 }