int do_util;
int do_backlog;
+ int updated;
+
+ RRDSET *st_avgsz;
+ RRDSET *st_await;
+ RRDSET *st_backlog;
+ RRDSET *st_io;
+ RRDSET *st_iotime;
+ RRDSET *st_mops;
+ RRDSET *st_ops;
+ RRDSET *st_qops;
+ RRDSET *st_svctm;
+ RRDSET *st_util;
+
struct disk *next;
} *disk_root = NULL;
+#define rrdset_obsolete_and_pointer_null(st) do { if(st) { rrdset_flag_set(st, RRDSET_FLAG_OBSOLETE); st = NULL; } } while(st)
+
static struct disk *get_disk(unsigned long major, unsigned long minor, char *disk) {
static char path_to_get_hw_sector_size[FILENAME_MAX + 1] = "";
static char path_to_get_hw_sector_size_partitions[FILENAME_MAX + 1] = "";
// get a disk structure for the disk
struct disk *d = get_disk(major, minor, disk);
-
+ d->updated = 1;
// --------------------------------------------------------------------------
// Set its family based on mount point
d->configured = 1;
}
- RRDSET *st;
-
// --------------------------------------------------------------------------
// Do performance metrics
if(d->do_io == CONFIG_BOOLEAN_YES || (d->do_io == CONFIG_BOOLEAN_AUTO && (readsectors || writesectors))) {
d->do_io = CONFIG_BOOLEAN_YES;
- st = rrdset_find_bytype_localhost(RRD_TYPE_DISK, disk);
- if(unlikely(!st)) {
- st = rrdset_create_localhost(RRD_TYPE_DISK, disk, NULL, family, "disk.io", "Disk I/O Bandwidth"
- , "kilobytes/s", 2000, update_every, RRDSET_TYPE_AREA);
-
- rrddim_add(st, "reads", NULL, d->sector_size, 1024, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "writes", NULL, d->sector_size * -1, 1024, RRD_ALGORITHM_INCREMENTAL);
+ if(unlikely(!d->st_io)) {
+ d->st_io = rrdset_create_localhost(
+ RRD_TYPE_DISK
+ , disk
+ , NULL
+ , family
+ , "disk.io"
+ , "Disk I/O Bandwidth"
+ , "kilobytes/s"
+ , 2000
+ , update_every
+ , RRDSET_TYPE_AREA
+ );
+
+ rrddim_add(d->st_io, "reads", NULL, d->sector_size, 1024, RRD_ALGORITHM_INCREMENTAL);
+ rrddim_add(d->st_io, "writes", NULL, d->sector_size * -1, 1024, RRD_ALGORITHM_INCREMENTAL);
}
- else rrdset_next(st);
+ else rrdset_next(d->st_io);
- last_readsectors = rrddim_set(st, "reads", readsectors);
- last_writesectors = rrddim_set(st, "writes", writesectors);
- rrdset_done(st);
+ last_readsectors = rrddim_set(d->st_io, "reads", readsectors);
+ last_writesectors = rrddim_set(d->st_io, "writes", writesectors);
+ rrdset_done(d->st_io);
}
// --------------------------------------------------------------------
if(d->do_ops == CONFIG_BOOLEAN_YES || (d->do_ops == CONFIG_BOOLEAN_AUTO && (reads || writes))) {
d->do_ops = CONFIG_BOOLEAN_YES;
- st = rrdset_find_bytype_localhost("disk_ops", disk);
- if(unlikely(!st)) {
- st = rrdset_create_localhost("disk_ops", disk, NULL, family, "disk.ops", "Disk Completed I/O Operations"
- , "operations/s", 2001, update_every, RRDSET_TYPE_LINE);
- rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
-
- rrddim_add(st, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "writes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ if(unlikely(!d->st_ops)) {
+ d->st_ops = rrdset_create_localhost(
+ "disk_ops"
+ , disk
+ , NULL
+ , family
+ , "disk.ops"
+ , "Disk Completed I/O Operations"
+ , "operations/s"
+ , 2001
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rrdset_flag_set(d->st_ops, RRDSET_FLAG_DETAIL);
+
+ rrddim_add(d->st_ops, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rrddim_add(d->st_ops, "writes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
- else rrdset_next(st);
+ else rrdset_next(d->st_ops);
- last_reads = rrddim_set(st, "reads", reads);
- last_writes = rrddim_set(st, "writes", writes);
- rrdset_done(st);
+ last_reads = rrddim_set(d->st_ops, "reads", reads);
+ last_writes = rrddim_set(d->st_ops, "writes", writes);
+ rrdset_done(d->st_ops);
}
// --------------------------------------------------------------------
if(d->do_qops == CONFIG_BOOLEAN_YES || (d->do_qops == CONFIG_BOOLEAN_AUTO && queued_ios)) {
d->do_qops = CONFIG_BOOLEAN_YES;
- st = rrdset_find_bytype_localhost("disk_qops", disk);
- if(unlikely(!st)) {
- st = rrdset_create_localhost("disk_qops", disk, NULL, family, "disk.qops", "Disk Current I/O Operations"
- , "operations", 2002, update_every, RRDSET_TYPE_LINE);
- rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
-
- rrddim_add(st, "operations", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ if(unlikely(!d->st_qops)) {
+ d->st_qops = rrdset_create_localhost(
+ "disk_qops"
+ , disk
+ , NULL
+ , family
+ , "disk.qops"
+ , "Disk Current I/O Operations"
+ , "operations"
+ , 2002
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rrdset_flag_set(d->st_qops, RRDSET_FLAG_DETAIL);
+
+ rrddim_add(d->st_qops, "operations", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
}
- else rrdset_next(st);
+ else rrdset_next(d->st_qops);
- rrddim_set(st, "operations", queued_ios);
- rrdset_done(st);
+ rrddim_set(d->st_qops, "operations", queued_ios);
+ rrdset_done(d->st_qops);
}
// --------------------------------------------------------------------
if(d->do_backlog == CONFIG_BOOLEAN_YES || (d->do_backlog == CONFIG_BOOLEAN_AUTO && backlog_ms)) {
d->do_backlog = CONFIG_BOOLEAN_YES;
- st = rrdset_find_bytype_localhost("disk_backlog", disk);
- if(unlikely(!st)) {
- st = rrdset_create_localhost("disk_backlog", disk, NULL, family, "disk.backlog", "Disk Backlog"
- , "backlog (ms)", 2003, update_every, RRDSET_TYPE_AREA);
- rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
-
- rrddim_add(st, "backlog", NULL, 1, 10, RRD_ALGORITHM_INCREMENTAL);
+ if(unlikely(!d->st_backlog)) {
+ d->st_backlog = rrdset_create_localhost(
+ "disk_backlog"
+ , disk
+ , NULL
+ , family
+ , "disk.backlog"
+ , "Disk Backlog"
+ , "backlog (ms)"
+ , 2003
+ , update_every
+ , RRDSET_TYPE_AREA
+ );
+
+ rrdset_flag_set(d->st_backlog, RRDSET_FLAG_DETAIL);
+
+ rrddim_add(d->st_backlog, "backlog", NULL, 1, 10, RRD_ALGORITHM_INCREMENTAL);
}
- else rrdset_next(st);
+ else rrdset_next(d->st_backlog);
- rrddim_set(st, "backlog", backlog_ms);
- rrdset_done(st);
+ rrddim_set(d->st_backlog, "backlog", backlog_ms);
+ rrdset_done(d->st_backlog);
}
// --------------------------------------------------------------------
if(d->do_util == CONFIG_BOOLEAN_YES || (d->do_util == CONFIG_BOOLEAN_AUTO && busy_ms)) {
d->do_util = CONFIG_BOOLEAN_YES;
- st = rrdset_find_bytype_localhost("disk_util", disk);
- if(unlikely(!st)) {
- st = rrdset_create_localhost("disk_util", disk, NULL, family, "disk.util", "Disk Utilization Time"
- , "% of time working", 2004, update_every, RRDSET_TYPE_AREA);
- rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
-
- rrddim_add(st, "utilization", NULL, 1, 10, RRD_ALGORITHM_INCREMENTAL);
+ if(unlikely(!d->st_util)) {
+ d->st_util = rrdset_create_localhost(
+ "disk_util"
+ , disk
+ , NULL
+ , family
+ , "disk.util"
+ , "Disk Utilization Time"
+ , "% of time working"
+ , 2004
+ , update_every
+ , RRDSET_TYPE_AREA
+ );
+
+ rrdset_flag_set(d->st_util, RRDSET_FLAG_DETAIL);
+
+ rrddim_add(d->st_util, "utilization", NULL, 1, 10, RRD_ALGORITHM_INCREMENTAL);
}
- else rrdset_next(st);
+ else rrdset_next(d->st_util);
- last_busy_ms = rrddim_set(st, "utilization", busy_ms);
- rrdset_done(st);
+ last_busy_ms = rrddim_set(d->st_util, "utilization", busy_ms);
+ rrdset_done(d->st_util);
}
// --------------------------------------------------------------------
if(d->do_mops == CONFIG_BOOLEAN_YES || (d->do_mops == CONFIG_BOOLEAN_AUTO && (mreads || mwrites))) {
d->do_mops = CONFIG_BOOLEAN_YES;
- st = rrdset_find_bytype_localhost("disk_mops", disk);
- if(unlikely(!st)) {
- st = rrdset_create_localhost("disk_mops", disk, NULL, family, "disk.mops", "Disk Merged Operations"
- , "merged operations/s", 2021, update_every, RRDSET_TYPE_LINE);
- rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
-
- rrddim_add(st, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "writes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ if(unlikely(!d->st_mops)) {
+ d->st_mops = rrdset_create_localhost(
+ "disk_mops"
+ , disk
+ , NULL
+ , family
+ , "disk.mops"
+ , "Disk Merged Operations"
+ , "merged operations/s"
+ , 2021
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rrdset_flag_set(d->st_mops, RRDSET_FLAG_DETAIL);
+
+ rrddim_add(d->st_mops, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rrddim_add(d->st_mops, "writes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
- else rrdset_next(st);
+ else rrdset_next(d->st_mops);
- rrddim_set(st, "reads", mreads);
- rrddim_set(st, "writes", mwrites);
- rrdset_done(st);
+ rrddim_set(d->st_mops, "reads", mreads);
+ rrddim_set(d->st_mops, "writes", mwrites);
+ rrdset_done(d->st_mops);
}
// --------------------------------------------------------------------
if(d->do_iotime == CONFIG_BOOLEAN_YES || (d->do_iotime == CONFIG_BOOLEAN_AUTO && (readms || writems))) {
d->do_iotime = CONFIG_BOOLEAN_YES;
- st = rrdset_find_bytype_localhost("disk_iotime", disk);
- if(unlikely(!st)) {
- st = rrdset_create_localhost("disk_iotime", disk, NULL, family, "disk.iotime", "Disk Total I/O Time"
- , "milliseconds/s", 2022, update_every, RRDSET_TYPE_LINE);
- rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
-
- rrddim_add(st, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
- rrddim_add(st, "writes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
+ if(unlikely(!d->st_iotime)) {
+ d->st_iotime = rrdset_create_localhost(
+ "disk_iotime"
+ , disk
+ , NULL
+ , family
+ , "disk.iotime"
+ , "Disk Total I/O Time"
+ , "milliseconds/s"
+ , 2022
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rrdset_flag_set(d->st_iotime, RRDSET_FLAG_DETAIL);
+
+ rrddim_add(d->st_iotime, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ rrddim_add(d->st_iotime, "writes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
}
- else rrdset_next(st);
+ else rrdset_next(d->st_iotime);
- last_readms = rrddim_set(st, "reads", readms);
- last_writems = rrddim_set(st, "writes", writems);
- rrdset_done(st);
+ last_readms = rrddim_set(d->st_iotime, "reads", readms);
+ last_writems = rrddim_set(d->st_iotime, "writes", writems);
+ rrdset_done(d->st_iotime);
}
// --------------------------------------------------------------------
if(likely(dt)) {
if( (d->do_iotime == CONFIG_BOOLEAN_YES || (d->do_iotime == CONFIG_BOOLEAN_AUTO && (readms || writems))) &&
(d->do_ops == CONFIG_BOOLEAN_YES || (d->do_ops == CONFIG_BOOLEAN_AUTO && (reads || writes)))) {
- st = rrdset_find_bytype_localhost("disk_await", disk);
- if(unlikely(!st)) {
- st = rrdset_create_localhost("disk_await", disk, NULL, family, "disk.await"
- , "Average Completed I/O Operation Time", "ms per operation", 2005
- , update_every, RRDSET_TYPE_LINE);
- rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
-
- rrddim_add(st, "reads", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
- rrddim_add(st, "writes", NULL, -1, 1, RRD_ALGORITHM_ABSOLUTE);
+
+ if(unlikely(!d->st_await)) {
+ d->st_await = rrdset_create_localhost(
+ "disk_await"
+ , disk
+ , NULL
+ , family
+ , "disk.await"
+ , "Average Completed I/O Operation Time"
+ , "ms per operation"
+ , 2005
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rrdset_flag_set(d->st_await, RRDSET_FLAG_DETAIL);
+
+ rrddim_add(d->st_await, "reads", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ rrddim_add(d->st_await, "writes", NULL, -1, 1, RRD_ALGORITHM_ABSOLUTE);
}
- else rrdset_next(st);
+ else rrdset_next(d->st_await);
- rrddim_set(st, "reads", (reads - last_reads) ? (readms - last_readms) / (reads - last_reads) : 0);
- rrddim_set(st, "writes", (writes - last_writes) ? (writems - last_writems) / (writes - last_writes) : 0);
- rrdset_done(st);
+ rrddim_set(d->st_await, "reads", (reads - last_reads) ? (readms - last_readms) / (reads - last_reads) : 0);
+ rrddim_set(d->st_await, "writes", (writes - last_writes) ? (writems - last_writems) / (writes - last_writes) : 0);
+ rrdset_done(d->st_await);
}
if( (d->do_io == CONFIG_BOOLEAN_YES || (d->do_io == CONFIG_BOOLEAN_AUTO && (readsectors || writesectors))) &&
(d->do_ops == CONFIG_BOOLEAN_YES || (d->do_ops == CONFIG_BOOLEAN_AUTO && (reads || writes)))) {
- st = rrdset_find_bytype_localhost("disk_avgsz", disk);
- if(unlikely(!st)) {
- st = rrdset_create_localhost("disk_avgsz", disk, NULL, family, "disk.avgsz"
- , "Average Completed I/O Operation Bandwidth"
- , "kilobytes per operation", 2006, update_every, RRDSET_TYPE_AREA);
- rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
-
- rrddim_add(st, "reads", NULL, d->sector_size, 1024, RRD_ALGORITHM_ABSOLUTE);
- rrddim_add(st, "writes", NULL, d->sector_size * -1, 1024, RRD_ALGORITHM_ABSOLUTE);
+
+ if(unlikely(!d->st_avgsz)) {
+ d->st_avgsz = rrdset_create_localhost(
+ "disk_avgsz"
+ , disk
+ , NULL
+ , family
+ , "disk.avgsz"
+ , "Average Completed I/O Operation Bandwidth"
+ , "kilobytes per operation"
+ , 2006
+ , update_every
+ , RRDSET_TYPE_AREA
+ );
+
+ rrdset_flag_set(d->st_avgsz, RRDSET_FLAG_DETAIL);
+
+ rrddim_add(d->st_avgsz, "reads", NULL, d->sector_size, 1024, RRD_ALGORITHM_ABSOLUTE);
+ rrddim_add(d->st_avgsz, "writes", NULL, d->sector_size * -1, 1024, RRD_ALGORITHM_ABSOLUTE);
}
- else rrdset_next(st);
+ else rrdset_next(d->st_avgsz);
- rrddim_set(st, "reads", (reads - last_reads) ? (readsectors - last_readsectors) / (reads - last_reads) : 0);
- rrddim_set(st, "writes", (writes - last_writes) ? (writesectors - last_writesectors) / (writes - last_writes) : 0);
- rrdset_done(st);
+ rrddim_set(d->st_avgsz, "reads", (reads - last_reads) ? (readsectors - last_readsectors) / (reads - last_reads) : 0);
+ rrddim_set(d->st_avgsz, "writes", (writes - last_writes) ? (writesectors - last_writesectors) / (writes - last_writes) : 0);
+ rrdset_done(d->st_avgsz);
}
if( (d->do_util == CONFIG_BOOLEAN_YES || (d->do_util == CONFIG_BOOLEAN_AUTO && busy_ms)) &&
(d->do_ops == CONFIG_BOOLEAN_YES || (d->do_ops == CONFIG_BOOLEAN_AUTO && (reads || writes)))) {
- st = rrdset_find_bytype_localhost("disk_svctm", disk);
- if(unlikely(!st)) {
- st = rrdset_create_localhost("disk_svctm", disk, NULL, family, "disk.svctm", "Average Service Time"
- , "ms per operation", 2007, update_every, RRDSET_TYPE_LINE);
- rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
- rrddim_add(st, "svctm", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ if(unlikely(!d->st_svctm)) {
+ d->st_svctm = rrdset_create_localhost(
+ "disk_svctm"
+ , disk
+ , NULL
+ , family
+ , "disk.svctm"
+ , "Average Service Time"
+ , "ms per operation"
+ , 2007
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rrdset_flag_set(d->st_svctm, RRDSET_FLAG_DETAIL);
+
+ rrddim_add(d->st_svctm, "svctm", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
}
- else rrdset_next(st);
+ else rrdset_next(d->st_svctm);
+
+ rrddim_set(d->st_svctm, "svctm", ((reads - last_reads) + (writes - last_writes)) ? (busy_ms - last_busy_ms) / ((reads - last_reads) + (writes - last_writes)) : 0);
+ rrdset_done(d->st_svctm);
+ }
+ }
+ }
- rrddim_set(st, "svctm", ((reads - last_reads) + (writes - last_writes)) ? (busy_ms - last_busy_ms) / ((reads - last_reads) + (writes - last_writes)) : 0);
- rrdset_done(st);
+ // cleanup removed disks
+
+ struct disk *d = disk_root, *last = NULL;
+ while(d) {
+ if(unlikely(!d->updated)) {
+ struct disk *t = d;
+
+ rrdset_obsolete_and_pointer_null(d->st_avgsz);
+ rrdset_obsolete_and_pointer_null(d->st_await);
+ rrdset_obsolete_and_pointer_null(d->st_backlog);
+ rrdset_obsolete_and_pointer_null(d->st_io);
+ rrdset_obsolete_and_pointer_null(d->st_iotime);
+ rrdset_obsolete_and_pointer_null(d->st_mops);
+ rrdset_obsolete_and_pointer_null(d->st_ops);
+ rrdset_obsolete_and_pointer_null(d->st_qops);
+ rrdset_obsolete_and_pointer_null(d->st_svctm);
+ rrdset_obsolete_and_pointer_null(d->st_util);
+
+ if(d == disk_root) {
+ disk_root = d = d->next;
+ last = NULL;
+ }
+ else if(last) {
+ last->next = d = d->next;
}
+
+ freez(t->disk);
+ freez(t->mount_point);
+ freez(t);
+ }
+ else {
+ d->updated = 0;
+ last = d;
+ d = d->next;
}
}