Merge branch 'collectd-4.10' into collectd-5.0
authorFlorian Forster <octo@collectd.org>
Sun, 23 Sep 2012 10:20:49 +0000 (12:20 +0200)
committerFlorian Forster <octo@collectd.org>
Sun, 23 Sep 2012 10:20:49 +0000 (12:20 +0200)
Conflicts:
src/utils_db_query.c
src/zfs_arc.c

1  2 
configure.in
src/collectd.c
src/common.c
src/exec.c
src/netlink.c
src/network.c
src/unixsock.c
src/utils_db_query.c
src/zfs_arc.c

diff --combined configure.in
@@@ -91,7 -91,6 +91,7 @@@ f
  if test "x$ac_system" = "xSolaris"
  then
        AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, [Define to enforce POSIX thread semantics under Solaris.])
 +      AC_DEFINE(_REENTRANT,               1, [Define to enable reentrancy interfaces.])
  fi
  if test "x$ac_system" = "xAIX"
  then
@@@ -110,13 -109,9 +110,13 @@@ AC_ARG_ENABLE(standards
  if test "x$enable_standards" = "xyes"
  then
        AC_DEFINE(_ISOC99_SOURCE,        1, [Define to enforce ISO C99 compliance.])
 -      AC_DEFINE(_POSIX_C_SOURCE, 200112L, [Define to enforce POSIX.1-2001 compliance.])
 -      AC_DEFINE(_XOPEN_SOURCE,       600, [Define to enforce X/Open 6 (XSI) compliance.])
 +      AC_DEFINE(_POSIX_C_SOURCE, 200809L, [Define to enforce POSIX.1-2008 compliance.])
 +      AC_DEFINE(_XOPEN_SOURCE,       700, [Define to enforce X/Open 7 (XSI) compliance.])
        AC_DEFINE(_REENTRANT,            1, [Define to enable reentrancy interfaces.])
 +      if test "x$GCC" = "xyes"
 +      then
 +              CFLAGS="$CFLAGS -std=c99"
 +      fi
  fi
  AM_CONDITIONAL(BUILD_FEATURE_STANDARDS, test "x$enable_standards" = "xyes")
  
@@@ -491,8 -486,6 +491,8 @@@ AC_CHECK_HEADERS(netinet/if_ether.h, []
  #endif
  ])
  
 +AC_CHECK_HEADERS(netinet/ip_compat.h)
 +
  # For the multimeter plugin
  have_termios_h="no"
  AC_CHECK_HEADERS(termios.h, [have_termios_h="yes"])
@@@ -594,27 -587,6 +594,27 @@@ socket_needs_socket="no
  AC_CHECK_FUNCS(socket, [], AC_CHECK_LIB(socket, socket, [socket_needs_socket="yes"], AC_MSG_ERROR(cannot find socket)))
  AM_CONDITIONAL(BUILD_WITH_LIBSOCKET, test "x$socket_needs_socket" = "xyes")
  
 +clock_gettime_needs_rt="no"
 +clock_gettime_needs_posix4="no"
 +have_clock_gettime="no"
 +AC_CHECK_FUNCS(clock_gettime, [have_clock_gettime="yes"])
 +if test "x$have_clock_gettime" = "xno"
 +then
 +      AC_CHECK_LIB(rt, clock_gettime, [clock_gettime_needs_rt="yes"
 +                                       have_clock_gettime="yes"])
 +fi
 +if test "x$have_clock_gettime" = "xno"
 +then
 +      AC_CHECK_LIB(posix4, clock_gettime, [clock_gettime_needs_posix4="yes"
 +                                           have_clock_gettime="yes"])
 +fi
 +if test "x$have_clock_gettime" = "xyes"
 +then
 +      AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [Define if the clock_gettime(2) function is available.])
 +else
 +      AC_MSG_WARN(cannot find clock_gettime)
 +fi
 +
  nanosleep_needs_rt="no"
  nanosleep_needs_posix4="no"
  AC_CHECK_FUNCS(nanosleep,
          AC_CHECK_LIB(posix4, nanosleep,
              [nanosleep_needs_posix4="yes"],
              AC_MSG_ERROR(cannot find nanosleep))))
 -AM_CONDITIONAL(BUILD_WITH_LIBRT, test "x$nanosleep_needs_rt" = "xyes")
 -AM_CONDITIONAL(BUILD_WITH_LIBPOSIX4, test "x$nanosleep_needs_posix4" = "xyes")
 +
 +AM_CONDITIONAL(BUILD_WITH_LIBRT, test "x$clock_gettime_needs_rt" = "xyes" || test "x$nanosleep_needs_rt" = "xyes")
 +AM_CONDITIONAL(BUILD_WITH_LIBPOSIX4, test "x$clock_gettime_needs_posix4" = "xyes" || test "x$nanosleep_needs_posix4" = "xyes")
  
  AC_CHECK_FUNCS(sysctl, [have_sysctl="yes"], [have_sysctl="no"])
  AC_CHECK_FUNCS(sysctlbyname, [have_sysctlbyname="yes"], [have_sysctlbyname="no"])
@@@ -636,127 -607,13 +636,127 @@@ AC_CHECK_FUNCS(thread_info, [have_threa
  AC_CHECK_FUNCS(statfs, [have_statfs="yes"], [have_statfs="no"])
  AC_CHECK_FUNCS(statvfs, [have_statvfs="yes"], [have_statvfs="no"])
  AC_CHECK_FUNCS(getifaddrs, [have_getifaddrs="yes"], [have_getifaddrs="no"])
 +AC_CHECK_FUNCS(getloadavg, [have_getloadavg="yes"], [have_getloadavg="no"])
  AC_CHECK_FUNCS(syslog, [have_syslog="yes"], [have_syslog="no"])
  AC_CHECK_FUNCS(getutent, [have_getutent="yes"], [have_getutent="no"])
  AC_CHECK_FUNCS(getutxent, [have_getutxent="yes"], [have_getutxent="no"])
 -AC_CHECK_FUNCS(swapctl, [have_swapctl="yes"], [have_swapctl="no"])
  
 -# For load module
 -AC_CHECK_FUNCS(getloadavg, [have_getloadavg="yes"], [have_getloadavg="no"])
 +# Check for strptime {{{
 +if test "x$GCC" = "xyes"
 +then
 +      SAVE_CFLAGS="$CFLAGS"
 +      CFLAGS="$CFLAGS -Wall -Wextra -Werror"
 +fi
 +
 +AC_CHECK_FUNCS(strptime, [have_strptime="yes"], [have_strptime="no"])
 +if test "x$have_strptime" = "xyes"
 +then
 +      AC_CACHE_CHECK([whether strptime is exported by default],
 +                     [c_cv_have_strptime_default],
 +                     AC_COMPILE_IFELSE(
 +AC_LANG_PROGRAM(
 +[[
 +AC_INCLUDES_DEFAULT
 +#include <time.h>
 +]],
 +[[
 + struct tm stm;
 + (void) strptime ("2010-12-30%13:42:42", "%Y-%m-%dT%T", &stm);
 +]]),
 +                     [c_cv_have_strptime_default="yes"],
 +                     [c_cv_have_strptime_default="no"]))
 +fi
 +if test "x$have_strptime" = "xyes" && test "x$c_cv_have_strptime_default" = "xno"
 +then
 +      AC_CACHE_CHECK([whether strptime needs standards mode],
 +                     [c_cv_have_strptime_standards],
 +                     AC_COMPILE_IFELSE(
 +AC_LANG_PROGRAM(
 +[[
 +#ifndef _ISOC99_SOURCE
 +# define _ISOC99_SOURCE 1
 +#endif
 +#ifndef _POSIX_C_SOURCE
 +# define _POSIX_C_SOURCE 200112L
 +#endif
 +#ifndef _XOPEN_SOURCE
 +# define _XOPEN_SOURCE 500
 +#endif
 +AC_INCLUDES_DEFAULT
 +#include <time.h>
 +]],
 +[[
 + struct tm stm;
 + (void) strptime ("2010-12-30%13:42:42", "%Y-%m-%dT%T", &stm);
 +]]),
 +                     [c_cv_have_strptime_standards="yes"],
 +                     [c_cv_have_strptime_standards="no"]))
 +
 +      if test "x$c_cv_have_strptime_standards" = "xyes"
 +      then
 +              AC_DEFINE([STRPTIME_NEEDS_STANDARDS], 1, [Set to true if strptime is only exported in X/Open mode (GNU libc).])
 +      else
 +              have_strptime="no"
 +      fi
 +fi
 +
 +if test "x$GCC" = "xyes"
 +then
 +      CFLAGS="$SAVE_CFLAGS"
 +fi
 +
 +# }}} Check for strptime
 +
 +AC_CHECK_FUNCS(swapctl, [have_swapctl="yes"], [have_swapctl="no"])
 +if test "x$have_swapctl" = "xyes"; then
 +        AC_CACHE_CHECK([whether swapctl takes two arguments],
 +                [c_cv_have_swapctl_two_args],
 +                AC_COMPILE_IFELSE(
 +                        AC_LANG_PROGRAM([[AC_INCLUDES_DEFAULT
 +#if HAVE_SYS_SWAP_H && !defined(_LP64) && _FILE_OFFSET_BITS == 64
 +#  undef _FILE_OFFSET_BITS
 +#  undef _LARGEFILE64_SOURCE
 +#endif
 +#include <sys/stat.h>
 +#include <sys/swap.h>]],
 +                                [[
 +                                int num = swapctl(0, NULL);
 +                                ]]
 +                        ),
 +                        [c_cv_have_swapctl_two_args="yes"],
 +                        [c_cv_have_swapctl_two_args="no"]
 +                )
 +        )
 +        AC_CACHE_CHECK([whether swapctl takes three arguments],
 +                [c_cv_have_swapctl_three_args],
 +                AC_COMPILE_IFELSE(
 +                        AC_LANG_PROGRAM([[AC_INCLUDES_DEFAULT
 +#if HAVE_SYS_SWAP_H && !defined(_LP64) && _FILE_OFFSET_BITS == 64
 +#  undef _FILE_OFFSET_BITS
 +#  undef _LARGEFILE64_SOURCE
 +#endif
 +#include <sys/stat.h>
 +#include <sys/swap.h>]],
 +                                [[
 +                                int num = swapctl(0, NULL,0);
 +                                ]]
 +                        ),
 +                        [c_cv_have_swapctl_three_args="yes"],
 +                        [c_cv_have_swapctl_three_args="no"]
 +                )
 +        )
 +fi
 +# Check for different versions of `swapctl' here..
 +if test "x$have_swapctl" = "xyes"; then
 +        if test "x$c_cv_have_swapctl_two_args" = "xyes"; then
 +                AC_DEFINE(HAVE_SWAPCTL_TWO_ARGS, 1,
 +                          [Define if the function swapctl exists and takes two arguments.])
 +        fi
 +        if test "x$c_cv_have_swapctl_three_args" = "xyes"; then
 +                AC_DEFINE(HAVE_SWAPCTL_THREE_ARGS, 1,
 +                          [Define if the function swapctl exists and takes three arguments.])
 +        fi
 +fi
  
  # Check for NAN
  AC_ARG_WITH(nan-emulation, [AS_HELP_STRING([--with-nan-emulation], [use emulated NAN. For crosscompiling only.])],
@@@ -778,7 -635,7 +778,7 @@@ if test "x$nan_type" = "xnone"; the
        [[
  #include <stdlib.h>
  #include <math.h>
 -static float foo = NAN;
 +static double foo = NAN;
        ]],
        [[
         if (isnan (foo))
@@@ -804,7 -661,7 +804,7 @@@ if test "x$nan_type" = "xnone"; the
  #include <stdlib.h>
  #define __USE_ISOC99 1
  #include <math.h>
 -static float foo = NAN;
 +static double foo = NAN;
        ]],
        [[
         if (isnan (foo))
@@@ -838,7 -695,7 +838,7 @@@ if test "x$nan_type" = "xnone"; the
  #ifndef isnan
  # define isnan(f) ((f) != (f))
  #endif
 -static float foo = NAN;
 +static double foo = NAN;
        ]],
        [[
         if (isnan (foo))
@@@ -1186,6 -1043,7 +1186,7 @@@ AC_CHECK_MEMBERS([struct kinfo_proc.ki_
                have_struct_kinfo_proc_freebsd="no"
        ],
        [
+ AC_INCLUDES_DEFAULT
  #include <kvm.h>
  #include <sys/param.h>
  #include <sys/sysctl.h>
@@@ -1202,6 -1060,7 +1203,7 @@@ AC_CHECK_MEMBERS([struct kinfo_proc.kp_
                have_struct_kinfo_proc_openbsd="no"
        ],
        [
+ AC_INCLUDES_DEFAULT
  #include <sys/param.h>
  #include <sys/sysctl.h>
  #include <kvm.h>
  if test "x$with_perfstat" = "xyes"
  then
         AC_DEFINE(HAVE_PERFSTAT, 1, [Define to 1 if you have the 'perfstat' library (-lperfstat)])
 +       # struct members pertaining to donation have been added to libperfstat somewhere between AIX5.3ML5 and AIX5.3ML9
 +       AC_CHECK_MEMBER([perfstat_partition_type_t.b.donate_enabled], [], [], [[#include <libperfstat.h]])
 +       if test "x$av_cv_member_perfstat_partition_type_t_b_donate_enabled" = "xyes"
 +       then
 +              AC_DEFINE(PERFSTAT_SUPPORTS_DONATION, 1, [Define to 1 if your version of the 'perfstat' library supports donation])
 +       fi
  fi
  AM_CONDITIONAL(BUILD_WITH_PERFSTAT, test "x$with_perfstat" = "xyes")
  
  fi
  AM_CONDITIONAL(BUILD_WITH_LIBKVM_OPENFILES, test "x$with_kvm_openfiles" = "xyes")
  
 +# --with-libcredis {{{
 +AC_ARG_WITH(libcredis, [AS_HELP_STRING([--with-libcredis@<:@=PREFIX@:>@], [Path to libcredis.])],
 +[
 + if test "x$withval" = "xyes"
 + then
 +       with_libcredis="yes"
 + else if test "x$withval" = "xno"
 + then
 +       with_libcredis="no"
 + else
 +       with_libcredis="yes"
 +       LIBCREDIS_CPPFLAGS="$LIBCREDIS_CPPFLAGS -I$withval/include"
 +       LIBCREDIS_LDFLAGS="$LIBCREDIS_LDFLAGS -L$withval/lib"
 + fi; fi
 +],
 +[with_libcredis="yes"])
 +
 +SAVE_CPPFLAGS="$CPPFLAGS"
 +SAVE_LDFLAGS="$LDFLAGS"
 +
 +CPPFLAGS="$CPPFLAGS $LIBCREDIS_CPPFLAGS"
 +LDFLAGS="$LDFLAGS $LIBCREDIS_LDFLAGS"
 +
 +if test "x$with_libcredis" = "xyes"
 +then
 +      if test "x$LIBCREDIS_CPPFLAGS" != "x"
 +      then
 +              AC_MSG_NOTICE([libcredis CPPFLAGS: $LIBCREDIS_CPPFLAGS])
 +      fi
 +      AC_CHECK_HEADERS(credis.h,
 +      [with_libcredis="yes"],
 +      [with_libcredis="no (credis.h not found)"])
 +fi
 +if test "x$with_libcredis" = "xyes"
 +then
 +      if test "x$LIBCREDIS_LDFLAGS" != "x"
 +      then
 +              AC_MSG_NOTICE([libcredis LDFLAGS: $LIBCREDIS_LDFLAGS])
 +      fi
 +      AC_CHECK_LIB(credis, credis_info,
 +      [with_libcredis="yes"],
 +      [with_libcredis="no (symbol 'credis_info' not found)"])
 +
 +fi
 +
 +CPPFLAGS="$SAVE_CPPFLAGS"
 +LDFLAGS="$SAVE_LDFLAGS"
 +
 +if test "x$with_libcredis" = "xyes"
 +then
 +      BUILD_WITH_LIBCREDIS_CPPFLAGS="$LIBCREDIS_CPPFLAGS"
 +      BUILD_WITH_LIBCREDIS_LDFLAGS="$LIBCREDIS_LDFLAGS"
 +      AC_SUBST(BUILD_WITH_LIBCREDIS_CPPFLAGS)
 +      AC_SUBST(BUILD_WITH_LIBCREDIS_LDFLAGS)
 +fi
 +AM_CONDITIONAL(BUILD_WITH_LIBCREDIS, test "x$with_libcredis" = "xyes")
 +# }}}
 +
  # --with-libcurl {{{
  with_curl_config="curl-config"
  with_curl_cflags=""
  # This could be in iptc or ip4tc
  if test "x$with_libiptc" = "xpkgconfig"
  then
+       SAVE_LIBS="$LIBS"
        AC_SEARCH_LIBS(iptc_init, [iptc ip4tc],
                        [with_libiptc="pkgconfig"],
                        [with_libiptc="no"],
                        [$with_libiptc_libs])
+       LIBS="$SAVE_LIBS"
  fi
  if test "x$with_libiptc" = "xpkgconfig"
  then
@@@ -2160,7 -1957,7 +2164,7 @@@ the
        $PKG_CONFIG --exists 'modbus' 2>/dev/null
        if test $? -ne 0
        then
 -              with_libmodbus="no (pkg-config doesn't know library)"
 +              with_libmodbus="no (pkg-config doesn't know modbus)"
        fi
  fi
  if test "x$with_libmodbus" = "xuse_pkgconfig"
@@@ -2200,9 -1997,9 +2204,9 @@@ the
        CPPFLAGS="$CPPFLAGS $with_libmodbus_cflags"
        LDFLAGS="$LDFLAGS $with_libmodbus_libs"
  
 -      AC_CHECK_LIB(modbus, modbus_init_tcp,
 +      AC_CHECK_LIB(modbus, modbus_connect,
                     [with_libmodbus="yes"],
 -                   [with_libmodbus="no (symbol modbus_init_tcp not found)"])
 +                   [with_libmodbus="no (symbol modbus_connect not found)"])
  
        CPPFLAGS="$SAVE_CPPFLAGS"
        LDFLAGS="$SAVE_LDFLAGS"
  fi
  if test "x$with_libnetlink" = "xyes"
  then
+       SAVE_CFLAGS="$CFLAGS"
+       CFLAGS="$CFLAGS $with_libnetlink_cflags"
+       AC_CACHE_CHECK(
+               [if function 'rtnl_dump_filter' expects five arguments],
+               [c_cv_rtnl_dump_filter_five_args],
+               AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+                               [
+ AC_INCLUDES_DEFAULT
+ #include <asm/types.h>
+ #include <sys/socket.h>
+ #if HAVE_LIBNETLINK_H
+ # include <libnetlink.h>
+ #elif HAVE_IPROUTE_LIBNETLINK_H
+ # include <iproute/libnetlink.h>
+ #elif HAVE_LINUX_LIBNETLINK_H
+ # include <linux/libnetlink.h>
+ #endif
+                               ],
+                               [
+ if (rtnl_dump_filter(NULL, NULL, NULL, NULL, NULL))
+       return 1;
+ return 0;
+                               ]
+                       )],
+                       [c_cv_rtnl_dump_filter_five_args="yes"],
+                       [c_cv_rtnl_dump_filter_five_args="no"]
+               )
+       )
+       AC_CACHE_CHECK(
+               [if function 'rtnl_dump_filter' expects three arguments],
+               [c_cv_rtnl_dump_filter_three_args],
+               AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+                               [
+ AC_INCLUDES_DEFAULT
+ #include <asm/types.h>
+ #include <sys/socket.h>
+ #if HAVE_LIBNETLINK_H
+ # include <libnetlink.h>
+ #elif HAVE_IPROUTE_LIBNETLINK_H
+ # include <iproute/libnetlink.h>
+ #elif HAVE_LINUX_LIBNETLINK_H
+ # include <linux/libnetlink.h>
+ #endif
+                               ],
+                               [
+ if (rtnl_dump_filter(NULL, NULL, NULL))
+       return 1;
+ return 0;
+                               ]
+                       )],
+                       [c_cv_rtnl_dump_filter_three_args="yes"],
+                       [c_cv_rtnl_dump_filter_three_args="no"]
+               )
+       )
+       CFLAGS="$SAVE_CFLAGS"
+       if test "x$c_cv_rtnl_dump_filter_five_args" = "xyes"
+       then
+               AC_DEFINE(RTNL_DUMP_FILTER_FIVE_ARGS, 1,
+                               [Define to 1 if function 'rtnl_dump_filter' expects five arguments.])
+       fi
+       if test "x$c_cv_rtnl_dump_filter_three_args" = "xyes"
+       then
+               AC_DEFINE(RTNL_DUMP_FILTER_THREE_ARGS, 1,
+                               [Define to 1 if function 'rtnl_dump_filter' expects three arguments.])
+       fi
        BUILD_WITH_LIBNETLINK_CFLAGS="$with_libnetlink_cflags"
        BUILD_WITH_LIBNETLINK_LIBS="$with_libnetlink_libs"
        AC_SUBST(BUILD_WITH_LIBNETLINK_CFLAGS)
@@@ -2625,7 -2492,7 +2699,7 @@@ the
        fi
        AC_CHECK_HEADERS(oping.h,
        [with_liboping="yes"],
 -      [with_liboping="no ('oping.h' not found)"])
 +      [with_liboping="no (oping.h not found)"])
  fi
  if test "x$with_liboping" = "xyes"
  then
@@@ -2796,8 -2663,7 +2870,8 @@@ the
  fi
  if test "x$with_libpcap" = "xyes"
  then
 -      AC_CHECK_HEADERS(pcap-bpf.h)
 +      AC_CHECK_HEADERS(pcap-bpf.h,,
 +                       [with_libpcap="no (pcap-bpf.h not found)"])
  fi
  AM_CONDITIONAL(BUILD_WITH_LIBPCAP, test "x$with_libpcap" = "xyes")
  # }}}
  fi
  # }}} --with-python
  
 +# --with-librabbitmq {{{
 +with_librabbitmq_cppflags=""
 +with_librabbitmq_ldflags=""
 +AC_ARG_WITH(librabbitmq, [AS_HELP_STRING([--with-librabbitmq@<:@=PREFIX@:>@], [Path to librabbitmq.])],
 +[
 +      if test "x$withval" != "xno" && test "x$withval" != "xyes"
 +      then
 +              with_librabbitmq_cppflags="-I$withval/include"
 +              with_librabbitmq_ldflags="-L$withval/lib"
 +              with_librabbitmq="yes"
 +      else
 +              with_librabbitmq="$withval"
 +      fi
 +],
 +[
 +      with_librabbitmq="yes"
 +])
 +SAVE_CPPFLAGS="$CPPFLAGS"
 +SAVE_LDFLAGS="$LDFLAGS"
 +CPPFLAGS="$CPPFLAGS $with_librabbitmq_cppflags"
 +LDFLAGS="$LDFLAGS $with_librabbitmq_ldflags"
 +if test "x$with_librabbitmq" = "xyes"
 +then
 +      AC_CHECK_HEADERS(amqp.h, [with_librabbitmq="yes"], [with_librabbitmq="no (amqp.h not found)"])
 +fi
 +if test "x$with_librabbitmq" = "xyes"
 +then
 +      # librabbitmq up to version 0.9.1 provides "library_errno", later
 +      # versions use "library_error". The library does not provide a version
 +      # macro :( Use "AC_CHECK_MEMBERS" (plural) for automatic defines.
 +      AC_CHECK_MEMBERS([amqp_rpc_reply_t.library_errno],,,
 +                       [
 +#if HAVE_STDLIB_H
 +# include <stdlib.h>
 +#endif
 +#if HAVE_STDIO_H
 +# include <stdio.h>
 +#endif
 +#if HAVE_STDINT_H
 +# include <stdint.h>
 +#endif
 +#if HAVE_INTTYPES_H
 +# include <inttypes.h>
 +#endif
 +#include <amqp.h>
 +                         ])
 +fi
 +if test "x$with_librabbitmq" = "xyes"
 +then
 +      AC_CHECK_LIB(rabbitmq, amqp_basic_publish, [with_librabbitmq="yes"], [with_librabbitmq="no (Symbol 'amqp_basic_publish' not found)"])
 +fi
 +if test "x$with_librabbitmq" = "xyes"
 +then
 +      BUILD_WITH_LIBRABBITMQ_CPPFLAGS="$with_librabbitmq_cppflags"
 +      BUILD_WITH_LIBRABBITMQ_LDFLAGS="$with_librabbitmq_ldflags"
 +      BUILD_WITH_LIBRABBITMQ_LIBS="-lrabbitmq"
 +      AC_SUBST(BUILD_WITH_LIBRABBITMQ_CPPFLAGS)
 +      AC_SUBST(BUILD_WITH_LIBRABBITMQ_LDFLAGS)
 +      AC_SUBST(BUILD_WITH_LIBRABBITMQ_LIBS)
 +      AC_DEFINE(HAVE_LIBRABBITMQ, 1, [Define if librabbitmq is present and usable.])
 +fi
 +CPPFLAGS="$SAVE_CPPFLAGS"
 +LDFLAGS="$SAVE_LDFLAGS"
 +AM_CONDITIONAL(BUILD_WITH_LIBRABBITMQ, test "x$with_librabbitmq" = "xyes")
 +# }}}
 +
  # --with-librouteros {{{
  AC_ARG_WITH(librouteros, [AS_HELP_STRING([--with-librouteros@<:@=PREFIX@:>@], [Path to librouteros.])],
  [
@@@ -3329,7 -3129,7 +3403,7 @@@ the
        fi
        AC_CHECK_HEADERS(routeros_api.h,
        [with_librouteros="yes"],
 -      [with_librouteros="no ('routeros_api.h' not found)"])
 +      [with_librouteros="no (routeros_api.h not found)"])
  fi
  if test "x$with_librouteros" = "xyes"
  then
@@@ -3528,7 -3328,7 +3602,7 @@@ the
      if test "$?" != "0"
      then
        with_libstatgrab_pkg_config="no"
 -      with_libstatgrab="no ($PKG_CONFIG doesn't know libstatgrab)"
 +      with_libstatgrab="no (pkg-config doesn't know libstatgrab)"
        temp_result="not found"
      fi
      AC_MSG_RESULT([$temp_result])
@@@ -3748,7 -3548,7 +3822,7 @@@ the
        $PKG_CONFIG --exists 'libupsclient' 2>/dev/null
        if test $? -ne 0
        then
 -              with_libupsclient="no (pkg-config doesn't know library)"
 +              with_libupsclient="no (pkg-config doesn't know libupsclient)"
        fi
  fi
  if test "x$with_libupsclient" = "xuse_pkgconfig"
  AM_CONDITIONAL(BUILD_WITH_LIBYAJL, test "x$with_libyajl" = "xyes")
  # }}}
  
 +# --with-libvarnish {{{
 +with_libvarnish_cppflags=""
 +with_libvarnish_cflags=""
 +with_libvarnish_libs=""
 +AC_ARG_WITH(libvarnish, [AS_HELP_STRING([--with-libvarnish@<:@=PREFIX@:>@], [Path to libvarnish.])],
 +[
 +      if test "x$withval" = "xno"
 +      then
 +              with_libvarnish="no"
 +      else if test "x$withval" = "xyes"
 +      then
 +              with_libvarnish="use_pkgconfig"
 +      else if test -d "$with_libvarnish/lib"
 +      then
 +              AC_MSG_NOTICE([Not checking for libvarnish: Manually configured])
 +              with_libvarnish_cflags="-I$withval/include"
 +              with_libvarnish_libs="-L$withval/lib -lvarnishapi"
 +              with_libvarnish="yes"
 +      fi; fi; fi
 +],
 +[with_libvarnish="use_pkgconfig"])
 +
 +# configure using pkg-config
 +if test "x$with_libvarnish" = "xuse_pkgconfig"
 +then
 +      if test "x$PKG_CONFIG" = "x"
 +      then
 +              with_libvarnish="no (Don't have pkg-config)"
 +      fi
 +fi
 +if test "x$with_libvarnish" = "xuse_pkgconfig"
 +then
 +      AC_MSG_NOTICE([Checking for varnishapi using $PKG_CONFIG])
 +      $PKG_CONFIG --exists 'varnishapi' 2>/dev/null
 +      if test $? -ne 0
 +      then
 +              with_libvarnish="no (pkg-config doesn't know varnishapi)"
 +      fi
 +fi
 +if test "x$with_libvarnish" = "xuse_pkgconfig"
 +then
 +      with_libvarnish_cflags="`$PKG_CONFIG --cflags 'varnishapi'`"
 +      if test $? -ne 0
 +      then
 +              with_libvarnish="no ($PKG_CONFIG failed)"
 +      fi
 +      with_libvarnish_libs="`$PKG_CONFIG --libs 'varnishapi'`"
 +      if test $? -ne 0
 +      then
 +              with_libvarnish="no ($PKG_CONFIG failed)"
 +      fi
 +fi
 +if test "x$with_libvarnish" = "xuse_pkgconfig"
 +then
 +      with_libvarnish="yes"
 +fi
 +
 +# with_libvarnish_cflags and with_libvarnish_libs are set up now, let's do
 +# the actual checks.
 +if test "x$with_libvarnish" = "xyes"
 +then
 +      SAVE_CPPFLAGS="$CPPFLAGS"
 +      CPPFLAGS="$CPPFLAGS $with_libvarnish_cflags"
 +      AC_CHECK_HEADERS(varnish/varnishapi.h, [], [with_libvarnish="no (varnish/varnishapi.h not found)"])
 +
 +      CPPFLAGS="$SAVE_CPPFLAGS"
 +fi
 +if test "x$with_libvarnish" = "xyes"
 +then
 +      SAVE_CPPFLAGS="$CPPFLAGS"
 +      #SAVE_LDFLAGS="$LDFLAGS"
 +
 +      CPPFLAGS="$CPPFLAGS $with_libvarnish_cflags"
 +      #LDFLAGS="$LDFLAGS $with_libvarnish_libs"
 +
 +      AC_CHECK_LIB(varnishapi, VSL_OpenStats,
 +                   [with_libvarnish="yes"],
 +                   [with_libvarnish="no (symbol VSL_OpenStats not found)"],
 +                   [$with_libvarnish_libs])
 +
 +      CPPFLAGS="$SAVE_CPPFLAGS"
 +      #LDFLAGS="$SAVE_LDFLAGS"
 +fi
 +if test "x$with_libvarnish" = "xyes"
 +then
 +      BUILD_WITH_LIBVARNISH_CFLAGS="$with_libvarnish_cflags"
 +      BUILD_WITH_LIBVARNISH_LIBS="$with_libvarnish_libs"
 +      AC_SUBST(BUILD_WITH_LIBVARNISH_CFLAGS)
 +      AC_SUBST(BUILD_WITH_LIBVARNISH_LIBS)
 +fi
 +# }}}
 +
  # pkg-config --exists 'libxml-2.0'; pkg-config --exists libvirt {{{
  with_libxml2="no (pkg-config isn't available)"
  with_libxml2_cflags=""
@@@ -4044,7 -3752,7 +4118,7 @@@ the
        then
                with_libxml2="yes"
        else
 -              with_libxml2="no (pkg-config doesn't know library)"
 +              with_libxml2="no (pkg-config doesn't know libxml-2.0)"
        fi
  
        pkg-config --exists libvirt 2>/dev/null
        then
                with_libvirt="yes"
        else
 -              with_libvirt="no (pkg-config doesn't know library)"
 +              with_libvirt="no (pkg-config doesn't know libvirt)"
        fi
  fi
  if test "x$with_libxml2" = "xyes"
@@@ -4169,7 -3877,7 +4243,7 @@@ the
        $PKG_CONFIG --exists OpenIPMIpthread 2>/dev/null
        if test "$?" != "0"
        then
 -              with_libopenipmipthread="no ($PKG_CONFIG doesn't know OpenIPMIpthread)"
 +              with_libopenipmipthread="no (pkg-config doesn't know OpenIPMIpthread)"
        fi
        AC_MSG_RESULT([$with_libopenipmipthread])
  fi
  
  PKG_CHECK_MODULES([LIBNOTIFY], [libnotify],
                [with_libnotify="yes"],
 -              [with_libnotify="no ($LIBNOTIFY_PKG_ERRORS)"])
 +              [if test "x$LIBNOTIFY_PKG_ERRORS" = "x"; then
 +                       with_libnotify="no"
 +               else
 +                       with_libnotify="no ($LIBNOTIFY_PKG_ERRORS)"
 +               fi])
  
  # Check for enabled/disabled features
  #
@@@ -4477,6 -4181,11 +4551,6 @@@ the
        plugin_tape="yes"
  fi
  
 -if test "x$have_sys_swap_h$with_kstat$ac_system" = "xyesyesSolaris"
 -then
 -      plugin_swap="yes"
 -fi
 -
  # libstatgrab
  if test "x$with_libstatgrab" = "xyes"
  then
  if test "x$with_libcurl" = "xyes" && test "x$with_libxml2" = "xyes"
  then
        plugin_ascent="yes"
 -      plugin_bind="yes"
 +      if test "x$have_strptime" = "xyes"
 +      then
 +              plugin_bind="yes"
 +      fi
  fi
  
  if test "x$with_libopenipmipthread" = "xyes"
@@@ -4521,15 -4227,11 +4595,15 @@@ if test "x$have_sysctl" = "xyes
  then
        plugin_cpu="yes"
        plugin_memory="yes"
 -      plugin_swap="yes"
        plugin_uptime="yes"
 +      if test "x$ac_system" = "xDarwin"
 +      then
 +              plugin_swap="yes"
 +      fi
  fi
  if test "x$have_sysctlbyname" = "xyes"
  then
 +      plugin_contextswitch="yes"
        plugin_cpu="yes"
        plugin_memory="yes"
        plugin_tcpconns="yes"
@@@ -4617,7 -4319,7 +4691,7 @@@ the
        plugin_swap="yes"
  fi
  
 -if test "x$have_swapctl" = "xyes"
 +if test "x$have_swapctl" = "xyes" && test "x$c_cv_have_swapctl_two_args" = "xyes"
  then
        plugin_swap="yes"
  fi
@@@ -4657,7 -4359,6 +4731,7 @@@ AC_ARG_ENABLE([all-plugins]
  
  m4_divert_once([HELP_ENABLE], [])
  
 +AC_PLUGIN([amqp],        [$with_librabbitmq],  [AMQP output plugin])
  AC_PLUGIN([apache],      [$with_libcurl],      [Apache httpd statistics])
  AC_PLUGIN([apcups],      [yes],                [Statistics of UPSes by APC])
  AC_PLUGIN([apple_sensors], [$with_libiokit],   [Apple's hardware sensors])
@@@ -4692,7 -4393,6 +4766,7 @@@ AC_PLUGIN([java],        [$with_java]
  AC_PLUGIN([libvirt],     [$plugin_libvirt],    [Virtual machine statistics])
  AC_PLUGIN([load],        [$plugin_load],       [System load])
  AC_PLUGIN([logfile],     [yes],                [File logging plugin])
 +AC_PLUGIN([lpar],        [$with_perfstat],     [AIX logical partitions statistics])
  AC_PLUGIN([madwifi],     [$have_linux_wireless_h], [Madwifi wireless statistics])
  AC_PLUGIN([match_empty_counter], [yes],        [The empty counter match])
  AC_PLUGIN([match_hashed], [yes],               [The hashed match])
@@@ -4728,7 -4428,6 +4802,7 @@@ AC_PLUGIN([powerdns],    [yes]
  AC_PLUGIN([processes],   [$plugin_processes],  [Process statistics])
  AC_PLUGIN([protocols],   [$plugin_protocols],  [Protocol (IP, TCP, ...) statistics])
  AC_PLUGIN([python],      [$with_python],       [Embed a Python interpreter])
 +AC_PLUGIN([redis],       [$with_libcredis],    [Redis plugin])
  AC_PLUGIN([routeros],    [$with_librouteros],  [RouterOS plugin])
  AC_PLUGIN([rrdcached],   [$librrd_rrdc_update], [RRDTool output plugin])
  AC_PLUGIN([rrdtool],     [$with_librrd],       [RRDTool output plugin])
@@@ -4744,23 -4443,19 +4818,23 @@@ AC_PLUGIN([target_notification], [yes]
  AC_PLUGIN([target_replace], [yes],             [The replace target])
  AC_PLUGIN([target_scale],[yes],                [The scale target])
  AC_PLUGIN([target_set],  [yes],                [The set target])
 +AC_PLUGIN([target_v5upgrade], [yes],           [The v5upgrade target])
  AC_PLUGIN([tcpconns],    [$plugin_tcpconns],   [TCP connection statistics])
  AC_PLUGIN([teamspeak2],  [yes],                [TeamSpeak2 server statistics])
  AC_PLUGIN([ted],         [$plugin_ted],        [Read The Energy Detective values])
  AC_PLUGIN([thermal],     [$plugin_thermal],    [Linux ACPI thermal zone statistics])
 +AC_PLUGIN([threshold],   [yes],                [Threshold checking plugin])
  AC_PLUGIN([tokyotyrant], [$with_libtokyotyrant],  [TokyoTyrant database statistics])
  AC_PLUGIN([unixsock],    [yes],                [Unixsock communication plugin])
  AC_PLUGIN([uptime],      [$plugin_uptime],     [Uptime statistics])
  AC_PLUGIN([users],       [$plugin_users],      [User statistics])
  AC_PLUGIN([uuid],        [yes],                [UUID as hostname plugin])
 +AC_PLUGIN([varnish],     [$with_libvarnish],   [Varnish cache statistics])
  AC_PLUGIN([vmem],        [$plugin_vmem],       [Virtual memory statistics])
  AC_PLUGIN([vserver],     [$plugin_vserver],    [Linux VServer statistics])
  AC_PLUGIN([wireless],    [$plugin_wireless],   [Wireless statistics])
  AC_PLUGIN([write_http],  [$with_libcurl],      [HTTP output plugin])
 +AC_PLUGIN([write_redis], [$with_libcredis],    [Redis output plugin])
  AC_PLUGIN([xmms],        [$with_libxmms],      [XMMS statistics])
  AC_PLUGIN([zfs_arc],     [$plugin_zfs_arc],    [ZFS ARC statistics])
  
@@@ -4935,7 -4630,6 +5009,7 @@@ Configuration
    Libraries:
      libcurl . . . . . . . $with_libcurl
      libdbi  . . . . . . . $with_libdbi
 +    libcredis . . . . . . $with_libcredis
      libesmtp  . . . . . . $with_libesmtp
      libganglia  . . . . . $with_libganglia
      libgcrypt . . . . . . $with_libgcrypt
      libperl . . . . . . . $with_libperl
      libpq . . . . . . . . $with_libpq
      libpthread  . . . . . $with_libpthread
 +    librabbitmq . . . . . $with_librabbitmq
      librouteros . . . . . $with_librouteros
      librrd  . . . . . . . $with_librrd
      libsensors  . . . . . $with_libsensors
      libstatgrab . . . . . $with_libstatgrab
      libtokyotyrant  . . . $with_libtokyotyrant
      libupsclient  . . . . $with_libupsclient
 +    libvarnish  . . . . . $with_libvarnish
      libvirt . . . . . . . $with_libvirt
      libxml2 . . . . . . . $with_libxml2
      libxmms . . . . . . . $with_libxmms
      perl  . . . . . . . . $with_perl_bindings
  
    Modules:
 +    amqp    . . . . . . . $enable_amqp
      apache  . . . . . . . $enable_apache
      apcups  . . . . . . . $enable_apcups
      apple_sensors . . . . $enable_apple_sensors
      libvirt . . . . . . . $enable_libvirt
      load  . . . . . . . . $enable_load
      logfile . . . . . . . $enable_logfile
 +    lpar... . . . . . . . $enable_lpar
      madwifi . . . . . . . $enable_madwifi
      match_empty_counter . $enable_match_empty_counter
      match_hashed  . . . . $enable_match_hashed
      processes . . . . . . $enable_processes
      protocols . . . . . . $enable_protocols
      python  . . . . . . . $enable_python
 +    redis . . . . . . . . $enable_redis
      routeros  . . . . . . $enable_routeros
      rrdcached . . . . . . $enable_rrdcached
      rrdtool . . . . . . . $enable_rrdtool
      target_replace  . . . $enable_target_replace
      target_scale  . . . . $enable_target_scale
      target_set  . . . . . $enable_target_set
 +    target_v5upgrade  . . $enable_target_v5upgrade
      tcpconns  . . . . . . $enable_tcpconns
      teamspeak2  . . . . . $enable_teamspeak2
      ted . . . . . . . . . $enable_ted
      thermal . . . . . . . $enable_thermal
 +    threshold . . . . . . $enable_threshold
      tokyotyrant . . . . . $enable_tokyotyrant
      unixsock  . . . . . . $enable_unixsock
      uptime  . . . . . . . $enable_uptime
      users . . . . . . . . $enable_users
      uuid  . . . . . . . . $enable_uuid
 +    varnish . . . . . . . $enable_varnish
      vmem  . . . . . . . . $enable_vmem
      vserver . . . . . . . $enable_vserver
      wireless  . . . . . . $enable_wireless
      write_http  . . . . . $enable_write_http
 +    write_redis . . . . . $enable_write_redis
      xmms  . . . . . . . . $enable_xmms
      zfs_arc . . . . . . . $enable_zfs_arc
  
diff --combined src/collectd.c
@@@ -40,7 -40,7 +40,7 @@@
   * Global variables
   */
  char hostname_g[DATA_MAX_NAME_LEN];
 -int  interval_g;
 +cdtime_t interval_g;
  int  timeout_g;
  #if HAVE_LIBKSTAT
  kstat_ctl_t *kc;
@@@ -51,9 -51,7 +51,9 @@@ static int loop = 0
  static void *do_flush (void __attribute__((unused)) *arg)
  {
        INFO ("Flushing all data.");
 -      plugin_flush (NULL, -1, NULL);
 +      plugin_flush (/* plugin = */ NULL,
 +                      /* timeout = */ 0,
 +                      /* ident = */ NULL);
        INFO ("Finished flushing all data.");
        pthread_exit (NULL);
        return NULL;
@@@ -79,6 -77,7 +79,7 @@@ static void sig_usr1_handler (int __att
        pthread_attr_init (&attr);
        pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
        pthread_create (&thread, &attr, do_flush, NULL);
+       pthread_attr_destroy (&attr);
  }
  
  static int init_hostname (void)
@@@ -141,25 -140,15 +142,25 @@@ static int init_global_variables (void
  
        str = global_option_get ("Interval");
        if (str == NULL)
 -              str = "10";
 -      interval_g = atoi (str);
 -      if (interval_g <= 0)
        {
 -              fprintf (stderr, "Cannot set the interval to a correct value.\n"
 -                              "Please check your settings.\n");
 -              return (-1);
 +              interval_g = TIME_T_TO_CDTIME_T (10);
 +      }
 +      else
 +      {
 +              double tmp;
 +
 +              tmp = atof (str);
 +              if (tmp <= 0.0)
 +              {
 +                      fprintf (stderr, "Cannot set the interval to a "
 +                                      "correct value.\n"
 +                                      "Please check your settings.\n");
 +                      return (-1);
 +              }
 +
 +              interval_g = DOUBLE_TO_CDTIME_T (tmp);
        }
 -      DEBUG ("interval_g = %i;", interval_g);
 +      DEBUG ("interval_g = %.3f;", CDTIME_T_TO_DOUBLE (interval_g));
  
        str = global_option_get ("Timeout");
        if (str == NULL)
@@@ -326,14 -315,22 +327,14 @@@ static int do_init (void
  
  static int do_loop (void)
  {
 -      struct timeval tv_now;
 -      struct timeval tv_next;
 -      struct timeval tv_wait;
 -      struct timespec ts_wait;
 +      cdtime_t wait_until;
 +
 +      wait_until = cdtime () + interval_g;
  
        while (loop == 0)
        {
 -              if (gettimeofday (&tv_next, NULL) < 0)
 -              {
 -                      char errbuf[1024];
 -                      ERROR ("gettimeofday failed: %s",
 -                                      sstrerror (errno, errbuf,
 -                                              sizeof (errbuf)));
 -                      return (-1);
 -              }
 -              tv_next.tv_sec += interval_g;
 +              struct timespec ts_wait = { 0, 0 };
 +              cdtime_t now;
  
  #if HAVE_LIBKSTAT
                update_kstat ();
                /* Issue all plugins */
                plugin_read_all ();
  
 -              if (gettimeofday (&tv_now, NULL) < 0)
 -              {
 -                      char errbuf[1024];
 -                      ERROR ("gettimeofday failed: %s",
 -                                      sstrerror (errno, errbuf,
 -                                              sizeof (errbuf)));
 -                      return (-1);
 -              }
 -
 -              if (timeval_cmp (tv_next, tv_now, &tv_wait) <= 0)
 +              now = cdtime ();
 +              if (now >= wait_until)
                {
                        WARNING ("Not sleeping because the next interval is "
 -                                      "%i.%06i seconds in the past!",
 -                                      (int) tv_wait.tv_sec, (int) tv_wait.tv_usec);
 +                                      "%.3f seconds in the past!",
 +                                      CDTIME_T_TO_DOUBLE (now - wait_until));
 +                      wait_until = now + interval_g;
                        continue;
                }
  
 -              ts_wait.tv_sec  = tv_wait.tv_sec;
 -              ts_wait.tv_nsec = (long) (1000 * tv_wait.tv_usec);
 +              CDTIME_T_TO_TIMESPEC (wait_until - now, &ts_wait);
 +              wait_until = wait_until + interval_g;
  
 -              while ((loop == 0) && (nanosleep (&ts_wait, &ts_wait) == -1))
 +              while ((loop == 0) && (nanosleep (&ts_wait, &ts_wait) != 0))
                {
                        if (errno != EINTR)
                        {
                }
        } /* while (loop == 0) */
  
 -      DEBUG ("return (0);");
        return (0);
  } /* int do_loop */
  
diff --combined src/common.c
@@@ -1,6 -1,6 +1,6 @@@
  /**
   * collectd - src/common.c
 - * Copyright (C) 2005-2009  Florian octo Forster
 + * Copyright (C) 2005-2010  Florian octo Forster
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License as published by the
@@@ -16,7 -16,7 +16,7 @@@
   * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
   *
   * Authors:
 - *   Florian octo Forster <octo at verplant.org>
 + *   Florian octo Forster <octo at collectd.org>
   *   Niki W. Waibel <niki.waibel@gmx.net>
   *   Sebastian Harl <sh at tokkee.org>
   *   MichaÅ‚ MirosÅ‚aw <mirq-linux at rere.qmqm.pl>
@@@ -29,7 -29,6 +29,7 @@@
  #include "collectd.h"
  #include "common.h"
  #include "plugin.h"
 +#include "utils_cache.h"
  
  #if HAVE_PTHREAD_H
  # include <pthread.h>
  # include <math.h>
  #endif
  
 -/* for ntohl and htonl */
 -#if HAVE_ARPA_INET_H
 -# include <arpa/inet.h>
 -#endif
 -
  /* for getaddrinfo */
  #include <sys/types.h>
  #include <sys/socket.h>
  # include <netinet/in.h>
  #endif
  
 +/* for ntohl and htonl */
 +#if HAVE_ARPA_INET_H
 +# include <arpa/inet.h>
 +#endif
 +
  #ifdef HAVE_LIBKSTAT
  extern kstat_ctl_t *kc;
  #endif
@@@ -636,24 -635,23 +636,23 @@@ long long get_kstat_value (kstat_t *ksp
        kstat_named_t *kn;
        long long retval = -1LL;
  
- #ifdef assert
-       assert (ksp != NULL);
-       assert (ksp->ks_type == KSTAT_TYPE_NAMED);
- #else
        if (ksp == NULL)
        {
-               ERROR ("ERROR: %s:%i: ksp == NULL\n", __FILE__, __LINE__);
+               ERROR ("get_kstat_value (\"%s\"): ksp is NULL.", name);
                return (-1LL);
        }
        else if (ksp->ks_type != KSTAT_TYPE_NAMED)
        {
-               ERROR ("ERROR: %s:%i: ksp->ks_type != KSTAT_TYPE_NAMED\n", __FILE__, __LINE__);
+               ERROR ("get_kstat_value (\"%s\"): ksp->ks_type (%#x) "
+                               "is not KSTAT_TYPE_NAMED (%#x).",
+                               name,
+                               (unsigned int) ksp->ks_type,
+                               (unsigned int) KSTAT_TYPE_NAMED);
                return (-1LL);
        }
- #endif
  
        if ((kn = (kstat_named_t *) kstat_data_lookup (ksp, name)) == NULL)
-               return (retval);
+               return (-1LL);
  
        if (kn->data_type == KSTAT_DATA_INT32)
                retval = (long long) kn->value.i32;
@@@ -804,75 -802,6 +803,75 @@@ int format_name (char *ret, int ret_len
        return (0);
  } /* int format_name */
  
 +int format_values (char *ret, size_t ret_len, /* {{{ */
 +              const data_set_t *ds, const value_list_t *vl,
 +              _Bool store_rates)
 +{
 +        size_t offset = 0;
 +        int status;
 +        int i;
 +        gauge_t *rates = NULL;
 +
 +        assert (0 == strcmp (ds->type, vl->type));
 +
 +        memset (ret, 0, ret_len);
 +
 +#define BUFFER_ADD(...) do { \
 +        status = ssnprintf (ret + offset, ret_len - offset, \
 +                        __VA_ARGS__); \
 +        if (status < 1) \
 +        { \
 +                sfree (rates); \
 +                return (-1); \
 +        } \
 +        else if (((size_t) status) >= (ret_len - offset)) \
 +        { \
 +                sfree (rates); \
 +                return (-1); \
 +        } \
 +        else \
 +                offset += ((size_t) status); \
 +} while (0)
 +
 +        BUFFER_ADD ("%.3f", CDTIME_T_TO_DOUBLE (vl->time));
 +
 +        for (i = 0; i < ds->ds_num; i++)
 +        {
 +                if (ds->ds[i].type == DS_TYPE_GAUGE)
 +                        BUFFER_ADD (":%f", vl->values[i].gauge);
 +                else if (store_rates)
 +                {
 +                        if (rates == NULL)
 +                                rates = uc_get_rate (ds, vl);
 +                        if (rates == NULL)
 +                        {
 +                                WARNING ("format_values: "
 +                                              "uc_get_rate failed.");
 +                                return (-1);
 +                        }
 +                        BUFFER_ADD (":%g", rates[i]);
 +                }
 +                else if (ds->ds[i].type == DS_TYPE_COUNTER)
 +                        BUFFER_ADD (":%llu", vl->values[i].counter);
 +                else if (ds->ds[i].type == DS_TYPE_DERIVE)
 +                        BUFFER_ADD (":%"PRIi64, vl->values[i].derive);
 +                else if (ds->ds[i].type == DS_TYPE_ABSOLUTE)
 +                        BUFFER_ADD (":%"PRIu64, vl->values[i].absolute);
 +                else
 +                {
 +                        ERROR ("format_values plugin: Unknown data source type: %i",
 +                                        ds->ds[i].type);
 +                        sfree (rates);
 +                        return (-1);
 +                }
 +        } /* for ds->ds_num */
 +
 +#undef BUFFER_ADD
 +
 +        sfree (rates);
 +        return (0);
 +} /* }}} int format_values */
 +
  int parse_identifier (char *str, char **ret_host,
                char **ret_plugin, char **ret_plugin_instance,
                char **ret_type, char **ret_type_instance)
        return (0);
  } /* int parse_identifier */
  
 +int parse_identifier_vl (const char *str, value_list_t *vl) /* {{{ */
 +{
 +      char str_copy[6 * DATA_MAX_NAME_LEN];
 +      char *host = NULL;
 +      char *plugin = NULL;
 +      char *plugin_instance = NULL;
 +      char *type = NULL;
 +      char *type_instance = NULL;
 +      int status;
 +
 +      if ((str == NULL) || (vl == NULL))
 +              return (EINVAL);
 +
 +      sstrncpy (str_copy, str, sizeof (str_copy));
 +
 +      status = parse_identifier (str_copy, &host,
 +                      &plugin, &plugin_instance,
 +                      &type, &type_instance);
 +      if (status != 0)
 +              return (status);
 +
 +      sstrncpy (vl->host, host, sizeof (vl->host));
 +      sstrncpy (vl->plugin, plugin, sizeof (vl->plugin));
 +      sstrncpy (vl->plugin_instance,
 +                      (plugin_instance != NULL) ? plugin_instance : "",
 +                      sizeof (vl->plugin_instance));
 +      sstrncpy (vl->type, type, sizeof (vl->type));
 +      sstrncpy (vl->type_instance,
 +                      (type_instance != NULL) ? type_instance : "",
 +                      sizeof (vl->type_instance));
 +
 +      return (0);
 +} /* }}} int parse_identifier_vl */
 +
  int parse_value (const char *value_orig, value_t *ret_value, int ds_type)
  {
    char *value;
@@@ -1036,22 -931,9 +1035,22 @@@ int parse_values (char *buffer, value_l
                if (i == -1)
                {
                        if (strcmp ("N", ptr) == 0)
 -                              vl->time = time (NULL);
 +                              vl->time = cdtime ();
                        else
 -                              vl->time = (time_t) atoi (ptr);
 +                      {
 +                              char *endptr = NULL;
 +                              double tmp;
 +
 +                              errno = 0;
 +                              tmp = strtod (ptr, &endptr);
 +                              if ((errno != 0)                    /* Overflow */
 +                                              || (endptr == ptr)  /* Invalid string */
 +                                              || (endptr == NULL) /* This should not happen */
 +                                              || (*endptr != 0))  /* Trailing chars */
 +                                      return (-1);
 +
 +                              vl->time = DOUBLE_TO_CDTIME_T (tmp);
 +                      }
                }
                else
                {
diff --combined src/exec.c
@@@ -270,14 -270,13 +270,14 @@@ static void set_environment (void) /* {
    char buffer[1024];
  
  #ifdef HAVE_SETENV
 -  ssnprintf (buffer, sizeof (buffer), "%i", interval_g);
 +  ssnprintf (buffer, sizeof (buffer), "%.3f", CDTIME_T_TO_DOUBLE (interval_g));
    setenv ("COLLECTD_INTERVAL", buffer, /* overwrite = */ 1);
  
    ssnprintf (buffer, sizeof (buffer), "%s", hostname_g);
    setenv ("COLLECTD_HOSTNAME", buffer, /* overwrite = */ 1);
  #else
 -  ssnprintf (buffer, sizeof (buffer), "COLLECTD_INTERVAL=%i", interval_g);
 +  ssnprintf (buffer, sizeof (buffer), "COLLECTD_INTERVAL=%.3f",
 +      CDTIME_T_TO_DOUBLE (interval_g));
    putenv (buffer);
  
    ssnprintf (buffer, sizeof (buffer), "COLLECTD_HOSTNAME=%s", hostname_g);
@@@ -538,9 -537,12 +538,9 @@@ static int parse_line (char *buffer) /
      return (handle_putnotif (stdout, buffer));
    else
    {
 -    /* For backwards compatibility */
 -    char tmp[1220];
 -    /* Let's annoy the user a bit.. */
 -    INFO ("exec plugin: Prepending `PUTVAL' to this line: %s", buffer);
 -    ssnprintf (tmp, sizeof (tmp), "PUTVAL %s", buffer);
 -    return (handle_putval (stdout, tmp));
 +    ERROR ("exec plugin: Unable to parse command, ignoring line: \"%s\"",
 +      buffer);
 +    return (-1);
    }
  } /* int parse_line }}} */
  
@@@ -635,17 -637,22 +635,22 @@@ static void *exec_read_one (void *arg) 
  
        if (len < 0)
        {
-         if (errno == EAGAIN || errno == EINTR)  continue;
+         if (errno == EAGAIN || errno == EINTR)
+           continue;
          break;
        }
        else if (len == 0)
        {
          /* We've reached EOF */
-         NOTICE ("exec plugin: Program `%s' has closed STDERR.",
-             pl->exec);
-         close (fd_err);
+         NOTICE ("exec plugin: Program `%s' has closed STDERR.", pl->exec);
+         /* Remove file descriptor form select() set. */
          FD_CLR (fd_err, &fdset);
+         copy = fdset;
          highest_fd = fd;
+         /* Clean up file descriptor */
+         close (fd_err);
          fd_err = -1;
          continue;
        }
@@@ -737,8 -744,8 +742,8 @@@ static void *exec_notification_one (voi
  
    fprintf (fh,
        "Severity: %s\n"
 -      "Time: %u\n",
 -      severity, (unsigned int) n->time);
 +      "Time: %.3f\n",
 +      severity, CDTIME_T_TO_DOUBLE (n->time));
  
    /* Print the optional fields */
    if (strlen (n->host) > 0)
@@@ -822,6 -829,7 +827,7 @@@ static int exec_read (void) /* {{{ *
      pthread_attr_init (&attr);
      pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
      pthread_create (&t, &attr, exec_read_one, (void *) pl);
+     pthread_attr_destroy (&attr);
    } /* for (pl) */
  
    return (0);
@@@ -865,6 -873,7 +871,7 @@@ static int exec_notification (const not
      pthread_attr_init (&attr);
      pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
      pthread_create (&t, &attr, exec_notification_one, (void *) pln);
+     pthread_attr_destroy (&attr);
    } /* for (pl) */
  
    return (0);
diff --combined src/netlink.c
@@@ -1,6 -1,6 +1,6 @@@
  /**
   * collectd - src/netlink.c
 - * Copyright (C) 2007  Florian octo Forster
 + * Copyright (C) 2007-2010  Florian octo Forster
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License as published by the
@@@ -16,7 -16,7 +16,7 @@@
   * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
   *
   * Authors:
 - *   Florian octo Forster <octo at verplant.org>
 + *   Florian octo Forster <octo at collectd.org>
   **/
  
  #include "collectd.h"
@@@ -161,12 -161,12 +161,12 @@@ static int check_ignorelist (const cha
  } /* int check_ignorelist */
  
  static void submit_one (const char *dev, const char *type,
 -    const char *type_instance, counter_t value)
 +    const char *type_instance, derive_t value)
  {
    value_t values[1];
    value_list_t vl = VALUE_LIST_INIT;
  
 -  values[0].counter = value;
 +  values[0].derive = value;
  
    vl.values = values;
    vl.values_len = 1;
  
  static void submit_two (const char *dev, const char *type,
      const char *type_instance,
 -    counter_t rx, counter_t tx)
 +    derive_t rx, derive_t tx)
  {
    value_t values[2];
    value_list_t vl = VALUE_LIST_INIT;
  
 -  values[0].counter = rx;
 -  values[1].counter = tx;
 +  values[0].derive = rx;
 +  values[1].derive = tx;
  
    vl.values = values;
    vl.values_len = 2;
@@@ -570,8 -570,14 +570,14 @@@ static int ir_read (void
      return (-1);
    }
  
+ #ifdef RTNL_DUMP_FILTER_FIVE_ARGS
    if (rtnl_dump_filter (&rth, link_filter, /* arg1 = */ NULL,
        NULL, NULL) != 0)
+ #elif defined(RTNL_DUMP_FILTER_THREE_ARGS)
+   if (rtnl_dump_filter (&rth, link_filter, /* arg = */ NULL) != 0)
+ #else
+ #error "Failed to determine the number of arguments to 'rtnl_dump_filter'!"
+ #endif
    {
      ERROR ("netlink plugin: ir_read: rtnl_dump_filter failed.");
      return (-1);
        continue;
        }
  
+ #ifdef RTNL_DUMP_FILTER_FIVE_ARGS
        if (rtnl_dump_filter (&rth, qos_filter, (void *) &ifindex,
            NULL, NULL) != 0)
+ #elif defined(RTNL_DUMP_FILTER_THREE_ARGS)
+       if (rtnl_dump_filter (&rth, qos_filter, /* arg = */ &ifindex) != 0)
+ #else
+ #error "Failed to determine the number of arguments to 'rtnl_dump_filter'!"
+ #endif
        {
        ERROR ("netlink plugin: ir_read: rtnl_dump_filter failed.");
        continue;
diff --combined src/network.c
@@@ -1,6 -1,6 +1,6 @@@
  /**
   * collectd - src/network.c
 - * Copyright (C) 2005-2009  Florian octo Forster
 + * Copyright (C) 2005-2010  Florian octo Forster
   * Copyright (C) 2009       Aman Gupta
   *
   * This program is free software; you can redistribute it and/or modify it
@@@ -58,6 -58,7 +58,7 @@@
  #endif
  
  #if HAVE_LIBGCRYPT
+ # include <pthread.h>
  # include <gcrypt.h>
  GCRY_THREAD_OPTION_PTHREAD_IMPL;
  #endif
@@@ -259,8 -260,7 +260,8 @@@ typedef struct receive_list_entry_s rec
   * Private variables
   */
  static int network_config_ttl = 0;
 -static size_t network_config_packet_size = 1024;
 +/* Ethernet - (IPv6 + UDP) = 1500 - (40 + 8) = 1452 */
 +static size_t network_config_packet_size = 1452;
  static int network_config_forward = 0;
  static int network_config_stats = 0;
  
@@@ -297,14 -297,14 +298,14 @@@ static pthread_mutex_t  send_buffer_loc
   * example). Only if neither is true, the stats_lock is acquired. The counters
   * are always read without holding a lock in the hope that writing 8 bytes to
   * memory is an atomic operation. */
 -static uint64_t stats_octets_rx  = 0;
 -static uint64_t stats_octets_tx  = 0;
 -static uint64_t stats_packets_rx = 0;
 -static uint64_t stats_packets_tx = 0;
 -static uint64_t stats_values_dispatched = 0;
 -static uint64_t stats_values_not_dispatched = 0;
 -static uint64_t stats_values_sent = 0;
 -static uint64_t stats_values_not_sent = 0;
 +static derive_t stats_octets_rx  = 0;
 +static derive_t stats_octets_tx  = 0;
 +static derive_t stats_packets_rx = 0;
 +static derive_t stats_packets_tx = 0;
 +static derive_t stats_values_dispatched = 0;
 +static derive_t stats_values_not_dispatched = 0;
 +static derive_t stats_values_sent = 0;
 +static derive_t stats_values_not_sent = 0;
  static pthread_mutex_t stats_lock = PTHREAD_MUTEX_INITIALIZER;
  
  /*
@@@ -321,30 -321,30 +322,30 @@@ static _Bool check_receive_okay (const 
    /* This is a value we already sent. Don't allow it to be received again in
     * order to avoid looping. */
    if ((status == 0) && (time_sent >= ((uint64_t) vl->time)))
 -    return (false);
 +    return (0);
  
 -  return (true);
 +  return (1);
  } /* }}} _Bool check_receive_okay */
  
  static _Bool check_send_okay (const value_list_t *vl) /* {{{ */
  {
 -  _Bool received = false;
 +  _Bool received = 0;
    int status;
  
    if (network_config_forward != 0)
 -    return (true);
 +    return (1);
  
    if (vl->meta == NULL)
 -    return (true);
 +    return (1);
  
    status = meta_data_get_boolean (vl->meta, "network:received", &received);
    if (status == -ENOENT)
 -    return (true);
 +    return (1);
    else if (status != 0)
    {
      ERROR ("network plugin: check_send_okay: meta_data_get_boolean failed "
        "with status %i.", status);
 -    return (true);
 +    return (1);
    }
  
    /* By default, only *send* value lists that were not *received* by the
@@@ -422,7 -422,7 +423,7 @@@ static int network_dispatch_values (val
      return (-ENOMEM);
    }
  
 -  status = meta_data_add_boolean (vl->meta, "network:received", true);
 +  status = meta_data_add_boolean (vl->meta, "network:received", 1);
    if (status != 0)
    {
      ERROR ("network plugin: meta_data_add_boolean failed.");
@@@ -1440,19 -1440,8 +1441,19 @@@ static int parse_packet (sockent_t *se
                                        &tmp);
                        if (status == 0)
                        {
 -                              vl.time = (time_t) tmp;
 -                              n.time = (time_t) tmp;
 +                              vl.time = TIME_T_TO_CDTIME_T (tmp);
 +                              n.time  = TIME_T_TO_CDTIME_T (tmp);
 +                      }
 +              }
 +              else if (pkg_type == TYPE_TIME_HR)
 +              {
 +                      uint64_t tmp = 0;
 +                      status = parse_part_number (&buffer, &buffer_size,
 +                                      &tmp);
 +                      if (status == 0)
 +                      {
 +                              vl.time = (cdtime_t) tmp;
 +                              n.time  = (cdtime_t) tmp;
                        }
                }
                else if (pkg_type == TYPE_INTERVAL)
                        status = parse_part_number (&buffer, &buffer_size,
                                        &tmp);
                        if (status == 0)
 -                              vl.interval = (int) tmp;
 +                              vl.interval = TIME_T_TO_CDTIME_T (tmp);
 +              }
 +              else if (pkg_type == TYPE_INTERVAL_HR)
 +              {
 +                      uint64_t tmp = 0;
 +                      status = parse_part_number (&buffer, &buffer_size,
 +                                      &tmp);
 +                      if (status == 0)
 +                              vl.interval = (cdtime_t) tmp;
                }
                else if (pkg_type == TYPE_HOST)
                {
@@@ -1665,7 -1646,7 +1666,7 @@@ static int network_set_ttl (const socke
                                        sizeof (network_config_ttl)) != 0)
                {
                        char errbuf[1024];
-                       ERROR ("setsockopt: %s",
+                       ERROR ("network plugin: setsockopt (ipv4-ttl): %s",
                                        sstrerror (errno, errbuf, sizeof (errbuf)));
                        return (-1);
                }
                                        sizeof (network_config_ttl)) != 0)
                {
                        char errbuf[1024];
-                       ERROR ("setsockopt: %s",
+                       ERROR ("network plugin: setsockopt(ipv6-ttl): %s",
                                        sstrerror (errno, errbuf,
                                                sizeof (errbuf)));
                        return (-1);
@@@ -1733,7 -1714,7 +1734,7 @@@ static int network_set_interface (cons
                                                &mreq, sizeof (mreq)) != 0)
                        {
                                char errbuf[1024];
-                               ERROR ("setsockopt: %s",
+                               ERROR ("network plugin: setsockopt (ipv4-multicast-if): %s",
                                                sstrerror (errno, errbuf, sizeof (errbuf)));
                                return (-1);
                        }
                                                sizeof (se->interface)) != 0)
                        {
                                char errbuf[1024];
-                               ERROR ("setsockopt: %s",
+                               ERROR ("network plugin: setsockopt (ipv6-multicast-if): %s",
                                                sstrerror (errno, errbuf,
                                                        sizeof (errbuf)));
                                return (-1);
                                        sizeof(interface_name)) == -1 )
                {
                        char errbuf[1024];
-                       ERROR ("setsockopt: %s",
+                       ERROR ("network plugin: setsockopt (bind-if): %s",
                                        sstrerror (errno, errbuf, sizeof (errbuf)));
                        return (-1);
                }
  
  static int network_bind_socket (int fd, const struct addrinfo *ai, const int interface_idx)
  {
+ #if KERNEL_SOLARIS
+       char loop   = 0;
+ #else
        int loop = 0;
+ #endif
        int yes  = 1;
  
        /* allow multiple sockets to use the same PORT number */
        if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR,
                                &yes, sizeof(yes)) == -1) {
                  char errbuf[1024];
-                 ERROR ("setsockopt: %s", 
+                 ERROR ("network plugin: setsockopt (reuseaddr): %s",
                                  sstrerror (errno, errbuf, sizeof (errbuf)));
                return (-1);
        }
                                                &loop, sizeof (loop)) == -1)
                        {
                                char errbuf[1024];
-                               ERROR ("setsockopt: %s",
+                               ERROR ("network plugin: setsockopt (multicast-loop): %s",
                                                sstrerror (errno, errbuf,
                                                        sizeof (errbuf)));
                                return (-1);
                                                &mreq, sizeof (mreq)) == -1)
                        {
                                char errbuf[1024];
-                               ERROR ("setsockopt: %s",
+                               ERROR ("network plugin: setsockopt (add-membership): %s",
                                                sstrerror (errno, errbuf,
                                                        sizeof (errbuf)));
                                return (-1);
                                                &loop, sizeof (loop)) == -1)
                        {
                                char errbuf[1024];
-                               ERROR ("setsockopt: %s",
+                               ERROR ("network plugin: setsockopt (ipv6-multicast-loop): %s",
                                                sstrerror (errno, errbuf,
                                                        sizeof (errbuf)));
                                return (-1);
                                                &mreq, sizeof (mreq)) == -1)
                        {
                                char errbuf[1024];
-                               ERROR ("setsockopt: %s",
+                               ERROR ("network plugin: setsockopt (ipv6-add-membership): %s",
                                                sstrerror (errno, errbuf,
                                                        sizeof (errbuf)));
                                return (-1);
                                        sizeof(interface_name)) == -1 )
                {
                        char errbuf[1024];
-                       ERROR ("setsockopt: %s",
+                       ERROR ("network plugin: setsockopt (bind-if): %s",
                                        sstrerror (errno, errbuf, sizeof (errbuf)));
                        return (-1);
                }
@@@ -2666,7 -2651,7 +2671,7 @@@ static int add_to_buffer (char *buffer
  
        if (vl_def->time != vl->time)
        {
 -              if (write_part_number (&buffer, &buffer_size, TYPE_TIME,
 +              if (write_part_number (&buffer, &buffer_size, TYPE_TIME_HR,
                                        (uint64_t) vl->time))
                        return (-1);
                vl_def->time = vl->time;
  
        if (vl_def->interval != vl->interval)
        {
 -              if (write_part_number (&buffer, &buffer_size, TYPE_INTERVAL,
 +              if (write_part_number (&buffer, &buffer_size, TYPE_INTERVAL_HR,
                                        (uint64_t) vl->interval))
                        return (-1);
                vl_def->interval = vl->interval;
@@@ -3136,6 -3121,8 +3141,6 @@@ static int network_config (oconfig_item
        network_config_set_boolean (child, &network_config_forward);
      else if (strcasecmp ("ReportStats", child->key) == 0)
        network_config_set_boolean (child, &network_config_stats);
 -    else if (strcasecmp ("CacheFlush", child->key) == 0)
 -      /* no op for backwards compatibility only */;
      else
      {
        WARNING ("network plugin: Option `%s' is not allowed here.",
@@@ -3159,7 -3146,7 +3164,7 @@@ static int network_notification (const 
  
    memset (buffer, 0, sizeof (buffer));
  
 -  status = write_part_number (&buffer_ptr, &buffer_free, TYPE_TIME,
 +  status = write_part_number (&buffer_ptr, &buffer_free, TYPE_TIME_HR,
        (uint64_t) n->time);
    if (status != 0)
      return (-1);
@@@ -3264,15 -3251,15 +3269,15 @@@ static int network_shutdown (void
  
  static int network_stats_read (void) /* {{{ */
  {
 -      uint64_t copy_octets_rx;
 -      uint64_t copy_octets_tx;
 -      uint64_t copy_packets_rx;
 -      uint64_t copy_packets_tx;
 -      uint64_t copy_values_dispatched;
 -      uint64_t copy_values_not_dispatched;
 -      uint64_t copy_values_sent;
 -      uint64_t copy_values_not_sent;
 -      uint64_t copy_receive_list_length;
 +      derive_t copy_octets_rx;
 +      derive_t copy_octets_tx;
 +      derive_t copy_packets_rx;
 +      derive_t copy_packets_tx;
 +      derive_t copy_values_dispatched;
 +      derive_t copy_values_not_dispatched;
 +      derive_t copy_values_sent;
 +      derive_t copy_values_not_sent;
 +      derive_t copy_receive_list_length;
        value_list_t vl = VALUE_LIST_INIT;
        value_t values[2];
  
        sstrncpy (vl.plugin, "network", sizeof (vl.plugin));
  
        /* Octets received / sent */
 -      vl.values[0].counter = (counter_t) copy_octets_rx;
 -      vl.values[1].counter = (counter_t) copy_octets_tx;
 +      vl.values[0].derive = (derive_t) copy_octets_rx;
 +      vl.values[1].derive = (derive_t) copy_octets_tx;
        sstrncpy (vl.type, "if_octets", sizeof (vl.type));
        plugin_dispatch_values_secure (&vl);
  
        /* Packets received / send */
 -      vl.values[0].counter = (counter_t) copy_packets_rx;
 -      vl.values[1].counter = (counter_t) copy_packets_tx;
 +      vl.values[0].derive = (derive_t) copy_packets_rx;
 +      vl.values[1].derive = (derive_t) copy_packets_tx;
        sstrncpy (vl.type, "if_packets", sizeof (vl.type));
        plugin_dispatch_values_secure (&vl);
  
  
  static int network_init (void)
  {
 -      static _Bool have_init = false;
 +      static _Bool have_init = 0;
  
        /* Check if we were already initialized. If so, just return - there's
         * nothing more to do (for now, that is). */
        if (have_init)
                return (0);
 -      have_init = true;
 +      have_init = 1;
  
  #if HAVE_LIBGCRYPT
        gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
   * just send the buffer if `flush'  is called - if the requested value was in
   * there, good. If not, well, then there is nothing to flush.. -octo
   */
 -static int network_flush (int timeout,
 -              const char __attribute__((unused)) *identifier,
 -              user_data_t __attribute__((unused)) *user_data)
 +static int network_flush (__attribute__((unused)) cdtime_t timeout,
 +              __attribute__((unused)) const char *identifier,
 +              __attribute__((unused)) user_data_t *user_data)
  {
        pthread_mutex_lock (&send_buffer_lock);
  
diff --combined src/unixsock.c
@@@ -26,6 -26,7 +26,6 @@@
  
  #include "utils_cmd_flush.h"
  #include "utils_cmd_getval.h"
 -#include "utils_cmd_getthreshold.h"
  #include "utils_cmd_listval.h"
  #include "utils_cmd_putval.h"
  #include "utils_cmd_putnotif.h"
@@@ -53,8 -54,7 +53,8 @@@ static const char *config_keys[] 
  {
        "SocketFile",
        "SocketGroup",
 -      "SocketPerms"
 +      "SocketPerms",
 +      "DeleteSocket"
  };
  static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
  
@@@ -65,7 -65,6 +65,7 @@@ static int   sock_fd    = -1
  static char *sock_file  = NULL;
  static char *sock_group = NULL;
  static int   sock_perms = S_IRWXU | S_IRWXG;
 +static _Bool delete_socket = 0;
  
  static pthread_t listen_thread = (pthread_t) 0;
  
@@@ -90,27 -89,10 +90,27 @@@ static int us_open_socket (void
        sa.sun_family = AF_UNIX;
        sstrncpy (sa.sun_path, (sock_file != NULL) ? sock_file : US_DEFAULT_PATH,
                        sizeof (sa.sun_path));
 -      /* unlink (sa.sun_path); */
  
        DEBUG ("unixsock plugin: socket path = %s", sa.sun_path);
  
 +      if (delete_socket)
 +      {
 +              errno = 0;
 +              status = unlink (sa.sun_path);
 +              if ((status != 0) && (errno != ENOENT))
 +              {
 +                      char errbuf[1024];
 +                      WARNING ("unixsock plugin: Deleting socket file \"%s\" failed: %s",
 +                                      sa.sun_path,
 +                                      sstrerror (errno, errbuf, sizeof (errbuf)));
 +              }
 +              else if (status == 0)
 +              {
 +                      INFO ("unixsock plugin: Successfully deleted socket file \"%s\".",
 +                                      sa.sun_path);
 +              }
 +      }
 +
        status = bind (sock_fd, (struct sockaddr *) &sa, sizeof (sa));
        if (status != 0)
        {
@@@ -205,6 -187,7 +205,7 @@@ static void *us_handle_client (void *ar
                close (fdin);
                close (fdout);
                pthread_exit ((void *) 1);
+               return ((void *) 1);
        }
  
        fhout = fdopen (fdout, "w");
                fclose (fhin); /* this closes fdin as well */
                close (fdout);
                pthread_exit ((void *) 1);
+               return ((void *) 1);
        }
  
        /* change output buffer to line buffered mode */
                fclose (fhin);
                fclose (fhout);
                pthread_exit ((void *) 1);
+               return ((void *) 0);
        }
  
        while (42)
                errno = 0;
                if (fgets (buffer, sizeof (buffer), fhin) == NULL)
                {
+                       if ((errno == EINTR) || (errno == EAGAIN))
+                               continue;
                        if (errno != 0)
                        {
                                char errbuf[1024];
                        fclose (fhin);
                        fclose (fhout);
                        pthread_exit ((void *) 1);
+                       return ((void *) 1);
                }
  
                if (strcasecmp (fields[0], "getval") == 0)
                {
                        handle_getval (fhout, buffer);
                }
 -              else if (strcasecmp (fields[0], "getthreshold") == 0)
 -              {
 -                      handle_getthreshold (fhout, buffer);
 -              }
                else if (strcasecmp (fields[0], "putval") == 0)
                {
                        handle_putval (fhout, buffer);
@@@ -318,6 -311,9 +325,9 @@@ static void *us_server_thread (void __a
        pthread_t th;
        pthread_attr_t th_attr;
  
+       pthread_attr_init (&th_attr);
+       pthread_attr_setdetachstate (&th_attr, PTHREAD_CREATE_DETACHED);
        if (us_open_socket () != 0)
                pthread_exit ((void *) 1);
  
                                        sstrerror (errno, errbuf, sizeof (errbuf)));
                        close (sock_fd);
                        sock_fd = -1;
+                       pthread_attr_destroy (&th_attr);
                        pthread_exit ((void *) 1);
                }
  
  
                DEBUG ("Spawning child to handle connection on fd #%i", *remote_fd);
  
-               pthread_attr_init (&th_attr);
-               pthread_attr_setdetachstate (&th_attr, PTHREAD_CREATE_DETACHED);
                status = pthread_create (&th, &th_attr, us_handle_client, (void *) remote_fd);
                if (status != 0)
                {
  
        close (sock_fd);
        sock_fd = -1;
+       pthread_attr_destroy (&th_attr);
  
        status = unlink ((sock_file != NULL) ? sock_file : US_DEFAULT_PATH);
        if (status != 0)
@@@ -406,13 -401,6 +415,13 @@@ static int us_config (const char *key, 
        {
                sock_perms = (int) strtol (val, NULL, 8);
        }
 +      else if (strcasecmp (key, "DeleteSocket") == 0)
 +      {
 +              if (IS_TRUE (val))
 +                      delete_socket = 1;
 +              else
 +                      delete_socket = 0;
 +      }
        else
        {
                return (-1);
diff --combined src/utils_db_query.c
@@@ -39,6 -39,15 +39,6 @@@ struct udb_result_
    char   **values;
    size_t   values_num;
  
 -  /* Legacy data */
 -  int legacy_mode;
 -  size_t legacy_position;
 -  /* When in legacy mode:
 -   * - type/ds hold the format of the data
 -   * - instance_prefix is used as type-instance if non-NULL
 -   * - legacy_position holds the index of the column to use as value.
 -   */
 -
    udb_result_t *next;
  }; /* }}} */
  
@@@ -48,6 -57,8 +48,6 @@@ struct udb_query_s /* {{{ *
    char *statement;
    void *user_data;
  
 -  int legacy_mode;
 -
    unsigned int min_version;
    unsigned int max_version;
  
@@@ -73,7 -84,7 +73,7 @@@ struct udb_query_preparation_area_s /* 
    char *plugin;
    char *db_name;
  
 -  int interval;
 +  cdtime_t interval;
  
    udb_result_preparation_area_t *result_prep_areas;
  }; /* }}} */
@@@ -180,6 -191,173 +180,6 @@@ static int udb_config_set_uint (unsigne
  } /* }}} int udb_config_set_uint */
  
  /*
 - * Legacy result private functions
 - */
 -static void udb_legacy_result_finish_result (const udb_result_t const *r, /* {{{ */
 -    udb_result_preparation_area_t *prep_area)
 -{
 -  if ((r == NULL) || (prep_area))
 -    return;
 -
 -  assert (r->legacy_mode == 1);
 -
 -  prep_area->ds = NULL;
 -} /* }}} void udb_legacy_result_finish_result */
 -
 -static int udb_legacy_result_handle_result (udb_result_t *r, /* {{{ */
 -    udb_query_preparation_area_t *q_area,
 -    udb_result_preparation_area_t *r_area,
 -    const udb_query_t const *q, char **column_values)
 -{
 -  value_list_t vl = VALUE_LIST_INIT;
 -  value_t value;
 -  char *value_str;
 -
 -  assert (r->legacy_mode == 1);
 -  assert (r_area->ds != NULL);
 -  assert (r_area->ds->ds_num == 1);
 -
 -  vl.values = &value;
 -  vl.values_len = 1;
 -
 -  value_str = column_values[r->legacy_position];
 -  if (0 != parse_value (value_str, &vl.values[0], r_area->ds->ds[0].type))
 -  {
 -    ERROR ("db query utils: udb_legacy_result_handle_result: "
 -        "Parsing `%s' as %s failed.", value_str,
 -        DS_TYPE_TO_STRING (r_area->ds->ds[0].type));
 -    errno = EINVAL;
 -    return (-1);
 -  }
 -
 -  if (q_area->interval > 0)
 -    vl.interval = q_area->interval;
 -
 -  sstrncpy (vl.host, q_area->host, sizeof (vl.host));
 -  sstrncpy (vl.plugin, q_area->plugin, sizeof (vl.plugin));
 -  sstrncpy (vl.plugin_instance, q_area->db_name, sizeof (vl.plugin_instance));
 -  sstrncpy (vl.type, r->type, sizeof (vl.type));
 -
 -  if (r->instance_prefix != NULL)
 -    sstrncpy (vl.type_instance, r->instance_prefix,
 -        sizeof (vl.type_instance));
 -
 -  plugin_dispatch_values (&vl);
 -
 -  return (0);
 -} /* }}} int udb_legacy_result_handle_result */
 -
 -static int udb_legacy_result_prepare_result (const udb_result_t const *r, /* {{{ */
 -    udb_result_preparation_area_t *prep_area,
 -    char **column_names, size_t column_num)
 -{
 -  if (r == NULL)
 -    return (-EINVAL);
 -
 -  assert (r->legacy_mode == 1);
 -
 -  /* Make sure previous preparations are cleaned up. */
 -  udb_legacy_result_finish_result (r, prep_area);
 -
 -  if (r->legacy_position >= column_num)
 -  {
 -    ERROR ("db query utils: The legacy configuration specified (at least) "
 -        "%zu `Column's, but the query returned only %zu columns!",
 -        r->legacy_position + 1, column_num);
 -    return (-ENOENT);
 -  }
 -
 -  /* Read `ds' and check number of values {{{ */
 -  prep_area->ds = plugin_get_ds (r->type);
 -  if (prep_area->ds == NULL)
 -  {
 -    ERROR ("db query utils: udb_result_prepare_result: Type `%s' is not "
 -        "known by the daemon. See types.db(5) for details.",
 -        r->type);
 -    return (-1);
 -  }
 -
 -  if (prep_area->ds->ds_num != 1)
 -  {
 -    ERROR ("db query utils: udb_result_prepare_result: The type `%s' "
 -        "requires exactly %i values, but the legacy configuration "
 -        "requires exactly one!",
 -        r->type,
 -        prep_area->ds->ds_num);
 -    return (-1);
 -  }
 -  /* }}} */
 -
 -  return (0);
 -} /* }}} int udb_legacy_result_prepare_result */
 -
 -static int udb_legacy_result_create (const char *query_name, /* {{{ */
 -    udb_result_t **r_head, oconfig_item_t *ci, size_t position)
 -{
 -  udb_result_t *r;
 -
 -  if ((ci->values_num < 1) || (ci->values_num > 2)
 -      || (ci->values[0].type != OCONFIG_TYPE_STRING)
 -      || ((ci->values_num == 2)
 -        && (ci->values[1].type != OCONFIG_TYPE_STRING)))
 -  {
 -    WARNING ("db query utils: The `Column' block needs either one or two "
 -        "string arguments.");
 -    return (-1);
 -  }
 -
 -  r = (udb_result_t *) malloc (sizeof (*r));
 -  if (r == NULL)
 -  {
 -    ERROR ("db query utils: malloc failed.");
 -    return (-1);
 -  }
 -  memset (r, 0, sizeof (*r));
 -
 -  r->legacy_mode = 1;
 -  r->legacy_position = position;
 -
 -  r->type = strdup (ci->values[0].value.string);
 -  if (r->type == NULL)
 -  {
 -    ERROR ("db query utils: strdup failed.");
 -    free (r);
 -    return (-1);
 -  }
 -
 -  r->instance_prefix = NULL;
 -  if (ci->values_num == 2)
 -  {
 -    r->instance_prefix = strdup (ci->values[1].value.string);
 -    if (r->instance_prefix == NULL)
 -    {
 -      ERROR ("db query utils: strdup failed.");
 -      free (r->type);
 -      free (r);
 -      return (-1);
 -    }
 -  }
 -
 -  /* If all went well, add this result to the list of results. */
 -  if (*r_head == NULL)
 -  {
 -    *r_head = r;
 -  }
 -  else
 -  {
 -    udb_result_t *last;
 -
 -    last = *r_head;
 -    while (last->next != NULL)
 -      last = last->next;
 -
 -    last->next = r;
 -  }
 -
 -  return (0);
 -} /* }}} int udb_legacy_result_create */
 -
 -/*
   * Result private functions
   */
  static int udb_result_submit (udb_result_t *r, /* {{{ */
    size_t i;
  
    assert (r != NULL);
 -  assert (r->legacy_mode == 0);
    assert (r_area->ds != NULL);
    assert (((size_t) r_area->ds->ds_num) == r->values_num);
  
  
    sstrncpy (vl.host, q_area->host, sizeof (vl.host));
    sstrncpy (vl.plugin, q_area->plugin, sizeof (vl.plugin));
-   sstrncpy (vl.plugin_instance, q_area->db_name, sizeof (vl.type_instance));
+   sstrncpy (vl.plugin_instance, q_area->db_name, sizeof (vl.plugin_instance));
    sstrncpy (vl.type, r->type, sizeof (vl.type));
  
    /* Set vl.type_instance {{{ */
@@@ -265,6 -444,14 +265,6 @@@ static void udb_result_finish_result (c
    if ((r == NULL) || (prep_area == NULL))
      return;
  
 -  if (r->legacy_mode == 1)
 -  {
 -    udb_legacy_result_finish_result (r, prep_area);
 -    return;
 -  }
 -
 -  assert (r->legacy_mode == 0);
 -
    prep_area->ds = NULL;
    sfree (prep_area->instances_pos);
    sfree (prep_area->values_pos);
@@@ -281,6 -468,12 +281,6 @@@ static int udb_result_handle_result (ud
  
    assert (r && q_area && r_area);
  
 -  if (r->legacy_mode == 1)
 -    return (udb_legacy_result_handle_result (r, q_area, r_area,
 -          q, column_values));
 -
 -  assert (r->legacy_mode == 0);
 -
    for (i = 0; i < r->instances_num; i++)
      r_area->instances_buffer[i] = column_values[r_area->instances_pos[i]];
  
@@@ -299,6 -492,12 +299,6 @@@ static int udb_result_prepare_result (c
    if ((r == NULL) || (prep_area == NULL))
      return (-EINVAL);
  
 -  if (r->legacy_mode == 1)
 -    return (udb_legacy_result_prepare_result (r, prep_area,
 -          column_names, column_num));
 -
 -  assert (r->legacy_mode == 0);
 -
  #define BAIL_OUT(status) \
    prep_area->ds = NULL; \
    sfree (prep_area->instances_pos); \
@@@ -560,7 -759,7 +560,7 @@@ void udb_query_free_one (udb_query_t *q
   */
  int udb_query_create (udb_query_t ***ret_query_list, /* {{{ */
      size_t *ret_query_list_len, oconfig_item_t *ci,
 -    udb_query_create_callback_t cb, int legacy_mode)
 +    udb_query_create_callback_t cb)
  {
    udb_query_t **query_list;
    size_t        query_list_len;
    int status;
    int i;
  
 -  size_t legacy_position;
 -
    if ((ret_query_list == NULL) || (ret_query_list_len == NULL))
      return (-EINVAL);
    query_list     = *ret_query_list;
      return (-1);
    }
    memset (q, 0, sizeof (*q));
 -  q->legacy_mode = legacy_mode;
    q->min_version = 0;
    q->max_version = UINT_MAX;
  
 -  legacy_position = 0;
 -
    status = udb_config_set_string (&q->name, ci);
    if (status != 0)
    {
      else if (strcasecmp ("MaxVersion", child->key) == 0)
        status = udb_config_set_uint (&q->max_version, child);
  
 -    /* PostgreSQL compatibility code */
 -    else if ((strcasecmp ("Query", child->key) == 0)
 -        && (q->legacy_mode == 1))
 -    {
 -      WARNING ("db query utils: Query `%s': The `Query' option is "
 -          "deprecated. Please use `Statement' instead.",
 -          q->name);
 -      status = udb_config_set_string (&q->statement, child);
 -    }
 -    else if ((strcasecmp ("Column", child->key) == 0)
 -        && (q->legacy_mode == 1))
 -    {
 -      WARNING ("db query utils: Query `%s': The `Column' option is "
 -          "deprecated. Please use the new syntax instead.",
 -          q->name);
 -      status = udb_legacy_result_create (q->name, &q->results, child,
 -          legacy_position);
 -      legacy_position++;
 -    }
 -    else if ((strcasecmp ("MinPGVersion", child->key) == 0)
 -        && (q->legacy_mode == 1))
 -    {
 -      WARNING ("db query utils: Query `%s': The `MinPGVersion' option is "
 -          "deprecated. Please use `MinVersion' instead.",
 -          q->name);
 -      status = udb_config_set_uint (&q->min_version, child);
 -    }
 -    else if ((strcasecmp ("MaxPGVersion", child->key) == 0)
 -        && (q->legacy_mode == 1))
 -    {
 -      WARNING ("db query utils: Query `%s': The `MaxPGVersion' option is "
 -          "deprecated. Please use `MaxVersion' instead.",
 -          q->name);
 -      status = udb_config_set_uint (&q->max_version, child);
 -    }
 -
      /* Call custom callbacks */
      else if (cb != NULL)
      {
@@@ -839,7 -1079,7 +839,7 @@@ void udb_query_finish_result (const udb
    sfree (prep_area->plugin);
    sfree (prep_area->db_name);
  
 -  prep_area->interval = -1;
 +  prep_area->interval = 0;
  
    for (r = q->results, r_area = prep_area->result_prep_areas;
        r != NULL; r = r->next, r_area = r_area->next)
@@@ -907,7 -1147,7 +907,7 @@@ int udb_query_handle_result (const udb_
  int udb_query_prepare_result (const udb_query_t const *q, /* {{{ */
      udb_query_preparation_area_t *prep_area,
      const char *host, const char *plugin, const char *db_name,
 -    char **column_names, size_t column_num, int interval)
 +    char **column_names, size_t column_num, cdtime_t interval)
  {
    udb_result_preparation_area_t *r_area;
    udb_result_t *r;
diff --combined src/zfs_arc.c
@@@ -26,7 -26,7 +26,7 @@@
  /*
   * Global variables
   */
- static kstat_t *ksp;
  extern kstat_ctl_t *kc;
  
  static void za_submit (const char* type, const char* type_instance, value_t* values, int values_len)
  
  static void za_submit_gauge (const char* type, const char* type_instance, gauge_t value)
  {
 -      value_t values[1];
 +      value_t vv;
  
 -      values[0].gauge = value;
 -
 -      za_submit (type, type_instance, values, STATIC_ARRAY_SIZE(values));
 +      vv.gauge = value;
 +      za_submit (type, type_instance, &vv, 1);
  }
  
 -static void za_submit_size (gauge_t size, gauge_t size_target, gauge_t limit_min, gauge_t limit_max)
 +static void za_submit_derive (const char* type, const char* type_instance, derive_t dv)
  {
 -      value_t values[4];
 -
 -      values[0].gauge = size;
 -      values[1].gauge = size_target;
 -      values[2].gauge = limit_min;
 -      values[3].gauge = limit_max;
 +      value_t vv;
  
 -      za_submit ("arc_size", "", values, STATIC_ARRAY_SIZE(values));
 +      vv.derive = dv;
 +      za_submit (type, type_instance, &vv, 1);
  }
  
 -static void za_submit_bytes (counter_t read, counter_t write)
 +static void za_submit_ratio (const char* type_instance, gauge_t hits, gauge_t misses)
  {
 -      value_t values[2];
 +      gauge_t ratio = NAN;
  
 -      values[0].counter = read;
 -      values[1].counter = write;
 +      if (!isfinite (hits) || (hits < 0.0))
 +              hits = 0.0;
 +      if (!isfinite (misses) || (misses < 0.0))
 +              misses = 0.0;
  
 -      za_submit ("arc_l2_bytes", "", values, STATIC_ARRAY_SIZE(values));
 -}
 -
 -static void za_submit_counts (char *type_instance, counter_t demand_data, counter_t demand_metadata,
 -      counter_t prefetch_data, counter_t prefetch_metadata)
 -{
 -      value_t values[4];
 +      if ((hits != 0.0) || (misses != 0.0))
 +              ratio = hits / (hits + misses);
  
 -      values[0].counter = demand_data;
 -      values[1].counter = demand_metadata;
 -      values[2].counter = prefetch_data;
 -      values[3].counter = prefetch_metadata;
 -
 -      za_submit ("arc_counts", type_instance, values, STATIC_ARRAY_SIZE(values));
 +      za_submit_gauge ("cache_ratio", type_instance, ratio);
  }
  
  static int za_read (void)
  {
 -      gauge_t   arcsize, targetsize, minlimit, maxlimit, hits, misses, l2_size, l2_hits, l2_misses;
 -      counter_t demand_data_hits, demand_metadata_hits, prefetch_data_hits, prefetch_metadata_hits;
 -      counter_t demand_data_misses, demand_metadata_misses, prefetch_data_misses, prefetch_metadata_misses;
 -      counter_t l2_read_bytes, l2_write_bytes;
 +      gauge_t  arc_size, l2_size;
 +      derive_t demand_data_hits,
 +               demand_metadata_hits,
 +               prefetch_data_hits,
 +               prefetch_metadata_hits,
 +               demand_data_misses,
 +               demand_metadata_misses,
 +               prefetch_data_misses,
 +               prefetch_metadata_misses;
 +      gauge_t  arc_hits, arc_misses, l2_hits, l2_misses;
 +      value_t  l2_io[2];
+       kstat_t  *ksp   = NULL;
  
        get_kstat (&ksp, "zfs", 0, "arcstats");
        if (ksp == NULL)
                return (-1);
        }
  
 -      arcsize    = get_kstat_value(ksp, "size");
 -      targetsize = get_kstat_value(ksp, "c");
 -      minlimit   = get_kstat_value(ksp, "c_min");
 -      maxlimit   = get_kstat_value(ksp, "c_max");
 +      /* Sizes */
 +      arc_size   = get_kstat_value(ksp, "size");
 +      l2_size    = get_kstat_value(ksp, "l2_size");
 +
 +      za_submit_gauge ("cache_size", "arc", arc_size);
 +      za_submit_gauge ("cache_size", "L2", l2_size);
  
 +      /* Hits / misses */
        demand_data_hits       = get_kstat_value(ksp, "demand_data_hits");
        demand_metadata_hits   = get_kstat_value(ksp, "demand_metadata_hits");
        prefetch_data_hits     = get_kstat_value(ksp, "prefetch_data_hits");
        prefetch_data_misses     = get_kstat_value(ksp, "prefetch_data_misses");
        prefetch_metadata_misses = get_kstat_value(ksp, "prefetch_metadata_misses");
  
 -      hits   = get_kstat_value(ksp, "hits");
 -      misses = get_kstat_value(ksp, "misses");
 +      za_submit_derive ("cache_result", "demand_data-hit",       demand_data_hits);
 +      za_submit_derive ("cache_result", "demand_metadata-hit",   demand_metadata_hits);
 +      za_submit_derive ("cache_result", "prefetch_data-hit",     prefetch_data_hits);
 +      za_submit_derive ("cache_result", "prefetch_metadata-hit", prefetch_metadata_hits);
  
 -      l2_size        = get_kstat_value(ksp, "l2_size");
 -      l2_read_bytes  = get_kstat_value(ksp, "l2_read_bytes");
 -      l2_write_bytes = get_kstat_value(ksp, "l2_write_bytes");
 -      l2_hits        = get_kstat_value(ksp, "l2_hits");
 -      l2_misses      = get_kstat_value(ksp, "l2_misses");
 +      za_submit_derive ("cache_result", "demand_data-miss",       demand_data_misses);
 +      za_submit_derive ("cache_result", "demand_metadata-miss",   demand_metadata_misses);
 +      za_submit_derive ("cache_result", "prefetch_data-miss",     prefetch_data_misses);
 +      za_submit_derive ("cache_result", "prefetch_metadata-miss", prefetch_metadata_misses);
  
 +      /* 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");
  
 -      za_submit_size (arcsize, targetsize, minlimit, maxlimit);
 -      za_submit_gauge ("arc_l2_size", "", l2_size);
 +      za_submit_ratio ("arc", arc_hits, arc_misses);
 +      za_submit_ratio ("L2", l2_hits, l2_misses);
  
 -      za_submit_counts ("hits",   demand_data_hits,     demand_metadata_hits,
 -                                  prefetch_data_hits,   prefetch_metadata_hits);
 -      za_submit_counts ("misses", demand_data_misses,   demand_metadata_misses,
 -                                  prefetch_data_misses, prefetch_metadata_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");
  
 -      za_submit_gauge ("arc_ratio", "L1", hits / (hits + misses));
 -      za_submit_gauge ("arc_ratio", "L2", l2_hits / (l2_hits + l2_misses));
 -
 -      za_submit_bytes (l2_read_bytes, l2_write_bytes);
 +      za_submit ("io_octets", "L2", l2_io, /* num values = */ 2);
  
        return (0);
 -}
 +} /* int za_read */
  
  static int za_init (void) /* {{{ */
  {
-       ksp = NULL;
        /* kstats chain already opened by update_kstat (using *kc), verify everything went fine. */
        if (kc == NULL)
        {