Merge remote-tracking branch 'github/pr/2105'
authorFlorian Forster <octo@collectd.org>
Thu, 18 May 2017 08:10:06 +0000 (10:10 +0200)
committerFlorian Forster <octo@collectd.org>
Thu, 18 May 2017 08:10:06 +0000 (10:10 +0200)
1  2 
Makefile.am
README
configure.ac
src/collectd.conf.in
src/collectd.conf.pod
src/daemon/utils_avltree.c
src/daemon/utils_cache.c

diff --combined Makefile.am
@@@ -114,7 -114,6 +114,7 @@@ noinst_LTLIBRARIES = 
        libformat_graphite.la \
        libformat_json.la \
        libheap.la \
 +      libignorelist.la \
        liblatency.la \
        liblookup.la \
        libmetadata.la \
@@@ -200,6 -199,8 +200,6 @@@ collectd_SOURCES = 
        src/daemon/utils_cache.h \
        src/daemon/utils_complain.c \
        src/daemon/utils_complain.h \
 -      src/daemon/utils_ignorelist.c \
 -      src/daemon/utils_ignorelist.h \
        src/daemon/utils_llist.c \
        src/daemon/utils_llist.h \
        src/daemon/utils_random.c \
@@@ -330,10 -331,6 +330,10 @@@ libheap_la_SOURCES = 
        src/daemon/utils_heap.c \
        src/daemon/utils_heap.h
  
 +libignorelist_la_SOURCES = \
 +      src/utils_ignorelist.c \
 +      src/utils_ignorelist.h
 +
  libmetadata_la_SOURCES = \
        src/daemon/meta_data.c \
        src/daemon/meta_data.h
@@@ -343,11 -340,13 +343,11 @@@ libplugin_mock_la_SOURCES = 
        src/daemon/utils_cache_mock.c \
        src/daemon/utils_complain.c \
        src/daemon/utils_complain.h \
 -      src/daemon/utils_ignorelist.c \
 -      src/daemon/utils_ignorelist.h \
        src/daemon/utils_time.c \
        src/daemon/utils_time.h
  
  libplugin_mock_la_CPPFLAGS = $(AM_CPPFLAGS) -DMOCK_TIME
 -libplugin_mock_la_LIBADD = libcommon.la $(COMMON_LIBS)
 +libplugin_mock_la_LIBADD = libcommon.la libignorelist.la $(COMMON_LIBS)
  
  libformat_graphite_la_SOURCES = \
        src/utils_format_graphite.c \
@@@ -603,14 -602,13 +603,14 @@@ if BUILD_PLUGIN_CGROUP
  pkglib_LTLIBRARIES += cgroups.la
  cgroups_la_SOURCES = src/cgroups.c
  cgroups_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 -cgroups_la_LIBADD = libmount.la
 +cgroups_la_LIBADD = libignorelist.la libmount.la
  endif
  
  if BUILD_PLUGIN_CHRONY
  pkglib_LTLIBRARIES += chrony.la
  chrony_la_SOURCES = src/chrony.c
  chrony_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 +chrony_la_LIBADD = -lm
  endif
  
  if BUILD_PLUGIN_CONNTRACK
@@@ -691,15 -689,6 +691,15 @@@ curl_json_la_CFLAGS = $(AM_CFLAGS) $(BU
  curl_json_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS)
  curl_json_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS)
  curl_json_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBYAJL_LIBS)
 +
 +test_plugin_curl_json_SOURCES = src/curl_json_test.c \
 +                              src/utils_curl_stats.c \
 +                              src/daemon/configfile.c \
 +                              src/daemon/types_list.c
 +test_plugin_curl_json_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS)
 +test_plugin_curl_json_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS)
 +test_plugin_curl_json_LDADD = libavltree.la liboconfig.la libplugin_mock.la $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBYAJL_LIBS)
 +check_PROGRAMS += test_plugin_curl_json
  endif
  
  if BUILD_PLUGIN_CURL_XML
@@@ -729,7 -718,7 +729,7 @@@ if BUILD_PLUGIN_D
  pkglib_LTLIBRARIES += df.la
  df_la_SOURCES = src/df.c
  df_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 -df_la_LIBADD = libmount.la
 +df_la_LIBADD = libignorelist.la libmount.la
  endif
  
  if BUILD_PLUGIN_DISK
@@@ -738,7 -727,7 +738,7 @@@ disk_la_SOURCES = src/disk.
  disk_la_CFLAGS = $(AM_CFLAGS)
  disk_la_CPPFLAGS = $(AM_CPPFLAGS)
  disk_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 -disk_la_LIBADD =
 +disk_la_LIBADD = libignorelist.la
  if BUILD_WITH_LIBKSTAT
  disk_la_LIBADD += -lkstat
  endif
@@@ -776,14 -765,6 +776,14 @@@ dns_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BU
  dns_la_LIBADD = $(BUILD_WITH_LIBPCAP_LIBS)
  endif
  
 +if BUILD_PLUGIN_DPDKEVENTS
 +pkglib_LTLIBRARIES += dpdkevents.la
 +dpdkevents_la_SOURCES = src/dpdkevents.c src/utils_dpdk.c src/utils_dpdk.h
 +dpdkevents_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBDPDK_CPPFLAGS)
 +dpdkevents_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBDPDK_LDFLAGS)
 +dpdkevents_la_LIBADD = -ldpdk
 +endif
 +
  if BUILD_PLUGIN_DPDKSTAT
  pkglib_LTLIBRARIES += dpdkstat.la
  dpdkstat_la_SOURCES = src/dpdkstat.c src/utils_dpdk.c src/utils_dpdk.h
@@@ -898,7 -879,7 +898,7 @@@ pkglib_LTLIBRARIES += interface.l
  interface_la_SOURCES = src/interface.c
  interface_la_CFLAGS = $(AM_CFLAGS)
  interface_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 -interface_la_LIBADD =
 +interface_la_LIBADD = libignorelist.la
  if BUILD_WITH_LIBSTATGRAB
  interface_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
  interface_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
@@@ -934,7 -915,7 +934,7 @@@ pkglib_LTLIBRARIES += ipmi.l
  ipmi_la_SOURCES = src/ipmi.c
  ipmi_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_OPENIPMI_CFLAGS)
  ipmi_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 -ipmi_la_LIBADD = $(BUILD_WITH_OPENIPMI_LIBS)
 +ipmi_la_LIBADD = libignorelist.la $(BUILD_WITH_OPENIPMI_LIBS)
  endif
  
  if BUILD_PLUGIN_IPVS
@@@ -951,7 -932,6 +951,7 @@@ if BUILD_PLUGIN_IR
  pkglib_LTLIBRARIES += irq.la
  irq_la_SOURCES = src/irq.c
  irq_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 +irq_la_LIBADD = libignorelist.la
  endif
  
  if BUILD_PLUGIN_JAVA
@@@ -1024,7 -1004,6 +1024,7 @@@ madwifi_la_SOURCES = 
        src/madwifi.c \
        src/madwifi.h
  madwifi_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 +madwifi_la_LIBADD = libignorelist.la
  endif
  
  if BUILD_PLUGIN_MATCH_EMPTY_COUNTER
@@@ -1077,7 -1056,6 +1077,7 @@@ if BUILD_PLUGIN_M
  pkglib_LTLIBRARIES += md.la
  md_la_SOURCES = src/md.c
  md_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 +md_la_LIBADD = libignorelist.la
  endif
  
  if BUILD_PLUGIN_MEMCACHEC
@@@ -1127,7 -1105,7 +1127,7 @@@ pkglib_LTLIBRARIES += mic.l
  mic_la_SOURCES = src/mic.c
  mic_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_MIC_CPPFLAGS)
  mic_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_MIC_LDFLAGS)
 -mic_la_LIBADD = $(BUILD_WITH_MIC_LIBS)
 +mic_la_LIBADD = libignorelist.la $(BUILD_WITH_MIC_LIBS)
  endif
  
  if BUILD_PLUGIN_MODBUS
@@@ -1165,7 -1143,7 +1165,7 @@@ pkglib_LTLIBRARIES += netapp.l
  netapp_la_SOURCES = src/netapp.c
  netapp_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBNETAPP_CPPFLAGS)
  netapp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBNETAPP_LDFLAGS)
 -netapp_la_LIBADD = $(LIBNETAPP_LIBS)
 +netapp_la_LIBADD = libignorelist.la $(LIBNETAPP_LIBS)
  endif
  
  if BUILD_PLUGIN_NETLINK
@@@ -1270,8 -1248,8 +1270,8 @@@ if BUILD_PLUGIN_ONEWIR
  pkglib_LTLIBRARIES += onewire.la
  onewire_la_SOURCES = src/onewire.c
  onewire_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBOWCAPI_CPPFLAGS)
 -onewire_la_LIBADD = $(BUILD_WITH_LIBOWCAPI_LIBS)
  onewire_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBOWCAPI_LDFLAGS)
 +onewire_la_LIBADD = libignorelist.la $(BUILD_WITH_LIBOWCAPI_LIBS)
  endif
  
  if BUILD_PLUGIN_OPENLDAP
@@@ -1310,17 -1288,6 +1310,17 @@@ ovs_events_la_LDFLAGS = $(PLUGIN_LDFLAG
  ovs_events_la_LIBADD = $(BUILD_WITH_LIBYAJL_LIBS)
  endif
  
 +if BUILD_PLUGIN_OVS_STATS
 +pkglib_LTLIBRARIES += ovs_stats.la
 +ovs_stats_la_SOURCES = \
 +      src/ovs_stats.c \
 +      src/utils_ovs.c \
 +      src/utils_ovs.h
 +ovs_stats_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS)
 +ovs_stats_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS)
 +ovs_stats_la_LIBADD = $(BUILD_WITH_LIBYAJL_LIBS)
 +endif
 +
  if BUILD_PLUGIN_PERL
  pkglib_LTLIBRARIES += perl.la
  perl_la_SOURCES = src/perl.c
@@@ -1409,7 -1376,6 +1409,7 @@@ if BUILD_PLUGIN_PROTOCOL
  pkglib_LTLIBRARIES += protocols.la
  protocols_la_SOURCES = src/protocols.c
  protocols_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 +protocols_la_LIBADD = libignorelist.la
  endif
  
  if BUILD_PLUGIN_REDIS
@@@ -1455,7 -1421,7 +1455,7 @@@ pkglib_LTLIBRARIES += sensors.l
  sensors_la_SOURCES = src/sensors.c
  sensors_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBSENSORS_CPPFLAGS)
  sensors_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBSENSORS_LDFLAGS)
 -sensors_la_LIBADD = $(BUILD_WITH_LIBSENSORS_LIBS)
 +sensors_la_LIBADD = libignorelist.la $(BUILD_WITH_LIBSENSORS_LIBS)
  endif
  
  if BUILD_PLUGIN_SERIAL
@@@ -1478,7 -1444,7 +1478,7 @@@ pkglib_LTLIBRARIES += smart.l
  smart_la_SOURCES = src/smart.c
  smart_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBATASMART_CPPFLAGS) $(BUILD_WITH_LIBUDEV_CPPFLAGS)
  smart_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBATASMART_LDFLAGS) $(BUILD_WITH_LIBUDEV_LDFLAGS)
 -smart_la_LIBADD = $(BUILD_WITH_LIBATASMART_LIBS) $(BUILD_WITH_LIBUDEV_LIBS)
 +smart_la_LIBADD = libignorelist.la $(BUILD_WITH_LIBATASMART_LIBS) $(BUILD_WITH_LIBUDEV_LIBS)
  endif
  endif
  
@@@ -1490,6 -1456,14 +1490,14 @@@ snmp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(B
  snmp_la_LIBADD = $(BUILD_WITH_LIBNETSNMP_LIBS)
  endif
  
+ if BUILD_PLUGIN_SNMP_AGENT
+ pkglib_LTLIBRARIES += snmp_agent.la
+ snmp_agent_la_SOURCES = src/snmp_agent.c
+ snmp_agent_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBNETSNMP_CPPFLAGS)
+ snmp_agent_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBNETSNMP_LDFLAGS)
+ snmp_agent_la_LIBADD = $(BUILD_WITH_LIBNETSNMP_LIBS)
+ endif
  if BUILD_PLUGIN_STATSD
  pkglib_LTLIBRARIES += statsd.la
  statsd_la_SOURCES = src/statsd.c
@@@ -1620,7 -1594,6 +1628,7 @@@ if BUILD_PLUGIN_THERMA
  pkglib_LTLIBRARIES += thermal.la
  thermal_la_SOURCES = src/thermal.c
  thermal_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 +thermal_la_LIBADD = libignorelist.la
  endif
  
  if BUILD_PLUGIN_THRESHOLD
@@@ -1650,7 -1623,7 +1658,7 @@@ if BUILD_PLUGIN_UNIXSOC
  pkglib_LTLIBRARIES += unixsock.la
  unixsock_la_SOURCES = src/unixsock.c
  unixsock_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 -unixsock_la_LIBS = libcmds.la
 +unixsock_la_LIBADD = libcmds.la
  endif
  
  if BUILD_PLUGIN_UPTIME
@@@ -1698,8 -1671,8 +1706,8 @@@ pkglib_LTLIBRARIES += virt.l
  virt_la_SOURCES = src/virt.c
  virt_la_CFLAGS = $(AM_CFLAGS) \
        $(BUILD_WITH_LIBVIRT_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS)
 -virt_la_LIBADD = $(BUILD_WITH_LIBVIRT_LIBS) $(BUILD_WITH_LIBXML2_LIBS)
  virt_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 +virt_la_LIBADD = libignorelist.la $(BUILD_WITH_LIBVIRT_LIBS) $(BUILD_WITH_LIBXML2_LIBS)
  
  # TODO: enable once we support only modern libvirts which depends on libnl-3
  # the libvirt on wheezy is linked in libnl v1, and there is a small leak here,
@@@ -1773,8 -1746,9 +1781,8 @@@ endi
  if BUILD_PLUGIN_WRITE_MONGODB
  pkglib_LTLIBRARIES += write_mongodb.la
  write_mongodb_la_SOURCES = src/write_mongodb.c
 -write_mongodb_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBMONGOC_CPPFLAGS)
 +write_mongodb_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBMONGOC_CFLAGS)
  write_mongodb_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBMONGOC_LDFLAGS)
 -write_mongodb_la_LIBADD = -lmongoc
  endif
  
  if BUILD_PLUGIN_WRITE_PROMETHEUS
diff --combined README
--- 1/README
--- 2/README
+++ b/README
@@@ -297,13 -297,6 +297,13 @@@ Feature
        OVS documentation.
        <http://openvswitch.org/support/dist-docs/INSTALL.rst.html>
  
 +    - ovs_stats
 +      The plugin collects the statistics of OVS connected bridges and
 +      interfaces. It requires YAJL library to be installed.
 +      Detailed instructions for installing and setting up Open vSwitch, see
 +      OVS documentation.
 +      <http://openvswitch.org/support/dist-docs/INSTALL.rst.html>
 +
      - perl
        The perl plugin implements a Perl-interpreter into collectd. You can
        write your own plugins in Perl and return arbitrary values using this
        updates to the files and write a bunch of updates at once, which lessens
        system load a lot.
  
+     - snmp_agent
+       Receives and handles queries from SNMP master agent and returns the data
+       collected by read plugins. Handles requests only for OIDs specified in
+       configuration file. To handle SNMP queries the plugin gets data from
+       collectd and translates requested values from collectd's internal format
+       to SNMP format.
      - unixsock
        One can query the values from the unixsock plugin whenever they're
        needed. Please read collectd-unixsock(5) for a description on how that's
@@@ -824,7 -824,11 +831,11 @@@ Prerequisite
      This library is part of the “Manage ONTAP SDK” published by NetApp.
  
    * libnetsnmp (optional)
-     For the `snmp' plugin.
+     For the `snmp' and 'snmp_agent' plugins.
+     <http://www.net-snmp.org/>
+   * libnetsnmpagent (optional)
+     Required for the 'snmp_agent' plugin.
      <http://www.net-snmp.org/>
  
    * libnotify (optional)
      <http://www.xmms.org/>
  
    * libyajl (optional)
 -    Parse JSON data. This is needed for the `ceph', `curl_json', 'ovs_events'
 -    and `log_logstash' plugins.
 +    Parse JSON data. This is needed for the `ceph', `curl_json', 'ovs_events',
 +    'ovs_stats' and `log_logstash' plugins.
      <http://github.com/lloyd/yajl>
  
    * libvarnish (optional)
diff --combined configure.ac
@@@ -585,22 -585,14 +585,22 @@@ if test "x$ac_system" = "xLinux"; the
    )
  
    if test "x$have_capability" = "xyes"; then
 -    AC_CHECK_LIB([cap], [cap_get_bound],
 +    AC_CHECK_LIB([cap], [cap_get_proc],
        [have_capability="yes"],
 -      [have_capability="no (cap_get_bound() not found)"]
 +      [have_capability="no (cap_get_proc() not found)"]
      )
    fi
  
    if test "x$have_capability" = "xyes"; then
 -    AC_DEFINE([HAVE_CAPABILITY], [1], [Define to 1 if you have cap_get_bound() (-lcap).])
 +    AC_CHECK_DECL([CAP_IS_SUPPORTED],
 +      [have_capability="yes"],
 +      [have_capability="no (CAP_IS_SUPPORTED not found)"],
 +      [[#include <sys/capability.h>]]
 +    )
 +  fi
 +
 +  if test "x$have_capability" = "xyes"; then
 +    AC_DEFINE([HAVE_CAPABILITY], [1], [Define to 1 if you have cap_get_proc() (-lcap).])
    fi
  
  else
@@@ -1039,92 -1031,6 +1039,92 @@@ if test "x$GCC" = "xyes"; the
  fi
  # }}} Check for strptime
  
 +# Check for timegm {{{
 +
 +# These checks need -Werror because implicit function declarations are only a
 +# warning ...
 +SAVE_CFLAGS="$CFLAGS"
 +CFLAGS="$CFLAGS -Werror"
 +
 +AC_CACHE_CHECK([for timegm],
 +  [c_cv_have_timegm],
 +  AC_LINK_IFELSE(
 +    [AC_LANG_PROGRAM(
 +[[[
 +#if STRPTIME_NEEDS_STANDARDS
 +# 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
 +#endif
 +#include <time.h>
 +]]],
 +[[[
 + time_t t = timegm(&(struct tm){0});
 + if (t == ((time_t) -1)) {
 +   return 1;
 + }
 +]]]
 +    )],
 +    [c_cv_have_timegm="yes"],
 +    [c_cv_have_timegm="no"]
 +  )
 +)
 +
 +if test "x$c_cv_have_timegm" != "xyes"
 +then
 +  AC_CACHE_CHECK([for timegm with _BSD_SOURCE],
 +    [c_cv_have_timegm_bsd],
 +    AC_LINK_IFELSE(
 +      [AC_LANG_PROGRAM(
 +[[[
 +#if STRPTIME_NEEDS_STANDARDS
 +# 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
 +#endif
 +#ifndef _BSD_SOURCE
 +# define _BSD_SOURCE 1
 +#endif
 +#include <time.h>
 +]]],
 +[[[
 + time_t t = timegm(&(struct tm){0});
 + if (t == ((time_t) -1)) {
 +   return 1;
 + }
 +]]]
 +      )],
 +      [c_cv_have_timegm_bsd="yes"
 +       c_cv_have_timegm="yes"],
 +      [c_cv_have_timegm_bsd="no"]
 +    )
 +  )
 +fi
 +
 +if test "x$c_cv_have_timegm" = "xyes"
 +then
 +  AC_DEFINE(HAVE_TIMEGM, 1, [Define if the timegm(3) function is available.])
 +  if test "x$c_cv_have_timegm_bsd" = "xyes"
 +  then
 +    AC_DEFINE(TIMEGM_NEEDS_BSD, 1, [Set to true if timegm is only exported in BSD mode.])
 +  fi
 +fi
 +
 +CFLAGS="$SAVE_CFLAGS"
 +# }}} Check for timegm
 +
  AC_MSG_CHECKING([for sysctl kern.cp_times])
  if test -x /sbin/sysctl; then
    /sbin/sysctl kern.cp_times >/dev/null 2>&1
@@@ -1399,8 -1305,8 +1399,8 @@@ if test "x$fp_layout_type" = "xunknown"
                    && (c[2] == 0xc0) && (c[3] == 0xc7)
                    && (c[4] == 0x43) && (c[5] == 0x2b)
                    && (c[6] == 0x1f) && (c[7] == 0x5b))
 -                return (0);
 -              return (1);
 +                return 0;
 +              return 1;
              ]]
            )
          ],
@@@ -1454,8 -1360,8 +1454,8 @@@ if test "x$fp_layout_type" = "xunknown"
                    && (c[2] == 0xc0) && (c[3] == 0xc7)
                    && (c[4] == 0x43) && (c[5] == 0x2b)
                    && (c[6] == 0x1f) && (c[7] == 0x5b))
 -                return (0);
 -              return (1);
 +                return 0;
 +              return 1;
              ]]
            )
          ],
@@@ -1503,8 -1409,8 +1503,8 @@@ if test "x$fp_layout_type" = "xunknown"
                    && (c[2] == 0xc0) && (c[3] == 0xc7)
                    && (c[4] == 0x43) && (c[5] == 0x2b)
                    && (c[6] == 0x1f) && (c[7] == 0x5b))
 -                return (0);
 -              return (1);
 +                return 0;
 +              return 1;
              ]]
            )
          ],
@@@ -2794,46 -2700,30 +2794,46 @@@ AC_ARG_VAR([LIBDPDK_LDFLAGS], [Linker f
  
  AC_ARG_WITH([libdpdk], [AS_HELP_STRING([--without-libdpdk], [Disable libdpdk.])])
  
 -if test "x$with_libdpdk" != "xno"
 -then
 -      if test "x$LIBDPDK_CPPFLAGS" = "x"
 -      then
 -              LIBDPDK_CPPFLAGS="-I/usr/include/dpdk"
 -      fi
 -      SAVE_CPPFLAGS="$CPPFLAGS"
 -      CPPFLAGS="$LIBDPDK_CPPFLAGS $CPPFLAGS"
 -      AC_CHECK_HEADERS([rte_config.h],
 -              [with_libdpdk="yes"],
 -              [with_libdpdk="no (rte_config.h not found)"]
 -      )
 -      CPPFLAGS="$SAVE_CPPFLAGS"
 +if test "x$with_libdpdk" != "xno"; then
 +  if test "x$LIBDPDK_CPPFLAGS" = "x"; then
 +    LIBDPDK_CPPFLAGS="-I/usr/include/dpdk"
 +  fi
 +  SAVE_CPPFLAGS="$CPPFLAGS"
 +  CPPFLAGS="$LIBDPDK_CPPFLAGS $CPPFLAGS"
 +  AC_CHECK_HEADERS([rte_config.h],
 +    [
 +      with_libdpdk="yes"
 +      AC_COMPILE_IFELSE(
 +        [
 +          AC_LANG_PROGRAM(
 +            [[
 +              #include <rte_version.h>
 +              #if RTE_VERSION < RTE_VERSION_NUM(16,7,0,0)
 +              #error "required DPDK >= 16.07"
 +              #endif
 +            ]],
 +            [[
 +              return 0;
 +            ]]
 +          )
 +        ],
 +        [dpdk_keepalive="yes"],
 +        [dpdk_keepalive="no (DPDK version < 16.07)"]
 +      )
 +    ],
 +    [with_libdpdk="no (rte_config.h not found)"]
 +  )
 +  CPPFLAGS="$SAVE_CPPFLAGS"
  fi
  
 -if test "x$with_libdpdk" = "xyes"
 -then
 -      SAVE_LDFLAGS="$LDFLAGS"
 -      LDFLAGS="$LIBDPDK_LDFLAGS $LDFLAGS"
 -      AC_CHECK_LIB([dpdk], [rte_eal_init],
 -              [with_libdpdk="yes"],
 -              [with_libdpdk="no (symbol 'rte_eal_init' not found)"]
 -      )
 -      LDFLAGS="$SAVE_LDFLAGS"
 +if test "x$with_libdpdk" = "xyes"; then
 +  SAVE_LDFLAGS="$LDFLAGS"
 +  LDFLAGS="$LIBDPDK_LDFLAGS $LDFLAGS"
 +  AC_CHECK_LIB([dpdk], [rte_eal_init],
 +    [with_libdpdk="yes"],
 +    [with_libdpdk="no (symbol 'rte_eal_init' not found)"]
 +  )
 +  LDFLAGS="$SAVE_LDFLAGS"
  fi
  
  # }}}
@@@ -3396,62 -3286,52 +3396,62 @@@ AC_ARG_WITH([libmongoc]
      else if test "x$withval" = "xno"; then
        with_libmongoc="no"
      else
 -      with_libmongoc="yes"
 -      LIBMONGOC_CPPFLAGS="$LIBMONGOC_CPPFLAGS -I$withval/include"
 -      LIBMONGOC_LDFLAGS="$LIBMONGOC_LDFLAGS -L$withval/lib"
 +      with_libmongoc="no"
      fi; fi
    ],
    [with_libmongoc="yes"]
  )
  
 -SAVE_CPPFLAGS="$CPPFLAGS"
 -SAVE_LDFLAGS="$LDFLAGS"
 -
 -CPPFLAGS="$CPPFLAGS $LIBMONGOC_CPPFLAGS"
 -LDFLAGS="$LDFLAGS $LIBMONGOC_LDFLAGS"
 +if test "x$with_libmongoc" = "xyes"; then
 +  PKG_CHECK_MODULES([LIBMONGOC], [libmongoc-1.0],
 +    [with_libmongoc="yes"],
 +    [with_libmongoc="no (pkg-config could not find libmongoc)"]
 +  )
 +fi
  
  if test "x$with_libmongoc" = "xyes"; then
 -  if test "x$LIBMONGOC_CPPFLAGS" != "x"; then
 -    AC_MSG_NOTICE([libmongoc CPPFLAGS: $LIBMONGOC_CPPFLAGS])
 +  SAVE_CPPFLAGS="$CPPFLAGS"
 +
 +  CPPFLAGS="$CPPFLAGS $LIBMONGOC_CFLAGS"
 +
 +  if test "x$CPPFLAGS" != "x"; then
 +    AC_MSG_NOTICE([libmongoc CPPFLAGS: $LIBMONGOC_CFLAGS])
    fi
  
 -  AC_CHECK_HEADERS([mongo.h],
 +  AC_CHECK_HEADERS([mongoc.h],
      [with_libmongoc="yes"],
 -    [with_libmongoc="no ('mongo.h' not found)"],
 -    [[#define MONGO_HAVE_STDINT 1]]
 +    [with_libmongoc="no ('mongoc.h' not found)"]
    )
 +
 +  CPPFLAGS="$SAVE_CPPFLAGS"
  fi
  
  if test "x$with_libmongoc" = "xyes"; then
 +  SAVE_CPPFLAGS="$CPPFLAGS"
 +  SAVE_LDFLAGS="$LDFLAGS"
 +
 +  CPPFLAGS="$CPPFLAGS $LIBMONGOC_CFLAGS"
 +  LDFLAGS="$LDFLAGS $LIBMONGOC_LDFLAGS"
 +
    if test "x$LIBMONGOC_LDFLAGS" != "x"; then
      AC_MSG_NOTICE([libmongoc LDFLAGS: $LIBMONGOC_LDFLAGS])
    fi
  
 -  AC_CHECK_LIB([mongoc], [mongo_run_command],
 +  AC_CHECK_LIB([mongoc-1.0], [mongoc_init],
      [with_libmongoc="yes"],
 -    [with_libmongoc="no (symbol 'mongo_run_command' not found)"]
 +    [with_libmongoc="no (symbol 'mongoc_init' not found)"]
    )
 -fi
  
 -CPPFLAGS="$SAVE_CPPFLAGS"
 -LDFLAGS="$SAVE_LDFLAGS"
 +  CPPFLAGS="$SAVE_CPPFLAGS"
 +  LDFLAGS="$SAVE_LDFLAGS"
 +fi
  
  if test "x$with_libmongoc" = "xyes"; then
 -  BUILD_WITH_LIBMONGOC_CPPFLAGS="$LIBMONGOC_CPPFLAGS"
 +  BUILD_WITH_LIBMONGOC_CFLAGS="$LIBMONGOC_CFLAGS"
    BUILD_WITH_LIBMONGOC_LDFLAGS="$LIBMONGOC_LDFLAGS"
  fi
  
 -AC_SUBST([BUILD_WITH_LIBMONGOC_CPPFLAGS])
 +AC_SUBST([BUILD_WITH_LIBMONGOC_CFLAGS])
  AC_SUBST([BUILD_WITH_LIBMONGOC_LDFLAGS])
  # }}}
  
@@@ -3653,7 -3533,7 +3653,7 @@@ if test "x$with_libmnl" = "xyes"; the
          ]],
          [[
            int retval = TCA_STATS2;
 -          return (retval);
 +          return retval;
          ]]
        )
      ],
          ]],
          [[
            int retval = TCA_STATS;
 -          return (retval);
 +          return retval;
          ]]
        )
      ],
@@@ -3763,6 -3643,7 +3763,7 @@@ AC_SUBST([LIBNETAPP_LIBS]
  # }}}
  
  # --with-libnetsnmp {{{
+ with_libnetsnmpagent="no"
  AC_ARG_WITH(libnetsnmp, [AS_HELP_STRING([--with-libnetsnmp@<:@=PREFIX@:>@], [Path to the Net-SNMPD library.])],
  [
        if test "x$withval" = "xno"
                with_libnetsnmp_cppflags="-I$withval/include"
                with_libnetsnmp_ldflags="-I$withval/lib"
                with_libnetsnmp="yes"
+               with_libnetsnmpagent="yes"
        fi; fi
  ],
  [with_libnetsnmp="yes"])
        [with_libnetsnmp="yes"],
        [with_libnetsnmp="no (net-snmp/net-snmp-config.h not found)"]
      )
+     AC_CHECK_HEADERS(net-snmp/agent/agent_module_config.h,
+       [],
+       [with_libnetsnmpagent="no (net-snmp/agent/agent_module_config.h not found)"]
+     )
  
        CPPFLAGS="$SAVE_CPPFLAGS"
  fi
                [with_libnetsnmp="no (libnetsnmp not found)"],
                [$with_snmp_libs])
  
+       AC_CHECK_LIB(netsnmpagent, init_agent,
+               [with_libnetsnmpagent="yes"],
+               [with_libnetsnmpagent="no (libnetsnmpagent not found)"],
+               [$with_snmp_libs])
        LDFLAGS="$SAVE_LDFLAGS"
  fi
  if test "x$with_libnetsnmp" = "xyes"
        BUILD_WITH_LIBNETSNMP_LDFLAGS="$with_libnetsnmp_ldflags"
        BUILD_WITH_LIBNETSNMP_LIBS="-lnetsnmp"
  fi
+ if test "x$with_libnetsnmpagent" = "xyes"
+ then
+       BUILD_WITH_LIBNETSNMP_LIBS+=" -lnetsnmpagent"
+ fi
  AC_SUBST(BUILD_WITH_LIBNETSNMP_CPPFLAGS)
  AC_SUBST(BUILD_WITH_LIBNETSNMP_LDFLAGS)
  AC_SUBST(BUILD_WITH_LIBNETSNMP_LIBS)
  fi
  if test "x$with_libpqos" = "xyes"
  then
 +  SAVE_CPPFLAGS="$CPPFLAGS"
 +  CPPFLAGS="$CPPFLAGS $with_libpqos_cppflags"
 +  AC_RUN_IFELSE([AC_LANG_PROGRAM(
 +    [[#include <pqos.h>]],
 +    [[return !(PQOS_VERSION >= 106)]])],
 +    [with_libpqos="yes"], [with_libpqos="no (pqos library version 1.06 or higher is required)"])
 +  CPPFLAGS="$SAVE_CPPFLAGS"
 +fi
 +if test "x$with_libpqos" = "xyes"
 +then
        BUILD_WITH_LIBPQOS_CPPFLAGS="$with_libpqos_cppflags"
        BUILD_WITH_LIBPQOS_LDFLAGS="$with_libpqos_ldflags"
        BUILD_WITH_LIBPQOS_LIBS="-lpqos"
@@@ -5306,10 -5191,6 +5321,10 @@@ if test "x$with_libupsclient" = "xyes"
      [with_libupsclient="no (symbol upscli_connect not found)"]
    )
  
 +  AC_CHECK_LIB([upsclient], [upscli_init],
 +    [AC_DEFINE([HAVE_UPSCLI_INIT], [1], [Define when upscli_init() (since version 2-7) is available.])]
 +  )
 +
    LDFLAGS="$SAVE_LDFLAGS"
  fi
  
@@@ -6005,7 -5886,6 +6020,7 @@@ plugin_curl_xml="no
  plugin_df="no"
  plugin_disk="no"
  plugin_drbd="no"
 +plugin_dpdkevents="no"
  plugin_dpdkstat="no"
  plugin_entropy="no"
  plugin_ethstat="no"
@@@ -6028,13 -5908,13 +6043,14 @@@ plugin_multimeter="no
  plugin_nfs="no"
  plugin_numa="no"
  plugin_ovs_events="no"
 +plugin_ovs_stats="no"
  plugin_perl="no"
  plugin_pinba="no"
  plugin_processes="no"
  plugin_protocols="no"
  plugin_python="no"
  plugin_serial="no"
+ plugin_snmp_agent="no"
  plugin_smart="no"
  plugin_swap="no"
  plugin_tape="no"
@@@ -6100,11 -5980,6 +6116,11 @@@ if test "x$ac_system" = "xLinux"; the
    if test "x$c_cv_have_clock_boottime_monotonic" = "xyes"; then
      plugin_cpusleep="yes"
    fi
 +
 +  if test "x$with_libyajl" = "xyes" && test "x$with_libyajl2" = "xyes"; then
 +    plugin_ovs_events="yes"
 +    plugin_ovs_stats="yes"
 +  fi
  fi
  
  if test "x$ac_system" = "xOpenBSD"; then
@@@ -6281,6 -6156,10 +6297,6 @@@ if test "x$with_libyajl" = "xyes"; the
    plugin_log_logstash="yes"
  fi
  
 -if test "x$with_libyajl" = "xyes" && test "x$with_libyajl2" = "xyes"; then
 -  plugin_ovs_events="yes"
 -fi
 -
  if test "x$with_libperl" = "xyes" && test "x$c_cv_have_perl_ithreads" = "xyes"; then
    plugin_perl="yes"
  fi
@@@ -6328,6 -6207,10 +6344,10 @@@ if test "x$with_kvm_getswapinfo" = "xye
    plugin_swap="yes"
  fi
  
+ if test "x$with_libnetsnmp" = "xyes" && test "x$with_libnetsnmpagent" = "xyes"; then
+   plugin_snmp_agent="yes"
+ fi
  if test "x$have_swapctl" = "xyes" && test "x$c_cv_have_swapctl_two_args" = "xyes"; then
    plugin_swap="yes"
  fi
  
  if test "x$with_libdpdk" = "xyes"
  then
 +  plugin_dpdkevents="$dpdk_keepalive"
    plugin_dpdkstat="yes"
  fi
  
@@@ -6407,7 -6289,6 +6427,7 @@@ AC_PLUGIN([dbi],                 [$with
  AC_PLUGIN([df],                  [$plugin_df],              [Filesystem usage statistics])
  AC_PLUGIN([disk],                [$plugin_disk],            [Disk usage statistics])
  AC_PLUGIN([dns],                 [$with_libpcap],           [DNS traffic analysis])
 +AC_PLUGIN([dpdkevents],          [$plugin_dpdkevents],      [Events from DPDK])
  AC_PLUGIN([dpdkstat],            [$plugin_dpdkstat],        [Stats from DPDK])
  AC_PLUGIN([drbd],                [$plugin_drbd],            [DRBD statistics])
  AC_PLUGIN([email],               [yes],                     [EMail statistics])
@@@ -6470,7 -6351,6 +6490,7 @@@ AC_PLUGIN([openldap],            [$with
  AC_PLUGIN([openvpn],             [yes],                     [OpenVPN client statistics])
  AC_PLUGIN([oracle],              [$with_oracle],            [Oracle plugin])
  AC_PLUGIN([ovs_events],          [$plugin_ovs_events],      [OVS events plugin])
 +AC_PLUGIN([ovs_stats],           [$plugin_ovs_stats],       [OVS statistics plugin])
  AC_PLUGIN([perl],                [$plugin_perl],            [Embed a Perl interpreter])
  AC_PLUGIN([pf],                  [$have_net_pfvar_h],       [BSD packet filter (PF) statistics])
  # FIXME: Check for libevent, too.
@@@ -6490,6 -6370,7 +6510,7 @@@ AC_PLUGIN([serial],              [$plug
  AC_PLUGIN([sigrok],              [$with_libsigrok],         [sigrok acquisition sources])
  AC_PLUGIN([smart],               [$plugin_smart],           [SMART statistics])
  AC_PLUGIN([snmp],                [$with_libnetsnmp],        [SNMP querying plugin])
+ AC_PLUGIN([snmp_agent],          [$plugin_snmp_agent],      [SNMP agent plugin])
  AC_PLUGIN([statsd],              [yes],                     [StatsD plugin])
  AC_PLUGIN([swap],                [$plugin_swap],            [Swap usage statistics])
  AC_PLUGIN([syslog],              [$have_syslog],            [Syslog logging plugin])
@@@ -6834,7 -6715,6 +6855,7 @@@ AC_MSG_RESULT([    dbi . . . . . . . . 
  AC_MSG_RESULT([    df  . . . . . . . . . $enable_df])
  AC_MSG_RESULT([    disk  . . . . . . . . $enable_disk])
  AC_MSG_RESULT([    dns . . . . . . . . . $enable_dns])
 +AC_MSG_RESULT([    dpdkevents. . . . . . $enable_dpdkevents])
  AC_MSG_RESULT([    dpdkstat  . . . . . . $enable_dpdkstat])
  AC_MSG_RESULT([    drbd  . . . . . . . . $enable_drbd])
  AC_MSG_RESULT([    email . . . . . . . . $enable_email])
@@@ -6897,7 -6777,6 +6918,7 @@@ AC_MSG_RESULT([    openldap  . . . . . 
  AC_MSG_RESULT([    openvpn . . . . . . . $enable_openvpn])
  AC_MSG_RESULT([    oracle  . . . . . . . $enable_oracle])
  AC_MSG_RESULT([    ovs_events  . . . . . $enable_ovs_events])
 +AC_MSG_RESULT([    ovs_stats . . . . . . $enable_ovs_stats])
  AC_MSG_RESULT([    perl  . . . . . . . . $enable_perl])
  AC_MSG_RESULT([    pf  . . . . . . . . . $enable_pf])
  AC_MSG_RESULT([    pinba . . . . . . . . $enable_pinba])
@@@ -6916,6 -6795,7 +6937,7 @@@ AC_MSG_RESULT([    serial  . . . . . . 
  AC_MSG_RESULT([    sigrok  . . . . . . . $enable_sigrok])
  AC_MSG_RESULT([    smart . . . . . . . . $enable_smart])
  AC_MSG_RESULT([    snmp  . . . . . . . . $enable_snmp])
+ AC_MSG_RESULT([    snmp_agent  . . . . . $enable_snmp_agent])
  AC_MSG_RESULT([    statsd  . . . . . . . $enable_statsd])
  AC_MSG_RESULT([    swap  . . . . . . . . $enable_swap])
  AC_MSG_RESULT([    syslog  . . . . . . . $enable_syslog])
diff --combined src/collectd.conf.in
  #@BUILD_PLUGIN_DF_TRUE@LoadPlugin df
  #@BUILD_PLUGIN_DISK_TRUE@LoadPlugin disk
  #@BUILD_PLUGIN_DNS_TRUE@LoadPlugin dns
 +#@BUILD_PLUGIN_DPDKEVENTS_TRUE@LoadPlugin dpdkevents
  #@BUILD_PLUGIN_DPDKSTAT_TRUE@LoadPlugin dpdkstat
  #@BUILD_PLUGIN_DRBD_TRUE@LoadPlugin drbd
  #@BUILD_PLUGIN_EMAIL_TRUE@LoadPlugin email
  #@BUILD_PLUGIN_OPENVPN_TRUE@LoadPlugin openvpn
  #@BUILD_PLUGIN_ORACLE_TRUE@LoadPlugin oracle
  #@BUILD_PLUGIN_OVS_EVENTS_TRUE@LoadPlugin ovs_events
 +#@BUILD_PLUGIN_OVS_STATS_TRUE@LoadPlugin ovs_stats
  #@BUILD_PLUGIN_PERL_TRUE@LoadPlugin perl
  #@BUILD_PLUGIN_PINBA_TRUE@LoadPlugin pinba
  #@BUILD_PLUGIN_PING_TRUE@LoadPlugin ping
  #@BUILD_PLUGIN_SIGROK_TRUE@LoadPlugin sigrok
  #@BUILD_PLUGIN_SMART_TRUE@LoadPlugin smart
  #@BUILD_PLUGIN_SNMP_TRUE@LoadPlugin snmp
+ #@BUILD_PLUGIN_SNMP_AGENT_TRUE@LoadPlugin snmp_agent
  #@BUILD_PLUGIN_STATSD_TRUE@LoadPlugin statsd
  #@BUILD_PLUGIN_SWAP_TRUE@LoadPlugin swap
  #@BUILD_PLUGIN_TABLE_TRUE@LoadPlugin table
  #     SelectNumericQueryTypes true
  #</Plugin>
  
 +#<Plugin "dpdkevents">
 +#  <EAL>
 +#    Coremask "0x1"
 +#    MemoryChannels "4"
 +#    ProcessType "secondary"
 +#    FilePrefix "rte"
 +#  </EAL>
 +#  <Event "link_status">
 +#    SendEventsOnUpdate true
 +#    EnabledPortMask 0xffff
 +#    PortName "interface1"
 +#    PortName "interface2"
 +#    SendNotification false
 +#  </Event>
 +#  <Event "keep_alive">
 +#    SendEventsOnUpdate true
 +#    LCoreMask "0xf"
 +#    KeepAliveShmName "/dpdk_keepalive_shm_name"
 +#    SendNotification false
 +#  </Event>
 +#</Plugin>
 +
  #<Plugin dpdkstat>
  #  <EAL>
  #    Coremask "0x2"
  #    ProcessType "secondary"
  #    FilePrefix "rte"
  #  </EAL>
 +#  SharedMemObj "dpdk_collectd_stats_0"
  #  EnabledPortMask 0xffff
  #  PortName "interface1"
  #  PortName "interface2"
  
  #<Plugin nut>
  #     UPS "upsname@hostname:port"
 +#     ForceSSL true
 +#     VerifyPeer true
 +#     CAPath "/path/to/folder"
  #</Plugin>
  
  #<Plugin olsrd>
  #  Address "127.0.0.1"
  #  Socket "/var/run/openvswitch/db.sock"
  #  Interfaces "br0" "veth0"
 -#  SendNotification false
 +#  SendNotification true
 +#  DispatchValues false
 +#</Plugin>
 +
 +#<Plugin ovs_stats>
 +#  Port "6640"
 +#  Address "127.0.0.1"
 +#  Socket "/var/run/openvswitch/db.sock"
 +#  Bridges "br0" "br_ext"
  #</Plugin>
  
  #<Plugin perl>
  #</Plugin>
  
  #<Plugin processes>
 +#     CollectFileDescriptor true
 +#     CollectContextSwitch true
  #     Process "name"
 +#     ProcessMatch "name" "regex"
 +#     <Process "collectd">
 +#             CollectFileDescriptor false
 +#             CollectContextSwitch false
 +#     </Process>
 +#     <ProcessMatch "name" "regex">
 +#             CollectFileDescriptor false
 +#             CollectContextSwitch true
 +#     </Process>
  #</Plugin>
  
  #<Plugin protocols>
  #   </Host>
  #</Plugin>
  
+ #<Plugin snmp_agent>
+ #  <Data "memAvailReal">
+ #    Plugin "memory"
+ #    Type "memory"
+ #    TypeInstance "free"
+ #    OIDs "1.3.6.1.4.1.2021.4.6.0"
+ #  </Data>
+ #  <Table "ifTable">
+ #    IndexOID "IF-MIB::ifIndex"
+ #    SizeOID "IF-MIB::ifNumber"
+ #    <Data "ifDescr">
+ #      Instance true
+ #      Plugin "interface"
+ #      OIDs "IF-MIB::ifDescr"
+ #    </Data>
+ #    <Data "ifOctets">
+ #      Plugin "interface"
+ #      Type "if_octets"
+ #      TypeInstance ""
+ #      OIDs "IF-MIB::ifInOctets" "IF-MIB::ifOutOctets"
+ #    </Data>
+ #  </Table>
+ #</Plugin>
  #<Plugin statsd>
  #  Host "::"
  #  Port "8125"
  #     InterfaceFormat name
  #     PluginInstanceFormat name
  #     Instances 1
 +#     ExtraStats "cpu_util disk disk_err domain_state fs_info job_stats_background pcpu perf vcpupin"
  #</Plugin>
  
  #<Plugin vmem>
  #             Header "X-Custom-Header: custom_value"
  #             SSLVersion "TLSv1"
  #             Format "Command"
 +#             Attribute "key" "value"     # only available for KAIROSDB format
 +#             TTL 0   # data ttl, only available for KAIROSDB format
  #             Metrics true
  #             Notifications false
  #             StoreRates false
diff --combined src/collectd.conf.pod
@@@ -338,7 -338,7 +338,7 @@@ is enabled by default
  =item B<PostCacheChain> I<ChainName>
  
  Configure the name of the "pre-cache chain" and the "post-cache chain". Please
 -see L<FILTER CONFIGURATION> below on information on chains and how these
 +see L</"FILTER CONFIGURATION"> below on information on chains and how these
  setting change the daemon's behavior.
  
  =back
@@@ -1372,8 -1372,6 +1372,8 @@@ Select I<cgroup> based on the name. Whe
  collected or if they are ignored is controlled by the B<IgnoreSelected> option;
  see below.
  
 +See F</"IGNORELISTS"> for details.
 +
  =item B<IgnoreSelected> B<true>|B<false>
  
  Invert the selection: If set to true, all cgroups I<except> the ones that
@@@ -2270,20 -2268,14 +2270,20 @@@ values. Defaults to the global hostnam
  
  Select partitions based on the devicename.
  
 +See F</"IGNORELISTS"> for details.
 +
  =item B<MountPoint> I<Directory>
  
  Select partitions based on the mountpoint.
  
 +See F</"IGNORELISTS"> for details.
 +
  =item B<FSType> I<FSType>
  
  Select partitions based on the filesystem type.
  
 +See F</"IGNORELISTS"> for details.
 +
  =item B<IgnoreSelected> B<true>|B<false>
  
  Invert the selection: If set to true, all partitions B<except> the ones that
@@@ -2345,8 -2337,6 +2345,8 @@@ is interpreted as a regular expression
    Disk "sdd"
    Disk "/hda[34]/"
  
 +See F</"IGNORELISTS"> for details.
 +
  =item B<IgnoreSelected> B<true>|B<false>
  
  Sets whether selected disks, i.E<nbsp>e. the ones matches by any of the B<Disk>
@@@ -2393,128 -2383,6 +2393,128 @@@ Enabled by default, collects unknown (a
  
  =back
  
 +=head2 Plugin C<dpdkevents>
 +
 +The I<dpdkevents plugin> collects events from DPDK such as link status of
 +network ports and Keep Alive status of DPDK logical cores.
 +In order to get Keep Alive events following requirements must be met:
 +- DPDK >= 16.07
 +- support for Keep Alive implemented in DPDK application. More details can
 +be found here: http://dpdk.org/doc/guides/sample_app_ug/keep_alive.html
 +
 +B<Synopsis:>
 +
 + <Plugin "dpdkevents">
 +   <EAL>
 +     Coremask "0x1"
 +     MemoryChannels "4"
 +     ProcessType "secondary"
 +     FilePrefix "rte"
 +   </EAL>
 +   <Event "link_status">
 +     SendEventsOnUpdate true
 +     EnabledPortMask 0xffff
 +     PortName "interface1"
 +     PortName "interface2"
 +     SendNotification false
 +   </Event>
 +   <Event "keep_alive">
 +     SendEventsOnUpdate true
 +     LCoreMask "0xf"
 +     KeepAliveShmName "/dpdk_keepalive_shm_name"
 +     SendNotification false
 +   </Event>
 + </Plugin>
 +
 +B<Options:>
 +
 +
 +=head3 The EAL block
 +
 +=over 5
 +
 +=item B<Coremask> I<Mask>
 +
 +=item B<Memorychannels> I<Channels>
 +
 +Number of memory channels per processor socket.
 +
 +=item B<ProcessType> I<type>
 +
 +The type of DPDK process instance.
 +
 +=item B<FilePrefix> I<File>
 +
 +The prefix text used for hugepage filenames. The filename will be set to
 +/var/run/.<prefix>_config where prefix is what is passed in by the user.
 +
 +=back
 +
 +=head3 The Event block
 +
 +The B<Event> block defines configuration for specific event. It accepts a
 +single argument which specifies the name of the event.
 +
 +=head4 Link Status event
 +
 +=over 5
 +
 +=item B<SendEventOnUpdate> I<true|false>
 +
 +If set to true link status value will be dispatched only when it is
 +different from previously read value. This is an optional argument - default
 +value is true.
 +
 +=item B<EnabledPortMask> I<Mask>
 +
 +A hexidecimal bit mask of the DPDK ports which should be enabled. A mask
 +of 0x0 means that all ports will be disabled. A bitmask of all F's means
 +that all ports will be enabled. This is an optional argument - by default
 +all ports are enabled.
 +
 +=item B<PortName> I<Name>
 +
 +A string containing an optional name for the enabled DPDK ports. Each PortName
 +option should contain only one port name; specify as many PortName options as
 +desired. Default naming convention will be used if PortName is blank. If there
 +are less PortName options than there are enabled ports, the default naming
 +convention will be used for the additional ports.
 +
 +=item B<SendNotification> I<true|false>
 +
 +If set to true, link status notifications are sent, instead of link status
 +being collected as a statistic. This is an optional argument - default
 +value is false.
 +
 +=back
 +
 +=head4 Keep Alive event
 +
 +=over 5
 +
 +=item B<SendEventOnUpdate> I<true|false>
 +
 +If set to true keep alive value will be dispatched only when it is
 +different from previously read value. This is an optional argument - default
 +value is true.
 +
 +=item B<LCoreMask> I<Mask>
 +
 +An hexadecimal bit mask of the logical cores to monitor keep alive state.
 +
 +=item B<KeepAliveShmName> I<Name>
 +
 +Shared memory name identifier that is used by secondary process to monitor
 +the keep alive cores state.
 +
 +=item B<SendNotification> I<true|false>
 +
 +If set to true, keep alive notifications are sent, instead of keep alive
 +information being collected as a statistic. This is an optional
 +argument - default value is false.
 +
 +=back
 +
  =head2 Plugin C<dpdkstat>
  
  The I<dpdkstat plugin> collects information about DPDK interfaces using the
@@@ -2530,7 -2398,6 +2530,7 @@@ B<Synopsis:
       FilePrefix "rte"
       SocketMemory "1024"
     </EAL>
 +   SharedMemObj "dpdk_collectd_stats_0"
     EnabledPortMask 0xffff
     PortName "interface1"
     PortName "interface2"
@@@ -2567,12 -2434,7 +2567,12 @@@ sockets in MB. This is an optional valu
  
  =back
  
 -=over 4
 +=over 3
 +
 +=item B<SharedMemObj> I<Mask>
 +A string containing the name of the shared memory object that should be used to
 +share stats from the DPDK secondary process to the collectd dpdkstat plugin.
 +Defaults to dpdk_collectd_stats if no other value is configured.
  
  =item B<EnabledPortMask> I<Mask>
  
@@@ -3096,10 -2958,6 +3096,10 @@@ allows to monitor instructions per cloc
  Monitor events are hardware dependant. Monitoring capabilities are detected on
  plugin initialization and only supported events are monitored.
  
 +B<Note:> I<intel_rdt> plugin is using model-specific registers (MSRs), which
 +require an additional capability to be enabled if collectd is run as a service.
 +Please refer to I<contrib/systemd.collectd.service> file for more details.
 +
  B<Synopsis:>
  
    <Plugin "intel_rdt">
@@@ -3149,8 -3007,6 +3149,8 @@@ than 1 sec
  Select this interface. By default these interfaces will then be collected. For
  a more detailed description see B<IgnoreSelected> below.
  
 +See F</"IGNORELISTS"> for details.
 +
  =item B<IgnoreSelected> I<true>|I<false>
  
  If no configuration if given, the B<interface>-plugin will collect data from
@@@ -3212,8 -3068,6 +3212,8 @@@ This option is only available on Solari
  
  Selects sensors to collect or to ignore, depending on B<IgnoreSelected>.
  
 +See F</"IGNORELISTS"> for details.
 +
  =item B<IgnoreSelected> I<true>|I<false>
  
  If no configuration if given, the B<ipmi> plugin will collect data from all
@@@ -3270,8 -3124,6 +3270,8 @@@ comment or the number
  Select this irq. By default these irqs will then be collected. For a more
  detailed description see B<IgnoreSelected> below.
  
 +See F</"IGNORELISTS"> for details.
 +
  =item B<IgnoreSelected> I<true>|I<false>
  
  If no configuration if given, the B<irq>-plugin will collect data from all
@@@ -3517,8 -3369,6 +3517,8 @@@ Select md devices based on device name
  the device, i.e. the name of the block device without the leading C</dev/>.
  See B<IgnoreSelected> for more details.
  
 +See F</"IGNORELISTS"> for details.
 +
  =item B<IgnoreSelected> B<true>|B<false>
  
  Invert device selection: If set to B<true>, all md devices B<except> those
@@@ -4682,8 -4532,6 +4682,8 @@@ regular and exact matching are case sen
  If no volume was specified at all for either of the three options, that data
  will be collected for all available volumes.
  
 +See F</"IGNORELISTS"> for details.
 +
  =item B<IgnoreSelectedIO> B<true>|B<false>
  
  =item B<IgnoreSelectedOps> B<true>|B<false>
@@@ -4869,8 -4717,6 +4869,8 @@@ Here are some examples to help you unde
      Filter "ppp0" "u32-1:0"
    </Plugin>
  
 +See F</"IGNORELISTS"> for details.
 +
  =item B<IgnoreSelected>
  
  The behavior is the same as with all other similar plugins: If nothing is
@@@ -5271,35 -5117,6 +5271,35 @@@ making it through
  Add a UPS to collect data from. The format is identical to the one accepted by
  L<upsc(8)>.
  
 +=item B<ForceSSL> B<true>|B<false>
 +
 +Stops connections from falling back to unsecured if an SSL connection
 +cannot be established. Defaults to false if undeclared.
 +
 +=item B<VerifyPeer> I<true>|I<false>
 +
 +If set to true, requires a CAPath be provided. Will use the CAPath to find
 +certificates to use as Trusted Certificates to validate a upsd server certificate.
 +If validation of the upsd server certificate fails, the connection will not be
 +established. If ForceSSL is undeclared or set to false, setting VerifyPeer to true
 +will override and set ForceSSL to true.
 +
 +=item B<CAPath> I/path/to/certs/folder
 +
 +If VerifyPeer is set to true, this is required. Otherwise this is ignored.
 +The folder pointed at must contain certificate(s) named according to their hash.
 +Ex: XXXXXXXX.Y where X is the hash value of a cert and Y is 0. If name collisions
 +occur because two different certs have the same hash value, Y can be  incremented
 +in order to avoid conflict. To create a symbolic link to a certificate the following
 +command can be used from within the directory where the cert resides:
 +
 +C<ln -s some.crt ./$(openssl x509 -hash -noout -in some.crt).0>
 +
 +Alternatively, the package openssl-perl provides a command C<c_rehash> that will
 +generate links like the one described above for ALL certs in a given folder.
 +Example usage:
 +C<c_rehash /path/to/certs/folder>
 +
  =back
  
  =head2 Plugin C<olsrd>
@@@ -5422,8 -5239,6 +5422,8 @@@ C</10.F10FCA000800/temperature>). B<Ign
  As there can be multiple devices on the bus you can list multiple sensor (use
  multiple B<Sensor> elements).
  
 +See F</"IGNORELISTS"> for details.
 +
  =item B<IgnoreSelected> I<true>|I<false>
  
  If no configuration is given, the B<onewire> plugin will collect data from all
@@@ -5661,8 -5476,7 +5661,8 @@@ B<Synopsis:
     Address "127.0.0.1"
     Socket "/var/run/openvswitch/db.sock"
     Interfaces "br0" "veth0"
 -   SendNotification false
 +   SendNotification true
 +   DispatchValues false
   </Plugin>
  
  The plugin provides the following configuration options:
@@@ -5700,13 -5514,7 +5700,13 @@@ Default: empty (all interfaces on all b
  =item B<SendNotification> I<true|false>
  
  If set to true, OVS link notifications (interface status and OVS DB connection
 -terminate) are sent to collectd. Default value is false.
 +terminate) are sent to collectd. Default value is true.
 +
 +=item B<DispatchValues> I<true|false>
 +
 +Dispatch the OVS DB interface link status value with configured plugin interval.
 +Defaults to false. Please note, if B<SendNotification> and B<DispatchValues>
 +options are false, no OVS information will be provided by the plugin.
  
  =back
  
@@@ -5716,54 -5524,6 +5716,54 @@@ use B<Interval> option of the OVS B<Loa
  simple divide the time by 1000 for example if the desired interval is 50ms, set
  interval to 0.05.
  
 +=head2 Plugin C<ovs_stats>
 +
 +The I<ovs_stats> plugin collects statistics of OVS connected interfaces.
 +This plugin uses OVSDB management protocol (RFC7047) monitor mechanism to get
 +statistics from OVSDB
 +
 +B<Synopsis:>
 +
 + <Plugin "ovs_stats">
 +   Port 6640
 +   Address "127.0.0.1"
 +   Socket "/var/run/openvswitch/db.sock"
 +   Bridges "br0" "br_ext"
 + </Plugin>
 +
 +The plugin provides the following configuration options:
 +
 +=over 4
 +
 +=item B<Address> I<node>
 +
 +The address of the OVS DB server JSON-RPC interface used by the plugin. To
 +enable the interface, OVS DB daemon should be running with C<--remote=ptcp:>
 +option. See L<ovsdb-server(1)> for more details. The option may be either
 +network hostname, IPv4 numbers-and-dots notation or IPv6 hexadecimal string
 +format. Defaults to B<'localhost'>.
 +
 +=item B<Port> I<service>
 +
 +TCP-port to connect to. Either a service name or a port number may be given.
 +Defaults to B<6640>.
 +
 +=item B<Socket> I<path>
 +
 +The UNIX domain socket path of OVS DB server JSON-RPC interface used by the
 +plugin. To enable the interface, the OVS DB daemon should be running with
 +C<--remote=punix:> option. See L<ovsdb-server(1)> for more details. If this
 +option is set, B<Address> and B<Port> options are ignored.
 +
 +=item B<Bridges> [I<brname> ...]
 +
 +List of OVS bridge names to be monitored by this plugin. If this option is
 +omitted or is empty then all OVS bridges will be monitored.
 +
 +Default: empty (monitor all bridges)
 +
 +=back
 +
  =head2 Plugin C<perl>
  
  This plugin embeds a Perl-interpreter into collectd and provides an interface
@@@ -5865,10 -5625,10 +5865,10 @@@ multiple hosts
  =item B<Interval> I<Seconds>
  
  Sets the interval in which to send ICMP echo packets to the configured hosts.
 -This is B<not> the interval in which statistics are queries from the plugin but
 -the interval in which the hosts are "pinged". Therefore, the setting here
 -should be smaller than or equal to the global B<Interval> setting. Fractional
 -times, such as "1.24" are allowed.
 +This is B<not> the interval in which metrics are read from the plugin but the
 +interval in which the hosts are "pinged". Therefore, the setting here should be
 +smaller than or equal to the global B<Interval> setting. Fractional times, such
 +as "1.24" are allowed.
  
  Default: B<1.0>
  
@@@ -6552,15 -6312,9 +6552,15 @@@ C<I<prefix>/var/run/collectd-powerdns>
  =item B<Process> I<Name>
  
  Select more detailed statistics of processes matching this name. The statistics
 -collected for these selected processes are size of the resident segment size
 -(RSS), user- and system-time used, number of processes and number of threads,
 -io data (where available) and minor and major pagefaults.
 +collected for these selected processes are:
 + - size of the resident segment size (RSS)
 + - user- and system-time used
 + - number of processes
 + - number of threads
 + - number of open files (under Linux)
 + - io data (where available)
 + - context switches (under Linux)
 + - minor and major pagefaults.
  
  Some platforms have a limit on the length of process names. I<Name> must stay
  below this limit.
@@@ -6606,8 -6360,6 +6606,8 @@@ Whether only matched values are selecte
  depends on the B<IgnoreSelected>. By default, only matched values are selected.
  If no value is configured at all, all values will be selected.
  
 +See F</"IGNORELISTS"> for details.
 +
  =item B<IgnoreSelected> B<true>|B<false>
  
  If set to B<true>, inverts the selection made by B<Value>, i.E<nbsp>e. all
@@@ -7036,8 -6788,6 +7036,8 @@@ on the B<IgnoreSelected> below. For exa
  I<it8712-isa-0290/voltage-in1>" will cause collectd to gather data for the
  voltage sensor I<in1> of the I<it8712> on the isa bus at the address 0290.
  
 +See F</"IGNORELISTS"> for details.
 +
  =item B<IgnoreSelected> I<true>|I<false>
  
  If no configuration if given, the B<sensors>-plugin will collect data from all
@@@ -7147,8 -6897,6 +7147,8 @@@ is interpreted as a regular expression
    Disk "sdd"
    Disk "/hda[34]/"
  
 +See F</"IGNORELISTS"> for details.
 +
  =item B<IgnoreSelected> B<true>|B<false>
  
  Sets whether selected disks, i.E<nbsp>e. the ones matches by any of the B<Disk>
@@@ -7182,6 -6930,115 +7182,115 @@@ Since the configuration of the C<snmp p
  other plugins, its documentation has been moved to an own manpage,
  L<collectd-snmp(5)>. Please see there for details.
  
+ =head2 Plugin C<snmp_agent>
+ The I<snmp_agent> plugin is an AgentX subagent that receives and handles queries
+ from SNMP master agent and returns the data collected by read plugins.
+ The I<snmp_agent> plugin handles requests only for OIDs specified in
+ configuration file. To handle SNMP queries the plugin gets data from collectd
+ and translates requested values from collectd's internal format to SNMP format.
+ This plugin is a generic plugin and cannot work without configuration.
+ For more details on AgentX subagent see
+ <http://www.net-snmp.org/tutorial/tutorial-5/toolkit/demon/>
+ B<Synopsis:>
+   <Plugin snmp_agent>
+     <Data "memAvailReal">
+       Plugin "memory"
+       Type "memory"
+       TypeInstance "free"
+       OIDs "1.3.6.1.4.1.2021.4.6.0"
+     </Data>
+     <Table "ifTable">
+       IndexOID "IF-MIB::ifIndex"
+       SizeOID "IF-MIB::ifNumber"
+       <Data "ifDescr">
+         Instance true
+         Plugin "interface"
+         OIDs "IF-MIB::ifDescr"
+       </Data>
+       <Data "ifOctets">
+         Plugin "interface"
+         Type "if_octets"
+         TypeInstance ""
+         OIDs "IF-MIB::ifInOctets" "IF-MIB::ifOutOctets"
+       </Data>
+     </Table>
+   </Plugin>
+ There are two types of blocks that can be contained in the
+ C<E<lt>PluginE<nbsp> snmp_agentE<gt>> block: B<Data> and B<Table>:
+ =head3 The B<Data> block
+ The B<Data> block defines a list OIDs that are to be handled. This block can
+ define scalar or table OIDs. If B<Data> block is defined inside of B<Table>
+ block it reperesents table OIDs.
+ The following options can be set:
+ =over 4
+ =item B<Instance> I<true|false>
+ When B<Instance> is set to B<true>, the value for requested OID is copied from
+ plugin instance field of corresponding collectd value. If B<Data> block defines
+ scalar data type B<Instance> has no effect and can be omitted.
+ =item B<Plugin> I<String>
+ Read plugin name whose collected data will be mapped to specified OIDs.
+ =item B<Type> I<String>
+ Collectd's type that is to be used for specified OID, e.E<nbsp>g. "if_octets"
+ for example. The types are read from the B<TypesDB> (see L<collectd.conf(5)>).
+ =item B<TypeInstance> I<String>
+ Collectd's type-instance that is to be used for specified OID.
+ =item B<OIDs> I<OID> [I<OID> ...]
+ Configures the OIDs to be handled by I<snmp_agent> plugin. Values for these OIDs
+ are taken from collectd data type specified by B<Plugin>, B<Type>,
+ B<TypeInstance> fields of this B<Data> block. Number of the OIDs configured
+ should correspond to number of values in specified B<Type>.
+ For example two OIDs "IF-MIB::ifInOctets" "IF-MIB::ifOutOctets" can be mapped to
+ "rx" and "tx" values of "if_octets" type.
+ =item B<Scale> I<Value>
+ The values taken from collectd are multiplied by I<Value>. The field is optional
+ and the default is B<1.0>.
+ =item B<Shift> I<Value>
+ I<Value> is added to values from collectd after they have been multiplied by
+ B<Scale> value. The field is optional and the default value is B<0.0>.
+ =back
+ =head3 The B<Table> block
+ The B<Table> block defines a collection of B<Data> blocks that belong to one
+ snmp table. In addition to multiple B<Data> blocks the following options can be
+ set:
+ =over 4
+ =item B<IndexOID> I<OID>
+ OID that is handled by the plugin and is mapped to numerical index value that is
+ generated by the plugin for each table record.
+ =item B<SizeOID> I<OID>
+ OID that is handled by the plugin. Returned value is the number of records in
+ the table. The field is optional.
+ =back
  =head2 Plugin C<statsd>
  
  The I<statsd plugin> listens to a UDP socket, reads "events" in the statsd
@@@ -7836,8 -7693,6 +7945,8 @@@ Selects the name of the thermal device 
  depending on the value of the B<IgnoreSelected> option. This option may be
  used multiple times to specify a list of devices.
  
 +See F</"IGNORELISTS"> for details.
 +
  =item B<IgnoreSelected> I<true>|I<false>
  
  Invert the selection: If set to true, all devices B<except> the ones that
@@@ -8178,11 -8033,11 +8287,11 @@@ Collect statistics about worker threads
  
  =head2 Plugin C<virt>
  
 -This plugin allows CPU, disk and network load to be collected for virtualized
 -guests on the machine. This means that these metrics can be collected for guest
 -systems without installing any software on them - I<collectd> only runs on the
 -host system. The statistics are collected through libvirt
 -(L<http://libvirt.org/>).
 +This plugin allows CPU, disk, network load and other metrics to be collected for
 +virtualized guests on the machine. The statistics are collected through libvirt
 +API (L<http://libvirt.org/>). Majority of metrics can be gathered without
 +installing any additional software on guests, especially I<collectd>, which runs
 +only on the host system.
  
  Only I<Connection> is required.
  
@@@ -8326,55 -8181,6 +8435,55 @@@ How many read instances you want to us
  and the sensible setting is a multiple of the B<ReadThreads> value.
  If you are not sure, just use the default setting.
  
 +=item B<ExtraStats> B<string>
 +
 +Report additional extra statistics. The default is no extra statistics, preserving
 +the previous behaviour of the plugin. If unsure, leave the default. If enabled,
 +allows the plugin to reported more detailed statistics about the behaviour of
 +Virtual Machines. The argument is a space-separated list of selectors.
 +
 +Currently supported selectors are:
 +
 +=over 4
 +
 +=item B<cpu_util>: report CPU utilization per domain in percentage.
 +
 +=item B<disk>: report extra statistics like number of flush operations and total
 +service time for read, write and flush operations. Requires libvirt API version
 +I<0.9.5> or later.
 +
 +=item B<disk_err>: report disk errors if any occured. Requires libvirt API version
 +I<0.9.10> or later.
 +
 +=item B<domain_state>: report domain state and reason in human-readable format as
 +a notification. If libvirt API version I<0.9.2> or later is available, domain
 +reason will be included in notification.
 +
 +=item B<fs_info>: report file system information as a notification. Requires
 +libvirt API version I<1.2.11> or later. Can be collected only if I<Guest Agent>
 +is installed and configured inside VM. Make sure that installed I<Guest Agent>
 +version supports retrieving  file system information.
 +
 +=item B<job_stats_background>: report statistics about progress of a background
 +job on a domain. Only one type of job statistics can be collected at the same time.
 +Requires libvirt API version I<1.2.9> or later.
 +
 +=item B<job_stats_completed>: report statistics about a recently completed job on
 +a domain. Only one type of job statistics can be collected at the same time.
 +Requires libvirt API version I<1.2.9> or later.
 +
 +=item B<pcpu>: report the physical user/system cpu time consumed by the hypervisor, per-vm.
 +Requires libvirt API version I<0.9.11> or later.
 +
 +=item B<perf>: report performance monitoring events. To collect performance
 +metrics they must be enabled for domain and supported by the platform. Requires
 +libvirt API version I<1.3.3> or later.
 +B<Note>: I<perf> metrics can't be collected if I<intel_rdt> plugin is enabled.
 +
 +=item B<vcpupin>: report pinning of domain VCPUs to host physical CPUs.
 +
 +=back
 +
  =back
  
  =head2 Plugin C<vmem>
@@@ -8801,23 -8607,6 +8910,23 @@@ create output in the I<JavaScript Objec
  
  Defaults to B<Command>.
  
 +=item B<Attribute> I<String> I<String>
 +
 +Only available for the KAIROSDB output format.
 +
 +Consider the two given strings to be the key and value of an additional tag for
 +each metric being sent out.
 +
 +You can add multiple B<Attribute>.
 +
 +=item B<TTL> I<Int>
 +
 +Only available for the KAIROSDB output format.
 +
 +Sets the Cassandra ttl for the data points.
 +
 +Please refer to L<http://kairosdb.github.io/docs/build/html/restapi/AddDataPoints.html?highlight=ttl>
 +
  =item B<Metrics> B<true>|B<false>
  
  Controls whether I<metrics> are POSTed to this location. Defaults to B<true>.
@@@ -10305,48 -10094,6 +10414,48 @@@ be an FQDN
     Target "write"
   </Chain>
  
 +=head1 IGNORELISTS
 +
 +B<Ignorelists> are a generic framework to either ignore some metrics or report
 +specific metircs only. Plugins usually provide one or more options to specify
 +the items (mounts points, devices, ...) and the boolean option
 +C<IgnoreSelected>.
 +
 +=over 4
 +
 +=item B<Select> I<String>
 +
 +Selects the item I<String>. This option often has a plugin specific name, e.g.
 +B<Sensor> in the C<sensors> plugin. It is also plugin specific what this string
 +is compared to. For example, the C<df> plugin's B<MountPoint> compares it to a
 +mount point and the C<sensors> plugin's B<Sensor> compares it to a sensor name.
 +
 +By default, this option is doing a case-sensitive full-string match. The
 +following config will match C<foo>, but not C<Foo>:
 +
 +  Select "foo"
 +
 +If I<String> starts and ends with C</> (a slash), the string is compiled as a
 +I<regular expression>. For example, so match all item starting with C<foo>, use
 +could use the following syntax:
 +
 +  Select "/^foo/"
 +
 +The regular expression is I<not> anchored, i.e. the following config will match
 +C<foobar>, C<barfoo> and C<AfooZ>:
 +
 +  Select "/foo/"
 +
 +The B<Select> option may be repeated to select multiple items.
 +
 +=item B<IgnoreSelected> B<true>|B<false>
 +
 +If set to B<true>, matching metrics are I<ignored> and all other metrics are
 +collected. If set to B<false>, matching metrics are I<collected> and all other
 +metrics are ignored.
 +
 +=back
 +
  =head1 SEE ALSO
  
  L<collectd(1)>,
@@@ -94,12 -94,12 +94,12 @@@ static int calc_height(c_avl_node_t *n
    int height_right;
  
    if (n == NULL)
 -    return (0);
 +    return 0;
  
    height_left = (n->left == NULL) ? 0 : n->left->height;
    height_right = (n->right == NULL) ? 0 : n->right->height;
  
 -  return (((height_left > height_right) ? height_left : height_right) + 1);
 +  return ((height_left > height_right) ? height_left : height_right) + 1;
  } /* int calc_height */
  
  static c_avl_node_t *search(c_avl_tree_t *t, const void *key) {
    while (n != NULL) {
      cmp = t->compare(key, n->key);
      if (cmp == 0)
 -      return (n);
 +      return n;
      else if (cmp < 0)
        n = n->left;
      else
        n = n->right;
    }
  
 -  return (NULL);
 +  return NULL;
  }
  
  /*         (x)             (y)
@@@ -159,7 -159,7 +159,7 @@@ static c_avl_node_t *rotate_right(c_avl
    x->height = calc_height(x);
    y->height = calc_height(y);
  
 -  return (y);
 +  return y;
  } /* void rotate_right */
  
  /*
@@@ -202,17 -202,17 +202,17 @@@ static c_avl_node_t *rotate_left(c_avl_
    x->height = calc_height(x);
    y->height = calc_height(y);
  
 -  return (y);
 +  return y;
  } /* void rotate_left */
  
  static c_avl_node_t *rotate_left_right(c_avl_tree_t *t, c_avl_node_t *x) {
    rotate_left(t, x->left);
 -  return (rotate_right(t, x));
 +  return rotate_right(t, x);
  } /* void rotate_left_right */
  
  static c_avl_node_t *rotate_right_left(c_avl_tree_t *t, c_avl_node_t *x) {
    rotate_right(t, x->right);
 -  return (rotate_left(t, x));
 +  return rotate_left(t, x);
  } /* void rotate_right_left */
  
  static void rebalance(c_avl_tree_t *t, c_avl_node_t *n) {
@@@ -256,7 -256,7 +256,7 @@@ static c_avl_node_t *c_avl_node_next(c_
    c_avl_node_t *r; /* return node */
  
    if (n == NULL) {
 -    return (NULL);
 +    return NULL;
    }
  
    /* If we can't descent any further, we have to backtrack to the first
       * r->left != n => r->right = n => r->parent == NULL */
      if ((r == NULL) || (r->left != n)) {
        assert((r == NULL) || (r->parent == NULL));
 -      return (NULL);
 +      return NULL;
      } else {
        assert(r->left == n);
 -      return (r);
 +      return r;
      }
    } else {
      r = n->right;
        r = r->left;
    }
  
 -  return (r);
 +  return r;
  } /* c_avl_node_t *c_avl_node_next */
  
  static c_avl_node_t *c_avl_node_prev(c_avl_node_t *n) {
    c_avl_node_t *r; /* return node */
  
    if (n == NULL) {
 -    return (NULL);
 +    return NULL;
    }
  
    /* If we can't descent any further, we have to backtrack to the first
       * r->right != n => r->left = n => r->parent == NULL */
      if ((r == NULL) || (r->right != n)) {
        assert((r == NULL) || (r->parent == NULL));
 -      return (NULL);
 +      return NULL;
      } else {
        assert(r->right == n);
 -      return (r);
 +      return r;
      }
    } else {
      r = n->left;
        r = r->right;
    }
  
 -  return (r);
 +  return r;
  } /* c_avl_node_t *c_avl_node_prev */
  
  static int _remove(c_avl_tree_t *t, c_avl_node_t *n) {
      assert(0);
    }
  
 -  return (0);
 +  return 0;
  } /* void *_remove */
  
  /*
@@@ -419,16 -419,16 +419,16 @@@ c_avl_tree_t *c_avl_create(int (*compar
    c_avl_tree_t *t;
  
    if (compare == NULL)
 -    return (NULL);
 +    return NULL;
  
    if ((t = malloc(sizeof(*t))) == NULL)
 -    return (NULL);
 +    return NULL;
  
    t->root = NULL;
    t->compare = compare;
    t->size = 0;
  
 -  return (t);
 +  return t;
  }
  
  void c_avl_destroy(c_avl_tree_t *t) {
@@@ -444,7 -444,7 +444,7 @@@ int c_avl_insert(c_avl_tree_t *t, void 
    int cmp;
  
    if ((new = malloc(sizeof(*new))) == NULL)
 -    return (-1);
 +    return -1;
  
    new->key = key;
    new->value = value;
      new->parent = NULL;
      t->root = new;
      t->size = 1;
 -    return (0);
 +    return 0;
    }
  
    nptr = t->root;
      cmp = t->compare(nptr->key, new->key);
      if (cmp == 0) {
        free_node(new);
 -      return (1);
 +      return 1;
      } else if (cmp < 0) {
        /* nptr < new */
        if (nptr->right == NULL) {
  
    verify_tree(t->root);
    ++t->size;
 -  return (0);
 +  return 0;
  } /* int c_avl_insert */
  
  int c_avl_remove(c_avl_tree_t *t, const void *key, void **rkey, void **rvalue) {
  
    n = search(t, key);
    if (n == NULL)
 -    return (-1);
 +    return -1;
  
    if (rkey != NULL)
      *rkey = n->key;
    status = _remove(t, n);
    verify_tree(t->root);
    --t->size;
 -  return (status);
 +  return status;
  } /* void *c_avl_remove */
  
  int c_avl_get(c_avl_tree_t *t, const void *key, void **value) {
  
    n = search(t, key);
    if (n == NULL)
 -    return (-1);
 +    return -1;
  
    if (value != NULL)
      *value = n->value;
  
 -  return (0);
 +  return 0;
  }
  
  int c_avl_pick(c_avl_tree_t *t, void **key, void **value) {
    c_avl_node_t *n;
    c_avl_node_t *p;
  
+   assert(t != NULL);
    if ((key == NULL) || (value == NULL))
 -    return (-1);
 +    return -1;
    if (t->root == NULL)
 -    return (-1);
 +    return -1;
  
    n = t->root;
    while ((n->left != NULL) || (n->right != NULL)) {
    --t->size;
    rebalance(t, p);
  
 -  return (0);
 +  return 0;
  } /* int c_avl_pick */
  
  c_avl_iterator_t *c_avl_get_iterator(c_avl_tree_t *t) {
    c_avl_iterator_t *iter;
  
    if (t == NULL)
 -    return (NULL);
 +    return NULL;
  
    iter = calloc(1, sizeof(*iter));
    if (iter == NULL)
 -    return (NULL);
 +    return NULL;
    iter->tree = t;
  
 -  return (iter);
 +  return iter;
  } /* c_avl_iterator_t *c_avl_get_iterator */
  
  int c_avl_iterator_next(c_avl_iterator_t *iter, void **key, void **value) {
    c_avl_node_t *n;
  
    if ((iter == NULL) || (key == NULL) || (value == NULL))
 -    return (-1);
 +    return -1;
  
    if (iter->node == NULL) {
      for (n = iter->tree->root; n != NULL; n = n->left)
    }
  
    if (n == NULL)
 -    return (-1);
 +    return -1;
  
    iter->node = n;
    *key = n->key;
    *value = n->value;
  
 -  return (0);
 +  return 0;
  } /* int c_avl_iterator_next */
  
  int c_avl_iterator_prev(c_avl_iterator_t *iter, void **key, void **value) {
    c_avl_node_t *n;
  
    if ((iter == NULL) || (key == NULL) || (value == NULL))
 -    return (-1);
 +    return -1;
  
    if (iter->node == NULL) {
      for (n = iter->tree->root; n != NULL; n = n->left)
    }
  
    if (n == NULL)
 -    return (-1);
 +    return -1;
  
    iter->node = n;
    *key = n->key;
    *value = n->value;
  
 -  return (0);
 +  return 0;
  } /* int c_avl_iterator_prev */
  
  void c_avl_iterator_destroy(c_avl_iterator_t *iter) { free(iter); }
  
  int c_avl_size(c_avl_tree_t *t) {
    if (t == NULL)
 -    return (0);
 -  return (t->size);
 +    return 0;
 +  return t->size;
  }
diff --combined src/daemon/utils_cache.c
@@@ -83,7 -83,7 +83,7 @@@ static int cache_compare(const cache_en
  #if COLLECT_DEBUG
    assert((a != NULL) && (b != NULL));
  #endif
 -  return (strcmp(a->name, b->name));
 +  return strcmp(a->name, b->name);
  } /* int cache_compare */
  
  static cache_entry_t *cache_alloc(size_t values_num) {
@@@ -92,7 -92,7 +92,7 @@@
    ce = calloc(1, sizeof(*ce));
    if (ce == NULL) {
      ERROR("utils_cache: cache_alloc: calloc failed.");
 -    return (NULL);
 +    return NULL;
    }
    ce->values_num = values_num;
  
      sfree(ce->values_raw);
      sfree(ce);
      ERROR("utils_cache: cache_alloc: calloc failed.");
 -    return (NULL);
 +    return NULL;
    }
  
    ce->history = NULL;
    ce->history_length = 0;
    ce->meta = NULL;
  
 -  return (ce);
 +  return ce;
  } /* cache_entry_t *cache_alloc */
  
  static void cache_free(cache_entry_t *ce) {
@@@ -148,14 -148,14 +148,14 @@@ static int uc_insert(const data_set_t *
    key_copy = strdup(key);
    if (key_copy == NULL) {
      ERROR("uc_insert: strdup failed.");
 -    return (-1);
 +    return -1;
    }
  
    ce = cache_alloc(ds->ds_num);
    if (ce == NULL) {
      sfree(key_copy);
      ERROR("uc_insert: cache_alloc (%zu) failed.", ds->ds_num);
 -    return (-1);
 +    return -1;
    }
  
    sstrncpy(ce->name, key, sizeof(ce->name));
              ds->ds[i].type);
        sfree(key_copy);
        cache_free(ce);
 -      return (-1);
 +      return -1;
      } /* switch (ds->ds[i].type) */
    }   /* for (i) */
  
    if (c_avl_insert(cache_tree, key_copy, ce) != 0) {
      sfree(key_copy);
      ERROR("uc_insert: c_avl_insert failed.");
 -    return (-1);
 +    return -1;
    }
  
    DEBUG("uc_insert: Added %s to the cache.", key);
 -  return (0);
 +  return 0;
  } /* int uc_insert */
  
  int uc_init(void) {
      cache_tree =
          c_avl_create((int (*)(const void *, const void *))cache_compare);
  
 -  return (0);
 +  return 0;
  } /* int uc_init */
  
  int uc_check_timeout(void) {
  
    if (expired_num == 0) {
      sfree(expired);
 -    return (0);
 +    return 0;
    }
  
    /* Call the "missing" callback for each value. Do this before removing the
    pthread_mutex_unlock(&cache_lock);
  
    sfree(expired);
 -  return (0);
 +  return 0;
  } /* int uc_check_timeout */
  
  int uc_update(const data_set_t *ds, const value_list_t *vl) {
  
    if (FORMAT_VL(name, sizeof(name), vl) != 0) {
      ERROR("uc_update: FORMAT_VL failed.");
 -    return (-1);
 +    return -1;
    }
  
    pthread_mutex_lock(&cache_lock);
    {
      status = uc_insert(ds, vl, name);
      pthread_mutex_unlock(&cache_lock);
 -    return (status);
 +    return status;
    }
  
    assert(ce != NULL);
             "last cache update = %.3f;",
             name, CDTIME_T_TO_DOUBLE(vl->time),
             CDTIME_T_TO_DOUBLE(ce->last_time));
 -    return (-1);
 +    return -1;
    }
  
    for (size_t i = 0; i < ds->ds_num; i++) {
        pthread_mutex_unlock(&cache_lock);
        ERROR("uc_update: Don't know how to handle data source type %i.",
              ds->ds[i].type);
 -      return (-1);
 +      return -1;
      } /* switch (ds->ds[i].type) */
  
      DEBUG("uc_update: %s: ds[%zu] = %lf", name, i, ce->values_gauge[i]);
  
    pthread_mutex_unlock(&cache_lock);
  
 -  return (0);
 +  return 0;
  } /* int uc_update */
  
  int uc_get_rate_by_name(const char *name, gauge_t **ret_values,
      *ret_values_num = ret_num;
    }
  
 -  return (status);
 +  return status;
  } /* gauge_t *uc_get_rate_by_name */
  
  gauge_t *uc_get_rate(const data_set_t *ds, const value_list_t *vl) {
  
    if (FORMAT_VL(name, sizeof(name), vl) != 0) {
      ERROR("utils_cache: uc_get_rate: FORMAT_VL failed.");
 -    return (NULL);
 +    return NULL;
    }
  
    status = uc_get_rate_by_name(name, &ret, &ret_num);
    if (status != 0)
 -    return (NULL);
 +    return NULL;
  
    /* This is important - the caller has no other way of knowing how many
     * values are returned. */
            "but uc_get_rate_by_name returned %zu.",
            ds->type, ds->ds_num, ret_num);
      sfree(ret);
 -    return (NULL);
 +    return NULL;
    }
  
 -  return (ret);
 +  return ret;
  } /* gauge_t *uc_get_rate */
  
+ int uc_get_value_by_name(const char *name, value_t **ret_values,
+                          size_t *ret_values_num) {
+   value_t *ret = NULL;
+   size_t ret_num = 0;
+   cache_entry_t *ce = NULL;
+   int status = 0;
+   pthread_mutex_lock(&cache_lock);
+   if (c_avl_get(cache_tree, name, (void *) &ce) == 0) {
+     assert(ce != NULL);
+     /* remove missing values from getval */
+     if (ce->state == STATE_MISSING) {
+       status = -1;
+     } else {
+       ret_num = ce->values_num;
+       ret = malloc(ret_num * sizeof(*ret));
+       if (ret == NULL) {
+         ERROR("utils_cache: uc_get_value_by_name: malloc failed.");
+         status = -1;
+       } else {
+         memcpy(ret, ce->values_raw, ret_num * sizeof(value_t));
+       }
+     }
+   }
+   else {
+     DEBUG("utils_cache: uc_get_value_by_name: No such value: %s", name);
+     status = -1;
+   }
+   pthread_mutex_unlock(&cache_lock);
+   if (status == 0) {
+     *ret_values = ret;
+     *ret_values_num = ret_num;
+   }
+   return (status);
+ } /* int uc_get_value_by_name */
+ value_t *uc_get_value(const data_set_t *ds, const value_list_t *vl) {
+   char name[6 * DATA_MAX_NAME_LEN];
+   value_t *ret = NULL;
+   size_t ret_num = 0;
+   int status;
+   if (FORMAT_VL(name, sizeof(name), vl) != 0) {
+     ERROR("utils_cache: uc_get_value: FORMAT_VL failed.");
+     return (NULL);
+   }
+   status = uc_get_value_by_name(name, &ret, &ret_num);
+   if (status != 0)
+     return (NULL);
+   /* This is important - the caller has no other way of knowing how many
+    * values are returned. */
+   if (ret_num != (size_t) ds->ds_num) {
+     ERROR("utils_cache: uc_get_value: ds[%s] has %zu values, "
+           "but uc_get_value_by_name returned %zu.", ds->type, ds->ds_num,
+           ret_num);
+     sfree(ret);
+     return (NULL);
+   }
+   return (ret);
+ } /* value_t *uc_get_value */
  size_t uc_get_size(void) {
    size_t size_arrays = 0;
  
    size_arrays = (size_t)c_avl_size(cache_tree);
    pthread_mutex_unlock(&cache_lock);
  
 -  return (size_arrays);
 +  return size_arrays;
  }
  
  int uc_get_names(char ***ret_names, cdtime_t **ret_times, size_t *ret_number) {
    int status = 0;
  
    if ((ret_names == NULL) || (ret_number == NULL))
 -    return (-1);
 +    return -1;
  
    pthread_mutex_lock(&cache_lock);
  
      /* Handle the "no values" case here, to avoid the error message when
       * calloc() returns NULL. */
      pthread_mutex_unlock(&cache_lock);
 -    return (0);
 +    return 0;
    }
  
    names = calloc(size_arrays, sizeof(*names));
      sfree(names);
      sfree(times);
      pthread_mutex_unlock(&cache_lock);
 -    return (ENOMEM);
 +    return ENOMEM;
    }
  
    iter = c_avl_get_iterator(cache_tree);
      sfree(names);
      sfree(times);
  
 -    return (-1);
 +    return -1;
    }
  
    *ret_names = names;
      sfree(times);
    *ret_number = number;
  
 -  return (0);
 +  return 0;
  } /* int uc_get_names */
  
  int uc_get_state(const data_set_t *ds, const value_list_t *vl) {
  
    if (FORMAT_VL(name, sizeof(name), vl) != 0) {
      ERROR("uc_get_state: FORMAT_VL failed.");
 -    return (STATE_ERROR);
 +    return STATE_ERROR;
    }
  
    pthread_mutex_lock(&cache_lock);
  
    pthread_mutex_unlock(&cache_lock);
  
 -  return (ret);
 +  return ret;
  } /* int uc_get_state */
  
  int uc_set_state(const data_set_t *ds, const value_list_t *vl, int state) {
  
    if (FORMAT_VL(name, sizeof(name), vl) != 0) {
      ERROR("uc_set_state: FORMAT_VL failed.");
 -    return (STATE_ERROR);
 +    return STATE_ERROR;
    }
  
    pthread_mutex_lock(&cache_lock);
  
    pthread_mutex_unlock(&cache_lock);
  
 -  return (ret);
 +  return ret;
  } /* int uc_set_state */
  
  int uc_get_history_by_name(const char *name, gauge_t *ret_history,
    status = c_avl_get(cache_tree, name, (void *)&ce);
    if (status != 0) {
      pthread_mutex_unlock(&cache_lock);
 -    return (-ENOENT);
 +    return -ENOENT;
    }
  
    if (((size_t)ce->values_num) != num_ds) {
      pthread_mutex_unlock(&cache_lock);
 -    return (-EINVAL);
 +    return -EINVAL;
    }
  
    /* Check if there are enough values available. If not, increase the buffer
          realloc(ce->history, sizeof(*ce->history) * num_steps * ce->values_num);
      if (tmp == NULL) {
        pthread_mutex_unlock(&cache_lock);
 -      return (-ENOMEM);
 +      return -ENOMEM;
      }
  
      for (size_t i = ce->history_length * ce->values_num;
  
    pthread_mutex_unlock(&cache_lock);
  
 -  return (0);
 +  return 0;
  } /* int uc_get_history_by_name */
  
  int uc_get_history(const data_set_t *ds, const value_list_t *vl,
  
    if (FORMAT_VL(name, sizeof(name), vl) != 0) {
      ERROR("utils_cache: uc_get_history: FORMAT_VL failed.");
 -    return (-1);
 +    return -1;
    }
  
 -  return (uc_get_history_by_name(name, ret_history, num_steps, num_ds));
 +  return uc_get_history_by_name(name, ret_history, num_steps, num_ds);
  } /* int uc_get_history */
  
  int uc_get_hits(const data_set_t *ds, const value_list_t *vl) {
  
    if (FORMAT_VL(name, sizeof(name), vl) != 0) {
      ERROR("uc_get_hits: FORMAT_VL failed.");
 -    return (STATE_ERROR);
 +    return STATE_ERROR;
    }
  
    pthread_mutex_lock(&cache_lock);
  
    pthread_mutex_unlock(&cache_lock);
  
 -  return (ret);
 +  return ret;
  } /* int uc_get_hits */
  
  int uc_set_hits(const data_set_t *ds, const value_list_t *vl, int hits) {
  
    if (FORMAT_VL(name, sizeof(name), vl) != 0) {
      ERROR("uc_set_hits: FORMAT_VL failed.");
 -    return (STATE_ERROR);
 +    return STATE_ERROR;
    }
  
    pthread_mutex_lock(&cache_lock);
  
    pthread_mutex_unlock(&cache_lock);
  
 -  return (ret);
 +  return ret;
  } /* int uc_set_hits */
  
  int uc_inc_hits(const data_set_t *ds, const value_list_t *vl, int step) {
  
    if (FORMAT_VL(name, sizeof(name), vl) != 0) {
      ERROR("uc_inc_hits: FORMAT_VL failed.");
 -    return (STATE_ERROR);
 +    return STATE_ERROR;
    }
  
    pthread_mutex_lock(&cache_lock);
  
    pthread_mutex_unlock(&cache_lock);
  
 -  return (ret);
 +  return ret;
  } /* int uc_inc_hits */
  
  /*
@@@ -760,24 -829,24 +829,24 @@@ uc_iter_t *uc_get_iterator(void) 
  
    iter = (uc_iter_t *)calloc(1, sizeof(*iter));
    if (iter == NULL)
 -    return (NULL);
 +    return NULL;
  
    pthread_mutex_lock(&cache_lock);
  
    iter->iter = c_avl_get_iterator(cache_tree);
    if (iter->iter == NULL) {
      free(iter);
 -    return (NULL);
 +    return NULL;
    }
  
 -  return (iter);
 +  return iter;
  } /* uc_iter_t *uc_get_iterator */
  
  int uc_iterator_next(uc_iter_t *iter, char **ret_name) {
    int status;
  
    if (iter == NULL)
 -    return (-1);
 +    return -1;
  
    while ((status = c_avl_iterator_next(iter->iter, (void *)&iter->name,
                                         (void *)&iter->entry)) == 0) {
    if (status != 0) {
      iter->name = NULL;
      iter->entry = NULL;
 -    return (-1);
 +    return -1;
    }
  
    if (ret_name != NULL)
      *ret_name = iter->name;
  
 -  return (0);
 +  return 0;
  } /* int uc_iterator_next */
  
  void uc_iterator_destroy(uc_iter_t *iter) {
  
  int uc_iterator_get_time(uc_iter_t *iter, cdtime_t *ret_time) {
    if ((iter == NULL) || (iter->entry == NULL) || (ret_time == NULL))
 -    return (-1);
 +    return -1;
  
    *ret_time = iter->entry->last_time;
 -  return (0);
 +  return 0;
  } /* int uc_iterator_get_name */
  
  int uc_iterator_get_values(uc_iter_t *iter, value_t **ret_values,
                             size_t *ret_num) {
    if ((iter == NULL) || (iter->entry == NULL) || (ret_values == NULL) ||
        (ret_num == NULL))
 -    return (-1);
 +    return -1;
  
    *ret_values =
        calloc(iter->entry->values_num, sizeof(*iter->entry->values_raw));
    if (*ret_values == NULL)
 -    return (-1);
 +    return -1;
    for (size_t i = 0; i < iter->entry->values_num; ++i)
      *ret_values[i] = iter->entry->values_raw[i];
  
    *ret_num = iter->entry->values_num;
  
 -  return (0);
 +  return 0;
  } /* int uc_iterator_get_values */
  
  int uc_iterator_get_interval(uc_iter_t *iter, cdtime_t *ret_interval) {
    if ((iter == NULL) || (iter->entry == NULL) || (ret_interval == NULL))
 -    return (-1);
 +    return -1;
  
    *ret_interval = iter->entry->interval;
 -  return (0);
 +  return 0;
  } /* int uc_iterator_get_name */
  
  /*
@@@ -855,7 -924,7 +924,7 @@@ static meta_data_t *uc_get_meta(const v
    status = FORMAT_VL(name, sizeof(name), vl);
    if (status != 0) {
      ERROR("utils_cache: uc_get_meta: FORMAT_VL failed.");
 -    return (NULL);
 +    return NULL;
    }
  
    pthread_mutex_lock(&cache_lock);
    status = c_avl_get(cache_tree, name, (void *)&ce);
    if (status != 0) {
      pthread_mutex_unlock(&cache_lock);
 -    return (NULL);
 +    return NULL;
    }
    assert(ce != NULL);
  
    if (ce->meta == NULL)
      pthread_mutex_unlock(&cache_lock);
  
 -  return (ce->meta);
 +  return ce->meta;
  } /* }}} meta_data_t *uc_get_meta */
  
  /* Sorry about this preprocessor magic, but it really makes this file much
      int status;                                                                \
      meta = uc_get_meta(vl);                                                    \
      if (meta == NULL)                                                          \
 -      return (-1);                                                             \
 +      return -1;                                                               \
      status = wrap_function(meta, key);                                         \
      pthread_mutex_unlock(&cache_lock);                                         \
 -    return (status);                                                           \
 +    return status;                                                             \
    }
  int uc_meta_data_exists(const value_list_t *vl,
                          const char *key) UC_WRAP(meta_data_exists)
      int status;                                                                \
      meta = uc_get_meta(vl);                                                    \
      if (meta == NULL)                                                          \
 -      return (-1);                                                             \
 +      return -1;                                                               \
      status = wrap_function(meta, key, value);                                  \
      pthread_mutex_unlock(&cache_lock);                                         \
 -    return (status);                                                           \
 +    return status;                                                             \
    }
          int uc_meta_data_add_string(const value_list_t *vl, const char *key,
                                      const char *value)