]> git.ipfire.org Git - thirdparty/collectd.git/commitdiff
Native (sysctl) NetBSD disk plugin implementation
authorEdgar Fuß <ef@math.uni-bonn.de>
Thu, 31 Oct 2019 18:09:37 +0000 (19:09 +0100)
committerDagobert Michelsen <dam@opencsw.org>
Tue, 18 Feb 2020 16:31:02 +0000 (17:31 +0100)
Natively implement the disk plugin on NetBSD using sysctl().
Based on prior work by Håvard Eidnes, <he@NetBSD.org>.

src/disk.c

index c02b6aba0b5cf61def3c48ea730cd2d686566c19..e5491e4c814d48df5a310e7c5ace4041c45de04b 100644 (file)
@@ -135,6 +135,16 @@ static int numdisk;
 static int pnumdisk;
 /* #endif HAVE_PERFSTAT */
 
+#elif HAVE_SYSCTL && KERNEL_NETBSD
+
+#include <sys/sysctl.h>
+#include <sys/iostat.h>
+
+static struct io_sysctl *drives = NULL;
+static size_t ndrive = 0;
+
+/* #endif HAVE_SYSCTL && KERNEL_NETBSD */
+
 #else
 #error "No applicable input method."
 #endif
@@ -253,7 +263,31 @@ 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 */
@@ -285,7 +319,7 @@ static void disk_submit(const char *plugin_instance, const char *type,
   plugin_dispatch_values(&vl);
 } /* void disk_submit */
 
-#if KERNEL_FREEBSD || KERNEL_LINUX
+#if KERNEL_FREEBSD || (HAVE_SYSCTL && KERNEL_NETBSD) || KERNEL_LINUX
 static void submit_io_time(char const *plugin_instance, derive_t io_time,
                            derive_t weighted_time) {
   value_list_t vl = VALUE_LIST_INIT;
@@ -302,7 +336,9 @@ static void submit_io_time(char const *plugin_instance, derive_t io_time,
 
   plugin_dispatch_values(&vl);
 } /* void submit_io_time */
+#endif /* KERNEL_FREEBSD || (HAVE_SYSCTL && KERNEL_NETBSD) || KERNEL_LINUX */
 
+#ifdef KERNEL_FREEBSD || KERNEL_LINUX
 static void submit_in_progress(char const *disk_name, gauge_t in_progress) {
   value_list_t vl = VALUE_LIST_INIT;
 
@@ -1023,7 +1059,58 @@ static int disk_read(void) {
                   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;
+
+  /* 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;
+    if (ignorelist_match(ignorelist, drives[i].name))
+      continue;
+
+    disk_submit(drives[i].name, "disk_octets",
+                drives[i].rbytes, drives[i].wbytes);
+    disk_submit(drives[i].name, "disk_ops",
+                drives[i].rxfer, drives[i].wxfer);
+    submit_io_time(drives[i].name,
+                   drives[i].time_sec * 1000 + drives[i].time_usec / 1000, 0);
+  }
+#endif /* HAVE_SYSCTL && KERNEL_NETBSD */
 
   return 0;
 } /* int disk_read */