37301e4e46
* entropy * memory * swap * disk by shamelessly copying code from vmstat/iostat/rndctl etc. Add comments to one patch missing one. Bump PKGREVISION.
209 lines
5.1 KiB
C
209 lines
5.1 KiB
C
$NetBSD: patch-src_disk.c,v 1.1 2015/08/11 13:19:21 he Exp $
|
|
|
|
Provide a port to NetBSD.
|
|
|
|
--- src/disk.c.orig 2015-03-10 14:14:45.000000000 +0000
|
|
+++ src/disk.c
|
|
@@ -124,6 +124,35 @@ static int numdisk;
|
|
static int pnumdisk;
|
|
/* #endif HAVE_PERFSTAT */
|
|
|
|
+#elif HAVE_SYSCTL && KERNEL_NETBSD
|
|
+
|
|
+#include <sys/sysctl.h>
|
|
+#include <sys/iostat.h>
|
|
+
|
|
+typedef struct diskstats {
|
|
+ char *name;
|
|
+
|
|
+ u_int poll_count;
|
|
+
|
|
+ derive_t read_ops;
|
|
+ derive_t write_ops;
|
|
+
|
|
+ derive_t read_bytes;
|
|
+ derive_t write_bytes;
|
|
+
|
|
+ derive_t avg_io_time;
|
|
+
|
|
+ struct io_sysctl stats;
|
|
+
|
|
+ struct diskstats *next;
|
|
+} diskstats_t;
|
|
+
|
|
+static diskstats_t *disklist;
|
|
+static struct io_sysctl *drives = NULL;
|
|
+static size_t ndrive = 0;
|
|
+
|
|
+/* #endif HAVE_SYSCTL && KERNEL_NETBSD */
|
|
+
|
|
#else
|
|
# error "No applicable input method."
|
|
#endif
|
|
@@ -241,7 +270,34 @@ static int disk_init (void)
|
|
continue;
|
|
ksp[numdisk++] = ksp_chain;
|
|
}
|
|
-#endif /* HAVE_LIBKSTAT */
|
|
+/* #endif HAVE_LIBKSTAT */
|
|
+
|
|
+#elif HAVE_SYSCTL && KERNEL_NETBSD
|
|
+ int mib[3];
|
|
+ size_t size;
|
|
+
|
|
+ /* figure out number of drives */
|
|
+ mib[0] = CTL_HW;
|
|
+ mib[1] = HW_IOSTATS;
|
|
+ mib[2] = sizeof(struct io_sysctl);
|
|
+ if (sysctl(mib, 3, NULL, &size, NULL, 0) == -1) {
|
|
+ ERROR ("disk plugin: sysctl for ndrives failed");
|
|
+ return -1;
|
|
+ }
|
|
+ ndrive = size / sizeof(struct io_sysctl);
|
|
+
|
|
+ if (size == 0 ) {
|
|
+ ERROR ("disk plugin: no drives found");
|
|
+ return -1;
|
|
+ }
|
|
+ drives = (struct io_sysctl *)malloc(size);
|
|
+ if (drives == NULL) {
|
|
+ ERROR ("disk plugin: memory allocation failure");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+#endif /* HAVE_SYSCTL && KERNEL_NETBSD */
|
|
+
|
|
|
|
return (0);
|
|
} /* int disk_init */
|
|
@@ -929,7 +985,129 @@ static int disk_read (void)
|
|
write_time *= ((double)(_system_configuration.Xint)/(double)(_system_configuration.Xfrac)) / 1000000.0;
|
|
disk_submit (stat_disk[i].name, "disk_time", read_time, write_time);
|
|
}
|
|
-#endif /* defined(HAVE_PERFSTAT) */
|
|
+/* #endif defined(HAVE_PERFSTAT) */
|
|
+
|
|
+#elif HAVE_SYSCTL && KERNEL_NETBSD
|
|
+ int mib[3];
|
|
+ size_t size, i, nndrive;
|
|
+ diskstats_t *ds, *pre_ds;
|
|
+ char *output_name;
|
|
+
|
|
+ u_int64_t ops;
|
|
+ u_int64_t delta_t;
|
|
+
|
|
+ /* figure out number of drives */
|
|
+ mib[0] = CTL_HW;
|
|
+ mib[1] = HW_IOSTATS;
|
|
+ mib[2] = sizeof(struct io_sysctl);
|
|
+ if (sysctl(mib, 3, NULL, &size, NULL, 0) == -1) {
|
|
+ ERROR ("disk plugin: sysctl for ndrives failed");
|
|
+ return -1;
|
|
+ }
|
|
+ nndrive = size / sizeof(struct io_sysctl);
|
|
+
|
|
+ if (size == 0 ) {
|
|
+ ERROR ("disk plugin: no drives found");
|
|
+ return -1;
|
|
+ }
|
|
+ /* number of drives changed, reallocate buffer */
|
|
+ if (nndrive != ndrive) {
|
|
+ drives = (struct io_sysctl *)realloc(drives, size);
|
|
+ if (drives == NULL) {
|
|
+ ERROR ("disk plugin: memory allocation failure");
|
|
+ return -1;
|
|
+ }
|
|
+ ndrive = nndrive;
|
|
+ }
|
|
+
|
|
+ /* get stats for all drives */
|
|
+ mib[0] = CTL_HW;
|
|
+ mib[1] = HW_IOSTATS;
|
|
+ mib[2] = sizeof(struct io_sysctl);
|
|
+ if (sysctl(mib, 3, drives, &size, NULL, 0) == -1) {
|
|
+ ERROR ("disk plugin: sysctl for drive stats failed");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < ndrive; i++) {
|
|
+
|
|
+ if (drives[i].type != IOSTAT_DISK)
|
|
+ continue;
|
|
+
|
|
+ /* find drive stats, if present */
|
|
+ for (ds = disklist, pre_ds = disklist;
|
|
+ ds != NULL;
|
|
+ pre_ds = ds, ds = ds->next) {
|
|
+ if (strcmp (drives[i].name, ds->name) == 0)
|
|
+ break;
|
|
+ }
|
|
+ if (ds == NULL) { /* not found; allocate & link in */
|
|
+ if ((ds = calloc(1, sizeof(diskstats_t))) == NULL)
|
|
+ continue;
|
|
+ if ((ds->name = strdup(drives[i].name)) == NULL) {
|
|
+ free(ds);
|
|
+ continue;
|
|
+ }
|
|
+ if (pre_ds == NULL)
|
|
+ disklist = ds;
|
|
+ else
|
|
+ pre_ds->next = ds;
|
|
+ }
|
|
+
|
|
+ ds->poll_count++;
|
|
+ if (ds->poll_count <= 2)
|
|
+ {
|
|
+ DEBUG ("disk plugin: (ds->poll_count = %i) <= "
|
|
+ "(min_poll_count = 2); => Not writing.",
|
|
+ ds->poll_count);
|
|
+ ds->stats = drives[i]; /* but save base values */
|
|
+ continue;
|
|
+ }
|
|
+ ds->read_ops = drives[i].rxfer - ds->stats.rxfer;
|
|
+ ds->write_ops = drives[i].wxfer - ds->stats.wxfer;
|
|
+ ds->read_bytes = drives[i].rbytes - ds->stats.rbytes;
|
|
+ ds->write_bytes = drives[i].wbytes - ds->stats.wbytes;
|
|
+
|
|
+ /* Need this dance because of unsigned values... */
|
|
+ if (drives[i].time_usec < ds->stats.time_usec) {
|
|
+ delta_t = ((drives[i].time_sec - 1 -
|
|
+ ds->stats.time_sec) * 1000) +
|
|
+ ((drives[i].time_usec + 1000000 -
|
|
+ ds->stats.time_usec) / 1000);
|
|
+ } else {
|
|
+ delta_t = ((drives[i].time_sec -
|
|
+ ds->stats.time_sec) * 1000) +
|
|
+ ((drives[i].time_usec -
|
|
+ ds->stats.time_usec) / 1000);
|
|
+ }
|
|
+
|
|
+ ops = ds->read_ops + ds->write_ops;
|
|
+ if (ops == 0) {
|
|
+ DEBUG ("disk plugin: read + write ops == 0, "
|
|
+ "not writing");
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ ds->avg_io_time = delta_t / ops;
|
|
+
|
|
+ output_name = drives[i].name;
|
|
+
|
|
+ if ((ds->read_bytes != 0) || (ds->write_bytes != 0))
|
|
+ disk_submit (output_name, "disk_octets",
|
|
+ ds->read_bytes, ds->write_bytes);
|
|
+
|
|
+ if ((ds->read_ops != 0) || (ds->write_ops != 0))
|
|
+ disk_submit (output_name, "disk_ops",
|
|
+ ds->read_ops, ds->write_ops);
|
|
+
|
|
+ if (ds->avg_io_time != 0)
|
|
+ disk_submit (output_name, "disk_time",
|
|
+ ds->avg_io_time, ds->avg_io_time);
|
|
+
|
|
+ ds->stats = drives[i];
|
|
+ }
|
|
+
|
|
+#endif /* HAVE_SYSCTL && KERNEL_NETBSD */
|
|
|
|
return (0);
|
|
} /* int disk_read */
|