Signed-off-by: Paul Guyot <[email protected]>
---
 configure.in    |  11 +++++
 src/Makefile.am |  18 ++++----
 src/zfs_arc.c   | 138 ++++++++++++++++++++++++++++++++++++++------------------
 3 files changed, 114 insertions(+), 53 deletions(-)

diff --git a/configure.in b/configure.in
index 98395ed..e51dbcf 100644
--- a/configure.in
+++ b/configure.in
@@ -67,6 +67,9 @@ case $host_os in
        *openbsd*)
        ac_system="OpenBSD"
        ;;
+       *freebsd*)
+       ac_system="FreeBSD"
+       ;;
        *aix*)
        AC_DEFINE([KERNEL_AIX], 1, [True if program is to be compiled for a AIX 
kernel])
        ac_system="AIX"
@@ -1395,6 +1398,8 @@ if test "x$with_kstat" = "xyes"
 then
        AC_DEFINE(HAVE_LIBKSTAT, 1,
                  [Define to 1 if you have the 'kstat' library (-lkstat)])
+        BUILD_WITH_LIBKSTAT_LIBS="-lkstat"
+        AC_SUBST(BUILD_WITH_LIBKSTAT_LIBS)
 fi
 AM_CONDITIONAL(BUILD_WITH_LIBKSTAT, test "x$with_kstat" = "xyes")
 AM_CONDITIONAL(BUILD_WITH_LIBDEVINFO, test "x$with_devinfo" = "xyes")
@@ -4661,6 +4666,12 @@ then
        plugin_zfs_arc="yes"
 fi
 
+# FreeBSD
+if test "x$ac_system" = "xFreeBSD"
+then
+       plugin_zfs_arc="yes"
+fi
+
 if test "x$with_devinfo$with_kstat" = "xyesyes"
 then
        plugin_cpu="yes"
diff --git a/src/Makefile.am b/src/Makefile.am
index 26c2355..07942c8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -63,7 +63,7 @@ if BUILD_WITH_LIBPTHREAD
 collectd_LDADD += -lpthread
 endif
 if BUILD_WITH_LIBKSTAT
-collectd_LDADD += -lkstat
+collectd_LDADD += $(BUILD_WITH_LIBKSTAT_LIBS)
 endif
 if BUILD_WITH_LIBDEVINFO
 collectd_LDADD += -ldevinfo
@@ -250,7 +250,7 @@ cpu_la_CFLAGS = $(AM_CFLAGS)
 cpu_la_LDFLAGS = -module -avoid-version
 cpu_la_LIBADD = 
 if BUILD_WITH_LIBKSTAT
-cpu_la_LIBADD += -lkstat
+cpu_la_LIBADD += $(BUILD_WITH_LIBKSTAT_LIBS)
 endif
 if BUILD_WITH_LIBDEVINFO
 cpu_la_LIBADD += -ldevinfo
@@ -348,7 +348,7 @@ disk_la_CFLAGS = $(AM_CFLAGS)
 disk_la_LDFLAGS = -module -avoid-version
 disk_la_LIBADD = 
 if BUILD_WITH_LIBKSTAT
-disk_la_LIBADD += -lkstat
+disk_la_LIBADD += $(BUILD_WITH_LIBKSTAT_LIBS)
 endif
 if BUILD_WITH_LIBDEVINFO
 disk_la_LIBADD += -ldevinfo
@@ -455,7 +455,7 @@ interface_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
 interface_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
 else
 if BUILD_WITH_LIBKSTAT
-interface_la_LIBADD += -lkstat
+interface_la_LIBADD += $(BUILD_WITH_LIBKSTAT_LIBS)
 endif
 if BUILD_WITH_LIBDEVINFO
 interface_la_LIBADD += -ldevinfo
@@ -660,7 +660,7 @@ memory_la_LIBADD =
 collectd_LDADD += "-dlopen" memory.la
 collectd_DEPENDENCIES += memory.la
 if BUILD_WITH_LIBKSTAT
-memory_la_LIBADD += -lkstat
+memory_la_LIBADD += $(BUILD_WITH_LIBKSTAT_LIBS)
 endif
 if BUILD_WITH_LIBDEVINFO
 memory_la_LIBADD += -ldevinfo
@@ -1055,7 +1055,7 @@ swap_la_LIBADD =
 collectd_LDADD += "-dlopen" swap.la
 collectd_DEPENDENCIES += swap.la
 if BUILD_WITH_LIBKSTAT
-swap_la_LIBADD += -lkstat
+swap_la_LIBADD += $(BUILD_WITH_LIBKSTAT_LIBS)
 endif
 if BUILD_WITH_LIBDEVINFO
 swap_la_LIBADD += -ldevinfo
@@ -1101,7 +1101,7 @@ if BUILD_PLUGIN_TAPE
 pkglib_LTLIBRARIES += tape.la
 tape_la_SOURCES = tape.c
 tape_la_LDFLAGS = -module -avoid-version
-tape_la_LIBADD = -lkstat -ldevinfo
+tape_la_LIBADD = $(BUILD_WITH_LIBKSTAT_LIBS) -ldevinfo
 collectd_LDADD += "-dlopen" tape.la
 collectd_DEPENDENCIES += tape.la
 endif
@@ -1224,7 +1224,7 @@ uptime_la_CFLAGS = $(AM_CFLAGS)
 uptime_la_LDFLAGS = -module -avoid-version
 uptime_la_LIBADD =
 if BUILD_WITH_LIBKSTAT
-uptime_la_LIBADD += -lkstat
+uptime_la_LIBADD += $(BUILD_WITH_LIBKSTAT_LIBS)
 endif
 if BUILD_WITH_PERFSTAT
 uptime_la_LIBADD += -lperfstat
@@ -1351,7 +1351,7 @@ pkglib_LTLIBRARIES += zfs_arc.la
 zfs_arc_la_SOURCES = zfs_arc.c
 zfs_arc_la_CFLAGS = $(AM_CFLAGS)
 zfs_arc_la_LDFLAGS = -module -avoid-version
-zfs_arc_la_LIBADD = -lkstat
+zfs_arc_la_LIBADD = $(BUILD_WITH_LIBKSTAT_LIBS)
 collectd_LDADD += "-dlopen" zfs_arc.la
 collectd_DEPENDENCIES += zfs_arc.la
 endif
diff --git a/src/zfs_arc.c b/src/zfs_arc.c
index 046b7b0..ab93ec9 100644
--- a/src/zfs_arc.c
+++ b/src/zfs_arc.c
@@ -25,11 +25,57 @@
 #include "common.h"
 #include "plugin.h"
 
+#if !defined(HAVE_LIBKSTAT) && defined(HAVE_SYSCTLBYNAME)
+#include <sys/sysctl.h>
+#endif
+
 /*
  * Global variables
  */
-
+#if defined(HAVE_LIBKSTAT)
 extern kstat_ctl_t *kc;
+#endif
+
+/*
+ * Context
+ */
+struct za_context {
+#if defined(HAVE_LIBKSTAT)
+    kstat_t *ksp;
+#endif
+};
+
+static int za_init_context(struct za_context *ctx)
+{
+#if defined(HAVE_LIBKSTAT)
+       get_kstat (&ctx->ksp, "zfs", 0, "arcstats");
+       if (ctx->ksp == NULL)
+       {
+               ERROR ("zfs_arc plugin: Cannot find zfs:0:arcstats kstat.");
+               return (-1);
+       }
+#endif
+       return 0;
+}
+
+static long long za_get_value(struct za_context *ctx, const char* name)
+{
+#if defined(HAVE_LIBKSTAT)
+       return get_kstat_value(ctx->ksp, name);
+#elif defined(HAVE_SYSCTLBYNAME)
+       // kstat values are available on FreeBSD through sysctl
+       char fullname[512];
+       long long result = 0;
+       size_t size = sizeof(result);
+       ssnprintf(fullname, sizeof(fullname), "kstat.zfs.misc.arcstats.%s", 
name);
+       if (sysctlbyname(fullname, &result, &size, NULL, 0) != 0 || size != 
sizeof(result))
+       {
+               ERROR ("zfs_arc plugin: Cannot find stats using sysctl");
+               result = 0;
+       }
+       return result;
+#endif
+}
 
 static void za_submit (const char* type, const char* type_instance, value_t* 
values, int values_len)
 {
@@ -54,13 +100,13 @@ static void za_submit_gauge (const char* type, const char* 
type_instance, gauge_
        za_submit (type, type_instance, &vv, 1);
 }
 
-static int za_read_derive (kstat_t *ksp, const char *kstat_value,
+static int za_read_derive (struct za_context *ctx, const char *kstat_value,
     const char *type, const char *type_instance)
 {
   long long tmp;
   value_t v;
 
-  tmp = get_kstat_value (ksp, (char *)kstat_value);
+  tmp = za_get_value (ctx, (char *)kstat_value);
   if (tmp == -1LL)
   {
     ERROR ("zfs_arc plugin: Reading kstat value \"%s\" failed.", kstat_value);
@@ -72,13 +118,13 @@ static int za_read_derive (kstat_t *ksp, const char 
*kstat_value,
   return (0);
 }
 
-static int za_read_gauge (kstat_t *ksp, const char *kstat_value,
+static int za_read_gauge (struct za_context *ctx, const char *kstat_value,
     const char *type, const char *type_instance)
 {
   long long tmp;
   value_t v;
 
-  tmp = get_kstat_value (ksp, (char *)kstat_value);
+  tmp = za_get_value (ctx, (char *)kstat_value);
   if (tmp == -1LL)
   {
     ERROR ("zfs_arc plugin: Reading kstat value \"%s\" failed.", kstat_value);
@@ -90,16 +136,11 @@ static int za_read_gauge (kstat_t *ksp, const char 
*kstat_value,
   return (0);
 }
 
-static void za_submit_ratio (const char* type_instance, gauge_t hits, gauge_t 
misses)
+static void za_submit_ratio (const char* type_instance, long long hits, long 
long misses)
 {
        gauge_t ratio = NAN;
 
-       if (!isfinite (hits) || (hits < 0.0))
-               hits = 0.0;
-       if (!isfinite (misses) || (misses < 0.0))
-               misses = 0.0;
-
-       if ((hits != 0.0) || (misses != 0.0))
+       if ((hits > 0) || (misses > 0))
                ratio = hits / (hits + misses);
 
        za_submit_gauge ("cache_ratio", type_instance, ratio);
@@ -107,57 +148,55 @@ static void za_submit_ratio (const char* type_instance, 
gauge_t hits, gauge_t mi
 
 static int za_read (void)
 {
-       gauge_t  arc_hits, arc_misses, l2_hits, l2_misses;
+       long long  arc_hits, arc_misses, l2_hits, l2_misses;
        value_t  l2_io[2];
-       kstat_t  *ksp   = NULL;
+       struct za_context ctx;
 
-       get_kstat (&ksp, "zfs", 0, "arcstats");
-       if (ksp == NULL)
+       if (za_init_context (&ctx) < 0)
        {
-               ERROR ("zfs_arc plugin: Cannot find zfs:0:arcstats kstat.");
                return (-1);
        }
 
        /* Sizes */
-       za_read_gauge (ksp, "size",    "cache_size", "arc");
-       za_read_gauge (ksp, "l2_size", "cache_size", "L2");
+       za_read_gauge (&ctx, "size",    "cache_size", "arc");
+       za_read_gauge (&ctx, "l2_size", "cache_size", "L2");
 
-        /* Operations */
-       za_read_derive (ksp, "allocated","cache_operation", "allocated");
-       za_read_derive (ksp, "deleted",  "cache_operation", "deleted");
-       za_read_derive (ksp, "stolen",   "cache_operation", "stolen");
+       /* Operations */
+       za_read_derive (&ctx, "allocated","cache_operation", "allocated");
+       za_read_derive (&ctx, "deleted",  "cache_operation", "deleted");
+       za_read_derive (&ctx, "stolen",   "cache_operation", "stolen");
 
-        /* Issue indicators */
-        za_read_derive (ksp, "mutex_miss", "mutex_operation", "miss");
-       za_read_derive (ksp, "hash_collisions", "hash_collisions", "");
+       /* Issue indicators */
+       za_read_derive (&ctx, "mutex_miss", "mutex_operation", "miss");
+       za_read_derive (&ctx, "hash_collisions", "hash_collisions", "");
        
-        /* Evictions */
-       za_read_derive (ksp, "evict_l2_cached",     "cache_eviction", "cached");
-       za_read_derive (ksp, "evict_l2_eligible",   "cache_eviction", 
"eligible");
-       za_read_derive (ksp, "evict_l2_ineligible", "cache_eviction", 
"ineligible");
+       /* Evictions */
+       za_read_derive (&ctx, "evict_l2_cached",     "cache_eviction", 
"cached");
+       za_read_derive (&ctx, "evict_l2_eligible",   "cache_eviction", 
"eligible");
+       za_read_derive (&ctx, "evict_l2_ineligible", "cache_eviction", 
"ineligible");
 
        /* Hits / misses */
-       za_read_derive (ksp, "demand_data_hits",         "cache_result", 
"demand_data-hit");
-       za_read_derive (ksp, "demand_metadata_hits",     "cache_result", 
"demand_metadata-hit");
-       za_read_derive (ksp, "prefetch_data_hits",       "cache_result", 
"prefetch_data-hit");
-       za_read_derive (ksp, "prefetch_metadata_hits",   "cache_result", 
"prefetch_metadata-hit");
-       za_read_derive (ksp, "demand_data_misses",       "cache_result", 
"demand_data-miss");
-       za_read_derive (ksp, "demand_metadata_misses",   "cache_result", 
"demand_metadata-miss");
-       za_read_derive (ksp, "prefetch_data_misses",     "cache_result", 
"prefetch_data-miss");
-       za_read_derive (ksp, "prefetch_metadata_misses", "cache_result", 
"prefetch_metadata-miss");
+       za_read_derive (&ctx, "demand_data_hits",         "cache_result", 
"demand_data-hit");
+       za_read_derive (&ctx, "demand_metadata_hits",     "cache_result", 
"demand_metadata-hit");
+       za_read_derive (&ctx, "prefetch_data_hits",       "cache_result", 
"prefetch_data-hit");
+       za_read_derive (&ctx, "prefetch_metadata_hits",   "cache_result", 
"prefetch_metadata-hit");
+       za_read_derive (&ctx, "demand_data_misses",       "cache_result", 
"demand_data-miss");
+       za_read_derive (&ctx, "demand_metadata_misses",   "cache_result", 
"demand_metadata-miss");
+       za_read_derive (&ctx, "prefetch_data_misses",     "cache_result", 
"prefetch_data-miss");
+       za_read_derive (&ctx, "prefetch_metadata_misses", "cache_result", 
"prefetch_metadata-miss");
 
        /* Ratios */
-       arc_hits   = (gauge_t) get_kstat_value(ksp, "hits");
-       arc_misses = (gauge_t) get_kstat_value(ksp, "misses");
-       l2_hits    = (gauge_t) get_kstat_value(ksp, "l2_hits");
-       l2_misses  = (gauge_t) get_kstat_value(ksp, "l2_misses");
+       arc_hits   = za_get_value (&ctx, "hits");
+       arc_misses = za_get_value (&ctx, "misses");
+       l2_hits    = za_get_value (&ctx, "l2_hits");
+       l2_misses  = za_get_value (&ctx, "l2_misses");
 
        za_submit_ratio ("arc", arc_hits, arc_misses);
        za_submit_ratio ("L2", l2_hits, l2_misses);
 
        /* I/O */
-       l2_io[0].derive = get_kstat_value(ksp, "l2_read_bytes");
-       l2_io[1].derive = get_kstat_value(ksp, "l2_write_bytes");
+       l2_io[0].derive = za_get_value (&ctx, "l2_read_bytes");
+       l2_io[1].derive = za_get_value (&ctx, "l2_write_bytes");
 
        za_submit ("io_octets", "L2", l2_io, /* num values = */ 2);
 
@@ -166,12 +205,23 @@ static int za_read (void)
 
 static int za_init (void) /* {{{ */
 {
+#if defined(HAVE_LIBKSTAT)
        /* kstats chain already opened by update_kstat (using *kc), verify 
everything went fine. */
        if (kc == NULL)
        {
                ERROR ("zfs_arc plugin: kstat chain control structure not 
available.");
                return (-1);
        }
+#elif defined(HAVE_SYSCTLBYNAME)
+       /* make sure ARC is available (arc_size is not null) */
+       unsigned long long arc_size;
+       size_t size = sizeof(arc_size);
+       if (sysctlbyname("kstat.zfs.misc.arcstats.size", &arc_size, &size, 
NULL, 0) != 0 || arc_size == 0)
+       {
+               ERROR ("zfs_arc plugin: could not get ARC size using sysctl, is 
ARC enabled?");
+               return (-1);
+       }
+#endif
 
        return (0);
 } /* }}} int za_init */
-- 
1.8.0


_______________________________________________
collectd mailing list
[email protected]
http://mailman.verplant.org/listinfo/collectd

Reply via email to