patch from Pedro Martelletto (again) to sync w/new separated read/write

statistics available in the kernel.  Pedro also did the kernel parts to
make this possible...
This commit is contained in:
jolan 2004-02-17 21:37:15 +00:00
parent 7da4ed7ff9
commit 044e012c97

View File

@ -1,25 +1,19 @@
$OpenBSD: patch-panel-plugin_devperf_c,v 1.1.1.1 2004/01/31 03:32:03 jolan Exp $
$OpenBSD: patch-panel-plugin_devperf_c,v 1.2 2004/02/17 21:37:15 jolan Exp $
--- panel-plugin/devperf.c.orig 2003-11-30 09:01:44.000000000 -0200
+++ panel-plugin/devperf.c 2004-01-30 23:37:45.000000000 -0200
@@ -310,6 +310,124 @@ int DevGetPerfData (const void *p_pvDevi
+++ panel-plugin/devperf.c 2004-02-15 22:51:32.000000000 -0300
@@ -310,6 +310,82 @@ int DevGetPerfData (const void *p_pvDevi
/* *INDENT-ON* */
/************************** NetBSD End ***************/
+#elif defined(__OpenBSD__)
+/*
+ * OpenBSD support. As of the moment of this writing OpenBSD didn't separate
+ * read and write disk statistics, they were assumed to have the same value.
+ * OpenBSD support.
+ */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/disk.h>
+
+#include <string.h>
+
+static char **disks = NULL;
+static int diskn = 0;
+
+int DevPerfInit ()
+{
+ return (0);
@ -32,93 +26,57 @@ $OpenBSD: patch-panel-plugin_devperf_c,v 1.1.1.1 2004/01/31 03:32:03 jolan Exp $
+
+int DevGetPerfData (const void *p_pvDevice, struct devperf_t *perf)
+{
+ int mib[3], cur_diskn, x;
+ int mib[3], diskn, x;
+ size_t len;
+ void *r;
+ char **tok, *names, *devname = (char *)p_pvDevice;
+ struct diskstats *diskstats;
+ char *devname = (char *)p_pvDevice;
+ struct diskstats *ds;
+ struct timeval tv;
+
+ mib[0] = CTL_HW;
+ mib[1] = HW_DISKCOUNT;
+ len = sizeof(cur_diskn);
+ len = sizeof(diskn);
+
+ if (sysctl(mib, 2, &cur_diskn, &len, NULL, 0) < 0)
+ return (-1);
+
+ if (cur_diskn != diskn) {
+ if (disks != NULL)
+ free(disks[0]);
+ r = realloc(disks, cur_diskn * sizeof(char *));
+ if (r == NULL) {
+error: free(disks);
+ disks = NULL;
+ diskn = 0;
+ return (-1);
+ } else
+ disks = (char **)r;
+
+ mib[0] = CTL_HW;
+ mib[1] = HW_DISKNAMES;
+ len = 0;
+
+ if (sysctl(mib, 2, NULL, &len, NULL, 0) < 0)
+ goto error;
+
+ names = malloc(len);
+ if (names == NULL)
+ goto error;
+
+ if (sysctl(mib, 2, names, &len, NULL, 0) < 0) {
+ free(names);
+ goto error;
+ }
+
+ diskn = cur_diskn;
+
+ for (tok = disks; tok <= &disks[cur_diskn - 1] &&
+ (*tok = strsep(&names, ",")) != NULL;)
+ if (**tok != '\0')
+ tok++;
+ }
+
+ for (x = 0; x < diskn; x++)
+ if (!strcmp(disks[x], devname))
+ break;
+
+ if (x == diskn)
+ if (sysctl(mib, 2, &diskn, &len, NULL, 0) < 0)
+ return (-1);
+
+ mib[0] = CTL_HW;
+ mib[1] = HW_DISKSTATS;
+ len = diskn * sizeof(struct diskstats);
+
+ diskstats = malloc(len);
+ if (diskstats == NULL)
+ ds = malloc(len);
+ if (ds == NULL)
+ return (-1);
+
+ if (sysctl(mib, 2, diskstats, &len, NULL, 0) < 0) {
+ free(diskstats);
+ if (sysctl(mib, 2, ds, &len, NULL, 0) < 0) {
+ free(ds);
+ return (-1);
+ }
+
+ for (x = 0; x < diskn; x++)
+ if (!strcmp(ds[x].ds_name, devname))
+ break;
+
+ if (x == diskn) {
+ free(ds);
+ return (-1);
+ }
+
+ if (gettimeofday(&tv, NULL)) {
+ free(diskstats);
+ free(ds);
+ return (-1);
+ }
+
+ perf->timestamp_ns = (uint64_t)1000ull * 1000ull * 1000ull * tv.tv_sec
+ + 1000ull * tv.tv_usec;
+ perf->rbusy_ns = ((uint64_t)1000ull * 1000ull * 1000ull *
+ diskstats[x].ds_time.tv_sec + 1000ull *
+ diskstats[x].ds_time.tv_usec) / 2ull;
+ ds[x].ds_time.tv_sec + 1000ull * ds[x].ds_time.tv_usec) / 2ull;
+
+ perf->wbusy_ns = perf->rbusy_ns / 2ull;
+ perf->rbytes = diskstats[x].ds_bytes;
+ perf->wbytes = perf->rbytes;
+ perf->qlen = diskstats[x].ds_xfer;
+ perf->rbytes = ds[x].ds_rbytes;
+ perf->wbytes = ds[x].ds_wbytes;
+ perf->qlen = ds[x].ds_rxfer + ds[x].ds_wxfer;
+
+ free(diskstats);
+ free(ds);
+
+ return (0);
+}