Merge branch 'collectd-5.7'
authorRuben Kerkhof <ruben@rubenkerkhof.com>
Fri, 24 Feb 2017 16:28:56 +0000 (17:28 +0100)
committerRuben Kerkhof <ruben@rubenkerkhof.com>
Fri, 24 Feb 2017 16:28:56 +0000 (17:28 +0100)
216 files changed:
.gitignore
.travis.yml
AUTHORS
Makefile.am
README
bindings/Makefile.am [deleted file]
bindings/java/Makefile.am [deleted file]
bindings/java/org/collectd/java/GenericJMXConfValue.java
build.sh
clean.sh
configure.ac
contrib/README
contrib/docker/50docker-apt-conf [new file with mode: 0644]
contrib/docker/Dockerfile [new file with mode: 0644]
contrib/docker/collectd.conf [new file with mode: 0644]
contrib/docker/collectd.conf.d/sample.conf [new file with mode: 0644]
contrib/docker/rootfs_prefix/.gitignore [new file with mode: 0644]
contrib/docker/rootfs_prefix/Makefile [new file with mode: 0644]
contrib/docker/rootfs_prefix/rootfs_prefix.c [new file with mode: 0644]
contrib/redhat/collectd.spec
contrib/systemd.collectd.service
docs/BUILD.dpdkstat.md
docs/README.virt.md [new file with mode: 0644]
m4/.gitignore [new file with mode: 0644]
proto/Makefile.am [deleted file]
src/Makefile.am [deleted file]
src/aggregation.c
src/amqp.c
src/apache.c
src/apple_sensors.c
src/aquaero.c
src/ascent.c
src/battery_statefs.c
src/bind.c
src/ceph.c
src/ceph_test.c
src/collectd-tg.c
src/collectd.conf.in
src/collectd.conf.pod
src/collectdctl.c
src/collectdmon.c
src/cpu.c
src/curl.c
src/curl_json.c
src/curl_xml.c
src/daemon/Makefile.am [deleted file]
src/daemon/collectd.h
src/daemon/common.c
src/daemon/common_test.c
src/daemon/configfile.c
src/daemon/filter_chain.c
src/daemon/filter_chain.h
src/daemon/meta_data.c
src/daemon/meta_data.h
src/daemon/meta_data_test.c
src/daemon/plugin.c
src/daemon/plugin.h
src/daemon/plugin_mock.c
src/daemon/types_list.c
src/daemon/utils_avltree_test.c
src/daemon/utils_cache.c
src/daemon/utils_cache.h
src/daemon/utils_complain.c
src/daemon/utils_complain.h
src/daemon/utils_heap.c
src/daemon/utils_heap.h
src/daemon/utils_heap_test.c
src/daemon/utils_random.c
src/daemon/utils_random.h
src/daemon/utils_subst.c
src/daemon/utils_subst.h
src/daemon/utils_subst_test.c
src/daemon/utils_threshold.h
src/daemon/utils_time.c
src/daemon/utils_time.h
src/daemon/utils_time_test.c
src/dbi.c
src/disk.c
src/dpdkevents.c [new file with mode: 0644]
src/dpdkstat.c
src/email.c
src/ethstat.c
src/exec.c
src/filecount.c
src/fscache.c
src/gmond.c
src/grpc.cc
src/intel_rdt.c
src/ipc.c
src/ipmi.c
src/ipvs.c
src/java.c
src/libcollectdclient/Makefile.am [deleted file]
src/libcollectdclient/client.c
src/libcollectdclient/collectd/client.h
src/libcollectdclient/collectd/lcc_features.h.in
src/libcollectdclient/collectd/network.h
src/libcollectdclient/collectd/network_buffer.h
src/libcollectdclient/network.c
src/libcollectdclient/network_buffer.c
src/liboconfig/Makefile.am [deleted file]
src/liboconfig/oconfig.c
src/liboconfig/oconfig.h
src/log_logstash.c
src/logfile.c
src/lpar.c
src/lua.c
src/match_empty_counter.c
src/match_hashed.c
src/match_regex.c
src/match_timediff.c
src/match_value.c
src/mcelog.c [new file with mode: 0644]
src/memcachec.c
src/mic.c
src/modbus.c
src/mqtt.c
src/multimeter.c
src/netapp.c
src/netlink.c
src/network.c
src/nginx.c
src/notify_desktop.c
src/notify_email.c
src/notify_nagios.c
src/ntpd.c
src/numa.c
src/nut.c
src/olsrd.c
src/onewire.c
src/openvpn.c
src/oracle.c
src/ovs_events.c [new file with mode: 0644]
src/perl.c
src/pinba.c
src/ping.c
src/postgresql.c
src/powerdns.c
src/processes.c
src/protocols.c
src/redis.c
src/routeros.c
src/rrdcached.c
src/snmp.c
src/statsd.c
src/swap.c
src/table.c
src/tail.c
src/tail_csv.c
src/target_notification.c
src/target_replace.c
src/target_scale.c
src/target_set.c
src/target_v5upgrade.c
src/tcpconns.c
src/teamspeak2.c
src/ted.c
src/threshold.c
src/tokyotyrant.c
src/unixsock.c
src/utils_cmd_flush.c
src/utils_cmd_flush.h
src/utils_cmd_getthreshold.c
src/utils_cmd_getthreshold.h
src/utils_cmd_getval.c
src/utils_cmd_getval.h
src/utils_cmd_listval.c
src/utils_cmd_listval.h
src/utils_cmd_putnotif.c
src/utils_cmd_putnotif.h
src/utils_cmds.c
src/utils_db_query.c
src/utils_db_query.h
src/utils_dns.c
src/utils_dpdk.c [new file with mode: 0644]
src/utils_dpdk.h [new file with mode: 0644]
src/utils_fbhash.c
src/utils_fbhash.h
src/utils_format_graphite.c
src/utils_format_graphite_test.c
src/utils_format_json.c
src/utils_format_kairosdb.c
src/utils_latency.c
src/utils_latency.h
src/utils_latency_test.c
src/utils_lua.c
src/utils_lua.h
src/utils_match.c
src/utils_match.h
src/utils_mount_test.c
src/utils_ovs.c [new file with mode: 0644]
src/utils_ovs.h [new file with mode: 0644]
src/utils_parse_option.c
src/utils_parse_option.h
src/utils_rrdcreate.c
src/utils_rrdcreate.h
src/utils_tail_match.c
src/utils_tail_match.h
src/uuid.c
src/varnish.c
src/virt.c
src/virt_test.c [new file with mode: 0644]
src/vmem.c
src/vserver.c
src/write_graphite.c
src/write_http.c
src/write_log.c
src/write_mongodb.c
src/write_prometheus.c
src/write_redis.c
src/write_riemann.c
src/write_riemann_threshold.c
src/write_sensu.c
src/write_tsdb.c
src/xmms.c
src/zfs_arc.c

index 8154d73..2911069 100644 (file)
@@ -4,6 +4,7 @@ Makefile.in
 /aclocal.m4
 /autom4te.cache
 /autom4te.cache
+/build-aux/
 /compile
 /config.guess
 /config.sub
@@ -12,8 +13,15 @@ Makefile.in
 /install-sh
 /libltdl/
 /ltmain.sh
+/m4/libtool.m4
+/m4/ltargz.m4
+/m4/ltdl.m4
+/m4/lt~obsolete.m4
+/m4/ltoptions.m4
+/m4/ltsugar.m4
+/m4/ltversion.m4
 /missing
-src/config.h.in
+/src/config.h.in
 
 # configure stuff:
 Makefile
@@ -29,12 +37,13 @@ src/stamp-h1
 *.la
 *.lo
 *.o
+.dirstamp
 .libs/
 .deps/
-src/collectd-nagios
-src/collectd-tg
-src/collectdctl
-src/collectdmon
+/collectd-nagios
+/collectd-tg
+/collectdctl
+/collectdmon
 src/*.1
 src/*.5
 src/.pod2man.tmp.*
@@ -51,26 +60,28 @@ src/liboconfig/parser.h
 src/liboconfig/scanner.c
 
 # protobuf stuff:
-src/*.pb-c.[ch]
-src/*.grpc.pb.cc
-src/*.pb.cc
-src/*.pb.h
+*.pb-c.[ch]
+*.grpc.pb.cc
+*.pb.cc
+*.pb.h
 
 # make dist stuff:
 /collectd-*.tar.gz
 /collectd-*.tar.bz2
 
 # perl stuff:
-bindings/.perl-directory-stamp
+/.perl-directory-stamp
 bindings/perl/Collectd/pm_to_blib
 bindings/perl/blib/
 bindings/perl/pm_to_blib
-bindings/buildperl
+/buildperl
 
 # java stuff
-bindings/java/java-build-stamp
-bindings/java/org/collectd/api/*.class
-bindings/java/org/collectd/java/*.class
+*.jar
+/org/collectd/api/*.class
+/org/collectd/java/*.class
+/bindings/java/java-build-stamp
+/classnoinst.stamp
 
 # python stuff
 *.pyc
@@ -94,4 +105,4 @@ src/test-suite.log
 test_*
 
 # src/daemon/...
-src/daemon/collectd
+/collectd
index 03d9dde..fc250cb 100644 (file)
@@ -16,12 +16,15 @@ before_install:
       libganglia1-dev
       libgcrypt11-dev
       libglib2.0-dev
+      libgps-dev
       libhiredis-dev
       libi2c-dev
       libldap2-dev
       libltdl-dev
+      liblua5.2-dev
       liblvm2-dev
       libmemcached-dev
+      libmicrohttpd-dev
       libmnl-dev
       libmodbus-dev
       libmosquitto0-dev
@@ -53,4 +56,4 @@ before_install:
       perl
       protobuf-c-compiler
       python-dev
-script: sh build.sh && ./configure --with-python=/usr/bin/python && make distcheck DISTCHECK_CONFIGURE_FLAGS="--with-python=/usr/bin/python"
+script: sh build.sh && ./configure && make distcheck
diff --git a/AUTHORS b/AUTHORS
index 8962e77..d866c70 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -294,6 +294,9 @@ Sjoerd van der Berg <harekiet at gmail.com>
 Stefan Hacker <stefan.hacker at web.de>
  - teamspeak2 plugin.
 
+Steven Bell <stv.bell07 at gmail.com>
+ - nut plugin.
+
 Sven Trenkel <collectd at semidefinite.de>
  - netapp plugin.
  - python plugin.
index 03bdd39..efc16f7 100644 (file)
-ACLOCAL_AMFLAGS = -I libltdl/m4
+ACLOCAL_AMFLAGS = -I m4
+AM_YFLAGS = -d
 
-SUBDIRS =
 
-if BUILD_INCLUDED_LTDL
-SUBDIRS += libltdl
+BUILT_SOURCES = \
+       src/libcollectdclient/collectd/lcc_features.h \
+       src/liboconfig/parser.h \
+       $(dist_man_MANS)
+
+
+CLEANFILES = \
+       .perl-directory-stamp \
+       bindings/buildperl/Collectd.pm \
+       bindings/buildperl/Collectd/Plugins/OpenVZ.pm \
+       bindings/buildperl/Collectd/Unixsock.pm \
+       bindings/buildperl/Makefile.PL \
+       collectd-api.jar \
+       collectd.grpc.pb.cc \
+       collectd.grpc.pb.h \
+       collectd.pb.cc \
+       collectd.pb.h \
+       generic-jmx.jar \
+       org/collectd/api/*.class \
+       org/collectd/java/*.class \
+       prometheus.pb-c.c \
+       prometheus.pb-c.h \
+       src/pinba.pb-c.c \
+       src/pinba.pb-c.h \
+       types.pb.cc \
+       types.pb.h
+
+
+EXTRA_DIST = \
+       bindings/perl/Makefile.PL \
+       bindings/perl/lib/Collectd.pm \
+       bindings/perl/lib/Collectd/Plugins/Monitorus.pm \
+       bindings/perl/lib/Collectd/Plugins/OpenVZ.pm \
+       bindings/perl/lib/Collectd/Unixsock.pm \
+       bindings/perl/uninstall_mod.pl \
+       contrib \
+       proto/collectd.proto \
+       proto/prometheus.proto \
+       proto/types.proto \
+       src/collectd-email.pod \
+       src/collectd-exec.pod \
+       src/collectd-java.pod \
+       src/collectd-lua.pod \
+       src/collectd-nagios.pod \
+       src/collectd-perl.pod \
+       src/collectd-python.pod \
+       src/collectd-snmp.pod \
+       src/collectd-tg.pod \
+       src/collectd-threshold.pod \
+       src/collectd-unixsock.pod \
+       src/collectd.conf.pod \
+       src/collectd.pod \
+       src/collectdctl.pod \
+       src/collectdmon.pod \
+       src/pinba.proto \
+       src/postgresql_default.conf \
+       src/types.db \
+       src/types.db.pod \
+       src/valgrind.FreeBSD.suppress \
+       testwrapper.sh \
+       version-gen.sh
+
+
+dist_man_MANS = \
+       src/collectd.1 \
+       src/collectd.conf.5 \
+       src/collectd-email.5 \
+       src/collectd-exec.5 \
+       src/collectdctl.1 \
+       src/collectd-java.5 \
+       src/collectd-lua.5 \
+       src/collectdmon.1 \
+       src/collectd-nagios.1 \
+       src/collectd-perl.5 \
+       src/collectd-python.5 \
+       src/collectd-snmp.5 \
+       src/collectd-tg.1 \
+       src/collectd-threshold.5 \
+       src/collectd-unixsock.5 \
+       src/types.db.5
+
+
+nodist_pkgconfig_DATA = \
+       src/libcollectdclient/libcollectdclient.pc
+
+pkginclude_HEADERS = \
+       src/libcollectdclient/collectd/client.h \
+       src/libcollectdclient/collectd/network.h \
+       src/libcollectdclient/collectd/network_buffer.h \
+       src/libcollectdclient/collectd/lcc_features.h
+
+lib_LTLIBRARIES = libcollectdclient.la
+
+
+sbin_PROGRAMS = \
+       collectd \
+       collectdmon
+
+
+bin_PROGRAMS = \
+       collectd-nagios \
+       collectd-tg \
+       collectdctl
+
+
+noinst_LTLIBRARIES = \
+       libavltree.la \
+       libcmds.la \
+       libcommon.la \
+       libformat_graphite.la \
+       libformat_json.la \
+       libheap.la \
+       liblatency.la \
+       liblookup.la \
+       libmetadata.la \
+       libmount.la \
+       liboconfig.la \
+       libplugin_mock.la
+
+
+check_PROGRAMS = \
+       test_common \
+       test_format_graphite \
+       test_meta_data \
+       test_utils_avltree \
+       test_utils_cmds \
+       test_utils_heap \
+       test_utils_latency \
+       test_utils_mount \
+       test_utils_subst \
+       test_utils_time \
+       test_utils_vl_lookup
+
+
+TESTS = $(check_PROGRAMS)
+
+LOG_COMPILER = env VALGRIND="@VALGRIND@" $(abs_srcdir)/testwrapper.sh
+
+
+jardir = $(pkgdatadir)/java
+
+pkglib_LTLIBRARIES =
+
+
+PLUGIN_LDFLAGS = \
+       -module \
+       -avoid-version \
+       -export-symbols-regex '\<module_register\>'
+
+
+AM_CPPFLAGS = \
+       -I$(top_srcdir)/src -I$(top_srcdir)/src/daemon \
+       -DPREFIX='"${prefix}"' \
+       -DCONFIGFILE='"${sysconfdir}/${PACKAGE_NAME}.conf"' \
+       -DLOCALSTATEDIR='"${localstatedir}"' \
+       -DPKGLOCALSTATEDIR='"${localstatedir}/lib/${PACKAGE_NAME}"' \
+       -DPLUGINDIR='"${pkglibdir}"' \
+       -DPKGDATADIR='"${pkgdatadir}"'
+
+
+# Link to these libraries..
+COMMON_LIBS = $(PTHREAD_LIBS)
+if BUILD_WITH_CAPABILITY
+COMMON_LIBS += -lcap
+endif
+if BUILD_WITH_LIBRT
+COMMON_LIBS += -lrt
+endif
+if BUILD_WITH_LIBPOSIX4
+COMMON_LIBS += -lposix4
+endif
+if BUILD_WITH_LIBSOCKET
+COMMON_LIBS += -lsocket
+endif
+if BUILD_WITH_LIBKSTAT
+COMMON_LIBS += -lkstat
+endif
+if BUILD_WITH_LIBDEVINFO
+COMMON_LIBS += -ldevinfo
+endif
+
+
+collectd_SOURCES = \
+       src/daemon/collectd.c \
+       src/daemon/collectd.h \
+       src/daemon/configfile.c \
+       src/daemon/configfile.h \
+       src/daemon/filter_chain.c \
+       src/daemon/filter_chain.h \
+       src/daemon/meta_data.c \
+       src/daemon/meta_data.h \
+       src/daemon/plugin.c \
+       src/daemon/plugin.h \
+       src/daemon/utils_cache.c \
+       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 \
+       src/daemon/utils_random.h \
+       src/daemon/utils_subst.c \
+       src/daemon/utils_subst.h \
+       src/daemon/utils_time.c \
+       src/daemon/utils_time.h \
+       src/daemon/types_list.c \
+       src/daemon/types_list.h \
+       src/daemon/utils_threshold.c \
+       src/daemon/utils_threshold.h
+
+
+collectd_CFLAGS = $(AM_CFLAGS)
+collectd_CPPFLAGS = $(AM_CPPFLAGS)
+collectd_LDFLAGS = -export-dynamic
+collectd_LDADD = \
+       libavltree.la \
+       libcommon.la \
+       libheap.la \
+       liboconfig.la \
+       -lm \
+       $(COMMON_LIBS) \
+       $(DLOPEN_LIBS)
+
+if BUILD_FEATURE_DAEMON
+collectd_CPPFLAGS += -DPIDFILE='"${localstatedir}/run/${PACKAGE_NAME}.pid"'
+endif
+
+# The daemon needs to call sg_init, so we need to link it against libstatgrab,
+# too. -octo
+if BUILD_WITH_LIBSTATGRAB
+collectd_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
+collectd_LDADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
+endif
+
+
+collectdmon_SOURCES = src/collectdmon.c
+
+
+collectd_nagios_SOURCES = src/collectd-nagios.c
+collectd_nagios_CPPFLAGS = $(AM_CPPFLAGS) \
+       -I$(srcdir)/src/libcollectdclient/collectd \
+       -I$(top_builddir)/src/libcollectdclient/collectd
+collectd_nagios_LDADD = libcollectdclient.la
+if BUILD_WITH_LIBSOCKET
+collectd_nagios_LDADD += -lsocket
+endif
+if BUILD_AIX
+collectd_nagios_LDADD += -lm
+endif
+
+
+collectdctl_SOURCES = src/collectdctl.c
+collectdctl_CPPFLAGS = $(AM_CPPFLAGS) \
+       -I$(srcdir)/src/libcollectdclient/collectd \
+       -I$(top_builddir)/src/libcollectdclient/collectd
+collectdctl_LDADD = libcollectdclient.la
+if BUILD_WITH_LIBSOCKET
+collectdctl_LDADD += -lsocket
+endif
+if BUILD_AIX
+collectdctl_LDADD += -lm
+endif
+
+
+collectd_tg_SOURCES = src/collectd-tg.c
+collectd_tg_CPPFLAGS = $(AM_CPPFLAGS) \
+       -I$(srcdir)/src/libcollectdclient/collectd \
+       -I$(top_builddir)/src/libcollectdclient/collectd
+collectd_tg_LDADD = \
+       $(PTHREAD_LIBS) \
+       libheap.la \
+       libcollectdclient.la
+if BUILD_WITH_LIBSOCKET
+collectd_tg_LDADD += -lsocket
+endif
+if BUILD_WITH_LIBRT
+collectd_tg_LDADD += -lrt
+endif
+if BUILD_AIX
+collectd_tg_LDADD += -lm
+endif
+
+
+test_common_SOURCES = \
+       src/daemon/common_test.c \
+       src/testing.h
+test_common_LDADD = libplugin_mock.la
+
+test_meta_data_SOURCES = \
+       src/daemon/meta_data_test.c \
+       src/testing.h
+test_meta_data_LDADD = libmetadata.la libplugin_mock.la
+
+test_utils_avltree_SOURCES = \
+       src/daemon/utils_avltree_test.c \
+       src/testing.h
+test_utils_avltree_LDADD = libavltree.la $(COMMON_LIBS)
+
+test_utils_heap_SOURCES = \
+       src/daemon/utils_heap_test.c \
+       src/testing.h
+test_utils_heap_LDADD = libheap.la $(COMMON_LIBS)
+
+test_utils_time_SOURCES = \
+       src/daemon/utils_time_test.c \
+       src/testing.h
+
+test_utils_subst_SOURCES = \
+       src/daemon/utils_subst_test.c \
+       src/testing.h \
+       src/daemon/utils_subst.c \
+       src/daemon/utils_subst.h
+test_utils_subst_LDADD = libplugin_mock.la
+
+libavltree_la_SOURCES = \
+       src/daemon/utils_avltree.c \
+       src/daemon/utils_avltree.h
+
+libcommon_la_SOURCES = \
+       src/daemon/common.c \
+       src/daemon/common.h
+libcommon_la_LIBADD = $(COMMON_LIBS)
+
+libheap_la_SOURCES = \
+       src/daemon/utils_heap.c \
+       src/daemon/utils_heap.h
+
+libmetadata_la_SOURCES = \
+       src/daemon/meta_data.c \
+       src/daemon/meta_data.h
+
+libplugin_mock_la_SOURCES = \
+       src/daemon/plugin_mock.c \
+       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)
+
+libformat_graphite_la_SOURCES = \
+       src/utils_format_graphite.c \
+       src/utils_format_graphite.h
+
+test_format_graphite_SOURCES = \
+       src/utils_format_graphite_test.c \
+       src/testing.h
+test_format_graphite_LDADD = \
+       libformat_graphite.la \
+       libmetadata.la \
+       libplugin_mock.la \
+       -lm
+
+libformat_json_la_SOURCES = \
+       src/utils_format_json.c \
+       src/utils_format_json.h
+libformat_json_la_CPPFLAGS  = $(AM_CPPFLAGS)
+libformat_json_la_LDFLAGS   = $(AM_LDFLAGS)
+libformat_json_la_LIBADD    =
+if BUILD_WITH_LIBYAJL
+libformat_json_la_CPPFLAGS += $(BUILD_WITH_LIBYAJL_CPPFLAGS)
+libformat_json_la_LDFLAGS  += $(BUILD_WITH_LIBYAJL_LDFLAGS)
+libformat_json_la_LIBADD   += $(BUILD_WITH_LIBYAJL_LIBS)
+
+check_PROGRAMS += test_format_json
+
+test_format_json_SOURCES = \
+       src/utils_format_json_test.c \
+       src/testing.h
+test_format_json_LDADD = \
+       libformat_json.la \
+       libmetadata.la \
+       libplugin_mock.la \
+       -lm
+endif
+
+if BUILD_PLUGIN_CEPH
+test_plugin_ceph_SOURCES = src/ceph_test.c
+test_plugin_ceph_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS)
+test_plugin_ceph_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS)
+test_plugin_ceph_LDADD = libplugin_mock.la $(BUILD_WITH_LIBYAJL_LIBS)
+check_PROGRAMS += test_plugin_ceph
+endif
+
+liblatency_la_SOURCES = \
+       src/utils_latency.c \
+       src/utils_latency.h \
+       src/utils_latency_config.c \
+       src/utils_latency_config.h
+liblatency_la_LIBADD = \
+       libcommon.la \
+       -lm
+
+test_utils_latency_SOURCES = \
+       src/utils_latency_test.c \
+       src/testing.h
+test_utils_latency_LDADD = \
+       liblatency.la \
+       libplugin_mock.la \
+       -lm
+
+libcmds_la_SOURCES = \
+       src/utils_cmds.c \
+       src/utils_cmds.h \
+       src/utils_cmd_flush.c \
+       src/utils_cmd_flush.h \
+       src/utils_cmd_getthreshold.c \
+       src/utils_cmd_getthreshold.h \
+       src/utils_cmd_getval.c \
+       src/utils_cmd_getval.h \
+       src/utils_cmd_listval.c \
+       src/utils_cmd_listval.h \
+       src/utils_cmd_putnotif.c \
+       src/utils_cmd_putnotif.h \
+       src/utils_cmd_putval.c \
+       src/utils_cmd_putval.h \
+       src/utils_parse_option.c \
+       src/utils_parse_option.h
+libcmds_la_LIBADD = \
+       libcommon.la \
+       libmetadata.la \
+       -lm
+
+test_utils_cmds_SOURCES = \
+       src/utils_cmds_test.c \
+       src/testing.h
+test_utils_cmds_LDADD = \
+       libcmds.la \
+       libplugin_mock.la
+
+liblookup_la_SOURCES = \
+       src/utils_vl_lookup.c \
+       src/utils_vl_lookup.h
+liblookup_la_LIBADD = libavltree.la
+
+test_utils_vl_lookup_SOURCES = \
+       src/utils_vl_lookup_test.c \
+       src/testing.h
+test_utils_vl_lookup_LDADD = \
+       liblookup.la \
+       libplugin_mock.la
+if BUILD_WITH_LIBKSTAT
+test_utils_vl_lookup_LDADD += -lkstat
+endif
+
+libmount_la_SOURCES = \
+       src/utils_mount.c \
+       src/utils_mount.h
+
+test_utils_mount_SOURCES = \
+       src/utils_mount_test.c \
+       src/testing.h
+test_utils_mount_LDADD = \
+       libmount.la \
+       libplugin_mock.la
+if BUILD_WITH_LIBKSTAT
+test_utils_mount_LDADD += -lkstat
 endif
 
-SUBDIRS += proto src bindings .
 
-AM_CPPFLAGS = $(LTDLINCL)
+libcollectdclient_la_SOURCES = \
+       src/libcollectdclient/client.c \
+       src/libcollectdclient/network.c \
+       src/libcollectdclient/network_buffer.c
+libcollectdclient_la_CPPFLAGS = \
+       $(AM_CPPFLAGS) \
+       -I$(srcdir)/src/libcollectdclient/collectd \
+       -I$(top_builddir)/src/libcollectdclient/collectd \
+       -I$(srcdir)/src/daemon
+libcollectdclient_la_LDFLAGS = -version-info 1:0:0
+libcollectdclient_la_LIBADD = 
+if BUILD_WITH_LIBGCRYPT
+libcollectdclient_la_CPPFLAGS += $(GCRYPT_CPPFLAGS)
+libcollectdclient_la_LDFLAGS += $(GCRYPT_LDFLAGS)
+libcollectdclient_la_LIBADD += $(GCRYPT_LIBS)
+endif
+
+
+liboconfig_la_SOURCES = \
+       src/liboconfig/oconfig.c \
+       src/liboconfig/oconfig.h \
+       src/liboconfig/aux_types.h \
+       src/liboconfig/scanner.l \
+       src/liboconfig/parser.y
+liboconfig_la_LDFLAGS = -avoid-version $(LEXLIB)
+
+
+if BUILD_PLUGIN_AGGREGATION
+pkglib_LTLIBRARIES += aggregation.la
+aggregation_la_SOURCES = \
+       src/aggregation.c \
+       src/utils_vl_lookup.c \
+       src/utils_vl_lookup.h
+aggregation_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+aggregation_la_LIBADD = -lm
+endif
+
+if BUILD_PLUGIN_AMQP
+pkglib_LTLIBRARIES += amqp.la
+amqp_la_SOURCES = src/amqp.c
+amqp_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBRABBITMQ_CPPFLAGS)
+amqp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRABBITMQ_LDFLAGS)
+amqp_la_LIBADD = \
+       $(BUILD_WITH_LIBRABBITMQ_LIBS) \
+       libcmds.la \
+       libformat_graphite.la \
+       libformat_json.la
+endif
+
+if BUILD_PLUGIN_APACHE
+pkglib_LTLIBRARIES += apache.la
+apache_la_SOURCES = src/apache.c
+apache_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS)
+apache_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+apache_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS)
+endif
+
+
+if BUILD_PLUGIN_APCUPS
+pkglib_LTLIBRARIES += apcups.la
+apcups_la_SOURCES = src/apcups.c
+apcups_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+apcups_la_LIBADD =
+if BUILD_WITH_LIBSOCKET
+apcups_la_LIBADD += -lsocket
+endif
+endif
+
+if BUILD_PLUGIN_APPLE_SENSORS
+pkglib_LTLIBRARIES += apple_sensors.la
+apple_sensors_la_SOURCES = src/apple_sensors.c
+apple_sensors_la_LDFLAGS = $(PLUGIN_LDFLAGS) -framework IOKit
+endif
+
+if BUILD_PLUGIN_AQUAERO
+pkglib_LTLIBRARIES += aquaero.la
+aquaero_la_SOURCES = src/aquaero.c
+aquaero_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBAQUAERO5_CFLAGS)
+aquaero_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBAQUAERO5_LDFLAGS)
+aquaero_la_LIBADD = -laquaero5
+endif
+
+if BUILD_PLUGIN_ASCENT
+pkglib_LTLIBRARIES += ascent.la
+ascent_la_SOURCES = src/ascent.c
+ascent_la_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(BUILD_WITH_LIBCURL_CFLAGS) \
+       $(BUILD_WITH_LIBXML2_CFLAGS)
+ascent_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+ascent_la_LIBADD = \
+       $(BUILD_WITH_LIBCURL_LIBS) \
+       $(BUILD_WITH_LIBXML2_LIBS)
+endif
+
+if BUILD_PLUGIN_BAROMETER
+pkglib_LTLIBRARIES += barometer.la
+barometer_la_SOURCES = src/barometer.c
+barometer_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+barometer_la_LIBADD = -lm
+endif
+
+if BUILD_PLUGIN_BATTERY
+pkglib_LTLIBRARIES += battery.la
+battery_la_SOURCES = \
+       src/battery.c \
+       src/battery_statefs.c
+battery_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+if BUILD_WITH_LIBIOKIT
+battery_la_LDFLAGS += -framework IOKit
+endif
+endif
+
+if BUILD_PLUGIN_BIND
+pkglib_LTLIBRARIES += bind.la
+bind_la_SOURCES = src/bind.c
+bind_la_CFLAGS = $(AM_CFLAGS) \
+       $(BUILD_WITH_LIBCURL_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS)
+bind_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+bind_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBXML2_LIBS)
+endif
+
+if BUILD_PLUGIN_CEPH
+pkglib_LTLIBRARIES += ceph.la
+ceph_la_SOURCES = src/ceph.c
+ceph_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS)
+ceph_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS)
+ceph_la_LIBADD = $(BUILD_WITH_LIBYAJL_LIBS)
+endif
 
-EXTRA_DIST = contrib version-gen.sh testwrapper.sh
+if BUILD_PLUGIN_CGROUPS
+pkglib_LTLIBRARIES += cgroups.la
+cgroups_la_SOURCES = src/cgroups.c
+cgroups_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+cgroups_la_LIBADD = 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
+pkglib_LTLIBRARIES += conntrack.la
+conntrack_la_SOURCES = src/conntrack.c
+conntrack_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_CONTEXTSWITCH
+pkglib_LTLIBRARIES += contextswitch.la
+contextswitch_la_SOURCES = src/contextswitch.c
+contextswitch_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+contextswitch_la_LIBADD =
+if BUILD_WITH_PERFSTAT
+contextswitch_la_LIBADD += -lperfstat
+endif
+endif
+
+if BUILD_PLUGIN_CPU
+pkglib_LTLIBRARIES += cpu.la
+cpu_la_SOURCES = src/cpu.c
+cpu_la_CFLAGS = $(AM_CFLAGS)
+cpu_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+cpu_la_LIBADD =
+if BUILD_WITH_LIBKSTAT
+cpu_la_LIBADD += -lkstat
+endif
+if BUILD_WITH_LIBDEVINFO
+cpu_la_LIBADD += -ldevinfo
+endif
+if BUILD_WITH_LIBSTATGRAB
+cpu_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
+cpu_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
+endif
+if BUILD_WITH_PERFSTAT
+cpu_la_LIBADD += -lperfstat
+endif
+endif
+
+if BUILD_PLUGIN_CPUFREQ
+pkglib_LTLIBRARIES += cpufreq.la
+cpufreq_la_SOURCES = src/cpufreq.c
+cpufreq_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_CPUSLEEP
+pkglib_LTLIBRARIES += cpusleep.la
+cpusleep_la_SOURCES = src/cpusleep.c
+cpusleep_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_CSV
+pkglib_LTLIBRARIES += csv.la
+csv_la_SOURCES = src/csv.c
+csv_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_CURL
+pkglib_LTLIBRARIES += curl.la
+curl_la_SOURCES = \
+       src/curl.c \
+       src/utils_curl_stats.c \
+       src/utils_curl_stats.h \
+       src/utils_match.c \
+       src/utils_match.h
+curl_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS)
+curl_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+curl_la_LIBADD = liblatency.la $(BUILD_WITH_LIBCURL_LIBS)
+endif
+
+if BUILD_PLUGIN_CURL_JSON
+pkglib_LTLIBRARIES += curl_json.la
+curl_json_la_SOURCES = \
+       src/curl_json.c \
+       src/utils_curl_stats.c \
+       src/utils_curl_stats.h
+curl_json_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS)
+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)
+endif
+
+if BUILD_PLUGIN_CURL_XML
+pkglib_LTLIBRARIES += curl_xml.la
+curl_xml_la_SOURCES = \
+       src/curl_xml.c \
+       src/utils_curl_stats.c \
+       src/utils_curl_stats.h
+curl_xml_la_CFLAGS = $(AM_CFLAGS) \
+               $(BUILD_WITH_LIBCURL_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS)
+curl_xml_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+curl_xml_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBXML2_LIBS)
+endif
+
+if BUILD_PLUGIN_DBI
+pkglib_LTLIBRARIES += dbi.la
+dbi_la_SOURCES = \
+       src/dbi.c \
+       src/utils_db_query.c \
+       src/utils_db_query.h
+dbi_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBDBI_CPPFLAGS)
+dbi_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBDBI_LDFLAGS)
+dbi_la_LIBADD = $(BUILD_WITH_LIBDBI_LIBS)
+endif
+
+if BUILD_PLUGIN_DF
+pkglib_LTLIBRARIES += df.la
+df_la_SOURCES = src/df.c
+df_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+df_la_LIBADD = libmount.la
+endif
+
+if BUILD_PLUGIN_DISK
+pkglib_LTLIBRARIES += disk.la
+disk_la_SOURCES = src/disk.c
+disk_la_CFLAGS = $(AM_CFLAGS)
+disk_la_CPPFLAGS = $(AM_CPPFLAGS)
+disk_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+disk_la_LIBADD =
+if BUILD_WITH_LIBKSTAT
+disk_la_LIBADD += -lkstat
+endif
+if BUILD_WITH_LIBDEVINFO
+disk_la_LIBADD += -ldevinfo
+endif
+if BUILD_WITH_LIBIOKIT
+disk_la_LDFLAGS += -framework IOKit
+endif
+if BUILD_WITH_LIBSTATGRAB
+disk_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
+disk_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
+endif
+if BUILD_WITH_LIBUDEV
+disk_la_CPPFLAGS += $(BUILD_WITH_LIBUDEV_CPPFLAGS)
+disk_la_LDFLAGS += $(BUILD_WITH_LIBUDEV_LDFLAGS)
+disk_la_LIBADD += $(BUILD_WITH_LIBUDEV_LIBS)
+endif
+if BUILD_FREEBSD
+disk_la_LIBADD += -ldevstat -lgeom
+endif
+if BUILD_WITH_PERFSTAT
+disk_la_LIBADD += -lperfstat
+endif
+endif
+
+if BUILD_PLUGIN_DNS
+pkglib_LTLIBRARIES += dns.la
+dns_la_SOURCES = \
+       src/dns.c \
+       src/utils_dns.c \
+       src/utils_dns.h
+dns_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBPCAP_CPPFLAGS)
+dns_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBPCAP_LDFLAGS)
+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
+dpdkstat_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBDPDK_CPPFLAGS)
+dpdkstat_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBDPDK_LDFLAGS)
+dpdkstat_la_LIBADD = -ldpdk
+endif
+
+if BUILD_PLUGIN_DRBD
+pkglib_LTLIBRARIES += drbd.la
+drbd_la_SOURCES = src/drbd.c
+drbd_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_EMAIL
+pkglib_LTLIBRARIES += email.la
+email_la_SOURCES = src/email.c
+email_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_ENTROPY
+pkglib_LTLIBRARIES += entropy.la
+entropy_la_SOURCES = src/entropy.c
+entropy_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_EXEC
+pkglib_LTLIBRARIES += exec.la
+exec_la_SOURCES = src/exec.c
+exec_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+exec_la_LIBADD = libcmds.la
+endif
+
+if BUILD_PLUGIN_ETHSTAT
+pkglib_LTLIBRARIES += ethstat.la
+ethstat_la_SOURCES = src/ethstat.c
+ethstat_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_FHCOUNT
+pkglib_LTLIBRARIES += fhcount.la
+fhcount_la_SOURCES = src/fhcount.c
+fhcount_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_FILECOUNT
+pkglib_LTLIBRARIES += filecount.la
+filecount_la_SOURCES = src/filecount.c
+filecount_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_FSCACHE
+pkglib_LTLIBRARIES += fscache.la
+fscache_la_SOURCES = src/fscache.c
+fscache_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_GMOND
+pkglib_LTLIBRARIES += gmond.la
+gmond_la_SOURCES = src/gmond.c
+gmond_la_CPPFLAGS = $(AM_CPPFLAGS) $(GANGLIA_CPPFLAGS)
+gmond_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(GANGLIA_LDFLAGS)
+gmond_la_LIBADD = $(GANGLIA_LIBS)
+endif
+
+if BUILD_PLUGIN_GPS
+pkglib_LTLIBRARIES += gps.la
+gps_la_SOURCES = src/gps.c
+gps_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBGPS_CFLAGS)
+gps_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBGPS_LDFLAGS)
+gps_la_LIBADD = -lpthread $(BUILD_WITH_LIBGPS_LIBS)
+endif
+
+if BUILD_PLUGIN_GRPC
+pkglib_LTLIBRARIES += grpc.la
+grpc_la_SOURCES = src/grpc.cc
+nodist_grpc_la_SOURCES = \
+       collectd.grpc.pb.cc \
+       collectd.pb.cc \
+       types.pb.cc
+grpc_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBGRPCPP_CPPFLAGS) $(BUILD_WITH_LIBPROTOBUF_CPPFLAGS)
+grpc_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBGRPCPP_LDFLAGS) $(BUILD_WITH_LIBPROTOBUF_LDFLAGS)
+grpc_la_LIBADD = $(BUILD_WITH_LIBGRPCPP_LIBS) $(BUILD_WITH_LIBPROTOBUF_LIBS)
+endif
+
+if BUILD_PLUGIN_HDDTEMP
+pkglib_LTLIBRARIES += hddtemp.la
+hddtemp_la_SOURCES = src/hddtemp.c
+hddtemp_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+hddtemp_la_LIBADD =
+if BUILD_WITH_LIBSOCKET
+hddtemp_la_LIBADD += -lsocket
+endif
+endif
+
+if BUILD_PLUGIN_HUGEPAGES
+pkglib_LTLIBRARIES += hugepages.la
+hugepages_la_SOURCES = src/hugepages.c
+hugepages_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_INTEL_RDT
+pkglib_LTLIBRARIES += intel_rdt.la
+intel_rdt_la_SOURCES = src/intel_rdt.c
+intel_rdt_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBPQOS_CPPFLAGS)
+intel_rdt_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBPQOS_LDFLAGS)
+intel_rdt_la_LIBADD = $(BUILD_WITH_LIBPQOS_LIBS)
+endif
+
+if BUILD_PLUGIN_INTERFACE
+pkglib_LTLIBRARIES += interface.la
+interface_la_SOURCES = src/interface.c
+interface_la_CFLAGS = $(AM_CFLAGS)
+interface_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+interface_la_LIBADD =
+if BUILD_WITH_LIBSTATGRAB
+interface_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
+interface_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
+else
+if BUILD_WITH_LIBKSTAT
+interface_la_LIBADD += -lkstat
+endif
+if BUILD_WITH_LIBDEVINFO
+interface_la_LIBADD += -ldevinfo
+endif # BUILD_WITH_LIBDEVINFO
+endif # !BUILD_WITH_LIBSTATGRAB
+if BUILD_WITH_PERFSTAT
+interface_la_LIBADD += -lperfstat
+endif
+endif # BUILD_PLUGIN_INTERFACE
+
+if BUILD_PLUGIN_IPC
+pkglib_LTLIBRARIES += ipc.la
+ipc_la_SOURCES = src/ipc.c
+ipc_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_IPTABLES
+pkglib_LTLIBRARIES += iptables.la
+iptables_la_SOURCES = src/iptables.c
+iptables_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBIPTC_CPPFLAGS)
+iptables_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+iptables_la_LIBADD = $(BUILD_WITH_LIBIPTC_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_IPMI
+pkglib_LTLIBRARIES += ipmi.la
+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)
+endif
+
+if BUILD_PLUGIN_IPVS
+pkglib_LTLIBRARIES += ipvs.la
+ipvs_la_SOURCES = src/ipvs.c
+ipvs_la_CFLAGS = $(AM_CFLAGS)
+if IP_VS_H_NEEDS_KERNEL_CFLAGS
+ipvs_la_CFLAGS += $(KERNEL_CFLAGS)
+endif
+ipvs_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_IRQ
+pkglib_LTLIBRARIES += irq.la
+irq_la_SOURCES = src/irq.c
+irq_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_JAVA
+pkglib_LTLIBRARIES += java.la
+java_la_SOURCES = src/java.c
+java_la_CPPFLAGS = $(AM_CPPFLAGS) $(JAVA_CPPFLAGS)
+java_la_CFLAGS = $(AM_CFLAGS) $(JAVA_CFLAGS)
+java_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(JAVA_LDFLAGS)
+java_la_LIBADD = $(JAVA_LIBS)
+endif
+
+if BUILD_PLUGIN_LOAD
+pkglib_LTLIBRARIES += load.la
+load_la_SOURCES = src/load.c
+load_la_CFLAGS = $(AM_CFLAGS)
+load_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+load_la_LIBADD =
+if BUILD_WITH_LIBSTATGRAB
+load_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
+load_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
+endif # BUILD_WITH_LIBSTATGRAB
+if BUILD_WITH_PERFSTAT
+load_la_LIBADD += -lperfstat
+endif
+endif # BUILD_PLUGIN_LOAD
+
+if BUILD_PLUGIN_LOGFILE
+pkglib_LTLIBRARIES += logfile.la
+logfile_la_SOURCES = src/logfile.c
+logfile_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_LOG_LOGSTASH
+pkglib_LTLIBRARIES += log_logstash.la
+log_logstash_la_SOURCES = src/log_logstash.c
+log_logstash_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS)
+log_logstash_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS)
+log_logstash_la_LIBADD = $(BUILD_WITH_LIBYAJL_LIBS)
+endif
+
+if BUILD_PLUGIN_LPAR
+pkglib_LTLIBRARIES += lpar.la
+lpar_la_SOURCES = src/lpar.c
+lpar_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+lpar_la_LIBADD = -lperfstat
+endif
+
+if BUILD_PLUGIN_LUA
+pkglib_LTLIBRARIES += lua.la
+lua_la_SOURCES = \
+       src/lua.c \
+       src/utils_lua.c \
+       src/utils_lua.h
+lua_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBLUA_CFLAGS)
+lua_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+lua_la_LIBADD = $(BUILD_WITH_LIBLUA_LIBS)
+endif
+
+if BUILD_PLUGIN_LVM
+pkglib_LTLIBRARIES += lvm.la
+lvm_la_SOURCES = src/lvm.c
+lvm_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBLVM2APP_CPPFLAGS)
+lvm_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBLVM2APP_LDFLAGS)
+lvm_la_LIBADD = $(BUILD_WITH_LIBLVM2APP_LIBS)
+endif
+
+if BUILD_PLUGIN_MADWIFI
+pkglib_LTLIBRARIES += madwifi.la
+madwifi_la_SOURCES = \
+       src/madwifi.c \
+       src/madwifi.h
+madwifi_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_MATCH_EMPTY_COUNTER
+pkglib_LTLIBRARIES += match_empty_counter.la
+match_empty_counter_la_SOURCES = src/match_empty_counter.c
+match_empty_counter_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_MATCH_HASHED
+pkglib_LTLIBRARIES += match_hashed.la
+match_hashed_la_SOURCES = src/match_hashed.c
+match_hashed_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_MATCH_REGEX
+pkglib_LTLIBRARIES += match_regex.la
+match_regex_la_SOURCES = src/match_regex.c
+match_regex_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_MATCH_TIMEDIFF
+pkglib_LTLIBRARIES += match_timediff.la
+match_timediff_la_SOURCES = src/match_timediff.c
+match_timediff_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_MATCH_VALUE
+pkglib_LTLIBRARIES += match_value.la
+match_value_la_SOURCES = src/match_value.c
+match_value_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_MBMON
+pkglib_LTLIBRARIES += mbmon.la
+mbmon_la_SOURCES = src/mbmon.c
+mbmon_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+mbmon_la_LIBADD =
+if BUILD_WITH_LIBSOCKET
+mbmon_la_LIBADD += -lsocket
+endif
+endif
+
+if BUILD_PLUGIN_MCELOG
+pkglib_LTLIBRARIES += mcelog.la
+mcelog_la_SOURCES = src/mcelog.c
+mcelog_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_MD
+pkglib_LTLIBRARIES += md.la
+md_la_SOURCES = src/md.c
+md_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_MEMCACHEC
+pkglib_LTLIBRARIES += memcachec.la
+memcachec_la_SOURCES = \
+       src/memcachec.c \
+       src/utils_match.c \
+       src/utils_match.h
+memcachec_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBMEMCACHED_CPPFLAGS)
+memcachec_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBMEMCACHED_LDFLAGS)
+memcachec_la_LIBADD = liblatency.la $(BUILD_WITH_LIBMEMCACHED_LIBS)
+endif
+
+if BUILD_PLUGIN_MEMCACHED
+pkglib_LTLIBRARIES += memcached.la
+memcached_la_SOURCES = src/memcached.c
+memcached_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+memcached_la_LIBADD =
+if BUILD_WITH_LIBSOCKET
+memcached_la_LIBADD += -lsocket
+endif
+endif
+
+if BUILD_PLUGIN_MEMORY
+pkglib_LTLIBRARIES += memory.la
+memory_la_SOURCES = src/memory.c
+memory_la_CFLAGS = $(AM_CFLAGS)
+memory_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+memory_la_LIBADD =
+if BUILD_WITH_LIBKSTAT
+memory_la_LIBADD += -lkstat
+endif
+if BUILD_WITH_LIBDEVINFO
+memory_la_LIBADD += -ldevinfo
+endif
+if BUILD_WITH_LIBSTATGRAB
+memory_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
+memory_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
+endif
+if BUILD_WITH_PERFSTAT
+memory_la_LIBADD += -lperfstat
+endif
+endif
+
+if BUILD_PLUGIN_MIC
+pkglib_LTLIBRARIES += mic.la
+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)
+endif
+
+if BUILD_PLUGIN_MODBUS
+pkglib_LTLIBRARIES += modbus.la
+modbus_la_SOURCES = src/modbus.c
+modbus_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBMODBUS_CFLAGS)
+modbus_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+modbus_la_LIBADD = $(BUILD_WITH_LIBMODBUS_LIBS)
+endif
+
+if BUILD_PLUGIN_MQTT
+pkglib_LTLIBRARIES += mqtt.la
+mqtt_la_SOURCES = src/mqtt.c
+mqtt_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBMOSQUITTO_CPPFLAGS)
+mqtt_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBMOSQUITTO_LDFLAGS)
+mqtt_la_LIBADD = $(BUILD_WITH_LIBMOSQUITTO_LIBS)
+endif
+
+if BUILD_PLUGIN_MULTIMETER
+pkglib_LTLIBRARIES += multimeter.la
+multimeter_la_SOURCES = src/multimeter.c
+multimeter_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_MYSQL
+pkglib_LTLIBRARIES += mysql.la
+mysql_la_SOURCES = src/mysql.c
+mysql_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBMYSQL_CFLAGS)
+mysql_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+mysql_la_LIBADD = $(BUILD_WITH_LIBMYSQL_LIBS)
+endif
+
+if BUILD_PLUGIN_NETAPP
+pkglib_LTLIBRARIES += netapp.la
+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)
+endif
+
+if BUILD_PLUGIN_NETLINK
+pkglib_LTLIBRARIES += netlink.la
+netlink_la_SOURCES = src/netlink.c
+netlink_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBMNL_CFLAGS)
+netlink_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+netlink_la_LIBADD = $(BUILD_WITH_LIBMNL_LIBS)
+endif
+
+if BUILD_PLUGIN_NETWORK
+pkglib_LTLIBRARIES += network.la
+network_la_SOURCES = \
+       src/network.c \
+       src/network.h \
+       src/utils_fbhash.c \
+       src/utils_fbhash.h
+network_la_CPPFLAGS = $(AM_CPPFLAGS)
+network_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+network_la_LIBADD =
+if BUILD_WITH_LIBSOCKET
+network_la_LIBADD += -lsocket
+endif
+if BUILD_WITH_LIBGCRYPT
+network_la_CPPFLAGS += $(GCRYPT_CPPFLAGS)
+network_la_LDFLAGS += $(GCRYPT_LDFLAGS)
+network_la_LIBADD += $(GCRYPT_LIBS)
+endif
+endif
+
+if BUILD_PLUGIN_NFS
+pkglib_LTLIBRARIES += nfs.la
+nfs_la_SOURCES = src/nfs.c
+nfs_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_NGINX
+pkglib_LTLIBRARIES += nginx.la
+nginx_la_SOURCES = src/nginx.c
+nginx_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS)
+nginx_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+nginx_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS)
+endif
+
+if BUILD_PLUGIN_NOTIFY_DESKTOP
+pkglib_LTLIBRARIES += notify_desktop.la
+notify_desktop_la_SOURCES = src/notify_desktop.c
+notify_desktop_la_CFLAGS = $(AM_CFLAGS) $(LIBNOTIFY_CFLAGS)
+notify_desktop_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+notify_desktop_la_LIBADD = $(LIBNOTIFY_LIBS)
+endif
+
+if BUILD_PLUGIN_NOTIFY_EMAIL
+pkglib_LTLIBRARIES += notify_email.la
+notify_email_la_SOURCES = src/notify_email.c
+notify_email_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBESMTP_CPPFLAGS)
+notify_email_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBESMTP_LDFLAGS)
+notify_email_la_LIBADD = $(BUILD_WITH_LIBESMTP_LIBS)
+endif
+
+if BUILD_PLUGIN_NOTIFY_NAGIOS
+pkglib_LTLIBRARIES += notify_nagios.la
+notify_nagios_la_SOURCES = src/notify_nagios.c
+notify_nagios_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_NTPD
+pkglib_LTLIBRARIES += ntpd.la
+ntpd_la_SOURCES = src/ntpd.c
+ntpd_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+ntpd_la_LIBADD =
+if BUILD_WITH_LIBSOCKET
+ntpd_la_LIBADD += -lsocket
+endif
+endif
+
+if BUILD_PLUGIN_NUMA
+pkglib_LTLIBRARIES += numa.la
+numa_la_SOURCES = src/numa.c
+numa_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_NUT
+pkglib_LTLIBRARIES += nut.la
+nut_la_SOURCES = src/nut.c
+nut_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBUPSCLIENT_CFLAGS)
+nut_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+nut_la_LIBADD = $(BUILD_WITH_LIBUPSCLIENT_LIBS)
+endif
+
+if BUILD_PLUGIN_OLSRD
+pkglib_LTLIBRARIES += olsrd.la
+olsrd_la_SOURCES = src/olsrd.c
+olsrd_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+olsrd_la_LIBADD =
+if BUILD_WITH_LIBSOCKET
+olsrd_la_LIBADD += -lsocket
+endif
+endif
+
+if BUILD_PLUGIN_ONEWIRE
+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)
+endif
+
+if BUILD_PLUGIN_OPENLDAP
+pkglib_LTLIBRARIES += openldap.la
+openldap_la_SOURCES = src/openldap.c
+openldap_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBLDAP_CPPFLAGS)
+openldap_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBLDAP_LDFLAGS)
+openldap_la_LIBADD = -lldap
+endif
+
+if BUILD_PLUGIN_OPENVPN
+pkglib_LTLIBRARIES += openvpn.la
+openvpn_la_SOURCES = src/openvpn.c
+openvpn_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_ORACLE
+pkglib_LTLIBRARIES += oracle.la
+oracle_la_SOURCES = \
+       src/oracle.c \
+       src/utils_db_query.c \
+       src/utils_db_query.h
+oracle_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_ORACLE_CPPFLAGS)
+oracle_la_LIBADD = $(BUILD_WITH_ORACLE_LIBS)
+oracle_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_OVS_EVENTS
+pkglib_LTLIBRARIES += ovs_events.la
+ovs_events_la_SOURCES = \
+       src/ovs_events.c \
+       src/utils_ovs.c \
+       src/utils_ovs.h
+ovs_events_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS)
+ovs_events_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS)
+ovs_events_la_LIBADD = $(BUILD_WITH_LIBYAJL_LIBS)
+endif
+
+if BUILD_PLUGIN_PERL
+pkglib_LTLIBRARIES += perl.la
+perl_la_SOURCES = src/perl.c
+# Despite C99 providing the "bool" type thru stdbool.h, Perl defines its own
+# version of that type if HAS_BOOL is not defined... *sigh*
+perl_la_CPPFLAGS = $(AM_CPPFLAGS) -DHAS_BOOL=1
+# Despite off_t being 64 bit wide on 64 bit platforms, Perl insist on using
+# off64_t which is only exposed when _LARGEFILE64_SOURCE is defined... *sigh*
+# On older platforms we also need _REENTRANT. _GNU_SOURCE sets both of these.
+perl_la_CPPFLAGS += -D_GNU_SOURCE
+perl_la_CFLAGS = $(AM_CFLAGS) \
+       $(PERL_CFLAGS) \
+       -DXS_VERSION=\"$(VERSION)\" -DVERSION=\"$(VERSION)\"
+perl_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(PERL_LDFLAGS)
+perl_la_LIBADD = $(PERL_LIBS)
+endif
+
+if BUILD_PLUGIN_PF
+pkglib_LTLIBRARIES += pf.la
+pf_la_SOURCES = src/pf.c
+pf_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_PINBA
+pkglib_LTLIBRARIES += pinba.la
+pinba_la_SOURCES = src/pinba.c
+nodist_pinba_la_SOURCES = \
+       src/pinba.pb-c.c \
+       src/pinba.pb-c.h
+pinba_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBPROTOBUF_C_CPPFLAGS)
+pinba_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBPROTOBUF_C_LDFLAGS)
+pinba_la_LIBADD = $(BUILD_WITH_LIBPROTOBUF_C_LIBS)
+endif
+
+if BUILD_PLUGIN_PING
+pkglib_LTLIBRARIES += ping.la
+ping_la_SOURCES = src/ping.c
+ping_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBOPING_CPPFLAGS)
+ping_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBOPING_LDFLAGS)
+ping_la_LIBADD = -loping -lm
+endif
+
+if BUILD_PLUGIN_POSTGRESQL
+pkglib_LTLIBRARIES += postgresql.la
+postgresql_la_SOURCES = \
+       src/postgresql.c \
+       src/utils_db_query.c \
+       src/utils_db_query.h
+postgresql_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBPQ_CPPFLAGS)
+postgresql_la_LDFLAGS = $(PLUGIN_LDFLAGS) \
+       $(BUILD_WITH_LIBPQ_LDFLAGS)
+postgresql_la_LIBADD = $(BUILD_WITH_LIBPQ_LIBS)
+endif
+
+if BUILD_PLUGIN_POWERDNS
+pkglib_LTLIBRARIES += powerdns.la
+powerdns_la_SOURCES = src/powerdns.c
+powerdns_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_PYTHON
+pkglib_LTLIBRARIES += python.la
+python_la_SOURCES = \
+       src/python.c \
+       src/pyconfig.c \
+       src/pyvalues.c \
+       src/cpython.h
+python_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBPYTHON_CPPFLAGS)
+if COMPILER_IS_GCC
+python_la_CPPFLAGS += -fno-strict-aliasing -Wno-strict-aliasing
+endif
+python_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBPYTHON_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_PROCESSES
+pkglib_LTLIBRARIES += processes.la
+processes_la_SOURCES = src/processes.c
+processes_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+processes_la_LIBADD =
+if BUILD_WITH_LIBKVM_GETPROCS
+processes_la_LIBADD += -lkvm
+endif
+endif
+
+if BUILD_PLUGIN_PROTOCOLS
+pkglib_LTLIBRARIES += protocols.la
+protocols_la_SOURCES = src/protocols.c
+protocols_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_REDIS
+pkglib_LTLIBRARIES += redis.la
+redis_la_SOURCES = src/redis.c
+redis_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBHIREDIS_CPPFLAGS)
+redis_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBHIREDIS_LDFLAGS)
+redis_la_LIBADD = -lhiredis
+endif
+
+if BUILD_PLUGIN_ROUTEROS
+pkglib_LTLIBRARIES += routeros.la
+routeros_la_SOURCES = src/routeros.c
+routeros_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBROUTEROS_CPPFLAGS)
+routeros_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBROUTEROS_LDFLAGS)
+routeros_la_LIBADD = -lrouteros
+endif
+
+if BUILD_PLUGIN_RRDCACHED
+pkglib_LTLIBRARIES += rrdcached.la
+rrdcached_la_SOURCES = \
+       src/rrdcached.c \
+       src/utils_rrdcreate.c \
+       src/utils_rrdcreate.h
+rrdcached_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBRRD_CFLAGS)
+rrdcached_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRRD_LDFLAGS)
+rrdcached_la_LIBADD = $(BUILD_WITH_LIBRRD_LIBS)
+endif
+
+if BUILD_PLUGIN_RRDTOOL
+pkglib_LTLIBRARIES += rrdtool.la
+rrdtool_la_SOURCES = \
+       src/rrdtool.c \
+       src/utils_rrdcreate.c \
+       src/utils_rrdcreate.h
+rrdtool_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBRRD_CFLAGS)
+rrdtool_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRRD_LDFLAGS)
+rrdtool_la_LIBADD = $(BUILD_WITH_LIBRRD_LIBS)
+endif
+
+if BUILD_PLUGIN_SENSORS
+pkglib_LTLIBRARIES += sensors.la
+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)
+endif
+
+if BUILD_PLUGIN_SERIAL
+pkglib_LTLIBRARIES += serial.la
+serial_la_SOURCES = src/serial.c
+serial_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_SIGROK
+pkglib_LTLIBRARIES += sigrok.la
+sigrok_la_SOURCES = src/sigrok.c
+sigrok_la_CFLAGS = $(AM_CFLAGS) $(LIBSIGROK_CFLAGS)
+sigrok_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+sigrok_la_LIBADD = $(LIBSIGROK_LIBS)
+endif
+
+if BUILD_PLUGIN_SMART
+if BUILD_WITH_LIBUDEV
+pkglib_LTLIBRARIES += smart.la
+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)
+endif
+endif
+
+if BUILD_PLUGIN_SNMP
+pkglib_LTLIBRARIES += snmp.la
+snmp_la_SOURCES = src/snmp.c
+snmp_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBNETSNMP_CPPFLAGS)
+snmp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBNETSNMP_LDFLAGS)
+snmp_la_LIBADD = $(BUILD_WITH_LIBNETSNMP_LIBS)
+endif
+
+if BUILD_PLUGIN_STATSD
+pkglib_LTLIBRARIES += statsd.la
+statsd_la_SOURCES = src/statsd.c
+statsd_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+statsd_la_LIBADD = liblatency.la
+endif
+
+if BUILD_PLUGIN_SWAP
+pkglib_LTLIBRARIES += swap.la
+swap_la_SOURCES = src/swap.c
+swap_la_CFLAGS = $(AM_CFLAGS)
+swap_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+swap_la_LIBADD =
+if BUILD_WITH_LIBKSTAT
+swap_la_LIBADD += -lkstat
+endif
+if BUILD_WITH_LIBDEVINFO
+swap_la_LIBADD += -ldevinfo
+endif
+if BUILD_WITH_LIBKVM_GETSWAPINFO
+swap_la_LIBADD += -lkvm
+endif
+if BUILD_WITH_LIBSTATGRAB
+swap_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
+swap_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
+endif
+if BUILD_WITH_PERFSTAT
+swap_la_LIBADD += -lperfstat
+endif
+
+endif
+
+if BUILD_PLUGIN_SYSLOG
+pkglib_LTLIBRARIES += syslog.la
+syslog_la_SOURCES = src/syslog.c
+syslog_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_TABLE
+pkglib_LTLIBRARIES += table.la
+table_la_SOURCES = src/table.c
+table_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_TAIL
+pkglib_LTLIBRARIES += tail.la
+tail_la_SOURCES = \
+       src/tail.c \
+       src/utils_match.c \
+       src/utils_match.h \
+       src/utils_tail.c \
+       src/utils_tail.h \
+       src/utils_tail_match.c \
+       src/utils_tail_match.h
+tail_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+tail_la_LIBADD = liblatency.la
+endif
+
+if BUILD_PLUGIN_TAIL_CSV
+pkglib_LTLIBRARIES += tail_csv.la
+tail_csv_la_SOURCES = \
+       src/tail_csv.c \
+       src/utils_tail.c \
+       src/utils_tail.h
+tail_csv_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_TAPE
+pkglib_LTLIBRARIES += tape.la
+tape_la_SOURCES = src/tape.c
+tape_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+tape_la_LIBADD = -lkstat -ldevinfo
+endif
+
+if BUILD_PLUGIN_TARGET_NOTIFICATION
+pkglib_LTLIBRARIES += target_notification.la
+target_notification_la_SOURCES = src/target_notification.c
+target_notification_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_TARGET_REPLACE
+pkglib_LTLIBRARIES += target_replace.la
+target_replace_la_SOURCES = src/target_replace.c
+target_replace_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_TARGET_SCALE
+pkglib_LTLIBRARIES += target_scale.la
+target_scale_la_SOURCES = src/target_scale.c
+target_scale_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_TARGET_SET
+pkglib_LTLIBRARIES += target_set.la
+target_set_la_SOURCES = src/target_set.c
+target_set_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_TARGET_V5UPGRADE
+pkglib_LTLIBRARIES += target_v5upgrade.la
+target_v5upgrade_la_SOURCES = src/target_v5upgrade.c
+target_v5upgrade_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_TCPCONNS
+pkglib_LTLIBRARIES += tcpconns.la
+tcpconns_la_SOURCES = src/tcpconns.c
+tcpconns_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+tcpconns_la_LIBADD =
+if BUILD_WITH_LIBKVM_NLIST
+tcpconns_la_LIBADD += -lkvm
+endif
+endif
+
+if BUILD_PLUGIN_TEAMSPEAK2
+pkglib_LTLIBRARIES += teamspeak2.la
+teamspeak2_la_SOURCES = src/teamspeak2.c
+teamspeak2_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_TED
+pkglib_LTLIBRARIES += ted.la
+ted_la_SOURCES = src/ted.c
+ted_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_THERMAL
+pkglib_LTLIBRARIES += thermal.la
+thermal_la_SOURCES = src/thermal.c
+thermal_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_THRESHOLD
+pkglib_LTLIBRARIES += threshold.la
+threshold_la_SOURCES = src/threshold.c
+threshold_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_TOKYOTYRANT
+pkglib_LTLIBRARIES += tokyotyrant.la
+tokyotyrant_la_SOURCES = src/tokyotyrant.c
+tokyotyrant_la_CPPFLAGS  = $(AM_CPPFLAGS) $(BUILD_WITH_LIBTOKYOTYRANT_CPPFLAGS)
+tokyotyrant_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBTOKYOTYRANT_LDFLAGS)
+tokyotyrant_la_LIBADD  = $(BUILD_WITH_LIBTOKYOTYRANT_LIBS)
+if BUILD_WITH_LIBSOCKET
+tokyotyrant_la_LIBADD += -lsocket
+endif
+endif
+
+if BUILD_PLUGIN_TURBOSTAT
+pkglib_LTLIBRARIES += turbostat.la
+turbostat_la_SOURCES = src/turbostat.c
+turbostat_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_UNIXSOCK
+pkglib_LTLIBRARIES += unixsock.la
+unixsock_la_SOURCES = src/unixsock.c
+unixsock_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+unixsock_la_LIBADD = libcmds.la
+endif
+
+if BUILD_PLUGIN_UPTIME
+pkglib_LTLIBRARIES += uptime.la
+uptime_la_SOURCES = src/uptime.c
+uptime_la_CFLAGS = $(AM_CFLAGS)
+uptime_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+uptime_la_LIBADD =
+if BUILD_WITH_LIBKSTAT
+uptime_la_LIBADD += -lkstat
+endif
+if BUILD_WITH_PERFSTAT
+uptime_la_LIBADD += -lperfstat
+endif
+endif
+
+if BUILD_PLUGIN_USERS
+pkglib_LTLIBRARIES += users.la
+users_la_SOURCES = src/users.c
+users_la_CFLAGS = $(AM_CFLAGS)
+users_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+users_la_LIBADD =
+if BUILD_WITH_LIBSTATGRAB
+users_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
+users_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
+endif
+endif
+
+if BUILD_PLUGIN_UUID
+pkglib_LTLIBRARIES += uuid.la
+uuid_la_SOURCES = src/uuid.c
+uuid_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_VARNISH
+pkglib_LTLIBRARIES += varnish.la
+varnish_la_SOURCES = src/varnish.c
+varnish_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBVARNISH_CFLAGS)
+varnish_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+varnish_la_LIBADD = $(BUILD_WITH_LIBVARNISH_LIBS)
+endif
+
+if BUILD_PLUGIN_VIRT
+pkglib_LTLIBRARIES += virt.la
+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)
+
+# 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,
+# triggered by the library initialization. There are no means to avoid it,
+# and libvirt switched to libnl3 anyway
+#test_plugin_virt_SOURCES = src/virt_test.c
+#test_plugin_virt_CPPFLAGS = $(AM_CPPFLAGS) \
+#      $(BUILD_WITH_LIBVIRT_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS)
+#test_plugin_virt_LDFLAGS = $(PLUGIN_LDFLAGS)
+#test_plugin_virt_LDADD = libplugin_mock.la \
+#      $(BUILD_WITH_LIBVIRT_LIBS) $(BUILD_WITH_LIBXML2_LIBS)
+#check_PROGRAMS += test_plugin_virt
+#TESTS += test_plugin_virt
+endif
+
+if BUILD_PLUGIN_VMEM
+pkglib_LTLIBRARIES += vmem.la
+vmem_la_SOURCES = src/vmem.c
+vmem_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_VSERVER
+pkglib_LTLIBRARIES += vserver.la
+vserver_la_SOURCES = src/vserver.c
+vserver_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_WIRELESS
+pkglib_LTLIBRARIES += wireless.la
+wireless_la_SOURCES = src/wireless.c
+wireless_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_WRITE_GRAPHITE
+pkglib_LTLIBRARIES += write_graphite.la
+write_graphite_la_SOURCES = src/write_graphite.c
+write_graphite_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+write_graphite_la_LIBADD = libformat_graphite.la
+endif
+
+if BUILD_PLUGIN_WRITE_HTTP
+pkglib_LTLIBRARIES += write_http.la
+write_http_la_SOURCES = \
+       src/write_http.c \
+       src/utils_format_kairosdb.c \
+       src/utils_format_kairosdb.h
+write_http_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS)
+write_http_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+write_http_la_LIBADD = libformat_json.la $(BUILD_WITH_LIBCURL_LIBS)
+endif
+
+if BUILD_PLUGIN_WRITE_KAFKA
+pkglib_LTLIBRARIES += write_kafka.la
+write_kafka_la_SOURCES = src/write_kafka.c
+write_kafka_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBRDKAFKA_CPPFLAGS)
+write_kafka_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRDKAFKA_LDFLAGS)
+write_kafka_la_LIBADD = \
+       libcmds.la \
+       libformat_graphite.la \
+       libformat_json.la \
+       $(BUILD_WITH_LIBRDKAFKA_LIBS)
+endif
+
+if BUILD_PLUGIN_WRITE_LOG
+pkglib_LTLIBRARIES += write_log.la
+write_log_la_SOURCES = src/write_log.c
+write_log_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+write_log_la_LIBADD = libformat_graphite.la libformat_json.la
+endif
+
+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_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBMONGOC_LDFLAGS)
+write_mongodb_la_LIBADD = -lmongoc
+endif
+
+if BUILD_PLUGIN_WRITE_PROMETHEUS
+pkglib_LTLIBRARIES += write_prometheus.la
+write_prometheus_la_SOURCES = src/write_prometheus.c
+nodist_write_prometheus_la_SOURCES = \
+       prometheus.pb-c.c \
+       prometheus.pb-c.h
+write_prometheus_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBPROTOBUF_C_CPPFLAGS) $(BUILD_WITH_LIBMICROHTTPD_CPPFLAGS)
+write_prometheus_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBPROTOBUF_C_LDFLAGS) $(BUILD_WITH_LIBMICROHTTPD_LDFLAGS)
+write_prometheus_la_LIBADD = $(BUILD_WITH_LIBPROTOBUF_C_LIBS) $(BUILD_WITH_LIBMICROHTTPD_LIBS)
+endif
+
+if BUILD_PLUGIN_WRITE_REDIS
+pkglib_LTLIBRARIES += write_redis.la
+write_redis_la_SOURCES = src/write_redis.c
+write_redis_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBHIREDIS_CPPFLAGS)
+write_redis_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBHIREDIS_LDFLAGS)
+write_redis_la_LIBADD = -lhiredis
+endif
+
+if BUILD_PLUGIN_WRITE_RIEMANN
+pkglib_LTLIBRARIES += write_riemann.la
+write_riemann_la_SOURCES = \
+       src/write_riemann.c \
+       src/write_riemann_threshold.c \
+       src/write_riemann_threshold.h
+write_riemann_la_CFLAGS = $(AM_CFLAGS) $(LIBRIEMANN_CLIENT_CFLAGS)
+write_riemann_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBRIEMANN_CLIENT_LIBS)
+endif
+
+if BUILD_PLUGIN_WRITE_SENSU
+pkglib_LTLIBRARIES += write_sensu.la
+write_sensu_la_SOURCES = src/write_sensu.c
+write_sensu_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_WRITE_TSDB
+pkglib_LTLIBRARIES += write_tsdb.la
+write_tsdb_la_SOURCES = src/write_tsdb.c
+write_tsdb_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_XENCPU
+pkglib_LTLIBRARIES += xencpu.la
+xencpu_la_SOURCES = src/xencpu.c
+xencpu_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBXENCTL_CPPFLAGS)
+xencpu_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBXENCTL_LDFLAGS)
+xencpu_la_LIBADD = -lxenctrl
+endif
+
+if BUILD_PLUGIN_XMMS
+pkglib_LTLIBRARIES += xmms.la
+xmms_la_SOURCES = src/xmms.c
+xmms_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBXMMS_CFLAGS)
+xmms_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+xmms_la_LIBADD = $(BUILD_WITH_LIBXMMS_LIBS)
+endif
+
+if BUILD_PLUGIN_ZFS_ARC
+pkglib_LTLIBRARIES += zfs_arc.la
+zfs_arc_la_SOURCES = src/zfs_arc.c
+zfs_arc_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+if BUILD_FREEBSD
+zfs_arc_la_LIBADD = -lm
+endif
+if BUILD_SOLARIS
+zfs_arc_la_LIBADD = -lkstat
+endif
+endif
+
+if BUILD_PLUGIN_ZOOKEEPER
+pkglib_LTLIBRARIES += zookeeper.la
+zookeeper_la_SOURCES = src/zookeeper.c
+zookeeper_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_ZONE
+pkglib_LTLIBRARIES += zone.la
+zone_la_SOURCES = src/zone.c
+zone_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+AM_V_POD2MAN_C = $(am__v_POD2MAN_C_@AM_V@)
+am__v_POD2MAN_C_ = $(am__v_POD2MAN_C_@AM_DEFAULT_V@)
+am__v_POD2MAN_C_0 = @echo "  POD2MAN " $@;
+am__v_POD2MAN_C_1 =
+
+.pod.1:
+       $(AM_V_POD2MAN_C)pod2man --release=$(VERSION) --center=$(PACKAGE) $< \
+               >.pod2man.tmp.$$$$ 2>/dev/null && mv -f .pod2man.tmp.$$$$ $@ || true
+       @if grep '\<POD ERRORS\>' $@ >/dev/null 2>&1; \
+       then \
+               echo "$@ has some POD errors!"; false; \
+       fi
+
+.pod.5:
+       $(AM_V_POD2MAN_C)pod2man --section=5 --release=$(VERSION) --center=$(PACKAGE) $< \
+               >.pod2man.tmp.$$$$ 2>/dev/null && mv -f .pod2man.tmp.$$$$ $@ || true
+       @if grep '\<POD ERRORS\>' $@ >/dev/null 2>&1; \
+       then \
+               echo "$@ has some POD errors!"; false; \
+       fi
+
+V_PROTOC = $(v_protoc_@AM_V@)
+v_protoc_ = $(v_protoc_@AM_DEFAULT_V@)
+v_protoc_0 = @echo "  PROTOC  " $@;
+
+AM_V_PROTOC_C = $(am__v_PROTOC_C_@AM_V@)
+am__v_PROTOC_C_ = $(am__v_PROTOC_C_@AM_DEFAULT_V@)
+am__v_PROTOC_C_0 = @echo "  PROTOC-C" $@;
+am__v_PROTOC_C_1 =
+
+# Protocol buffer for the "pinba" plugin.
+if BUILD_PLUGIN_PINBA
+BUILT_SOURCES += src/pinba.pb-c.c src/pinba.pb-c.h
+
+src/pinba.pb-c.c src/pinba.pb-c.h: $(srcdir)/src/pinba.proto
+       $(AM_V_PROTOC_C)$(PROTOC_C) -I$(srcdir) --c_out . $(srcdir)/src/pinba.proto
+endif
+
+# Protocol buffer for the "write_prometheus" plugin.
+if BUILD_PLUGIN_WRITE_PROMETHEUS
+BUILT_SOURCES += prometheus.pb-c.c prometheus.pb-c.h
+
+prometheus.pb-c.c prometheus.pb-c.h: $(srcdir)/proto/prometheus.proto
+       $(AM_V_PROTOC_C)$(PROTOC_C) -I$(srcdir)/proto --c_out=$(builddir) $(srcdir)/proto/prometheus.proto
+endif
+
+if HAVE_PROTOC3
+if HAVE_GRPC_CPP
+BUILT_SOURCES += collectd.grpc.pb.cc collectd.pb.cc types.pb.cc
+
+collectd.grpc.pb.cc: $(srcdir)/proto/collectd.proto $(srcdir)/proto/types.proto
+       $(V_PROTOC)$(PROTOC) -I$(srcdir)/proto \
+               --grpc_out=$(builddir) --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN) $<
+
+collectd.pb.cc: $(srcdir)/proto/collectd.proto $(srcdir)/proto/types.proto
+       $(V_PROTOC)$(PROTOC) -I$(srcdir)/proto --cpp_out=$(builddir) $<
+
+types.pb.cc: $(srcdir)/proto/types.proto
+       $(V_PROTOC)$(PROTOC) -I$(srcdir)/proto --cpp_out=$(builddir) $<
+endif
+endif
 
 install-exec-hook:
        $(mkinstalldirs) $(DESTDIR)$(localstatedir)/run
        $(mkinstalldirs) $(DESTDIR)$(localstatedir)/lib/$(PACKAGE_NAME)
        $(mkinstalldirs) $(DESTDIR)$(localstatedir)/log
+       $(mkinstalldirs) $(DESTDIR)$(sysconfdir)
+       if test -e $(DESTDIR)$(sysconfdir)/collectd.conf; \
+       then \
+               $(INSTALL) -m 0640 $(srcdir)/src/collectd.conf $(DESTDIR)$(sysconfdir)/collectd.conf.pkg-orig; \
+       else \
+               $(INSTALL) -m 0640 $(srcdir)/src/collectd.conf $(DESTDIR)$(sysconfdir)/collectd.conf; \
+       fi; \
+       $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
+       $(INSTALL) -m 0644 $(srcdir)/src/types.db $(DESTDIR)$(pkgdatadir)/types.db;
+       $(INSTALL) -m 0644 $(srcdir)/src/postgresql_default.conf \
+               $(DESTDIR)$(pkgdatadir)/postgresql_default.conf;
+
+uninstall-hook:
+       rm -f $(DESTDIR)$(pkgdatadir)/types.db;
+       rm -f $(DESTDIR)$(sysconfdir)/collectd.conf
+       rm -f $(DESTDIR)$(pkgdatadir)/postgresql_default.conf;
 
-maintainer-clean-local:
-       -rm -f -r libltdl
-       -rm -f INSTALL
-       -rm -f aclocal.m4
+all-local: @PERL_BINDINGS@
+
+install-exec-local:
+       [ ! -f buildperl/Makefile ] || ( cd buildperl && $(MAKE) install )
+
+# Perl 'make uninstall' does not work as well as wanted.
+# So we do the work here.
+uninstall-local:
+       @PERL@ -I$(DESTDIR)$(prefix) $(srcdir)/bindings/perl/uninstall_mod.pl Collectd
+       find $(DESTDIR)$(prefix) -name "perllocal.pod" -exec rm {} \;
+
+clean-local:
+       rm -rf buildperl
+
+perl: buildperl/Makefile
+       cd buildperl && $(MAKE)
+
+buildperl/Makefile: .perl-directory-stamp buildperl/Makefile.PL \
+       $(top_builddir)/config.status
+       @# beautify the output a bit
+       @echo 'cd buildperl && @PERL@ Makefile.PL @PERL_BINDINGS_OPTIONS@'
+       @cd buildperl && ( if ! @PERL@ Makefile.PL @PERL_BINDINGS_OPTIONS@; then \
+                       echo ""; \
+                       echo 'Check whether you have set $$PERL_MM_OPT in your environment and try using ./configure --with-perl-bindings=""'; \
+                       echo ""; \
+               fi )
+
+buildperl/Makefile.PL: .perl-directory-stamp $(top_builddir)/config.status
+
+.perl-directory-stamp:
+       if test ! -d buildperl; then \
+         mkdir -p buildperl/Collectd/Plugins; \
+         cp $(srcdir)/bindings/perl/lib/Collectd.pm buildperl/; \
+         cp $(srcdir)/bindings/perl/Makefile.PL buildperl/; \
+         cp $(srcdir)/bindings/perl/lib/Collectd/Unixsock.pm buildperl/Collectd/; \
+         cp $(srcdir)/bindings/perl/lib/Collectd/Plugins/OpenVZ.pm buildperl/Collectd/Plugins/; \
+       fi
+       touch $@
+
+.PHONY: perl
+
+
+if BUILD_WITH_JAVA
+dist_noinst_JAVA = \
+       bindings/java/org/collectd/api/Collectd.java \
+       bindings/java/org/collectd/api/CollectdConfigInterface.java \
+       bindings/java/org/collectd/api/CollectdFlushInterface.java \
+       bindings/java/org/collectd/api/CollectdInitInterface.java \
+       bindings/java/org/collectd/api/CollectdLogInterface.java \
+       bindings/java/org/collectd/api/CollectdMatchFactoryInterface.java \
+       bindings/java/org/collectd/api/CollectdMatchInterface.java \
+       bindings/java/org/collectd/api/CollectdNotificationInterface.java \
+       bindings/java/org/collectd/api/CollectdReadInterface.java \
+       bindings/java/org/collectd/api/CollectdShutdownInterface.java \
+       bindings/java/org/collectd/api/CollectdTargetFactoryInterface.java \
+       bindings/java/org/collectd/api/CollectdTargetInterface.java \
+       bindings/java/org/collectd/api/CollectdWriteInterface.java \
+       bindings/java/org/collectd/api/DataSet.java \
+       bindings/java/org/collectd/api/DataSource.java \
+       bindings/java/org/collectd/api/Notification.java \
+       bindings/java/org/collectd/api/OConfigItem.java \
+       bindings/java/org/collectd/api/OConfigValue.java \
+       bindings/java/org/collectd/api/PluginData.java \
+       bindings/java/org/collectd/api/ValueList.java \
+       bindings/java/org/collectd/java/GenericJMX.java \
+       bindings/java/org/collectd/java/GenericJMXConfConnection.java \
+       bindings/java/org/collectd/java/GenericJMXConfMBean.java \
+       bindings/java/org/collectd/java/GenericJMXConfValue.java \
+       bindings/java/org/collectd/java/JMXMemory.java
+
+collectd-api.jar: classnoinst.stamp
+       $(JAR) cf $(JARFLAGS) $@ org/collectd/api/*.class
+
+generic-jmx.jar: classnoinst.stamp
+       $(JAR) cf $(JARFLAGS) $@ org/collectd/java/*.class
+
+jar_DATA = collectd-api.jar generic-jmx.jar
+endif
diff --git a/README b/README
index 803fbaa..fb3aa27 100644 (file)
--- a/README
+++ b/README
@@ -198,14 +198,19 @@ Features
       Queries very detailed usage statistics from wireless LAN adapters and
       interfaces that use the Atheros chipset and the MadWifi driver.
 
-    - md
-      Linux software-RAID device information (number of active, failed, spare
-      and missing disks).
-
     - mbmon
       Motherboard sensors: temperature, fan speed and voltage information,
       using mbmon(1).
 
+    - mcelog
+      Monitor machine check exceptions (hardware errors detected by hardware
+      and reported to software) reported by mcelog and generate appropriate
+      notifications when machine check exceptions are detected.
+
+    - md
+      Linux software-RAID device information (number of active, failed, spare
+      and missing disks).
+
     - memcachec
       Query and parse data from a memcache daemon (memcached).
 
@@ -283,6 +288,15 @@ Features
     - oracle
       Query data from an Oracle database.
 
+    - ovs_events
+      The plugin monitors the link status of Open vSwitch (OVS) connected
+      interfaces, dispatches the values to collectd and sends the notification
+      whenever the link state change occurs in the OVS database. 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
@@ -750,10 +764,6 @@ Prerequisites
     Used by the `gps' plugin.
     <http://developer.berlios.de/projects/gpsd/>
 
-  * libhal (optional)
-    If present, the `uuid' plugin will check for UUID from HAL.
-    <http://hal.freedesktop.org/>
-
   * libi2c-dev (optional)
     Used for the plugin `barometer', provides just the i2c-dev.h header file
     for user space i2c development.
@@ -925,8 +935,8 @@ Prerequisites
     <http://www.xmms.org/>
 
   * libyajl (optional)
-    Parse JSON data. This is needed for the `ceph', `curl_json' and
-    `log_logstash' plugins.
+    Parse JSON data. This is needed for the `ceph', `curl_json', 'ovs_events'
+    and `log_logstash' plugins.
     <http://github.com/lloyd/yajl>
 
   * libvarnish (optional)
@@ -981,7 +991,6 @@ To generate the `configure` script, you'll need the following dependencies:
 - flex
 - bison
 - libtool
-- libtool-ltdl
 - pkg-config
 
 The `build.sh' script takes no arguments.
diff --git a/bindings/Makefile.am b/bindings/Makefile.am
deleted file mode 100644 (file)
index 07373e8..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-SUBDIRS =
-
-if BUILD_WITH_JAVA
-SUBDIRS += java
-endif
-
-EXTRA_DIST = perl/Makefile.PL \
-            perl/uninstall_mod.pl \
-            perl/lib/Collectd.pm \
-            perl/lib/Collectd/Unixsock.pm \
-            perl/lib/Collectd/Plugins/Monitorus.pm \
-            perl/lib/Collectd/Plugins/OpenVZ.pm
-
-CLEANFILES = \
-       buildperl/Collectd.pm \
-       buildperl/Collectd/Plugins/OpenVZ.pm \
-       buildperl/Collectd/Unixsock.pm \
-       buildperl/Makefile.PL \
-       .perl-directory-stamp
-
-DISTCLEANFILES = \
-       buildperl/Collectd.pm \
-       buildperl/Collectd/Plugins/OpenVZ.pm \
-       buildperl/Collectd/Unixsock.pm \
-       buildperl/Makefile.PL \
-       .perl-directory-stamp
-
-all-local: @PERL_BINDINGS@
-
-
-install-exec-local:
-       [ ! -f buildperl/Makefile ] || ( cd buildperl && $(MAKE) install )
-
-# Perl 'make uninstall' does not work as well as wanted.
-# So we do the work here.
-uninstall-local:
-       @PERL@ -I$(DESTDIR)$(prefix) $(srcdir)/perl/uninstall_mod.pl Collectd
-       find $(DESTDIR)$(prefix) -name "perllocal.pod" -exec rm {} \;
-
-clean-local:
-       rm -rf buildperl
-
-perl: buildperl/Makefile
-       cd buildperl && $(MAKE)
-
-buildperl/Makefile: .perl-directory-stamp buildperl/Makefile.PL \
-       $(top_builddir)/config.status
-       @# beautify the output a bit
-       @echo 'cd buildperl && @PERL@ Makefile.PL @PERL_BINDINGS_OPTIONS@'
-       @cd buildperl && ( if ! @PERL@ Makefile.PL @PERL_BINDINGS_OPTIONS@; then \
-                       echo ""; \
-                       echo 'Check whether you have set $$PERL_MM_OPT in your environment and try using ./configure --with-perl-bindings=""'; \
-                       echo ""; \
-               fi )
-
-buildperl/Makefile.PL: .perl-directory-stamp $(top_builddir)/config.status
-
-.perl-directory-stamp:
-       if test ! -d buildperl; then \
-         mkdir -p buildperl/Collectd/Plugins; \
-         cp $(srcdir)/perl/lib/Collectd.pm buildperl/; \
-         cp $(srcdir)/perl/Makefile.PL buildperl/; \
-         cp $(srcdir)/perl/lib/Collectd/Unixsock.pm buildperl/Collectd/; \
-         cp $(srcdir)/perl/lib/Collectd/Plugins/OpenVZ.pm buildperl/Collectd/Plugins/; \
-       fi
-       touch $@
-
-.PHONY: perl
-
diff --git a/bindings/java/Makefile.am b/bindings/java/Makefile.am
deleted file mode 100644 (file)
index 8d2e49d..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-EXTRA_DIST = org/collectd/api/CollectdConfigInterface.java \
-            org/collectd/api/CollectdFlushInterface.java \
-            org/collectd/api/CollectdInitInterface.java \
-            org/collectd/api/Collectd.java \
-            org/collectd/api/CollectdLogInterface.java \
-            org/collectd/api/CollectdMatchFactoryInterface.java \
-            org/collectd/api/CollectdMatchInterface.java \
-            org/collectd/api/CollectdNotificationInterface.java \
-            org/collectd/api/CollectdReadInterface.java \
-            org/collectd/api/CollectdShutdownInterface.java \
-            org/collectd/api/CollectdTargetFactoryInterface.java \
-            org/collectd/api/CollectdTargetInterface.java \
-            org/collectd/api/CollectdWriteInterface.java \
-            org/collectd/api/DataSet.java \
-            org/collectd/api/DataSource.java \
-            org/collectd/api/Notification.java \
-            org/collectd/api/OConfigItem.java \
-            org/collectd/api/OConfigValue.java \
-            org/collectd/api/PluginData.java \
-            org/collectd/api/ValueList.java \
-            org/collectd/java/GenericJMXConfConnection.java \
-            org/collectd/java/GenericJMXConfMBean.java \
-            org/collectd/java/GenericJMXConfValue.java \
-            org/collectd/java/GenericJMX.java \
-            org/collectd/java/JMXMemory.java
-
-java-build-stamp: $(srcdir)/org/collectd/api/*.java $(srcdir)/org/collectd/java/*.java
-       $(JAVAC) -d "." "$(srcdir)/org/collectd/api"/*.java
-       $(JAVAC) -d "." "$(srcdir)/org/collectd/java"/*.java
-       mkdir -p .libs
-       $(JAR) cf .libs/collectd-api.jar "org/collectd/api"/*.class
-       $(JAR) cf .libs/generic-jmx.jar "org/collectd/java"/*.class
-       touch "$@"
-
-all-local: java-build-stamp
-
-install-exec-local: java-build-stamp
-       mkdir -p "$(DESTDIR)$(pkgdatadir)/java"
-       $(INSTALL) -m 644 .libs/collectd-api.jar \
-               "$(DESTDIR)$(pkgdatadir)/java"
-       $(INSTALL) -m 644 .libs/generic-jmx.jar \
-               "$(DESTDIR)$(pkgdatadir)/java"
-
-uninstall-local:
-       rm -f "$(DESTDIR)$(pkgdatadir)/java/collectd-api.jar"
-       rm -f "$(DESTDIR)$(pkgdatadir)/java/generic-jmx.jar"
-       rmdir "$(DESTDIR)$(pkgdatadir)/java" || true
-
-clean-local:
-       rm -f "org/collectd/api"/*.class
-       rm -f "org/collectd/java"/*.class
-       rm -f .libs
-       rm -f "java-build-stamp"
index 63b7628..6d3d688 100644 (file)
@@ -30,6 +30,8 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.Collection;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
 import java.util.Iterator;
 import java.util.ArrayList;
 
@@ -128,6 +130,14 @@ class GenericJMXConfValue
     {
       return (BigInteger.ZERO.add ((BigInteger) obj));
     }
+    else if (obj instanceof AtomicInteger)
+    {
+        return (new Integer(((AtomicInteger) obj).get()));
+    }
+    else if (obj instanceof AtomicLong)
+    {
+        return (new Long(((AtomicLong) obj).get()));
+    }
 
     return (null);
   } /* }}} Number genericObjectToNumber */
index 57f3d44..465eff9 100755 (executable)
--- a/build.sh
+++ b/build.sh
@@ -54,6 +54,6 @@ set -x
 
 autoheader \
 && aclocal \
-&& $libtoolize --ltdl --copy --force \
+&& $libtoolize --copy --force \
 && automake --add-missing --copy \
 && autoconf
index 6780cda..ac3c310 100755 (executable)
--- a/clean.sh
+++ b/clean.sh
@@ -15,7 +15,6 @@ true \
 && rm -f configure \
 && rm -f depcomp \
 && rm -f install-sh \
-&& rm -f -r libltdl \
 && rm -f libtool \
 && rm -f ltmain.sh \
 && rm -f Makefile \
index ab6f229..0154d82 100644 (file)
@@ -3,34 +3,15 @@ AC_PREREQ([2.60])
 AC_INIT([collectd],[m4_esyscmd(./version-gen.sh)])
 AC_CONFIG_SRCDIR(src/target_set.c)
 AC_CONFIG_HEADERS(src/config.h)
-AC_CONFIG_AUX_DIR([libltdl/config])
+AC_CONFIG_AUX_DIR([build-aux])
+AC_CONFIG_MACRO_DIR([m4])
 
 dnl older automake's default of ARFLAGS=cru is noisy on newer binutils;
 dnl we don't really need the 'u' even in older toolchains.  Then there is
 dnl older libtool, which spelled it AR_FLAGS
 m4_divert_text([DEFAULTS], [: "${ARFLAGS=cr} ${AR_FLAGS=cr}"])
 
-m4_ifdef([LT_PACKAGE_VERSION],
-       # libtool >= 2.2
-       [
-        LT_CONFIG_LTDL_DIR([libltdl])
-        LT_INIT([dlopen])
-        LTDL_INIT([convenience])
-        AC_DEFINE(LIBTOOL_VERSION, 2, [Define to used libtool version.])
-       ]
-,
-       # libtool <= 1.5
-       [
-        AC_LIBLTDL_CONVENIENCE
-        AC_SUBST(LTDLINCL)
-        AC_SUBST(LIBLTDL)
-        AC_LIBTOOL_DLOPEN
-        AC_CONFIG_SUBDIRS(libltdl)
-        AC_DEFINE(LIBTOOL_VERSION, 1, [Define to used libtool version.])
-       ]
-)
-
-AM_CONDITIONAL([BUILD_INCLUDED_LTDL], [test "x$LTDLDEPS" != "x"])
+LT_INIT([dlopen disable-static])
 
 AM_INIT_AUTOMAKE([subdir-objects tar-pax dist-bzip2 no-dist-gzip foreign])
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
@@ -53,10 +34,8 @@ AC_PROG_INSTALL
 AC_PROG_LN_S
 AC_PROG_MAKE_SET
 AM_PROG_CC_C_O
-AM_CONDITIONAL(COMPILER_IS_GCC, test "x$GCC" = "xyes")
+AM_CONDITIONAL([COMPILER_IS_GCC], [test "x$GCC" = "xyes"])
 
-AC_DISABLE_STATIC
-AC_PROG_LIBTOOL
 AC_PROG_LEX
 AC_PROG_YACC
 
@@ -67,78 +46,60 @@ m4_pattern_forbid([^_?PKG_[A-Z_]+$],[*** pkg.m4 missing, please install pkg-conf
 
 PKG_PROG_PKG_CONFIG
 
-AC_CACHE_CHECK([if bison is the parser generator],
-       [collectd_cv_prog_bison],
-       [AS_IF([$YACC --version 2>/dev/null | $EGREP -q '^bison '],
-               [collectd_cv_prog_bison=yes], [collectd_cv_prog_bison=no]
-       )]
+AC_CACHE_CHECK([if Bison is the parser generator],
+  [collectd_cv_prog_bison],
+  [
+    AS_IF([$YACC --version 2>/dev/null | $EGREP -q '^bison '],
+      [collectd_cv_prog_bison=yes],
+      [collectd_cv_prog_bison=no]
+    )
+  ]
 )
 
-if test "x$collectd_cv_prog_bison" = "xno" && test ! -f "${srcdir}/src/liboconfig/parser.c"
-then
-       AC_MSG_ERROR([bison is missing and you do not have ${srcdir}/src/liboconfig/parser.c. Please install bison])
+if test "x$collectd_cv_prog_bison" = "xno" && test ! -f "${srcdir}/src/liboconfig/parser.c"; then
+  AC_MSG_ERROR([bison is missing and you do not have ${srcdir}/src/liboconfig/parser.c. Please install bison])
 fi
 
-AC_ARG_VAR([PROTOC], [path to the protoc binary])
-AC_PATH_PROG([PROTOC], [protoc])
-have_protoc3="no"
-if test "x$PROTOC" != "x"; then
-       AC_MSG_CHECKING([for protoc 3.0.0+])
-       if $PROTOC --version | $EGREP libprotoc.3 >/dev/null; then
-               protoc3="yes (`$PROTOC --version`)"
-               have_protoc3="yes"
-       else
-               protoc3="no (`$PROTOC --version`)"
-       fi
-       AC_MSG_RESULT([$protoc3])
-fi
-AM_CONDITIONAL(HAVE_PROTOC3, test "x$have_protoc3" = "xyes")
+AS_IF([test "x$lt_cv_dlopen" = "xno"],
+  [AC_MSG_ERROR([Your system does not support dlopen])]
+)
 
-AC_ARG_VAR([GRPC_CPP_PLUGIN], [path to the grpc_cpp_plugin binary])
-AC_PATH_PROG([GRPC_CPP_PLUGIN], [grpc_cpp_plugin])
-AM_CONDITIONAL(HAVE_GRPC_CPP, test "x$GRPC_CPP_PLUGIN" != "x")
+AC_SUBST([DLOPEN_LIBS], [$lt_cv_dlopen_libs])
 
-AC_ARG_VAR([PROTOC_C], [path to the protoc-c binary])
-AC_PATH_PROG([PROTOC_C], [protoc-c])
-if test "x$PROTOC_C" = "x"
-then
-  have_protoc_c="no (protoc-c compiler not found)"
-else
-  have_protoc_c="yes"
-fi
 
 AC_MSG_CHECKING([for kernel type ($host_os)])
 case $host_os in
-       *linux*)
-       AC_DEFINE([KERNEL_LINUX], 1, [True if program is to be compiled for a Linux kernel])
-       ac_system="Linux"
-       ;;
-       *solaris*)
-       AC_DEFINE([KERNEL_SOLARIS], 1, [True if program is to be compiled for a Solaris kernel])
-       ac_system="Solaris"
-       ;;
-       *darwin*)
-       AC_DEFINE([KERNEL_DARWIN], 1, [True if program is to be compiled for a Darwin kernel])
-       ac_system="Darwin"
-       ;;
-       *openbsd*)
-       AC_DEFINE([KERNEL_OPENBSD], 1, [True if program is to be compiled for an OpenBSD kernel])
-       ac_system="OpenBSD"
-       ;;
-       *netbsd*)
-       AC_DEFINE([KERNEL_NETBSD], 1, [True if program is to be compiled for a NetBSD kernel])
-       ac_system="NetBSD"
-       ;;
-       *aix*)
-       AC_DEFINE([KERNEL_AIX], 1, [True if program is to be compiled for a AIX kernel])
-       ac_system="AIX"
-       ;;
-       *freebsd*)
-       AC_DEFINE([KERNEL_FREEBSD], 1, [True if program is to be compiled for a FreeBSD kernel])
-       ac_system="FreeBSD"
-       ;;
-       *)
-       ac_system="unknown"
+  *aix*)
+    AC_DEFINE([KERNEL_AIX], [1], [True if program is to be compiled for a AIX kernel])
+    ac_system="AIX"
+    ;;
+  *darwin*)
+    AC_DEFINE([KERNEL_DARWIN], [1], [True if program is to be compiled for a Darwin kernel])
+    ac_system="Darwin"
+    ;;
+  *freebsd*)
+    AC_DEFINE([KERNEL_FREEBSD], [1], [True if program is to be compiled for a FreeBSD kernel])
+    ac_system="FreeBSD"
+    ;;
+  *linux*)
+    AC_DEFINE([KERNEL_LINUX], [1], [True if program is to be compiled for a Linux kernel])
+    ac_system="Linux"
+    ;;
+  *netbsd*)
+    AC_DEFINE([KERNEL_NETBSD], [1], [True if program is to be compiled for a NetBSD kernel])
+    ac_system="NetBSD"
+    ;;
+  *openbsd*)
+    AC_DEFINE([KERNEL_OPENBSD], [1], [True if program is to be compiled for an OpenBSD kernel])
+    ac_system="OpenBSD"
+    ;;
+  *solaris*)
+    AC_DEFINE([KERNEL_SOLARIS], [1], [True if program is to be compiled for a Solaris kernel])
+    ac_system="Solaris"
+    ;;
+  *)
+    ac_system="unknown"
+    ;;
 esac
 AC_MSG_RESULT([$ac_system])
 
@@ -149,77 +110,55 @@ AM_CONDITIONAL([BUILD_LINUX], [test "x$ac_system" = "xLinux"])
 AM_CONDITIONAL([BUILD_OPENBSD], [test "x$ac_system" = "xOpenBSD"])
 AM_CONDITIONAL([BUILD_SOLARIS], [test "x$ac_system" = "xSolaris"])
 
-if test "x$ac_system" = "xLinux"
-then
-       AC_ARG_VAR([KERNEL_DIR], [path to Linux kernel sources])
-       if test -z "$KERNEL_DIR"
-       then
-               KERNEL_DIR="/lib/modules/`uname -r`/source"
-       fi
+if test "x$ac_system" = "xLinux"; then
+  AC_ARG_VAR([KERNEL_DIR], [path to Linux kernel sources])
+  if test "x$KERNEL_DIR" = "x"; then
+    KERNEL_DIR="/lib/modules/`uname -r`/source"
+  fi
+  KERNEL_CFLAGS="-I$KERNEL_DIR/include"
+  AC_SUBST([KERNEL_CFLAGS])
+fi
+
+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.])
 
-       KERNEL_CFLAGS="-I$KERNEL_DIR/include"
-       AC_SUBST(KERNEL_CFLAGS)
+  AC_MSG_CHECKING([whether compiler builds 64bit binaries])
+  AC_COMPILE_IFELSE(
+    [
+      AC_LANG_PROGRAM(
+        [
+          #ifndef _LP64
+          # error "Compiler not in 64bit mode."
+          #endif
+        ]
+      )
+    ],
+    [AC_MSG_RESULT([yes])],
+    [
+      AC_MSG_RESULT([no])
+      AC_MSG_NOTICE([Solaris detected. Please consider building a 64-bit binary.])
+    ]
+  )
 fi
 
-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.])
-
-       AC_MSG_CHECKING([whether compiler builds 64bit binaries])
-       AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
-                          #ifndef _LP64
-                          # error "Compiler not in 64bit mode."
-                          #endif
-                          ])],
-                          [AC_MSG_RESULT([yes])],
-                          [
-                           AC_MSG_RESULT([no])
-                           AC_MSG_NOTICE([Solaris detected. Please consider building a 64-bit binary.])
-                          ])
-fi
-
-if test "x$ac_system" = "xAIX"
-then
-       AC_DEFINE(_THREAD_SAFE_ERRNO, 1, [Define to use the thread-safe version of errno under AIX.])
+if test "x$ac_system" = "xAIX"; then
+  AC_DEFINE([_THREAD_SAFE_ERRNO], [1], [Define to use the thread-safe version of errno under AIX.])
 fi
 
 # Where to install .pc files.
 pkgconfigdir="${libdir}/pkgconfig"
-AC_SUBST(pkgconfigdir)
-
-# Check for standards compliance mode
-AC_ARG_ENABLE(standards,
-             AS_HELP_STRING([--enable-standards], [Enable standards compliance mode]),
-             [enable_standards="$enableval"],
-             [enable_standards="no"])
-if test "x$enable_standards" = "xyes"
-then
-       AC_DEFINE(_ISOC99_SOURCE,        1, [Define to enforce ISO C99 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")
+AC_SUBST([pkgconfigdir])
 
 #
 # Checks for header files.
 #
-AC_HEADER_STDC
 AC_HEADER_SYS_WAIT
 AC_HEADER_DIRENT
-AC_HEADER_STDBOOL
 
-AC_CHECK_HEADERS([ \
+AC_CHECK_HEADERS_ONCE([ \
   arpa/inet.h \
-  assert.h \
-  ctype.h \
   endian.h \
-  errno.h \
   fcntl.h \
   fnmatch.h \
   fs_info.h \
@@ -228,9 +167,6 @@ AC_CHECK_HEADERS([ \
   kstat.h \
   kvm.h \
   libgen.h \
-  limits.h \
-  locale.h \
-  math.h \
   mntent.h \
   mnttab.h \
   netdb.h \
@@ -239,9 +175,6 @@ AC_CHECK_HEADERS([ \
   pthread_np.h \
   pwd.h \
   regex.h \
-  signal.h \
-  stdarg.h \
-  stdio.h \
   sys/fs_types.h \
   sys/fstyp.h \
   sys/ioctl.h \
@@ -260,450 +193,461 @@ AC_CHECK_HEADERS([ \
   sys/vfstab.h \
   sys/vmmeter.h \
   syslog.h \
-  wordexp.h \
+  wordexp.h
 ])
 
-# For entropy plugin on newer NetBSD
-AC_CHECK_HEADERS(sys/rndio.h, [], [],
-[#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_SYS_IOCTL_H
-# include <sys/ioctl.h>
-#endif
-#if HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif
-])
+if test "x$ac_system" = "xNetBSD"; then
+  # For entropy plugin on newer NetBSD
+  AC_CHECK_HEADERS([sys/rndio.h], [], [],
+    [[
+      #if HAVE_SYS_TYPES_H
+      # include <sys/types.h>
+      #endif
+      #if HAVE_SYS_IOCTL_H
+      # include <sys/ioctl.h>
+      #endif
+      #if HAVE_SYS_PARAM_H
+      # include <sys/param.h>
+      #endif
+    ]]
+  )
+fi
 
 # For ping library
-AC_CHECK_HEADERS(netinet/in_systm.h, [], [],
-[#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-])
-AC_CHECK_HEADERS(netinet/in.h, [], [],
-[#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-])
-AC_CHECK_HEADERS(netinet/ip.h, [], [],
-[#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-])
-AC_CHECK_HEADERS(netinet/ip_icmp.h, [], [],
-[#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#if HAVE_NETINET_IP_H
-# include <netinet/ip.h>
-#endif
-])
-AC_CHECK_HEADERS(netinet/ip_var.h, [], [],
-[#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#if HAVE_NETINET_IP_H
-# include <netinet/ip.h>
-#endif
-])
-AC_CHECK_HEADERS(netinet/ip6.h, [], [],
-[#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-])
-AC_CHECK_HEADERS(netinet/icmp6.h, [], [],
-[#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#if HAVE_NETINET_IP6_H
-# include <netinet/ip6.h>
-#endif
-])
-AC_CHECK_HEADERS(netinet/tcp.h, [], [],
-[#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#if HAVE_NETINET_IP_H
-# include <netinet/ip.h>
-#endif
-])
-AC_CHECK_HEADERS(netinet/udp.h, [], [],
-[#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#if HAVE_NETINET_IP_H
-# include <netinet/ip.h>
-#endif
-])
-
-have_ip6_ext="no"
-AC_CHECK_TYPES([struct ip6_ext], [have_ip6_ext="yes"], [have_ip6_ext="no"],
-[#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#if HAVE_NETINET_IP6_H
-# include <netinet/ip6.h>
-#endif
-])
+AC_CHECK_HEADERS([netinet/in_systm.h], [], [],
+  [[
+    #include <stdint.h>
+    #if HAVE_SYS_TYPES_H
+    # include <sys/types.h>
+    #endif
+  ]]
+)
 
-if test "x$have_ip6_ext" = "xno"; then
-       SAVE_CFLAGS="$CFLAGS"
-       CFLAGS="$CFLAGS -DSOLARIS2=8"
-
-       AC_CHECK_TYPES([struct ip6_ext],
-                      [have_ip6_ext="yes, with -DSOLARIS2=8"],
-                      [have_ip6_ext="no"],
-[#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#if HAVE_NETINET_IP6_H
-# include <netinet/ip6.h>
-#endif
-])
+AC_CHECK_HEADERS([netinet/in.h], [], [],
+  [[
+    #include <stdint.h>
+    #if HAVE_SYS_TYPES_H
+    # include <sys/types.h>
+    #endif
+    #if HAVE_NETINET_IN_SYSTM_H
+    # include <netinet/in_systm.h>
+    #endif
+  ]]
+)
 
-       if test "x$have_ip6_ext" = "xno"; then
-               CFLAGS="$SAVE_CFLAGS"
-       fi
-fi
+AC_CHECK_HEADERS([netinet/ip.h], [], [],
+  [[
+    #include <stdint.h>
+    #if HAVE_SYS_TYPES_H
+    # include <sys/types.h>
+    #endif
+    #if HAVE_NETINET_IN_SYSTM_H
+    # include <netinet/in_systm.h>
+    #endif
+    #if HAVE_NETINET_IN_H
+    # include <netinet/in.h>
+    #endif
+  ]]
+)
 
-# For cpu modules
-AC_CHECK_HEADERS(sys/dkstat.h)
-if test "x$ac_system" = "xDarwin"
-then
-       AC_CHECK_HEADERS(mach/mach_init.h mach/host_priv.h mach/mach_error.h mach/mach_host.h mach/mach_port.h mach/mach_types.h mach/message.h mach/processor_set.h mach/processor.h mach/processor_info.h mach/task.h mach/thread_act.h mach/vm_region.h mach/vm_map.h mach/vm_prot.h mach/vm_statistics.h mach/kern_return.h)
-       AC_CHECK_HEADERS(CoreFoundation/CoreFoundation.h IOKit/IOKitLib.h IOKit/IOTypes.h IOKit/ps/IOPSKeys.h IOKit/IOBSD.h IOKit/storage/IOBlockStorageDriver.h)
-       # For the battery plugin
-       AC_CHECK_HEADERS(IOKit/ps/IOPowerSources.h, [], [],
-[
-#if HAVE_IOKIT_IOKITLIB_H
-#  include <IOKit/IOKitLib.h>
-#endif
-#if HAVE_IOKIT_IOTYPES_H
-#  include <IOKit/IOTypes.h>
-#endif
-])
+AC_CHECK_HEADERS([netinet/ip_icmp.h], [], [],
+  [[
+    #include <stdint.h>
+    #if HAVE_SYS_TYPES_H
+    # include <sys/types.h>
+    #endif
+    #if HAVE_NETINET_IN_SYSTM_H
+    # include <netinet/in_systm.h>
+    #endif
+    #if HAVE_NETINET_IN_H
+    # include <netinet/in.h>
+    #endif
+    #if HAVE_NETINET_IP_H
+    # include <netinet/ip.h>
+    #endif
+  ]]
+)
 
-fi
+AC_CHECK_HEADERS([netinet/ip_var.h], [], [],
+  [[
+    #include <stdint.h>
+    #if HAVE_SYS_TYPES_H
+    # include <sys/types.h>
+    #endif
+    #if HAVE_NETINET_IN_SYSTM_H
+    # include <netinet/in_systm.h>
+    #endif
+    #if HAVE_NETINET_IN_H
+    # include <netinet/in.h>
+    #endif
+    #if HAVE_NETINET_IP_H
+    # include <netinet/ip.h>
+    #endif
+  ]]
+)
 
-AC_CHECK_HEADERS(sys/sysctl.h, [], [],
-[
-#if HAVE_SYS_TYPES_H
-#  include <sys/types.h>
-#endif
-#if HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif
-])
+AC_CHECK_HEADERS([netinet/ip6.h], [], [],
+  [[
+    #include <stdint.h>
+    #if HAVE_SYS_TYPES_H
+    # include <sys/types.h>
+    #endif
+    #if HAVE_NETINET_IN_SYSTM_H
+    # include <netinet/in_systm.h>
+    #endif
+    #if HAVE_NETINET_IN_H
+    # include <netinet/in.h>
+    #endif
+  ]]
+)
 
-AC_MSG_CHECKING([for sysctl kern.cp_times])
-if test -x /sbin/sysctl
-then
-       /sbin/sysctl kern.cp_times >/dev/null 2>&1
-       if test $? -eq 0
-       then
-               AC_MSG_RESULT([yes])
-               AC_DEFINE(HAVE_SYSCTL_KERN_CP_TIMES, 1,
-               [Define if sysctl supports kern.cp_times])
-       else
-               AC_MSG_RESULT([no])
-       fi
-else
-       AC_MSG_RESULT([no])
-fi
+AC_CHECK_HEADERS([netinet/icmp6.h], [], [],
+  [[
+    #include <stdint.h>
+    #if HAVE_SYS_TYPES_H
+    # include <sys/types.h>
+    #endif
+    #if HAVE_NETINET_IN_SYSTM_H
+    # include <netinet/in_systm.h>
+    #endif
+    #if HAVE_NETINET_IN_H
+    # include <netinet/in.h>
+    #endif
+    #if HAVE_NETINET_IP6_H
+    # include <netinet/ip6.h>
+    #endif
+  ]]
+)
 
-AC_MSG_CHECKING([for sysctl kern.cp_time])
-if test -x /sbin/sysctl
-then
-       /sbin/sysctl kern.cp_time >/dev/null 2>&1
-       if test $? -eq 0
-       then
-               AC_MSG_RESULT([yes])
-               AC_DEFINE(HAVE_SYSCTL_KERN_CP_TIME, 1,
-                       [Define if sysctl supports kern.cp_time])
-       else
-               AC_MSG_RESULT([no])
-       fi
-else
-       AC_MSG_RESULT([no])
-fi
+AC_CHECK_HEADERS([netinet/tcp.h], [], [],
+  [[
+    #include <stdint.h>
+    #if HAVE_SYS_TYPES_H
+    # include <sys/types.h>
+    #endif
+    #if HAVE_NETINET_IN_SYSTM_H
+    # include <netinet/in_systm.h>
+    #endif
+    #if HAVE_NETINET_IN_H
+    # include <netinet/in.h>
+    #endif
+    #if HAVE_NETINET_IP_H
+    # include <netinet/ip.h>
+    #endif
+  ]]
+)
 
-# For hddtemp module
-AC_CHECK_HEADERS(linux/major.h)
+AC_CHECK_HEADERS([netinet/udp.h], [], [],
+  [[
+    #include <stdint.h>
+    #if HAVE_SYS_TYPES_H
+    # include <sys/types.h>
+    #endif
+    #if HAVE_NETINET_IN_SYSTM_H
+    # include <netinet/in_systm.h>
+    #endif
+    #if HAVE_NETINET_IN_H
+    # include <netinet/in.h>
+    #endif
+    #if HAVE_NETINET_IP_H
+    # include <netinet/ip.h>
+    #endif
+  ]]
+)
 
-# For md module (Linux only)
-if test "x$ac_system" = "xLinux"
-then
-       AC_CHECK_HEADERS(linux/raid/md_u.h,
-                        [have_linux_raid_md_u_h="yes"],
-                        [have_linux_raid_md_u_h="no"],
-[
-#include <sys/ioctl.h>
-#include <linux/major.h>
-#include <linux/types.h>
-])
-       AC_CHECK_HEADERS([sys/sysmacros.h])
-else
-       have_linux_raid_md_u_h="no"
-fi
+# For cpu modules
+AC_CHECK_HEADERS([sys/dkstat.h])
+if test "x$ac_system" = "xDarwin"; then
+  AC_CHECK_HEADERS(
+    [[ \
+      mach/mach_init.h \
+      mach/host_priv.h \
+      mach/mach_error.h \
+      mach/mach_host.h \
+      mach/mach_port.h \
+      mach/mach_types.h \
+      mach/message.h \
+      mach/processor_set.h \
+      mach/processor.h \
+      mach/processor_info.h \
+      mach/task.h \
+      mach/thread_act.h \
+      mach/vm_region.h \
+      mach/vm_map.h \
+      mach/vm_prot.h \
+      mach/vm_statistics.h \
+      mach/kern_return.h \
+      CoreFoundation/CoreFoundation.h \
+      IOKit/IOKitLib.h \
+      IOKit/IOTypes.h \
+      IOKit/ps/IOPSKeys.h \
+      IOKit/IOBSD.h \
+      IOKit/storage/IOBlockStorageDriver.h
+    ]]
+  )
 
-# For the wireless module
-have_linux_wireless_h="no"
-if test "x$ac_system" = "xLinux"
-then
-  AC_CHECK_HEADERS(linux/wireless.h,
-                  [have_linux_wireless_h="yes"],
-                  [have_linux_wireless_h="no"],
-[
-#include <dirent.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-])
+  # For the battery plugin
+  AC_CHECK_HEADERS([IOKit/ps/IOPowerSources.h], [], [],
+    [[
+      #if HAVE_IOKIT_IOKITLIB_H
+      #  include <IOKit/IOKitLib.h>
+      #endif
+      #if HAVE_IOKIT_IOTYPES_H
+      #  include <IOKit/IOTypes.h>
+      #endif
+    ]]
+  )
 fi
 
-# For the swap module
-have_sys_swap_h="yes"
-AC_CHECK_HEADERS(sys/swap.h vm/anon.h, [], [have_sys_swap_h="no"],
-[
-#undef _FILE_OFFSET_BITS
-#undef _LARGEFILE64_SOURCE
-#if HAVE_SYS_TYPES_H
-#  include <sys/types.h>
-#endif
-#if HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif
-])
-
-# For load module
-# For the processes plugin
-# For users module
-AC_CHECK_HEADERS(sys/loadavg.h linux/config.h utmp.h utmpx.h)
+AC_CHECK_HEADERS([sys/sysctl.h], [], [],
+  [[
+    #if HAVE_SYS_TYPES_H
+    #  include <sys/types.h>
+    #endif
+    #if HAVE_SYS_PARAM_H
+    # include <sys/param.h>
+    #endif
+  ]]
+)
 
 # For interface plugin
-AC_CHECK_HEADERS(ifaddrs.h)
-AC_CHECK_HEADERS(net/if.h, [], [],
-[
-#if HAVE_SYS_TYPES_H
-#  include <sys/types.h>
-#endif
-#if HAVE_SYS_SOCKET_H
-#  include <sys/socket.h>
-#endif
-])
-AC_CHECK_HEADERS(linux/if.h, [], [],
-[
-#if HAVE_SYS_TYPES_H
-#  include <sys/types.h>
-#endif
-#if HAVE_SYS_SOCKET_H
-#  include <sys/socket.h>
-#endif
-])
-AC_CHECK_HEADERS(linux/inet_diag.h, [], [],
-[
-#if HAVE_SYS_TYPES_H
-#  include <sys/types.h>
-#endif
-#if HAVE_SYS_SOCKET_H
-#  include <sys/socket.h>
-#endif
-#if HAVE_LINUX_INET_DIAG_H
-# include <linux/inet_diag.h>
-#endif
-])
-AC_CHECK_HEADERS(linux/netdevice.h, [], [],
-[
-#if HAVE_SYS_TYPES_H
-#  include <sys/types.h>
-#endif
-#if HAVE_SYS_SOCKET_H
-#  include <sys/socket.h>
-#endif
-#if HAVE_LINUX_IF_H
-# include <linux/if.h>
-#endif
-])
+AC_CHECK_HEADERS([ifaddrs.h])
+AC_CHECK_HEADERS([net/if.h], [], [],
+  [[
+    #if HAVE_SYS_TYPES_H
+    #  include <sys/types.h>
+    #endif
+    #if HAVE_SYS_SOCKET_H
+    #  include <sys/socket.h>
+    #endif
+  ]]
+)
+
+if test "x$ac_system" = "xLinux"; then
+  # For hddtemp module
+  AC_CHECK_HEADERS([linux/major.h])
+
+  # For md module (Linux only)
+  AC_CHECK_HEADERS([linux/raid/md_u.h],
+    [have_linux_raid_md_u_h="yes"],
+    [have_linux_raid_md_u_h="no"],
+    [[
+      #include <sys/ioctl.h>
+      #include <linux/major.h>
+      #include <linux/types.h>
+    ]]
+  )
+  AC_CHECK_HEADERS([sys/sysmacros.h])
+
+  AC_CHECK_HEADERS([linux/wireless.h],
+    [have_linux_wireless_h="yes"],
+    [have_linux_wireless_h="no"],
+    [[
+      #include <dirent.h>
+      #include <sys/ioctl.h>
+      #include <sys/socket.h>
+    ]]
+  )
 
-# For ethstat module
-AC_CHECK_HEADERS(linux/sockios.h,
+  AC_CHECK_HEADERS([linux/if.h], [], [],
+    [[
+      #if HAVE_SYS_TYPES_H
+      #  include <sys/types.h>
+      #endif
+      #if HAVE_SYS_SOCKET_H
+      #  include <sys/socket.h>
+      #endif
+    ]]
+  )
+  
+  AC_CHECK_HEADERS([linux/inet_diag.h], [], [],
+    [[
+      #if HAVE_SYS_TYPES_H
+      #  include <sys/types.h>
+      #endif
+      #if HAVE_SYS_SOCKET_H
+      #  include <sys/socket.h>
+      #endif
+    ]]
+  )
+  
+  AC_CHECK_HEADERS([linux/netdevice.h], [], [],
+    [[
+      #if HAVE_SYS_TYPES_H
+      #  include <sys/types.h>
+      #endif
+      #if HAVE_SYS_SOCKET_H
+      #  include <sys/socket.h>
+      #endif
+      #if HAVE_LINUX_IF_H
+      # include <linux/if.h>
+      #endif
+    ]]
+  )
+  
+  # For ethstat module
+  AC_CHECK_HEADERS([linux/sockios.h],
     [have_linux_sockios_h="yes"],
     [have_linux_sockios_h="no"],
-    [
-#if HAVE_SYS_IOCTL_H
-# include <sys/ioctl.h>
-#endif
-#if HAVE_NET_IF_H
-# include <net/if.h>
-#endif
-    ])
-AC_CHECK_HEADERS(linux/ethtool.h,
+    [[
+      #if HAVE_SYS_IOCTL_H
+      # include <sys/ioctl.h>
+      #endif
+      #if HAVE_NET_IF_H
+      # include <net/if.h>
+      #endif
+    ]]
+  )
+  
+  AC_CHECK_HEADERS([linux/ethtool.h],
     [have_linux_ethtool_h="yes"],
     [have_linux_ethtool_h="no"],
-    [
-#if HAVE_SYS_IOCTL_H
-# include <sys/ioctl.h>
-#endif
-#if HAVE_NET_IF_H
-# include <net/if.h>
-#endif
-#if HAVE_LINUX_SOCKIOS_H
-# include <linux/sockios.h>
-#endif
-    ])
-
-# For ipvs module
-have_linux_ip_vs_h="no"
-have_net_ip_vs_h="no"
-have_ip_vs_h="no"
-ip_vs_h_needs_kernel_cflags="no"
-if test "x$ac_system" = "xLinux"
-then
-       AC_CHECK_HEADERS(linux/ip_vs.h, [have_linux_ip_vs_h="yes"])
-       AC_CHECK_HEADERS(net/ip_vs.h, [have_net_ip_vs_h="yes"])
-       AC_CHECK_HEADERS(ip_vs.h, [have_ip_vs_h="yes"])
+    [[
+      #if HAVE_SYS_IOCTL_H
+      # include <sys/ioctl.h>
+      #endif
+      #if HAVE_NET_IF_H
+      # include <net/if.h>
+      #endif
+      #if HAVE_LINUX_SOCKIOS_H
+      # include <linux/sockios.h>
+      #endif
+    ]]
+  )
 
-       if test "x$have_linux_ip_vs_h$have_net_ip_vs_h$have_ip_vs_h" = "xnonono" && test -d "$KERNEL_DIR"
-       then
-               SAVE_CFLAGS="$CFLAGS"
-               CFLAGS="$CFLAGS $KERNEL_CFLAGS"
+  # For ipvs module
+  AC_CHECK_HEADERS([linux/ip_vs.h], [have_linux_ip_vs_h="yes"], [have_linux_ip_vs="no"])
+  AC_CHECK_HEADERS([net/ip_vs.h], [have_net_ip_vs_h="yes"], [have_net_ip_vs_h="no"])
+  AC_CHECK_HEADERS([ip_vs.h], [have_ip_vs_h="yes"], [have_ip_vs_h="no"])
+
+  ip_vs_h_needs_kernel_cflags="no"
+  
+  if test "x$have_linux_ip_vs_h$have_net_ip_vs_h$have_ip_vs_h" = "xnonono" && test -d "$KERNEL_DIR"; then
+    SAVE_CFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS $KERNEL_CFLAGS"
+    
+    AC_MSG_NOTICE([Did not find ip_vs.h. Trying again using headers from $KERNEL_DIR.])
+    
+    AC_CHECK_HEADERS([linux/ip_vs.h], [have_linux_ip_vs_h="yes"])
+    AC_CHECK_HEADERS([net/ip_vs.h], [have_net_ip_vs_h="yes"])
+    AC_CHECK_HEADERS([ip_vs.h], [have_ip_vs_h="yes"])
+    
+    if test "x$have_linux_ip_vs_h" = "xyes" || test "x$have_net_ip_vs_h" = "xyes" || test "x$have_ip_vs_h" = "xyes"; then
+      ip_vs_h_needs_kernel_cflags="yes"
+    fi
+    
+    CFLAGS="$SAVE_CFLAGS"
+  fi
 
-               AC_MSG_NOTICE([Did not find ip_vs.h. Trying again using headers from $KERNEL_DIR.])
+  # For the email plugin
+  AC_CHECK_HEADERS([linux/un.h], [], [],
+    [[
+      #if HAVE_SYS_SOCKET_H
+      #  include <sys/socket.h>
+      #endif
+    ]]
+  )
+  # For the turbostat plugin
+  AC_CHECK_HEADERS([asm/msr-index.h],
+    [have_asm_msrindex_h="yes"],
+    [have_asm_msrindex_h="no"]
+  )
+  
+  if test "x$have_asm_msrindex_h" = "xyes"; then
+    AC_CACHE_CHECK([whether asm/msr-index.h has MSR_PKG_C10_RESIDENCY],
+      [c_cv_have_usable_asm_msrindex_h],
+      [
+        AC_COMPILE_IFELSE(
+          [
+            AC_LANG_PROGRAM(
+              [[#include<asm/msr-index.h>]],
+              [[
+                int y = MSR_PKG_C10_RESIDENCY;
+                return(y);
+              ]]
+            )
+          ],
+          [c_cv_have_usable_asm_msrindex_h="yes"],
+          [c_cv_have_usable_asm_msrindex_h="no"],
+        )
+      ]
+    )
+  fi
+  
+  AC_CHECK_HEADERS([cpuid.h],
+    [have_cpuid_h="yes"],
+    [have_cpuid_h="no (cpuid.h not found)"]
+  )
+  
+  AC_CHECK_HEADERS([sys/capability.h],
+    [have_capability="yes"],
+    [have_capability="no (<sys/capability.h> not found)"]
+  )
 
-               AC_CHECK_HEADERS(linux/ip_vs.h, [have_linux_ip_vs_h="yes"])
-               AC_CHECK_HEADERS(net/ip_vs.h, [have_net_ip_vs_h="yes"])
-               AC_CHECK_HEADERS(ip_vs.h, [have_ip_vs_h="yes"])
+  if test "x$have_capability" = "xyes"; then
+    AC_CHECK_LIB([cap], [cap_get_bound],
+      [have_capability="yes"],
+      [have_capability="no (cap_get_bound() not found)"]
+    )
+  fi
 
-               if test "x$have_linux_ip_vs_h" = "xyes" || test "x$have_net_ip_vs_h" = "xyes" || test "x$have_ip_vs_h" = "xyes"
-               then
-                       ip_vs_h_needs_kernel_cflags="yes"
-               fi
+  if test "x$have_capability" = "xyes"; then
+    AC_DEFINE([HAVE_CAPABILITY], [1], [Define to 1 if you have cap_get_bound() (-lcap).])
+  fi
 
-               CFLAGS="$SAVE_CFLAGS"
-       fi
+else
+  have_linux_raid_md_u_h="no"
+  have_linux_wireless_h="no"
 fi
-AM_CONDITIONAL(IP_VS_H_NEEDS_KERNEL_CFLAGS, test "x$ip_vs_h_needs_kernel_cflags" = "xyes")
+
+AM_CONDITIONAL([IP_VS_H_NEEDS_KERNEL_CFLAGS], [test "x$ip_vs_h_needs_kernel_cflags" = "xyes"])
+AM_CONDITIONAL([BUILD_WITH_CAPABILITY], [test "x$have_capability" = "xyes"])
+
+# For the swap module
+have_sys_swap_h="yes"
+AC_CHECK_HEADERS([sys/swap.h vm/anon.h],
+  [],
+  [have_sys_swap_h="no"],
+  [[
+    #undef _FILE_OFFSET_BITS
+    #undef _LARGEFILE64_SOURCE
+    #if HAVE_SYS_TYPES_H
+    #  include <sys/types.h>
+    #endif
+    #if HAVE_SYS_PARAM_H
+    # include <sys/param.h>
+    #endif
+  ]]
+)
+
+# For load module
+# For the processes plugin
+# For users module
+AC_CHECK_HEADERS([sys/loadavg.h linux/config.h utmp.h utmpx.h])
 
 # For quota module
-AC_CHECK_HEADERS(sys/ucred.h, [], [],
-[
-#if HAVE_SYS_TYPES_H
-#  include <sys/types.h>
-#endif
-#if HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif
-])
+AC_CHECK_HEADERS([sys/ucred.h], [], [],
+  [[
+    #if HAVE_SYS_TYPES_H
+    #  include <sys/types.h>
+    #endif
+    #if HAVE_SYS_PARAM_H
+    # include <sys/param.h>
+    #endif
+  ]]
+)
 
 # For mount interface
-AC_CHECK_HEADERS(sys/mount.h, [], [],
-[
-#if HAVE_SYS_TYPES_H
-#  include <sys/types.h>
-#endif
-#if HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif
-])
-
-# For the email plugin
-AC_CHECK_HEADERS(linux/un.h, [], [],
-[
-#if HAVE_SYS_SOCKET_H
-#      include <sys/socket.h>
-#endif
-])
+AC_CHECK_HEADERS([sys/mount.h], [], [],
+  [[
+    #if HAVE_SYS_TYPES_H
+    #  include <sys/types.h>
+    #endif
+    #if HAVE_SYS_PARAM_H
+    # include <sys/param.h>
+    #endif
+  ]]
+)
 
 # --enable-xfs {{{
 AC_ARG_ENABLE([xfs],
@@ -727,122 +671,95 @@ fi
 # }}}
 
 # For the dns plugin
-AC_CHECK_HEADERS(arpa/nameser.h)
-AC_CHECK_HEADERS(arpa/nameser_compat.h, [], [],
-[
-#if HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#endif
-])
+AC_CHECK_HEADERS([arpa/nameser.h])
+AC_CHECK_HEADERS([arpa/nameser_compat.h], [], [],
+  [[
+    #if HAVE_ARPA_NAMESER_H
+    # include <arpa/nameser.h>
+    #endif
+  ]]
+)
 
-AC_CHECK_HEADERS(net/if_arp.h, [], [],
-[#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-])
-AC_CHECK_HEADERS(net/ppp_defs.h)
-AC_CHECK_HEADERS(net/if_ppp.h, [], [],
-[#if HAVE_NET_PPP_DEFS_H
-# include <net/ppp_defs.h>
-#endif
-])
-AC_CHECK_HEADERS(netinet/if_ether.h, [], [],
-[#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-#if HAVE_NET_IF_H
-# include <net/if.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-])
+AC_CHECK_HEADERS([net/if_arp.h], [], [],
+  [[
+    #if HAVE_SYS_SOCKET_H
+    # include <sys/socket.h>
+    #endif
+  ]]
+)
 
-have_net_pfvar_h="no"
-AC_CHECK_HEADERS(net/pfvar.h,
-               [have_net_pfvar_h="yes"],
-               [have_net_pfvar_h="no"],
-[
-#if HAVE_SYS_IOCTL_H
-# include <sys/ioctl.h>
-#endif
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-#if HAVE_NET_IF_H
-# include <net/if.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-])
+AC_CHECK_HEADERS([net/ppp_defs.h])
+AC_CHECK_HEADERS([net/if_ppp.h], [], [],
+  [[
+    #if HAVE_NET_PPP_DEFS_H
+    # include <net/ppp_defs.h>
+    #endif
+  ]]
+)
+
+AC_CHECK_HEADERS([netinet/if_ether.h], [], [],
+  [[
+    #include <stdint.h>
+    #if HAVE_SYS_TYPES_H
+    # include <sys/types.h>
+    #endif
+    #if HAVE_SYS_SOCKET_H
+    # include <sys/socket.h>
+    #endif
+    #if HAVE_NET_IF_H
+    # include <net/if.h>
+    #endif
+    #if HAVE_NETINET_IN_H
+    # include <netinet/in.h>
+    #endif
+  ]]
+)
+
+AC_CHECK_HEADERS([net/pfvar.h],
+  [have_net_pfvar_h="yes"],
+  [have_net_pfvar_h="no"],
+  [[
+    #if HAVE_SYS_IOCTL_H
+    # include <sys/ioctl.h>
+    #endif
+    #if HAVE_SYS_SOCKET_H
+    # include <sys/socket.h>
+    #endif
+    #if HAVE_NET_IF_H
+    # include <net/if.h>
+    #endif
+    #if HAVE_NETINET_IN_H
+    # include <netinet/in.h>
+    #endif
+  ]]
+)
 
 # For the multimeter plugin
-have_termios_h="no"
-AC_CHECK_HEADERS(termios.h, [have_termios_h="yes"])
+AC_CHECK_HEADERS([termios.h],
+  [have_termios_h="yes"],
+  [have_termios_h="no"]
+)
 
 # For cpusleep plugin
 AC_CACHE_CHECK([whether clock_boottime and clock_monotonic are supported],
-                      [c_cv_have_clock_boottime_monotonic],
-                      AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
-[[
-#include <time.h>
-]],
-[[
- struct timespec b, m;
- clock_gettime(CLOCK_BOOTTIME, &b );
- clock_gettime(CLOCK_MONOTONIC, &m );
-]]
-                      )],
-                      [c_cv_have_clock_boottime_monotonic="yes"],
-                      [c_cv_have_clock_boottime_monotonic="no"]))
-
-
-# For the turbostat plugin
-have_asm_msrindex_h="no"
-AC_CHECK_HEADERS(asm/msr-index.h, [have_asm_msrindex_h="yes"])
-
-if test "x$have_asm_msrindex_h" = "xyes"
-then
-  AC_CACHE_CHECK([whether asm/msr-index.h has MSR_PKG_C10_RESIDENCY],
-                 [c_cv_have_usable_asm_msrindex_h],
-                 AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
-[[[
-#include<asm/msr-index.h>
-]]],
-[[[
-int y = MSR_PKG_C10_RESIDENCY;
-return(y);
-]]]
-  )],
-                 [c_cv_have_usable_asm_msrindex_h="yes"],
-                 [c_cv_have_usable_asm_msrindex_h="no"],
-                                  )
-                 )
-fi
-
-have_cpuid_h="no"
-AC_CHECK_HEADERS(cpuid.h, [have_cpuid_h="yes"])
-
-have_capability="yes"
-AC_CHECK_HEADERS(sys/capability.h,
-                 [have_capability="yes"],
-                 [have_capability="no (<sys/capability.h> not found)"])
-if test "x$have_capability" = "xyes"; then
-AC_CHECK_LIB(cap, cap_get_bound,
-                 [have_capability="yes"],
-                 [have_capability="no (cap_get_bound() 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).])
-fi
-AM_CONDITIONAL(BUILD_WITH_CAPABILITY, test "x$have_capability" = "xyes")
+  [c_cv_have_clock_boottime_monotonic],
+  [
+    AC_COMPILE_IFELSE(
+      [AC_LANG_PROGRAM(
+        [[#include <time.h>]],
+        [[
+          struct timespec b, m;
+          clock_gettime(CLOCK_BOOTTIME, &b );
+          clock_gettime(CLOCK_MONOTONIC, &m );
+        ]]
+      )
+      ],
+      [c_cv_have_clock_boottime_monotonic="yes"],
+      [c_cv_have_clock_boottime_monotonic="no"]
+    )
+  ]
+)
+
 
 #
 # Checks for typedefs, structures, and compiler characteristics.
@@ -853,1412 +770,1602 @@ AC_TYPE_SIZE_T
 AC_TYPE_UID_T
 AC_HEADER_TIME
 
+test_cxx_flags() {
+  AC_LANG_PUSH([C++])
+  AC_LANG_CONFTEST(
+    [AC_LANG_SOURCE([[int main(void){}]]) ]
+  )
+  $CXX -c conftest.cpp $CXXFLAGS $@ > /dev/null 2> /dev/null
+  ret=$?
+  rm -f conftest.o
+  AC_LANG_POP([C++])
+  return $ret
+}
+
 #
 # Checks for library functions.
 #
-AC_CHECK_FUNCS(gettimeofday select strdup strtol getaddrinfo getnameinfo strchr memcpy strstr strcmp strncmp strncpy strlen strncasecmp strcasecmp openlog closelog sysconf setenv if_indextoname setlocale asprintf)
+AC_CHECK_FUNCS_ONCE([ \
+    asprintf \
+    closelog \
+    getaddrinfo \
+    getgrnam_r \
+    getnameinfo \
+    getpwnam_r \
+    gettimeofday \
+    if_indextoname \
+    openlog \
+    regcomp \
+    regerror \
+    regexec \
+    regfree \
+    select \
+    setenv \
+    setgroups \
+    strcasecmp \
+    strdup \
+    strncasecmp \
+    sysconf
+  ]
+)
 
 AC_FUNC_STRERROR_R
 
-test_cxx_flags() {
-       AC_LANG_PUSH([C++])
-       AC_LANG_CONFTEST([
-               AC_LANG_SOURCE([[int main(void){}]])
-       ])
-       $CXX -c conftest.cpp $CXXFLAGS $@ > /dev/null 2> /dev/null
-       ret=$?
-       rm -f conftest.o
-       AC_LANG_POP([C++])
-       return $ret
-}
-
 SAVE_CFLAGS="$CFLAGS"
 # Emulate behavior of src/Makefile.am
-if test "x$GCC" = "xyes"
-then
-       CFLAGS="$CFLAGS -Wall -Werror"
+if test "x$GCC" = "xyes"; then
+  CFLAGS="$CFLAGS -Wall -Werror"
 fi
 
 AC_CACHE_CHECK([for strtok_r],
   [c_cv_have_strtok_r_default],
-  AC_LINK_IFELSE(
-    [AC_LANG_PROGRAM(
-[[[
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-]]],
-[[[
-      char buffer[] = "foo,bar,baz";
-      char *token;
-      char *dummy;
-      char *saveptr;
-
-      dummy = buffer;
-      saveptr = NULL;
-      while ((token = strtok_r (dummy, ",", &saveptr)) != NULL)
-      {
-        dummy = NULL;
-        printf ("token = %s;\n", token);
-      }
-]]]
-    )],
-    [c_cv_have_strtok_r_default="yes"],
-    [c_cv_have_strtok_r_default="no"]
-  )
+  [
+    AC_LINK_IFELSE(
+      [
+        AC_LANG_PROGRAM(
+          [[
+            #include <stdlib.h>
+            #include <stdio.h>
+            #include <string.h>
+          ]],
+          [[
+            char buffer[] = "foo,bar,baz";
+            char *token;
+            char *dummy;
+            char *saveptr;
+
+            dummy = buffer;
+            saveptr = NULL;
+            while ((token = strtok_r (dummy, ",", &saveptr)) != NULL)
+            {
+              dummy = NULL;
+              printf ("token = %s;\n", token);
+            }
+          ]]
+        )
+      ],
+      [c_cv_have_strtok_r_default="yes"],
+      [c_cv_have_strtok_r_default="no"]
+    )
+  ]
 )
 
-if test "x$c_cv_have_strtok_r_default" = "xno"
-then
+if test "x$c_cv_have_strtok_r_default" = "xno"; then
   CFLAGS="$CFLAGS -D_REENTRANT=1"
 
   AC_CACHE_CHECK([if strtok_r needs _REENTRANT],
     [c_cv_have_strtok_r_reentrant],
-    AC_LINK_IFELSE(
-      [AC_LANG_PROGRAM(
-[[[
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-]]],
-[[[
-        char buffer[] = "foo,bar,baz";
-        char *token;
-        char *dummy;
-        char *saveptr;
-
-        dummy = buffer;
-        saveptr = NULL;
-        while ((token = strtok_r (dummy, ",", &saveptr)) != NULL)
-        {
-          dummy = NULL;
-          printf ("token = %s;\n", token);
-        }
-]]]
-      )],
-      [c_cv_have_strtok_r_reentrant="yes"],
-      [AC_MSG_FAILURE([strtok_r isn't available. Please file a bugreport!])]
-    )
+    [
+      AC_LINK_IFELSE(
+        [
+          AC_LANG_PROGRAM(
+            [[
+              #include <stdlib.h>
+              #include <stdio.h>
+              #include <string.h>
+            ]],
+            [[
+              char buffer[] = "foo,bar,baz";
+              char *token;
+              char *dummy;
+              char *saveptr;
+
+              dummy = buffer;
+              saveptr = NULL;
+              while ((token = strtok_r (dummy, ",", &saveptr)) != NULL)
+              {
+                dummy = NULL;
+                printf ("token = %s;\n", token);
+              }
+            ]]
+          )
+        ],
+        [c_cv_have_strtok_r_reentrant="yes"],
+        [AC_MSG_FAILURE([strtok_r is not available. Please file a bugreport!])]
+      )
+    ]
   )
 fi
 
 CFLAGS="$SAVE_CFLAGS"
-if test "x$c_cv_have_strtok_r_reentrant" = "xyes"
-then
-       CFLAGS="$CFLAGS -D_REENTRANT=1"
+if test "x$c_cv_have_strtok_r_reentrant" = "xyes"; then
+  CFLAGS="$CFLAGS -D_REENTRANT=1"
 fi
 
-AC_CHECK_FUNCS(getpwnam_r getgrnam_r setgroups regcomp regerror regexec regfree)
-
-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")
+AC_CHECK_FUNCS([socket],
+  [],
+  [
+    AC_CHECK_LIB([socket], [socket],
+      [socket_needs_socket="yes"],
+      [AC_MSG_ERROR([cannot find socket() in libsocket])]
+    )
+  ]
+)
+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"])
+AC_CHECK_FUNCS([clock_gettime],
+  [have_clock_gettime="yes"],
+  [have_clock_gettime="no"]
+)
+
+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"])
+
+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.])
+
+if test "x$have_clock_gettime" = "xyes"; then
+  AC_DEFINE([HAVE_CLOCK_GETTIME], [1], [Define if the clock_gettime(2) function is available.])
 fi
 
-nanosleep_needs_rt="no"
-nanosleep_needs_posix4="no"
-AC_CHECK_FUNCS(nanosleep,
-    [],
-    AC_CHECK_LIB(rt, nanosleep,
-        [nanosleep_needs_rt="yes"],
-        AC_CHECK_LIB(posix4, nanosleep,
-            [nanosleep_needs_posix4="yes"],
-            AC_MSG_ERROR(cannot find nanosleep))))
-
-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"])
-AC_CHECK_FUNCS(host_statistics, [have_host_statistics="yes"], [have_host_statistics="no"])
-AC_CHECK_FUNCS(processor_info, [have_processor_info="yes"], [have_processor_info="no"])
-AC_CHECK_FUNCS(thread_info, [have_thread_info="yes"], [have_thread_info="no"])
-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([nanosleep], [],
+  AC_CHECK_LIB([rt], [nanosleep],
+    [nanosleep_needs_rt="yes"],
+    [
+      AC_CHECK_LIB([posix4], [nanosleep],
+        [nanosleep_needs_posix4="yes"],
+        [AC_MSG_ERROR([cannot find nanosleep])]
+      )
+    ]
+  )
+)
+
+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([getifaddrs], [have_getifaddrs="yes"], [have_getifaddrs="no"])
+AC_CHECK_FUNCS([getloadavg], [have_getloadavg="yes"], [have_getloadavg="no"])
+AC_CHECK_FUNCS([getutent], [have_getutent="yes"], [have_getutent="no"])
+AC_CHECK_FUNCS([getutxent], [have_getutxent="yes"], [have_getutxent="no"])
+AC_CHECK_FUNCS([host_statistics], [have_host_statistics="yes"], [have_host_statistics="no"])
+AC_CHECK_FUNCS([processor_info], [have_processor_info="yes"], [have_processor_info="no"])
+AC_CHECK_FUNCS([statfs], [have_statfs="yes"], [have_statfs="no"])
+AC_CHECK_FUNCS([statvfs], [have_statvfs="yes"], [have_statvfs="no"])
+AC_CHECK_FUNCS([sysctl], [have_sysctl="yes"], [have_sysctl="no"])
+AC_CHECK_FUNCS([sysctlbyname], [have_sysctlbyname="yes"], [have_sysctlbyname="no"])
+AC_CHECK_FUNCS([syslog], [have_syslog="yes"], [have_syslog="no"])
+AC_CHECK_FUNCS([thread_info], [have_thread_info="yes"], [have_thread_info="no"])
 
 # Check for strptime {{{
-if test "x$GCC" = "xyes"
-then
-       SAVE_CFLAGS="$CFLAGS"
-       CFLAGS="$CFLAGS -Wall -Wextra -Werror"
+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(
-[[[
-#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
-#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
+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(
+            [[#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$GCC" = "xyes"
-then
-       CFLAGS="$SAVE_CFLAGS"
+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
+              #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"])
+AC_MSG_CHECKING([for sysctl kern.cp_times])
+if test -x /sbin/sysctl; then
+  /sbin/sysctl kern.cp_times >/dev/null 2>&1
+  if test $? -eq 0; then
+    AC_MSG_RESULT([yes])
+    AC_DEFINE([HAVE_SYSCTL_KERN_CP_TIMES], [1], [Define if sysctl supports kern.cp_times])
+  else
+    AC_MSG_RESULT([no])
+  fi
+else
+  AC_MSG_RESULT([no])
+fi
+
+AC_MSG_CHECKING([for sysctl kern.cp_time])
+if test -x /sbin/sysctl; then
+  /sbin/sysctl kern.cp_time >/dev/null 2>&1
+  if test $? -eq 0
+  then
+    AC_MSG_RESULT([yes])
+    AC_DEFINE([HAVE_SYSCTL_KERN_CP_TIME], [1], [Define if sysctl supports kern.cp_time])
+  else
+    AC_MSG_RESULT([no])
+  fi
+else
+  AC_MSG_RESULT([no])
+fi
+
+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(
-[[[
-#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/param.h>
-#include <sys/swap.h>
-#include <unistd.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(
-[[[
-#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/param.h>
-#include <sys/swap.h>
-#include <unistd.h>
-]]],
-[[[
-int num = swapctl(0, NULL, 0);
-]]]
-                        )],
-                        [c_cv_have_swapctl_three_args="yes"],
-                        [c_cv_have_swapctl_three_args="no"]
-                )
-        )
+  AC_CACHE_CHECK([whether swapctl takes two arguments],
+    [c_cv_have_swapctl_two_args],
+    [
+      AC_COMPILE_IFELSE(
+        [
+          AC_LANG_PROGRAM(
+            [[
+              #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/param.h>
+              #include <sys/swap.h>
+              #include <unistd.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(
+            [[
+              #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/param.h>
+              #include <sys/swap.h>
+              #include <unistd.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
+  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.])],
-[
- if test "x$withval" = "xno"; then
-        nan_type="none"
- else if test "x$withval" = "xyes"; then
-        nan_type="zero"
- else
-        nan_type="$withval"
- fi; fi
-],
-[nan_type="none"])
+AC_ARG_WITH([nan-emulation],
+  [AS_HELP_STRING([--with-nan-emulation], [use emulated NAN. For crosscompiling only.])],
+  [
+    if test "x$withval" = "xno"; then
+      nan_type="none"
+    else if test "x$withval" = "xyes"; then
+      nan_type="zero"
+    else
+      nan_type="$withval"
+    fi; fi
+  ],
+  [nan_type="none"]
+)
+
 if test "x$nan_type" = "xnone"; then
   AC_CACHE_CHECK([whether NAN is defined by default],
     [c_cv_have_nan_default],
-    AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
-[[[
-#include <stdlib.h>
-#include <math.h>
-static double foo = NAN;
-]]],
-[[[
-       if (isnan (foo))
-        return 0;
-       else
-       return 1;
-]]]
-      )],
-      [c_cv_have_nan_default="yes"],
-      [c_cv_have_nan_default="no"]
-    )
+    [
+      AC_COMPILE_IFELSE(
+        [
+          AC_LANG_PROGRAM(
+            [[
+              #include <stdlib.h>
+              #include <math.h>
+              static double foo = NAN;
+            ]],
+            [[
+              if (isnan (foo))
+                return 0;
+              return 1;
+            ]]
+          )
+        ],
+        [c_cv_have_nan_default="yes"],
+        [c_cv_have_nan_default="no"]
+      )
+    ]
   )
-  if test "x$c_cv_have_nan_default" = "xyes"
-  then
-    nan_type="default"
-  fi
 fi
+
+if test "x$c_cv_have_nan_default" = "xyes"; then
+  nan_type="default"
+fi
+
 if test "x$nan_type" = "xnone"; then
   AC_CACHE_CHECK([whether NAN is defined by __USE_ISOC99],
     [c_cv_have_nan_isoc],
-    AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
-[[[
-#include <stdlib.h>
-#define __USE_ISOC99 1
-#include <math.h>
-static double foo = NAN;
-]]],
-[[[
-       if (isnan (foo))
-        return 0;
-       else
-       return 1;
-]]]
-      )],
-      [c_cv_have_nan_isoc="yes"],
-      [c_cv_have_nan_isoc="no"]
-    )
+    [
+      AC_COMPILE_IFELSE(
+        [
+          AC_LANG_PROGRAM(
+            [[
+              #include <stdlib.h>
+              #define __USE_ISOC99 1
+              #include <math.h>
+              static double foo = NAN;
+            ]],
+            [[
+              if (isnan (foo))
+                return 0;
+              return 1;
+            ]]
+          )
+        ],
+        [c_cv_have_nan_isoc="yes"],
+        [c_cv_have_nan_isoc="no"]
+      )
+    ]
   )
-  if test "x$c_cv_have_nan_isoc" = "xyes"
-  then
-    nan_type="isoc99"
-  fi
 fi
+
+if test "x$c_cv_have_nan_isoc" = "xyes"; then
+  nan_type="isoc99"
+fi
+
 if test "x$nan_type" = "xnone"; then
-  SAVE_LDFLAGS=$LDFLAGS
+  SAVE_LDFLAGS="$LDFLAGS"
   LDFLAGS="$LDFLAGS -lm"
   AC_CACHE_CHECK([whether NAN can be defined by 0/0],
     [c_cv_have_nan_zero],
-    AC_RUN_IFELSE([AC_LANG_PROGRAM(
-[[[
-#include <stdlib.h>
-#include <math.h>
-#ifdef NAN
-# undef NAN
-#endif
-#define NAN (0.0 / 0.0)
-#ifndef isnan
-# define isnan(f) ((f) != (f))
-#endif
-static double foo = NAN;
-]]],
-[[[
-       if (isnan (foo))
-        return 0;
-       else
-       return 1;
-]]]
-      )],
-      [c_cv_have_nan_zero="yes"],
-      [c_cv_have_nan_zero="no"]
-    )
+    [
+      AC_RUN_IFELSE(
+        [
+          AC_LANG_PROGRAM(
+            [[
+              #include <stdlib.h>
+              #include <math.h>
+              #ifdef NAN
+              # undef NAN
+              #endif
+              #define NAN (0.0 / 0.0)
+              #ifndef isnan
+              # define isnan(f) ((f) != (f))
+              #endif
+              static double foo = NAN;
+            ]],
+            [[
+              if (isnan (foo))
+                return 0;
+              return 1;
+            ]]
+          )
+        ],
+        [c_cv_have_nan_zero="yes"],
+        [c_cv_have_nan_zero="no"]
+      )
+    ]
   )
   LDFLAGS=$SAVE_LDFLAGS
-  if test "x$c_cv_have_nan_zero" = "xyes"
-  then
-    nan_type="zero"
-  fi
+fi
+
+if test "x$c_cv_have_nan_zero" = "xyes"; then
+  nan_type="zero"
 fi
 
 if test "x$nan_type" = "xdefault"; then
-  AC_DEFINE(NAN_STATIC_DEFAULT, 1,
-    [Define if NAN is defined by default and can initialize static variables.])
+  AC_DEFINE([NAN_STATIC_DEFAULT], [1],
+    [Define if NAN is defined by default and can initialize static variables.]
+  )
 else if test "x$nan_type" = "xisoc99"; then
-  AC_DEFINE(NAN_STATIC_ISOC, 1,
-    [Define if NAN is defined by __USE_ISOC99 and can initialize static variables.])
+  AC_DEFINE([NAN_STATIC_ISOC], [1],
+    [Define if NAN is defined by __USE_ISOC99 and can initialize static variables.]
+  )
 else if test "x$nan_type" = "xzero"; then
-  AC_DEFINE(NAN_ZERO_ZERO, 1,
-    [Define if NAN can be defined as (0.0 / 0.0)])
+  AC_DEFINE([NAN_ZERO_ZERO], [1],
+    [Define if NAN can be defined as (0.0 / 0.0)]
+  )
 else
   AC_MSG_ERROR([Didn't find out how to statically initialize variables to NAN. Sorry.])
 fi; fi; fi
 
-AC_ARG_WITH(fp-layout, [AS_HELP_STRING([--with-fp-layout], [set the memory layout of doubles. For crosscompiling only.])],
-[
- if test "x$withval" = "xnothing"; then
-       fp_layout_type="nothing"
- else if test "x$withval" = "xendianflip"; then
-       fp_layout_type="endianflip"
- else if test "x$withval" = "xintswap"; then
-       fp_layout_type="intswap"
- else
-       AC_MSG_ERROR([Invalid argument for --with-fp-layout. Valid arguments are: nothing, endianflip, intswap]);
-fi; fi; fi
-],
-[fp_layout_type="unknown"])
+AC_ARG_WITH([fp-layout],
+  [
+    AS_HELP_STRING([--with-fp-layout],
+      [set the memory layout of doubles. For crosscompiling only.]
+    )
+  ],
+  [
+    if test "x$withval" = "xnothing"; then
+      fp_layout_type="nothing"
+    else if test "x$withval" = "xendianflip"; then
+      fp_layout_type="endianflip"
+    else if test "x$withval" = "xintswap"; then
+      fp_layout_type="intswap"
+    else
+      AC_MSG_ERROR([Invalid argument for --with-fp-layout. Valid arguments are: nothing, endianflip, intswap]);
+    fi; fi; fi
+  ],
+  [fp_layout_type="unknown"]
+)
 
 if test "x$fp_layout_type" = "xunknown"; then
   AC_CACHE_CHECK([if doubles are stored in x86 representation],
     [c_cv_fp_layout_need_nothing],
-    AC_RUN_IFELSE([AC_LANG_PROGRAM(
-[[[
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#if HAVE_STDBOOL_H
-# include <stdbool.h>
-#endif
-]]],
-[[[
-       uint64_t i0;
-       uint64_t i1;
-       uint8_t c[8];
-       double d;
-
-       d = 8.642135e130;
-       memcpy ((void *) &i0, (void *) &d, 8);
-
-       i1 = i0;
-       memcpy ((void *) c, (void *) &i1, 8);
-
-       if ((c[0] == 0x2f) && (c[1] == 0x25)
-                       && (c[2] == 0xc0) && (c[3] == 0xc7)
-                       && (c[4] == 0x43) && (c[5] == 0x2b)
-                       && (c[6] == 0x1f) && (c[7] == 0x5b))
-               return (0);
-       else
-               return (1);
-]]]
-      )],
-      [c_cv_fp_layout_need_nothing="yes"],
-      [c_cv_fp_layout_need_nothing="no"]
-    )
+    [
+      AC_RUN_IFELSE(
+        [
+          AC_LANG_PROGRAM(
+            [[
+              #include <stdlib.h>
+              #include <stdio.h>
+              #include <string.h>
+              #include <stdint.h>
+              #include <inttypes.h>
+              #include <stdbool.h>
+            ]],
+            [[
+              uint64_t i0;
+              uint64_t i1;
+              uint8_t c[8];
+              double d;
+
+              d = 8.642135e130;
+              memcpy ((void *) &i0, (void *) &d, 8);
+
+              i1 = i0;
+              memcpy ((void *) c, (void *) &i1, 8);
+
+              if ((c[0] == 0x2f) && (c[1] == 0x25)
+                  && (c[2] == 0xc0) && (c[3] == 0xc7)
+                  && (c[4] == 0x43) && (c[5] == 0x2b)
+                  && (c[6] == 0x1f) && (c[7] == 0x5b))
+                return (0);
+              return (1);
+            ]]
+          )
+        ],
+        [c_cv_fp_layout_need_nothing="yes"],
+        [c_cv_fp_layout_need_nothing="no"]
+      )
+    ]
   )
-  if test "x$c_cv_fp_layout_need_nothing" = "xyes"; then
-    fp_layout_type="nothing"
-  fi
 fi
+
+if test "x$c_cv_fp_layout_need_nothing" = "xyes"; then
+  fp_layout_type="nothing"
+fi
+
 if test "x$fp_layout_type" = "xunknown"; then
   AC_CACHE_CHECK([if endianflip converts to x86 representation],
     [c_cv_fp_layout_need_endianflip],
-    AC_RUN_IFELSE([AC_LANG_PROGRAM(
-[[[
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#if HAVE_STDBOOL_H
-# include <stdbool.h>
-#endif
-#define endianflip(A) ((((uint64_t)(A) & 0xff00000000000000LL) >> 56) | \
-                       (((uint64_t)(A) & 0x00ff000000000000LL) >> 40) | \
-                       (((uint64_t)(A) & 0x0000ff0000000000LL) >> 24) | \
-                       (((uint64_t)(A) & 0x000000ff00000000LL) >> 8)  | \
-                       (((uint64_t)(A) & 0x00000000ff000000LL) << 8)  | \
-                       (((uint64_t)(A) & 0x0000000000ff0000LL) << 24) | \
-                       (((uint64_t)(A) & 0x000000000000ff00LL) << 40) | \
-                       (((uint64_t)(A) & 0x00000000000000ffLL) << 56))
-]]],
-[[[
-       uint64_t i0;
-       uint64_t i1;
-       uint8_t c[8];
-       double d;
-
-       d = 8.642135e130;
-       memcpy ((void *) &i0, (void *) &d, 8);
-
-       i1 = endianflip (i0);
-       memcpy ((void *) c, (void *) &i1, 8);
-
-       if ((c[0] == 0x2f) && (c[1] == 0x25)
-                       && (c[2] == 0xc0) && (c[3] == 0xc7)
-                       && (c[4] == 0x43) && (c[5] == 0x2b)
-                       && (c[6] == 0x1f) && (c[7] == 0x5b))
-               return (0);
-       else
-               return (1);
-]]]
-      )],
-      [c_cv_fp_layout_need_endianflip="yes"],
-      [c_cv_fp_layout_need_endianflip="no"]
+    [
+      AC_RUN_IFELSE(
+        [
+          AC_LANG_PROGRAM(
+            [[
+              #include <stdlib.h>
+              #include <stdio.h>
+              #include <string.h>
+              #include <stdint.h>
+              #include <inttypes.h>
+              #include <stdbool.h>
+              #define endianflip(A) ((((uint64_t)(A) & 0xff00000000000000LL) >> 56) | \
+                                     (((uint64_t)(A) & 0x00ff000000000000LL) >> 40) | \
+                                     (((uint64_t)(A) & 0x0000ff0000000000LL) >> 24) | \
+                                     (((uint64_t)(A) & 0x000000ff00000000LL) >> 8)  | \
+                                     (((uint64_t)(A) & 0x00000000ff000000LL) << 8)  | \
+                                     (((uint64_t)(A) & 0x0000000000ff0000LL) << 24) | \
+                                     (((uint64_t)(A) & 0x000000000000ff00LL) << 40) | \
+                                     (((uint64_t)(A) & 0x00000000000000ffLL) << 56))
+            ]],
+            [[
+              uint64_t i0;
+              uint64_t i1;
+              uint8_t c[8];
+              double d;
+              
+              d = 8.642135e130;
+              memcpy ((void *) &i0, (void *) &d, 8);
+              
+              i1 = endianflip (i0);
+              memcpy ((void *) c, (void *) &i1, 8);
+              
+              if ((c[0] == 0x2f) && (c[1] == 0x25)
+                  && (c[2] == 0xc0) && (c[3] == 0xc7)
+                  && (c[4] == 0x43) && (c[5] == 0x2b)
+                  && (c[6] == 0x1f) && (c[7] == 0x5b))
+                return (0);
+              return (1);
+            ]]
+          )
+        ],
+        [c_cv_fp_layout_need_endianflip="yes"],
+        [c_cv_fp_layout_need_endianflip="no"]
+      ]
     )
   )
-  if test "x$c_cv_fp_layout_need_endianflip" = "xyes"; then
-    fp_layout_type="endianflip"
-  fi
 fi
+
+if test "x$c_cv_fp_layout_need_endianflip" = "xyes"; then
+  fp_layout_type="endianflip"
+fi
+
 if test "x$fp_layout_type" = "xunknown"; then
   AC_CACHE_CHECK([if intswap converts to x86 representation],
     [c_cv_fp_layout_need_intswap],
-    AC_RUN_IFELSE([AC_LANG_PROGRAM(
-[[[
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#if HAVE_STDBOOL_H
-# include <stdbool.h>
-#endif
-#define intswap(A)    ((((uint64_t)(A) & 0xffffffff00000000LL) >> 32) | \
-                       (((uint64_t)(A) & 0x00000000ffffffffLL) << 32))
-]]],
-[[[
-       uint64_t i0;
-       uint64_t i1;
-       uint8_t c[8];
-       double d;
-
-       d = 8.642135e130;
-       memcpy ((void *) &i0, (void *) &d, 8);
-
-       i1 = intswap (i0);
-       memcpy ((void *) c, (void *) &i1, 8);
-
-       if ((c[0] == 0x2f) && (c[1] == 0x25)
-                       && (c[2] == 0xc0) && (c[3] == 0xc7)
-                       && (c[4] == 0x43) && (c[5] == 0x2b)
-                       && (c[6] == 0x1f) && (c[7] == 0x5b))
-               return (0);
-       else
-               return (1);
-]]]
-      )],
-      [c_cv_fp_layout_need_intswap="yes"],
-      [c_cv_fp_layout_need_intswap="no"]
-    )
+    [
+      AC_RUN_IFELSE(
+        [
+          AC_LANG_PROGRAM(
+            [[
+              #include <stdlib.h>
+              #include <stdio.h>
+              #include <string.h>
+              #include <stdint.h>
+              #include <inttypes.h>
+              #include <stdbool.h>
+              #define intswap(A)    ((((uint64_t)(A) & 0xffffffff00000000LL) >> 32) | \
+                                     (((uint64_t)(A) & 0x00000000ffffffffLL) << 32))
+            ]],
+            [[
+              uint64_t i0;
+              uint64_t i1;
+              uint8_t c[8];
+              double d;
+              
+              d = 8.642135e130;
+              memcpy ((void *) &i0, (void *) &d, 8);
+              
+              i1 = intswap (i0);
+              memcpy ((void *) c, (void *) &i1, 8);
+              
+              if ((c[0] == 0x2f) && (c[1] == 0x25)
+                  && (c[2] == 0xc0) && (c[3] == 0xc7)
+                  && (c[4] == 0x43) && (c[5] == 0x2b)
+                  && (c[6] == 0x1f) && (c[7] == 0x5b))
+                return (0);
+              return (1);
+            ]]
+          )
+        ],
+        [c_cv_fp_layout_need_intswap="yes"],
+        [c_cv_fp_layout_need_intswap="no"]
+      )
+    ]
   )
-  if test "x$c_cv_fp_layout_need_intswap" = "xyes"; then
-    fp_layout_type="intswap"
-  fi
+fi
+
+if test "x$c_cv_fp_layout_need_intswap" = "xyes"; then
+  fp_layout_type="intswap"
 fi
 
 if test "x$fp_layout_type" = "xnothing"; then
-  AC_DEFINE(FP_LAYOUT_NEED_NOTHING, 1,
-  [Define if doubles are stored in x86 representation.])
+  AC_DEFINE([FP_LAYOUT_NEED_NOTHING], [1],
+    [Define if doubles are stored in x86 representation.]
+  )
 else if test "x$fp_layout_type" = "xendianflip"; then
-  AC_DEFINE(FP_LAYOUT_NEED_ENDIANFLIP, 1,
-  [Define if endianflip is needed to convert to x86 representation.])
+  AC_DEFINE([FP_LAYOUT_NEED_ENDIANFLIP], [1],
+    [Define if endianflip is needed to convert to x86 representation.]
+  )
 else if test "x$fp_layout_type" = "xintswap"; then
-  AC_DEFINE(FP_LAYOUT_NEED_INTSWAP, 1,
-  [Define if intswap is needed to convert to x86 representation.])
+  AC_DEFINE([FP_LAYOUT_NEED_INTSWAP], [1],
+    [Define if intswap is needed to convert to x86 representation.]
+  )
 else
   AC_MSG_ERROR([Didn't find out how doubles are stored in memory. Sorry.])
 fi; fi; fi
 
+# For cpusleep plugin
+AC_CACHE_CHECK([whether clock_boottime and clock_monotonic are supported],
+  [c_cv_have_clock_boottime_monotonic],
+  [
+    AC_COMPILE_IFELSE(
+      [AC_LANG_PROGRAM(
+        [[#include <time.h>]],
+        [[
+          struct timespec b, m;
+          clock_gettime(CLOCK_BOOTTIME, &b );
+          clock_gettime(CLOCK_MONOTONIC, &m );
+        ]]
+      )
+      ],
+      [c_cv_have_clock_boottime_monotonic="yes"],
+      [c_cv_have_clock_boottime_monotonic="no"]
+    )
+  ]
+)
+
 # --with-useragent {{{
-AC_ARG_WITH(useragent, [AS_HELP_STRING([--with-useragent@<:@=AGENT@:>@], [User agent to use on http requests])],
-[
-    if test "x$withval" != "xno" && test "x$withval" != "xyes"
-    then
-        AC_DEFINE_UNQUOTED(COLLECTD_USERAGENT, ["$withval"], [User agent for http requests])
+AC_ARG_WITH([useragent],
+  [AS_HELP_STRING([--with-useragent@<:@=AGENT@:>@], [User agent to use on http requests])],
+  [
+    if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
+      AC_DEFINE_UNQUOTED([COLLECTD_USERAGENT], ["$withval"], [User agent for http requests])
     fi
-])
+  ]
+)
 
 # }}}
 
 # --with-data-max-name-len {{{
-AC_ARG_WITH(data-max-name-len, [AS_HELP_STRING([--with-data-max-name-len@<:@=VALUE@:>@], [Maximum length of data buffers])],
-[
-    if test "x$withval" != "x" && test $withval -gt 0
-    then
-        AC_DEFINE_UNQUOTED(DATA_MAX_NAME_LEN, [$withval], [Maximum length of data buffers])
+AC_ARG_WITH([data-max-name-len],
+  [AS_HELP_STRING([--with-data-max-name-len@<:@=VALUE@:>@], [Maximum length of data buffers])],
+  [
+    if test "x$withval" != "x" && test $withval -gt 0; then
+      AC_DEFINE_UNQUOTED([DATA_MAX_NAME_LEN], [$withval], [Maximum length of data buffers])
     else
-        AC_MSG_ERROR([DATA_MAX_NAME_LEN must be a positive integer -- $withval given])
+      AC_MSG_ERROR([DATA_MAX_NAME_LEN must be a positive integer -- $withval given])
     fi
-],
-[   AC_DEFINE(DATA_MAX_NAME_LEN, 128, [Maximum length of data buffers])]
+  ],
+  [AC_DEFINE([DATA_MAX_NAME_LEN], [128], [Maximum length of data buffers])]
 )
 # }}}
 
-have_getfsstat="no"
-AC_CHECK_FUNCS(getfsstat, [have_getfsstat="yes"])
-have_getvfsstat="no"
-AC_CHECK_FUNCS(getvfsstat, [have_getvfsstat="yes"])
-have_listmntent="no"
-AC_CHECK_FUNCS(listmntent, [have_listmntent="yes"])
-have_getmntent_r="no"
-AC_CHECK_FUNCS(getmntent_r, [have_getmntent_r="yes"])
-
-have_getmntent="no"
-AC_CHECK_FUNCS(getmntent, [have_getmntent="c"])
+AC_CHECK_FUNCS([getfsstat], [have_getfsstat="yes"], [have_getfsstat="no"])
+AC_CHECK_FUNCS(getvfsstat, [have_getvfsstat="yes"], [have_getvfsstat="no"])
+AC_CHECK_FUNCS(listmntent, [have_listmntent="yes"], [have_listmntent="no"])
+AC_CHECK_FUNCS(getmntent_r, [have_getmntent_r="yes"], [have_getmntent_r="no"])
+
+AC_CHECK_FUNCS(getmntent, [have_getmntent="libc"], [have_getmntent="no"])
 if test "x$have_getmntent" = "xno"; then
-       AC_CHECK_LIB(sun, getmntent, [have_getmntent="sun"])
+  AC_CHECK_LIB([sun], [getmntent],
+    [have_getmntent="sun"],
+    [have_gemntent="no"]
+  )
 fi
+
 if test "x$have_getmntent" = "xno"; then
-       AC_CHECK_LIB(seq, getmntent, [have_getmntent="seq"])
+  AC_CHECK_LIB([seq], [getmntent],
+    [have_getmntent="seq"],
+    [have_getmntent="no"]
+  )
 fi
+
 if test "x$have_getmntent" = "xno"; then
-       AC_CHECK_LIB(gen, getmntent, [have_getmntent="gen"])
-fi
-
-if test "x$have_getmntent" = "xc"; then
-       AC_CACHE_CHECK([whether getmntent takes one argument],
-               [c_cv_have_one_getmntent],
-               AC_COMPILE_IFELSE(
-                       [AC_LANG_PROGRAM(
-[[[
-#include "$srcdir/src/utils_mount.h"
-]]],
-[[[
-FILE *fh;
-struct mntent *me;
-fh = setmntent ("/etc/mtab", "r");
-me = getmntent (fh);
-return(me->mnt_passno);
-]]]
-                       )],
-                       [c_cv_have_one_getmntent="yes"],
-                       [c_cv_have_one_getmntent="no"]
-               )
-       )
-       AC_CACHE_CHECK([whether getmntent takes two arguments],
-               [c_cv_have_two_getmntent],
-               AC_COMPILE_IFELSE(
-                       [AC_LANG_PROGRAM(
-[[[
-#include "$srcdir/src/utils_mount.h"
-]]],
-[[[
-                                FILE *fh;
-                                struct mnttab mt;
-                                int status;
-                                fh = fopen ("/etc/mnttab", "r");
-                                status = getmntent (fh, &mt);
-                                return(status);
-]]]
-                       )],
-                       [c_cv_have_two_getmntent="yes"],
-                       [c_cv_have_two_getmntent="no"]
-               )
-       )
+  AC_CHECK_LIB([gen], [getmntent],
+    [have_getmntent="gen"],
+    [have_getmntent="no"]
+  )
+fi
+
+if test "x$have_getmntent" = "xlibc"; then
+  AC_CACHE_CHECK([whether getmntent takes one argument],
+    [c_cv_have_one_getmntent],
+    [
+      AC_COMPILE_IFELSE(
+        [
+          AC_LANG_PROGRAM(
+            [[#include "$srcdir/src/utils_mount.h"]],
+            [[
+              FILE *fh;
+              struct mntent *me;
+              fh = setmntent ("/etc/mtab", "r");
+              me = getmntent (fh);
+              return(me->mnt_passno);
+            ]]
+          )
+        ],
+        [c_cv_have_one_getmntent="yes"],
+        [c_cv_have_one_getmntent="no"]
+      )
+    ]
+  )
+
+  AC_CACHE_CHECK([whether getmntent takes two arguments],
+    [c_cv_have_two_getmntent],
+    [
+      AC_COMPILE_IFELSE(
+        [
+          AC_LANG_PROGRAM(
+            [[#include "$srcdir/src/utils_mount.h"]],
+            [[
+              FILE *fh;
+              struct mnttab mt;
+              int status;
+              fh = fopen ("/etc/mnttab", "r");
+              status = getmntent (fh, &mt);
+              return(status);
+            ]]
+          )
+        ],
+        [c_cv_have_two_getmntent="yes"],
+        [c_cv_have_two_getmntent="no"]
+      )
+    ]
+  )
 fi
 
 # Check for different versions of `getmntent' here..
 
-if test "x$have_getmntent" = "xc"; then
-       if test "x$c_cv_have_one_getmntent" = "xyes"; then
-               AC_DEFINE(HAVE_ONE_GETMNTENT, 1,
-                         [Define if the function getmntent exists and takes one argument.])
-       fi
-       if test "x$c_cv_have_two_getmntent" = "xyes"; then
-               AC_DEFINE(HAVE_TWO_GETMNTENT, 1,
-                         [Define if the function getmntent exists and takes two arguments.])
-       fi
+if test "x$have_getmntent" = "xlibc"; then
+  if test "x$c_cv_have_one_getmntent" = "xyes"; then
+    AC_DEFINE([HAVE_ONE_GETMNTENT], [1],
+      [Define if the function getmntent exists and takes one argument.]
+    )
+  fi
+
+  if test "x$c_cv_have_two_getmntent" = "xyes"; then
+    AC_DEFINE([HAVE_TWO_GETMNTENT], [1],
+      [Define if the function getmntent exists and takes two arguments.]
+    )
+  fi
 fi
+
 if test "x$have_getmntent" = "xsun"; then
-       AC_DEFINE(HAVE_SUN_GETMNTENT, 1,
-                 [Define if the function getmntent exists. It is the version from libsun.])
-fi
-if test "x$have_getmntent" = "xseq"; then
-       AC_DEFINE(HAVE_SEQ_GETMNTENT, 1,
-                 [Define if the function getmntent exists. It is the version from libseq.])
+  AC_DEFINE([HAVE_SUN_GETMNTENT], [1],
+    [Define if the function getmntent exists. It is the version from libsun.]
+  )
 fi
+
 if test "x$have_getmntent" = "xgen"; then
-       AC_DEFINE(HAVE_GEN_GETMNTENT, 1,
-                 [Define if the function getmntent exists. It is the version from libgen.])
+  AC_DEFINE([HAVE_GEN_GETMNTENT], [1],
+    [Define if the function getmntent exists. It is the version from libgen.]
+  )
 fi
 
 # Check for htonll
-AC_CACHE_CHECK([if have htonll defined],
-                  [c_cv_have_htonll],
-                  AC_LINK_IFELSE([AC_LANG_PROGRAM(
-[[[
-#include <sys/types.h>
-#include <netinet/in.h>
-#if HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-]]],
-[[[
-          return htonll(0);
-]]]
-    )],
-    [c_cv_have_htonll="yes"],
-    [c_cv_have_htonll="no"]
-  )
+AC_CACHE_CHECK([whether htonll is defined],
+  [c_cv_have_htonll],
+  [
+    AC_LINK_IFELSE(
+      [
+        AC_LANG_PROGRAM(
+          [[
+            #include <inttypes.h>
+            #include <sys/types.h>
+            #include <netinet/in.h>
+          ]],
+          [[return htonll(0);]]
+        )
+      ],
+      [c_cv_have_htonll="yes"],
+      [c_cv_have_htonll="no"]
+    )
+  ]
 )
-if test "x$c_cv_have_htonll" = "xyes"
-then
-    AC_DEFINE(HAVE_HTONLL, 1, [Define if the function htonll exists.])
+
+if test "x$c_cv_have_htonll" = "xyes"; then
+  AC_DEFINE([HAVE_HTONLL], [1], [Define if the function htonll exists.])
 fi
 
 # Check for structures
 AC_CHECK_MEMBERS([struct if_data.ifi_ibytes, struct if_data.ifi_opackets, struct if_data.ifi_ierrors],
-       [AC_DEFINE(HAVE_STRUCT_IF_DATA, 1, [Define if struct if_data exists and is usable.])],
-       [],
-       [
-       #include <sys/types.h>
-       #include <sys/socket.h>
-       #include <net/if.h>
-       ])
+  [AC_DEFINE([HAVE_STRUCT_IF_DATA], [1], [Define if struct if_data exists and is usable.])],
+  [],
+  [[
+    #include <sys/types.h>
+    #include <sys/socket.h>
+    #include <net/if.h>
+  ]]
+)
+
 AC_CHECK_MEMBERS([struct net_device_stats.rx_bytes, struct net_device_stats.tx_packets, struct net_device_stats.rx_errors],
-       [AC_DEFINE(HAVE_STRUCT_NET_DEVICE_STATS, 1, [Define if struct net_device_stats exists and is usable.])],
-       [],
-       [
-       #include <sys/types.h>
-       #include <sys/socket.h>
-       #include <linux/if.h>
-       #include <linux/netdevice.h>
-       ])
-AC_CHECK_MEMBERS([struct inet_diag_req.id, struct inet_diag_req.idiag_states],
-       [AC_DEFINE(HAVE_STRUCT_LINUX_INET_DIAG_REQ, 1, [Define if struct inet_diag_req exists and is usable.])],
-       [],
-       [
-       #include <linux/inet_diag.h>
-       ])
+  [AC_DEFINE([HAVE_STRUCT_NET_DEVICE_STATS], [1], [Define if struct net_device_stats exists and is usable.])],
+  [],
+  [[
+    #include <sys/types.h>
+    #include <sys/socket.h>
+    #include <linux/if.h>
+    #include <linux/netdevice.h>
+  ]]
+)
 
+AC_CHECK_MEMBERS([struct inet_diag_req.id, struct inet_diag_req.idiag_states],
+  [AC_DEFINE([HAVE_STRUCT_LINUX_INET_DIAG_REQ], [1], [Define if struct inet_diag_req exists and is usable.])],
+  [],
+  [[#include <linux/inet_diag.h>]]
+)
 
 AC_CHECK_MEMBERS([struct ip_mreqn.imr_ifindex], [],
-       [],
-       [
-       #include <netinet/in.h>
-       #include <net/if.h>
-       ])
+  [],
+  [[
+    #include <netinet/in.h>
+    #include <net/if.h>
+  ]]
+)
 
 AC_CHECK_MEMBERS([struct kinfo_proc.ki_pid, struct kinfo_proc.ki_rssize, struct kinfo_proc.ki_rusage],
-       [
-               AC_DEFINE(HAVE_STRUCT_KINFO_PROC_FREEBSD, 1,
-                       [Define if struct kinfo_proc exists in the FreeBSD variant.])
-               have_struct_kinfo_proc_freebsd="yes"
-       ],
-       [
-               have_struct_kinfo_proc_freebsd="no"
-       ],
-       [
-#include <kvm.h>
-#include <sys/param.h>
-#include <sys/sysctl.h>
-#include <sys/user.h>
-       ])
+  [
+    AC_DEFINE([HAVE_STRUCT_KINFO_PROC_FREEBSD], [1], [Define if struct kinfo_proc exists in the FreeBSD variant.])
+    have_struct_kinfo_proc_freebsd="yes"
+  ],
+  [],
+  [[
+    #include <kvm.h>
+    #include <sys/param.h>
+    #include <sys/sysctl.h>
+    #include <sys/user.h>
+  ]]
+)
 
 AC_CHECK_MEMBERS([struct kinfo_proc.p_pid, struct kinfo_proc.p_vm_rssize],
-       [
-               AC_DEFINE(HAVE_STRUCT_KINFO_PROC_OPENBSD, 1,
-                       [Define if struct kinfo_proc exists in the OpenBSD variant.])
-               have_struct_kinfo_proc_openbsd="yes"
-       ],
-       [
-               have_struct_kinfo_proc_openbsd="no"
-       ],
-       [
-#include <sys/param.h>
-#include <sys/sysctl.h>
-#include <kvm.h>
-       ])
-
+  [
+    AC_DEFINE([HAVE_STRUCT_KINFO_PROC_OPENBSD], [1], [Define if struct kinfo_proc exists in the OpenBSD variant.])
+    have_struct_kinfo_proc_openbsd="yes"
+  ],
+  [],
+  [[
+    #include <sys/param.h>
+    #include <sys/sysctl.h>
+    #include <kvm.h>
+  ]]
+)
 
 AC_CHECK_MEMBERS([struct kinfo_proc2.p_pid, struct kinfo_proc2.p_uru_maxrss],
-       [
-               AC_DEFINE(HAVE_STRUCT_KINFO_PROC2_NETBSD, 1,
-                       [Define if struct kinfo_proc2 exists in the NetBSD variant.])
-               have_struct_kinfo_proc2_netbsd="yes"
-       ],
-       [
-               have_struct_kinfo_proc2_netbsd="no"
-       ],
-       [
-#include <sys/param.h>
-#include <sys/sysctl.h>
-#include <kvm.h>
-       ])
-
-
-
-AC_CHECK_MEMBERS([struct udphdr.uh_dport, struct udphdr.uh_sport], [], [],
-[#define _BSD_SOURCE
-#define _DEFAULT_SOURCE
-#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#if HAVE_NETINET_IP_H
-# include <netinet/ip.h>
-#endif
-#if HAVE_NETINET_UDP_H
-# include <netinet/udp.h>
-#endif
-])
-AC_CHECK_MEMBERS([struct udphdr.dest, struct udphdr.source], [], [],
-[#define _BSD_SOURCE
-#define _DEFAULT_SOURCE
-#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#if HAVE_NETINET_IP_H
-# include <netinet/ip.h>
-#endif
-#if HAVE_NETINET_UDP_H
-# include <netinet/udp.h>
-#endif
-])
+  [
+    AC_DEFINE([HAVE_STRUCT_KINFO_PROC2_NETBSD], [1], [Define if struct kinfo_proc2 exists in the NetBSD variant.])
+    have_struct_kinfo_proc2_netbsd="yes"
+  ],
+  [],
+  [[
+    #include <sys/param.h>
+    #include <sys/sysctl.h>
+    #include <kvm.h>
+  ]]
+)
 
-AC_CHECK_MEMBERS([kstat_io_t.nwritten, kstat_io_t.writes, kstat_io_t.nwrites, kstat_io_t.wtime],
-       [],
-       [],
-       [
-#if HAVE_KSTAT_H
-# include <kstat.h>
-#endif
-       ])
+AC_CHECK_MEMBERS([struct udphdr.uh_dport, struct udphdr.uh_sport],
+  [],
+  [],
+  [[
+    #define _BSD_SOURCE
+    #define _DEFAULT_SOURCE
+    #include <stdint.h>
+    #if HAVE_SYS_TYPES_H
+    # include <sys/types.h>
+    #endif
+    #if HAVE_NETINET_IN_SYSTM_H
+    # include <netinet/in_systm.h>
+    #endif
+    #if HAVE_NETINET_IN_H
+    # include <netinet/in.h>
+    #endif
+    #if HAVE_NETINET_IP_H
+    # include <netinet/ip.h>
+    #endif
+    #if HAVE_NETINET_UDP_H
+    # include <netinet/udp.h>
+    #endif
+  ]]
+)
 
-# check for pthread_setname_np
-SAVE_LDFLAGS="$LDFLAGS"
+AC_CHECK_MEMBERS([struct udphdr.dest, struct udphdr.source],
+  [],
+  [],
+  [[
+    #define _BSD_SOURCE
+    #define _DEFAULT_SOURCE
+    #include <stdint.h>
+    #if HAVE_SYS_TYPES_H
+    # include <sys/types.h>
+    #endif
+    #if HAVE_NETINET_IN_SYSTM_H
+    # include <netinet/in_systm.h>
+    #endif
+    #if HAVE_NETINET_IN_H
+    # include <netinet/in.h>
+    #endif
+    #if HAVE_NETINET_IP_H
+    # include <netinet/ip.h>
+    #endif
+    #if HAVE_NETINET_UDP_H
+    # include <netinet/udp.h>
+    #endif
+  ]]
+)
+
+AC_CHECK_MEMBERS([kstat_io_t.nwritten, kstat_io_t.writes, kstat_io_t.nwrites, kstat_io_t.wtime],
+  [],
+  [],
+  [[# include <kstat.h>]]
+)
+
+# check for pthread_setname_np
+SAVE_LDFLAGS="$LDFLAGS"
 LDFLAGS="$LDFLAGS -lpthread"
 
 AC_MSG_CHECKING([for pthread_setname_np])
-       have_pthread_setname_np="no"
-       AC_LINK_IFELSE([AC_LANG_PROGRAM(
-[[
-#define _GNU_SOURCE
-#include <pthread.h>
-]],
-[[
-        pthread_setname_np((pthread_t) {0}, "conftest");
-]]
-       )], [
-               have_pthread_setname_np="yes"
-               AC_DEFINE(HAVE_PTHREAD_SETNAME_NP, 1, [pthread_setname_np() is available.])
-       ])
+have_pthread_setname_np="no"
+AC_LINK_IFELSE(
+  [
+    AC_LANG_PROGRAM(
+      [[
+        #define _GNU_SOURCE
+        #include <pthread.h>
+      ]],
+      [[pthread_setname_np((pthread_t) {0}, "conftest");]]
+    )
+  ],
+  [
+    have_pthread_setname_np="yes"
+    AC_DEFINE(HAVE_PTHREAD_SETNAME_NP, 1, [pthread_setname_np() is available.])
+  ]
+)
 
 AC_MSG_RESULT([$have_pthread_setname_np])
 
 # check for pthread_set_name_np(3) (FreeBSD)
 AC_MSG_CHECKING([for pthread_set_name_np])
-       have_pthread_set_name_np="no"
-       AC_LINK_IFELSE([AC_LANG_PROGRAM(
-[[
-#include <pthread_np.h>
-]],
-[[
-        pthread_set_name_np((pthread_t) {0}, "conftest");
-]]
-       )], [
-               have_pthread_set_name_np="yes"
-               AC_DEFINE(HAVE_PTHREAD_SET_NAME_NP, 1, [pthread_set_name_np() is available.])
-       ])
+have_pthread_set_name_np="no"
+AC_LINK_IFELSE(
+  [
+    AC_LANG_PROGRAM(
+      [[#include <pthread_np.h>]],
+      [[pthread_set_name_np((pthread_t) {0}, "conftest");]]
+    )
+   ],
+  [
+    have_pthread_set_name_np="yes"
+    AC_DEFINE(HAVE_PTHREAD_SET_NAME_NP, 1, [pthread_set_name_np() is available.])
+  ]
+)
 AC_MSG_RESULT([$have_pthread_set_name_np])
 
 LDFLAGS="$SAVE_LDFLAGS"
 
-#
-# Checks for libraries begin here
-#
+AC_CHECK_TYPES([struct ip6_ext],
+  [have_ip6_ext="yes"],
+  [have_ip6_ext="no"],
+  [[
+    #include <stdint.h>
+    #if HAVE_SYS_TYPES_H
+    # include <sys/types.h>
+    #endif
+    #if HAVE_NETINET_IN_SYSTM_H
+    # include <netinet/in_systm.h>
+    #endif
+    #if HAVE_NETINET_IN_H
+    # include <netinet/in.h>
+    #endif
+    #if HAVE_NETINET_IP6_H
+    # include <netinet/ip6.h>
+    #endif
+  ]]
+)
 
-with_libresolv="yes"
-AC_CHECK_LIB(resolv, res_search,
-[
-       AC_DEFINE(HAVE_LIBRESOLV, 1, [Define to 1 if you have the 'resolv' library (-lresolv).])
-],
-[with_libresolv="no"])
-AM_CONDITIONAL(BUILD_WITH_LIBRESOLV, test "x$with_libresolv" = "xyes")
+if test "x$have_ip6_ext" = "xno"; then
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -DSOLARIS2=8"
+  AC_CHECK_TYPES([struct ip6_ext],
+    [have_ip6_ext="yes, with -DSOLARIS2=8"],
+    [have_ip6_ext="no"],
+    [[
+      #include <stdint.h>
+      #if HAVE_SYS_TYPES_H
+      # include <sys/types.h>
+      #endif
+      #if HAVE_NETINET_IN_SYSTM_H
+      # include <netinet/in_systm.h>
+      #endif
+      #if HAVE_NETINET_IN_H
+      # include <netinet/in.h>
+      #endif
+      #if HAVE_NETINET_IP6_H
+      # include <netinet/ip6.h>
+      #endif
+    ]]
+  )
+  if test "x$have_ip6_ext" = "xno"; then
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+fi
 
-dnl Check for HAL (hardware abstraction library)
-with_libhal="no"
-PKG_CHECK_MODULES([HAL], [hal],
-  [
-    SAVE_LIBS="$LIBS"
-    LIBS="$HAL_LIBS $LIBS"
-    AC_CHECK_LIB([hal], [libhal_device_property_exists],
-      [
-        SAVE_CPPFLAGS="$CPPFLAGS"
-        CPPFLAGS="$HAL_CFLAGS $CPPFLAGS"
-        AC_CHECK_HEADERS([libhal.h],
-        [
-          with_libhal="yes"
-          BUILD_WITH_LIBHAL_CFLAGS="$HAL_CFLAGS"
-          BUILD_WITH_LIBHAL_LIBS="$HAL_LIBS"
-        ])
-        CPPFLAGS="$SAVE_CPPFLAGS"
-      ],
-      [ : ]
-    )
-    LIBS="$SAVE_LIBS"
-  ],
-  [ : ]
-)
-AC_SUBST(BUILD_WITH_LIBHAL_CFLAGS)
-AC_SUBST(BUILD_WITH_LIBHAL_LIBS)
+# libi2c-dev
+if test "x$ac_system" = "xLinux"; then
+  AC_CHECK_DECL([i2c_smbus_read_i2c_block_data],
+    [with_libi2c="yes"],
+    [with_libi2c="no (symbol i2c_smbus_read_i2c_block_data not found - have you installed libi2c-dev ?)"],
+    [[
+      #include <stdlib.h>
+      #include <linux/i2c-dev.h>
+    ]]
+  )
+else
+  with_libi2c="no (Linux only)"
+fi
 
+#
+# Checks for libraries begin here
+#
 
+# Check for libpthread
 SAVE_LIBS="$LIBS"
 AC_CHECK_LIB([pthread],
   [pthread_create],
   [],
-  [AC_MSG_ERROR([Symbol 'pthread_create' not found in libpthread"])],
+  [AC_MSG_ERROR([Symbol 'pthread_create' not found in libpthread])],
   []
 )
 PTHREAD_LIBS="$LIBS"
 LIBS="$SAVE_LIBS"
+AC_SUBST([PTHREAD_LIBS])
 
 AC_CHECK_HEADERS([pthread.h],
   [],
   [AC_MSG_ERROR([pthread.h not found])]
 )
-AC_SUBST([PTHREAD_LIBS])
 
 m4_divert_once([HELP_WITH], [
-collectd additional packages:])
+Collectd additional packages:])
 
-if test "x$ac_system" = "xAIX"
-then
-       with_perfstat="yes"
-       with_procinfo="yes"
+if test "x$ac_system" = "xAIX"; then
+  with_perfstat="yes"
+  with_procinfo="yes"
 else
-       with_perfstat="no (AIX only)"
-       with_procinfo="no (AIX only)"
+  with_perfstat="no (AIX only)"
+  with_procinfo="no (AIX only)"
 fi
 
-if test "x$with_perfstat" = "xyes"
-then
-       AC_CHECK_LIB(perfstat, perfstat_reset, [with_perfstat="yes"], [with_perfstat="no (perfstat not found)"], [])
-#      AC_CHECK_HEADERS(sys/protosw.h libperfstat.h,, [with_perfstat="no (perfstat not found)"])
+if test "x$with_perfstat" = "xyes"; then
+  AC_CHECK_LIB([perfstat], [perfstat_reset],
+    [with_perfstat="yes"],
+    [with_perfstat="no (perfstat not found)"]
+  )
 fi
-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
+
+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")
+AM_CONDITIONAL([BUILD_WITH_PERFSTAT], [test "x$with_perfstat" = "xyes"])
 
 # Processes plugin under AIX.
-if test "x$with_procinfo" = "xyes"
-then
-       AC_CHECK_HEADERS(procinfo.h,, [with_procinfo="no (procinfo.h not found)"])
-fi
-if test "x$with_procinfo" = "xyes"
-then
-        AC_DEFINE(HAVE_PROCINFO_H, 1, [Define to 1 if you have the procinfo.h])
+if test "x$with_procinfo" = "xyes"; then
+  AC_CHECK_HEADERS([procinfo.h],
+    [AC_DEFINE([HAVE_PROCINFO_H], [1], [Define to 1 if you have the procinfo.h])],
+    [with_procinfo="no (procinfo.h not found)"]
+  )
 fi
 
-if test "x$ac_system" = "xSolaris"
-then
-       with_kstat="yes"
-       with_devinfo="yes"
+if test "x$ac_system" = "xSolaris"; then
+  with_kstat="yes"
+  with_devinfo="yes"
 else
-       with_kstat="no (Solaris only)"
-       with_devinfo="no (Solaris only)"
+  with_kstat="no (Solaris only)"
+  with_devinfo="no (Solaris only)"
 fi
 
-if test "x$with_kstat" = "xyes"
-then
-       AC_CHECK_LIB(kstat, kstat_open, [with_kstat="yes"], [with_kstat="no (libkstat not found)"], [])
-fi
-if test "x$with_kstat" = "xyes"
-then
-       AC_CHECK_LIB(devinfo, di_init, [with_devinfo="yes"], [with_devinfo="no (not found)"], [])
-       AC_CHECK_HEADERS(kstat.h,, [with_kstat="no (kstat.h not found)"])
+if test "x$with_kstat" = "xyes"; then
+  AC_CHECK_LIB([kstat], [kstat_open],
+    [with_kstat="yes"],
+    [with_kstat="no (libkstat not found)"]
+  )
 fi
-if test "x$with_kstat" = "xyes"
-then
-       AC_DEFINE(HAVE_LIBKSTAT, 1,
-                 [Define to 1 if you have the 'kstat' library (-lkstat)])
+
+if test "x$with_kstat" = "xyes"; then
+  AC_CHECK_LIB([devinfo], [di_init],
+    [with_devinfo="yes"],
+    [with_devinfo="no (not found)"]
+  )
+  AC_CHECK_HEADERS([kstat.h],
+    [AC_DEFINE(HAVE_LIBKSTAT, [1], [Define to 1 if you have the 'kstat' library (-lkstat)])],
+    [with_kstat="no (kstat.h not found)"]
+  )
 fi
-AM_CONDITIONAL(BUILD_WITH_LIBKSTAT, test "x$with_kstat" = "xyes")
-AM_CONDITIONAL(BUILD_WITH_LIBDEVINFO, test "x$with_devinfo" = "xyes")
 
-with_libiokit="no"
-if test "x$ac_system" = "xDarwin"
-then
-       with_libiokit="yes"
+AM_CONDITIONAL([BUILD_WITH_LIBDEVINFO], [test "x$with_devinfo" = "xyes"])
+AM_CONDITIONAL([BUILD_WITH_LIBKSTAT], [test "x$with_kstat" = "xyes"])
+
+if test "x$ac_system" = "xDarwin"; then
+  with_libiokit="yes"
 else
-       with_libiokit="no"
+  with_libiokit="no"
 fi
-AM_CONDITIONAL(BUILD_WITH_LIBIOKIT, test "x$with_libiokit" = "xyes")
+AM_CONDITIONAL([BUILD_WITH_LIBIOKIT], [test "x$with_libiokit" = "xyes"])
 
 with_libkvm="no"
-AC_CHECK_LIB(kvm, kvm_getprocs, [with_kvm_getprocs="yes"], [with_kvm_getprocs="no"])
-if test "x$with_kvm_getprocs" = "xyes"
-then
-       AC_DEFINE(HAVE_LIBKVM_GETPROCS, 1,
-                 [Define to 1 if you have the 'kvm' library with the 'kvm_getprocs' symbol (-lkvm)])
-       with_libkvm="yes"
+AC_CHECK_LIB([kvm], [kvm_getprocs],
+  [with_kvm_getprocs="yes"],
+  [with_kvm_getprocs="no"]
+)
+
+if test "x$with_kvm_getprocs" = "xyes"; then
+  AC_DEFINE([HAVE_LIBKVM_GETPROCS], [1],
+    [Define to 1 if you have the 'kvm' library with the 'kvm_getprocs' symbol (-lkvm)]
+  )
+  with_libkvm="yes"
 fi
-AM_CONDITIONAL(BUILD_WITH_LIBKVM_GETPROCS, test "x$with_kvm_getprocs" = "xyes")
 
-AC_CHECK_LIB(kvm, kvm_getswapinfo, [with_kvm_getswapinfo="yes"], [with_kvm_getswapinfo="no"])
-if test "x$with_kvm_getswapinfo" = "xyes"
-then
-       AC_DEFINE(HAVE_LIBKVM_GETSWAPINFO, 1,
-                 [Define to 1 if you have the 'kvm' library with the 'kvm_getswapinfo' symbol (-lkvm)])
-       with_libkvm="yes"
+AM_CONDITIONAL([BUILD_WITH_LIBKVM_GETPROCS], [test "x$with_kvm_getprocs" = "xyes"])
+
+AC_CHECK_LIB([kvm], [kvm_getswapinfo],
+  [with_kvm_getswapinfo="yes"],
+  [with_kvm_getswapinfo="no"]
+)
+
+if test "x$with_kvm_getswapinfo" = "xyes"; then
+  AC_DEFINE([HAVE_LIBKVM_GETSWAPINFO], [1],
+    [Define to 1 if you have the 'kvm' library with the 'kvm_getswapinfo' symbol (-lkvm)]
+  )
+  with_libkvm="yes"
 fi
-AM_CONDITIONAL(BUILD_WITH_LIBKVM_GETSWAPINFO, test "x$with_kvm_getswapinfo" = "xyes")
 
-AC_CHECK_LIB(kvm, kvm_nlist, [with_kvm_nlist="yes"], [with_kvm_nlist="no"])
-if test "x$with_kvm_nlist" = "xyes"
-then
-       AC_CHECK_HEADERS(bsd/nlist.h nlist.h)
-       AC_DEFINE(HAVE_LIBKVM_NLIST, 1,
-                 [Define to 1 if you have the 'kvm' library with the 'kvm_nlist' symbol (-lkvm)])
-       with_libkvm="yes"
+AM_CONDITIONAL([BUILD_WITH_LIBKVM_GETSWAPINFO], [test "x$with_kvm_getswapinfo" = "xyes"])
+
+AC_CHECK_LIB([kvm], [kvm_nlist],
+  [with_kvm_nlist="yes"],
+  [with_kvm_nlist="no"]
+)
+
+if test "x$with_kvm_nlist" = "xyes"; then
+  AC_CHECK_HEADERS([bsd/nlist.h nlist.h])
+  AC_DEFINE([HAVE_LIBKVM_NLIST], [1],
+    [Define to 1 if you have the 'kvm' library with the 'kvm_nlist' symbol (-lkvm)]
+  )
+  with_libkvm="yes"
 fi
-AM_CONDITIONAL(BUILD_WITH_LIBKVM_NLIST, test "x$with_kvm_nlist" = "xyes")
 
-AC_CHECK_LIB(kvm, kvm_openfiles, [with_kvm_openfiles="yes"], [with_kvm_openfiles="no"])
-if test "x$with_kvm_openfiles" = "xyes"
-then
-       AC_DEFINE(HAVE_LIBKVM_NLIST, 1,
-                 [Define to 1 if you have the 'kvm' library with the 'kvm_openfiles' symbol (-lkvm)])
-       with_libkvm="yes"
+AM_CONDITIONAL([BUILD_WITH_LIBKVM_NLIST], [test "x$with_kvm_nlist" = "xyes"])
+
+AC_CHECK_LIB([kvm], [kvm_openfiles],
+  [with_kvm_openfiles="yes"],
+  [with_kvm_openfiles="no"]
+)
+
+if test "x$with_kvm_openfiles" = "xyes"; then
+  AC_DEFINE([HAVE_LIBKVM_NLIST], [1],
+    [Define to 1 if you have the 'kvm' library with the 'kvm_openfiles' symbol (-lkvm)]
+  )
+  with_libkvm="yes"
 fi
-AM_CONDITIONAL(BUILD_WITH_LIBKVM_OPENFILES, test "x$with_kvm_openfiles" = "xyes")
 
 # --with-libaquaero5 {{{
-AC_ARG_WITH(libaquaero5, [AS_HELP_STRING([--with-libaquaero5@<:@=PREFIX@:>@], [Path to aquatools-ng source code.])],
-[
- if test "x$withval" = "xyes"
- then
-        with_libaquaero5="yes"
- else if test "x$withval" = "xno"
- then
-        with_libaquaero5="no"
- else
-        with_libaquaero5="yes"
-        LIBAQUAERO5_CFLAGS="$LIBAQUAERO5_CFLAGS -I$withval/src"
-        LIBAQUAERO5_LDFLAGS="$LIBAQUAERO5_LDFLAGS -L$withval/obj"
- fi; fi
-],
-[with_libaquaero5="yes"])
+AC_ARG_WITH([libaquaero5],
+  [AS_HELP_STRING([--with-libaquaero5@<:@=PREFIX@:>@], [Path to aquatools-ng source code.])],
+  [
   if test "x$withval" = "xyes"; then
+      with_libaquaero5="yes"
+    else if test "x$withval" = "xno"; then
+      with_libaquaero5="no"
+    else
+      with_libaquaero5="yes"
+      LIBAQUAERO5_CFLAGS="$LIBAQUAERO5_CFLAGS -I$withval/src"
+      LIBAQUAERO5_LDFLAGS="$LIBAQUAERO5_LDFLAGS -L$withval/obj"
+    fi; fi
+  ],
+  [with_libaquaero5="yes"]
+)
 
 SAVE_CPPFLAGS="$CPPFLAGS"
 SAVE_LDFLAGS="$LDFLAGS"
-
 CPPFLAGS="$CPPFLAGS $LIBAQUAERO5_CFLAGS"
 LDFLAGS="$LDFLAGS $LIBAQUAERO5_LDFLAGS"
 
-if test "x$with_libaquaero5" = "xyes"
-then
-       if test "x$LIBAQUAERO5_CFLAGS" != "x"
-       then
-               AC_MSG_NOTICE([libaquaero5 CPPFLAGS: $LIBAQUAERO5_CFLAGS])
-       fi
-       AC_CHECK_HEADERS(libaquaero5.h,
-       [with_libaquaero5="yes"],
-       [with_libaquaero5="no (libaquaero5.h not found)"])
+if test "x$with_libaquaero5" = "xyes"; then
+  if test "x$LIBAQUAERO5_CFLAGS" != "x"; then
+    AC_MSG_NOTICE([libaquaero5 CPPFLAGS: $LIBAQUAERO5_CFLAGS])
+  fi
+  AC_CHECK_HEADERS([libaquaero5.h],
+    [with_libaquaero5="yes"],
+    [with_libaquaero5="no (libaquaero5.h not found)"]
+  )
 fi
-if test "x$with_libaquaero5" = "xyes"
-then
-       if test "x$LIBAQUAERO5_LDFLAGS" != "x"
-       then
-               AC_MSG_NOTICE([libaquaero5 LDFLAGS: $LIBAQUAERO5_LDFLAGS])
-       fi
-       AC_CHECK_LIB(aquaero5, libaquaero5_poll,
-       [with_libaquaero5="yes"],
-       [with_libaquaero5="no (symbol 'libaquaero5_poll' not found)"])
+
+if test "x$with_libaquaero5" = "xyes"; then
+  if test "x$LIBAQUAERO5_LDFLAGS" != "x"; then
+    AC_MSG_NOTICE([libaquaero5 LDFLAGS: $LIBAQUAERO5_LDFLAGS])
+  fi
+  AC_CHECK_LIB([aquaero5], libaquaero5_poll,
+    [with_libaquaero5="yes"],
+    [with_libaquaero5="no (symbol 'libaquaero5_poll' not found)"]
+  )
 fi
 
 CPPFLAGS="$SAVE_CPPFLAGS"
 LDFLAGS="$SAVE_LDFLAGS"
 
-if test "x$with_libaquaero5" = "xyes"
-then
-       BUILD_WITH_LIBAQUAERO5_CFLAGS="$LIBAQUAERO5_CFLAGS"
-       BUILD_WITH_LIBAQUAERO5_LDFLAGS="$LIBAQUAERO5_LDFLAGS"
-       AC_SUBST(BUILD_WITH_LIBAQUAERO5_CFLAGS)
-       AC_SUBST(BUILD_WITH_LIBAQUAERO5_LDFLAGS)
+if test "x$with_libaquaero5" = "xyes"; then
+  BUILD_WITH_LIBAQUAERO5_CFLAGS="$LIBAQUAERO5_CFLAGS"
+  BUILD_WITH_LIBAQUAERO5_LDFLAGS="$LIBAQUAERO5_LDFLAGS"
 fi
-AM_CONDITIONAL(BUILD_WITH_LIBAQUAERO5, test "x$with_libaquaero5" = "xyes")
+AC_SUBST([BUILD_WITH_LIBAQUAERO5_CFLAGS])
+AC_SUBST([BUILD_WITH_LIBAQUAERO5_LDFLAGS])
 # }}}
 
 # --with-libhiredis {{{
-AC_ARG_WITH(libhiredis, [AS_HELP_STRING([--with-libhiredis@<:@=PREFIX@:>@],
-      [Path to libhiredis.])],
-[
- if test "x$withval" = "xyes"
- then
-        with_libhiredis="yes"
- else if test "x$withval" = "xno"
- then
-        with_libhiredis="no"
- else
-        with_libhiredis="yes"
-        LIBHIREDIS_CPPFLAGS="$LIBHIREDIS_CPPFLAGS -I$withval/include"
-        LIBHIREDIS_LDFLAGS="$LIBHIREDIS_LDFLAGS -L$withval/lib"
- fi; fi
-],
-[with_libhiredis="yes"])
+AC_ARG_WITH([libhiredis],
+  [AS_HELP_STRING([--with-libhiredis@<:@=PREFIX@:>@], [Path to libhiredis.])],
+  [
+    if test "x$withval" = "xyes"; then
+      with_libhiredis="yes"
+    else if test "x$withval" = "xno"; then
+      with_libhiredis="no"
+    else
+      with_libhiredis="yes"
+      LIBHIREDIS_CPPFLAGS="$LIBHIREDIS_CPPFLAGS -I$withval/include"
+      LIBHIREDIS_LDFLAGS="$LIBHIREDIS_LDFLAGS -L$withval/lib"
+    fi; fi
+  ],
+  [with_libhiredis="yes"]
+)
 
 SAVE_CPPFLAGS="$CPPFLAGS"
 SAVE_LDFLAGS="$LDFLAGS"
-
 CPPFLAGS="$CPPFLAGS $LIBHIREDIS_CPPFLAGS"
 LDFLAGS="$LDFLAGS $LIBHIREDIS_LDFLAGS"
 
-if test "x$with_libhiredis" = "xyes"
-then
-       if test "x$LIBHIREDIS_CPPFLAGS" != "x"
-       then
-               AC_MSG_NOTICE([libhiredis CPPFLAGS: $LIBHIREDIS_CPPFLAGS])
-       fi
-       AC_CHECK_HEADERS(hiredis/hiredis.h,
-       [with_libhiredis="yes"],
-       [with_libhiredis="no (hiredis.h not found)"])
+if test "x$with_libhiredis" = "xyes"; then
+  if test "x$LIBHIREDIS_CPPFLAGS" != "x"; then
+    AC_MSG_NOTICE([libhiredis CPPFLAGS: $LIBHIREDIS_CPPFLAGS])
+  fi
+  AC_CHECK_HEADERS([hiredis/hiredis.h],
+    [with_libhiredis="yes"],
+    [with_libhiredis="no (hiredis.h not found)"]
+  )
 fi
-if test "x$with_libhiredis" = "xyes"
-then
-       if test "x$LIBHIREDIS_LDFLAGS" != "x"
-       then
-               AC_MSG_NOTICE([libhiredis LDFLAGS: $LIBHIREDIS_LDFLAGS])
-       fi
-       AC_CHECK_LIB(hiredis, redisCommand,
-       [with_libhiredis="yes"],
-       [with_libhiredis="no (symbol 'redisCommand' not found)"])
 
+if test "x$with_libhiredis" = "xyes"; then
+  if test "x$LIBHIREDIS_LDFLAGS" != "x"; then
+    AC_MSG_NOTICE([libhiredis LDFLAGS: $LIBHIREDIS_LDFLAGS])
+  fi
+  AC_CHECK_LIB([hiredis], [redisCommand],
+    [with_libhiredis="yes"],
+    [with_libhiredis="no (symbol 'redisCommand' not found)"]
+  )
 fi
 
 CPPFLAGS="$SAVE_CPPFLAGS"
 LDFLAGS="$SAVE_LDFLAGS"
 
-if test "x$with_libhiredis" = "xyes"
-then
-       BUILD_WITH_LIBHIREDIS_CPPFLAGS="$LIBHIREDIS_CPPFLAGS"
-       BUILD_WITH_LIBHIREDIS_LDFLAGS="$LIBHIREDIS_LDFLAGS"
-       AC_SUBST(BUILD_WITH_LIBHIREDIS_CPPFLAGS)
-       AC_SUBST(BUILD_WITH_LIBHIREDIS_LDFLAGS)
+if test "x$with_libhiredis" = "xyes"; then
+  BUILD_WITH_LIBHIREDIS_CPPFLAGS="$LIBHIREDIS_CPPFLAGS"
+  BUILD_WITH_LIBHIREDIS_LDFLAGS="$LIBHIREDIS_LDFLAGS"
 fi
-AM_CONDITIONAL(BUILD_WITH_LIBHIREDIS, test "x$with_libhiredis" = "xyes")
+
+AC_SUBST([BUILD_WITH_LIBHIREDIS_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBHIREDIS_LDFLAGS])
 # }}}
 
 # --with-libcurl {{{
 with_curl_config="curl-config"
 with_curl_cflags=""
 with_curl_libs=""
-AC_ARG_WITH(libcurl, [AS_HELP_STRING([--with-libcurl@<:@=PREFIX@:>@], [Path to libcurl.])],
-[
-       if test "x$withval" = "xno"
-       then
-               with_libcurl="no"
-       else if test "x$withval" = "xyes"
-       then
-               with_libcurl="yes"
-       else
-               if test -f "$withval" && test -x "$withval"
-               then
-                       with_curl_config="$withval"
-                       with_libcurl="yes"
-               else if test -x "$withval/bin/curl-config"
-               then
-                       with_curl_config="$withval/bin/curl-config"
-                       with_libcurl="yes"
-               fi; fi
-               with_libcurl="yes"
-       fi; fi
-],
-[
-       with_libcurl="yes"
-])
-if test "x$with_libcurl" = "xyes"
-then
-       with_curl_cflags=`$with_curl_config --cflags 2>/dev/null`
-       curl_config_status=$?
+AC_ARG_WITH(libcurl,
+  [AS_HELP_STRING([--with-libcurl@<:@=PREFIX@:>@], [Path to libcurl.])],
+  [
+    if test "x$withval" = "xno"; then
+      with_libcurl="no"
+    else if test "x$withval" = "xyes"; then
+      with_libcurl="yes"
+    else
+      if test -f "$withval" && test -x "$withval"; then
+        with_curl_config="$withval"
+        with_libcurl="yes"
+      else if test -x "$withval/bin/curl-config"; then
+        with_curl_config="$withval/bin/curl-config"
+        with_libcurl="yes"
+      fi; fi
+      with_libcurl="yes"
+    fi; fi
+  ],
+  [with_libcurl="yes"]
+)
 
-       if test $curl_config_status -ne 0
-       then
-               with_libcurl="no ($with_curl_config failed)"
-       else
-               SAVE_CPPFLAGS="$CPPFLAGS"
-               CPPFLAGS="$CPPFLAGS $with_curl_cflags"
+if test "x$with_libcurl" = "xyes"; then
+  with_curl_cflags=`$with_curl_config --cflags 2>/dev/null`
+  curl_config_status=$?
 
-               AC_CHECK_HEADERS(curl/curl.h, [], [with_libcurl="no (curl/curl.h not found)"], [])
+  if test $curl_config_status -ne 0; then
+    with_libcurl="no ($with_curl_config failed)"
+  else
+    SAVE_CPPFLAGS="$CPPFLAGS"
+    CPPFLAGS="$CPPFLAGS $with_curl_cflags"
 
-               CPPFLAGS="$SAVE_CPPFLAGS"
-       fi
+    AC_CHECK_HEADERS([curl/curl.h],
+      [with_libcurl="yes"],
+      [with_libcurl="no (curl/curl.h not found)"]
+    )
+
+    CPPFLAGS="$SAVE_CPPFLAGS"
+  fi
 fi
-if test "x$with_libcurl" = "xyes"
-then
-       with_curl_libs=`$with_curl_config --libs 2>/dev/null`
-       curl_config_status=$?
 
-       if test $curl_config_status -ne 0
-       then
-               with_libcurl="no ($with_curl_config failed)"
-       else
-               AC_CHECK_LIB(curl, curl_easy_init,
-                [with_libcurl="yes"],
-                [with_libcurl="no (symbol 'curl_easy_init' not found)"],
-                [$with_curl_libs])
-               AC_CHECK_DECL(CURLOPT_USERNAME,
-                [have_curlopt_username="yes"],
-                [have_curlopt_username="no"],
-                [[#include <curl/curl.h>]])
-               AC_CHECK_DECL(CURLOPT_TIMEOUT_MS,
-                [have_curlopt_timeout="yes"],
-                [have_curlopt_timeout="no"],
-                [[#include <curl/curl.h>]])
-       fi
+if test "x$with_libcurl" = "xyes"; then
+  with_curl_libs=`$with_curl_config --libs 2>/dev/null`
+  curl_config_status=$?
+
+  if test $curl_config_status -ne 0; then
+    with_libcurl="no ($with_curl_config failed)"
+  else
+    AC_CHECK_LIB([curl], [curl_easy_init],
+      [with_libcurl="yes"],
+      [with_libcurl="no (symbol 'curl_easy_init' not found)"],
+      [$with_curl_libs]
+    )
+
+    AC_CHECK_DECL([CURLOPT_USERNAME],
+      [have_curlopt_username="yes"],
+      [have_curlopt_username="no"],
+      [[#include <curl/curl.h>]]
+    )
+
+    AC_CHECK_DECL(CURLOPT_TIMEOUT_MS,
+      [have_curlopt_timeout="yes"],
+      [have_curlopt_timeout="no"],
+      [[#include <curl/curl.h>]]
+    )
+  fi
 fi
-if test "x$with_libcurl" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       SAVE_LDFLAGS="$LDFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_curl_cflags"
-       LDFLAGS="$LDFLAGS $with_curl_libs"
-       AC_CACHE_CHECK([for CURLINFO_APPCONNECT_TIME],
-               [c_cv_have_curlinfo_appconnect_time],
-               AC_LINK_IFELSE([AC_LANG_PROGRAM(
-[[
-#include <curl/curl.h>
-]],
-[[
-int val = CURLINFO_APPCONNECT_TIME;
-return val;
-]]
-                       )],
-                       [c_cv_have_curlinfo_appconnect_time="yes"],
-                       [c_cv_have_curlinfo_appconnect_time="no"]
-               )
-       )
-       CPPFLAGS="$SAVE_CPPFLAGS"
-       LDFLAGS="$SAVE_LDFLAGS"
+
+if test "x$with_libcurl" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  SAVE_LDFLAGS="$LDFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_curl_cflags"
+  LDFLAGS="$LDFLAGS $with_curl_libs"
+  AC_CACHE_CHECK([for CURLINFO_APPCONNECT_TIME],
+    [c_cv_have_curlinfo_appconnect_time],
+    [
+      AC_LINK_IFELSE(
+        [
+          AC_LANG_PROGRAM(
+            [[#include <curl/curl.h>]],
+            [[
+              int val = CURLINFO_APPCONNECT_TIME;
+              return val;
+            ]]
+          )
+        ],
+        [c_cv_have_curlinfo_appconnect_time="yes"],
+        [c_cv_have_curlinfo_appconnect_time="no"]
+      )
+    ]
+  )
+  CPPFLAGS="$SAVE_CPPFLAGS"
+  LDFLAGS="$SAVE_LDFLAGS"
 fi
-AM_CONDITIONAL(BUILD_WITH_LIBCURL, test "x$with_libcurl" = "xyes")
-if test "x$c_cv_have_curlinfo_appconnect_time" = "xyes"
-then
-       AC_DEFINE(HAVE_CURLINFO_APPCONNECT_TIME, 1, [Define if curl.h defines CURLINFO_APPCONNECT_TIME.])
+
+if test "x$c_cv_have_curlinfo_appconnect_time" = "xyes"; then
+  AC_DEFINE([HAVE_CURLINFO_APPCONNECT_TIME], [1],
+    [Define if curl.h defines CURLINFO_APPCONNECT_TIME.]
+  )
 fi
 
-if test "x$with_libcurl" = "xyes"
-then
-       BUILD_WITH_LIBCURL_CFLAGS="$with_curl_cflags"
-       BUILD_WITH_LIBCURL_LIBS="$with_curl_libs"
-       AC_SUBST(BUILD_WITH_LIBCURL_CFLAGS)
-       AC_SUBST(BUILD_WITH_LIBCURL_LIBS)
+if test "x$with_libcurl" = "xyes"; then
+  BUILD_WITH_LIBCURL_CFLAGS="$with_curl_cflags"
+  BUILD_WITH_LIBCURL_LIBS="$with_curl_libs"
 
-       if test "x$have_curlopt_username" = "xyes"
-       then
-               AC_DEFINE(HAVE_CURLOPT_USERNAME, 1, [Define if libcurl supports CURLOPT_USERNAME option.])
-       fi
+  if test "x$have_curlopt_username" = "xyes"; then
+    AC_DEFINE([HAVE_CURLOPT_USERNAME], [1],
+      [Define if libcurl supports CURLOPT_USERNAME option.]
+    )
+  fi
 
-       if test "x$have_curlopt_timeout" = "xyes"
-       then
-               AC_DEFINE(HAVE_CURLOPT_TIMEOUT_MS, 1, [Define if libcurl supports CURLOPT_TIMEOUT_MS option.])
-       fi
+  if test "x$have_curlopt_timeout" = "xyes"; then
+    AC_DEFINE([HAVE_CURLOPT_TIMEOUT_MS], [1],
+      [Define if libcurl supports CURLOPT_TIMEOUT_MS option.]
+    )
+  fi
 fi
+
+AC_SUBST(BUILD_WITH_LIBCURL_CFLAGS)
+AC_SUBST(BUILD_WITH_LIBCURL_LIBS)
 # }}}
 
 # --with-libdbi {{{
-with_libdbi_cppflags=""
-with_libdbi_ldflags=""
-AC_ARG_WITH(libdbi, [AS_HELP_STRING([--with-libdbi@<:@=PREFIX@:>@], [Path to libdbi.])],
-[
-       if test "x$withval" != "xno" && test "x$withval" != "xyes"
-       then
-               with_libdbi_cppflags="-I$withval/include"
-               with_libdbi_ldflags="-L$withval/lib"
-               with_libdbi="yes"
-       else
-               with_libdbi="$withval"
-       fi
-],
-[
-       with_libdbi="yes"
-])
-if test "x$with_libdbi" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_libdbi_cppflags"
+AC_ARG_WITH([libdbi],
+  [AS_HELP_STRING([--with-libdbi@<:@=PREFIX@:>@], [Path to libdbi.])],
+  [
+    if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
+      with_libdbi_cppflags="-I$withval/include"
+      with_libdbi_ldflags="-L$withval/lib"
+      with_libdbi="yes"
+    else
+      with_libdbi="$withval"
+    fi
+  ],
+  [with_libdbi="yes"]
+)
+
+if test "x$with_libdbi" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_libdbi_cppflags"
 
-       AC_CHECK_HEADERS(dbi/dbi.h, [with_libdbi="yes"], [with_libdbi="no (dbi/dbi.h not found)"])
+  AC_CHECK_HEADERS([dbi/dbi.h],
+    [with_libdbi="yes"],
+    [with_libdbi="no (dbi/dbi.h not found)"]
+  )
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
+  CPPFLAGS="$SAVE_CPPFLAGS"
 fi
-if test "x$with_libdbi" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       SAVE_LDFLAGS="$LDFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_libdbi_cppflags"
-       LDFLAGS="$LDFLAGS $with_libdbi_ldflags"
 
-       AC_CHECK_LIB(dbi, dbi_initialize, [with_libdbi="yes"], [with_libdbi="no (Symbol 'dbi_initialize' not found)"])
+if test "x$with_libdbi" = "xyes"; then
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $with_libdbi_ldflags"
+
+  AC_CHECK_LIB([dbi], [dbi_initialize],
+    [with_libdbi="yes"],
+    [with_libdbi="no (Symbol 'dbi_initialize' not found)"]
+  )
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
-       LDFLAGS="$SAVE_LDFLAGS"
+  LDFLAGS="$SAVE_LDFLAGS"
 fi
-if test "x$with_libdbi" = "xyes"
-then
-       BUILD_WITH_LIBDBI_CPPFLAGS="$with_libdbi_cppflags"
-       BUILD_WITH_LIBDBI_LDFLAGS="$with_libdbi_ldflags"
-       BUILD_WITH_LIBDBI_LIBS="-ldbi"
-       AC_SUBST(BUILD_WITH_LIBDBI_CPPFLAGS)
-       AC_SUBST(BUILD_WITH_LIBDBI_LDFLAGS)
-       AC_SUBST(BUILD_WITH_LIBDBI_LIBS)
-fi
-AM_CONDITIONAL(BUILD_WITH_LIBDBI, test "x$with_libdbi" = "xyes")
+
+BUILD_WITH_LIBDBI_CPPFLAGS="$with_libdbi_cppflags"
+BUILD_WITH_LIBDBI_LDFLAGS="$with_libdbi_ldflags"
+BUILD_WITH_LIBDBI_LIBS="-ldbi"
+AC_SUBST(BUILD_WITH_LIBDBI_CPPFLAGS)
+AC_SUBST(BUILD_WITH_LIBDBI_LDFLAGS)
+AC_SUBST(BUILD_WITH_LIBDBI_LIBS)
 # }}}
 
 # --with-libesmtp {{{
-AC_ARG_WITH(libesmtp, [AS_HELP_STRING([--with-libesmtp@<:@=PREFIX@:>@], [Path to libesmtp.])],
-[
-       if test "x$withval" != "xno" && test "x$withval" != "xyes"
-       then
-               LDFLAGS="$LDFLAGS -L$withval/lib"
-               CPPFLAGS="$CPPFLAGS -I$withval/include -D_THREAD_SAFE"
-               with_libesmtp="yes"
-       else
-               with_libesmtp="$withval"
-       fi
-],
-[
-       with_libesmtp="yes"
-])
-if test "x$with_libesmtp" = "xyes"
-then
-       AC_CHECK_LIB(esmtp, smtp_create_session,
-       [
-               AC_DEFINE(HAVE_LIBESMTP, 1, [Define to 1 if you have the esmtp library (-lesmtp).])
-       ], [with_libesmtp="no (libesmtp not found)"])
-fi
-if test "x$with_libesmtp" = "xyes"
-then
-       AC_CHECK_HEADERS(libesmtp.h,
-       [
-               AC_DEFINE(HAVE_LIBESMTP_H, 1, [Define to 1 if you have the <libesmtp.h> header file.])
-       ], [with_libesmtp="no (libesmtp.h not found)"])
-fi
-if test "x$with_libesmtp" = "xyes"
-then
-       collect_libesmtp=1
-else
-       collect_libesmtp=0
-fi
-AC_DEFINE_UNQUOTED(COLLECT_LIBESMTP, [$collect_libesmtp],
-       [Wether or not to use the esmtp library])
-AM_CONDITIONAL(BUILD_WITH_LIBESMTP, test "x$with_libesmtp" = "xyes")
-# }}}
+AC_ARG_WITH([libesmtp],
+  [AS_HELP_STRING([--with-libesmtp@<:@=PREFIX@:>@], [Path to libesmtp.])],
+  [
+    if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
+      with_libesmtp_cppflags="-I$withval/include"
+      with_libesmtp_ldflags="-L$withval/lib"
+      with_libesmtp="yes"
+    else
+      with_libesmtp="$withval"
+    fi
+  ],
+  [with_libesmtp="yes"]
+)
 
-# --with-libganglia {{{
-AC_ARG_WITH(libganglia, [AS_HELP_STRING([--with-libganglia@<:@=PREFIX@:>@], [Path to libganglia.])],
-[
- if test -f "$withval" && test -x "$withval"
- then
-        with_libganglia_config="$withval"
-        with_libganglia="yes"
- else if test -f "$withval/bin/ganglia-config" && test -x "$withval/bin/ganglia-config"
- then
-        with_libganglia_config="$withval/bin/ganglia-config"
-        with_libganglia="yes"
- else if test -d "$withval"
- then
-        GANGLIA_CPPFLAGS="-I$withval/include"
-        GANGLIA_LDFLAGS="-L$withval/lib"
-        with_libganglia="yes"
- else
-        with_libganglia="$withval"
- fi; fi; fi
-],
-[
- with_libganglia="yes"
-])
+if test "x$with_libesmtp" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_libesmtp_cppflags"
 
-if test "x$with_libganglia" = "xyes"
-then
-       if test "x$with_libganglia_config" != "x"
-       then
-               if test "x$GANGLIA_CPPFLAGS" = "x"
-               then
-                       GANGLIA_CPPFLAGS=`"$with_libganglia_config" --cflags 2>/dev/null`
-               fi
-
-               if test "x$GANGLIA_LDFLAGS" = "x"
-               then
-                       GANGLIA_LDFLAGS=`"$with_libganglia_config" --ldflags 2>/dev/null`
-               fi
-
-               if test "x$GANGLIA_LIBS" = "x"
-               then
-                       GANGLIA_LIBS=`"$with_libganglia_config" --libs 2>/dev/null`
-               fi
-       else
-               GANGLIA_LIBS="-lganglia"
-       fi
+  AC_CHECK_HEADERS([libesmtp.h],
+    [with_libesmtp="yes"],
+    [with_libesmtp="no (libesmtp.h not found)"]
+  )
+
+  CPPFLAGS="$SAVE_CPPFLAGS"
+fi
+
+if test "x$with_libesmtp" = "xyes"; then
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $with_esmtp_ldflags"
+
+  AC_CHECK_LIB([esmtp], [smtp_create_session],
+    [with_libesmtp="yes"],
+    [with_libesmtp="no (Symbol 'smtp_create_session' not found)"]
+  )
+
+  LDFLAGS="$SAVE_LDFLAGS"
+fi
+
+BUILD_WITH_LIBESMTP_CPPFLAGS="$with_libesmtp_cppflags"
+BUILD_WITH_LIBESMTP_LDFLAGS="$with_libesmtp_ldflags"
+BUILD_WITH_LIBESMTP_LIBS="-lesmtp"
+AC_SUBST(BUILD_WITH_LIBESMTP_CPPFLAGS)
+AC_SUBST(BUILD_WITH_LIBESMTP_LDFLAGS)
+AC_SUBST(BUILD_WITH_LIBESMTP_LIBS)
+# }}}
+
+# --with-libganglia {{{
+AC_ARG_WITH([libganglia],
+  [AS_HELP_STRING([--with-libganglia@<:@=PREFIX@:>@], [Path to libganglia.])],
+  [
+    if test -f "$withval" && test -x "$withval"; then
+      with_libganglia_config="$withval"
+      with_libganglia="yes"
+    else if test -f "$withval/bin/ganglia-config" && test -x "$withval/bin/ganglia-config"; then
+      with_libganglia_config="$withval/bin/ganglia-config"
+      with_libganglia="yes"
+    else if test -d "$withval"; then
+      GANGLIA_CPPFLAGS="-I$withval/include"
+      GANGLIA_LDFLAGS="-L$withval/lib"
+      with_libganglia="yes"
+    else
+      with_libganglia="$withval"
+    fi; fi; fi
+  ],
+  [with_libganglia="yes"]
+)
+
+if test "x$with_libganglia" = "xyes"; then
+  if test "x$with_libganglia_config" != "x"; then
+    if test "x$GANGLIA_CPPFLAGS" = "x"; then
+      GANGLIA_CPPFLAGS=`"$with_libganglia_config" --cflags 2>/dev/null`
+    fi
+
+    if test "x$GANGLIA_LDFLAGS" = "x"; then
+      GANGLIA_LDFLAGS=`"$with_libganglia_config" --ldflags 2>/dev/null`
+    fi
+
+    if test "x$GANGLIA_LIBS" = "x"; then
+      GANGLIA_LIBS=`"$with_libganglia_config" --libs 2>/dev/null`
+    fi
+  else
+    GANGLIA_LIBS="-lganglia"
+  fi
 fi
 
 SAVE_CPPFLAGS="$CPPFLAGS"
@@ -2266,22 +2373,18 @@ SAVE_LDFLAGS="$LDFLAGS"
 CPPFLAGS="$CPPFLAGS $GANGLIA_CPPFLAGS"
 LDFLAGS="$LDFLAGS $GANGLIA_LDFLAGS"
 
-if test "x$with_libganglia" = "xyes"
-then
-       AC_CHECK_HEADERS(gm_protocol.h,
-       [
-               AC_DEFINE(HAVE_GM_PROTOCOL_H, 1,
-                         [Define to 1 if you have the <gm_protocol.h> header file.])
-       ], [with_libganglia="no (gm_protocol.h not found)"])
+if test "x$with_libganglia" = "xyes"; then
+  AC_CHECK_HEADERS([gm_protocol.h],
+    [with_libganglia="yes"],
+    [with_libganglia="no (gm_protocol.h not found)"]
+  )
 fi
 
-if test "x$with_libganglia" = "xyes"
-then
-       AC_CHECK_LIB(ganglia, xdr_Ganglia_value_msg,
-       [
-               AC_DEFINE(HAVE_LIBGANGLIA, 1,
-                         [Define to 1 if you have the ganglia library (-lganglia).])
-       ], [with_libganglia="no (symbol xdr_Ganglia_value_msg not found)"])
+if test "x$with_libganglia" = "xyes"; then
+  AC_CHECK_LIB([ganglia], [xdr_Ganglia_value_msg],
+    [with_libganglia="yes"],
+    [with_libganglia="no (symbol xdr_Ganglia_value_msg not found)"]
+  )
 fi
 
 CPPFLAGS="$SAVE_CPPFLAGS"
@@ -2290,49 +2393,44 @@ LDFLAGS="$SAVE_LDFLAGS"
 AC_SUBST(GANGLIA_CPPFLAGS)
 AC_SUBST(GANGLIA_LDFLAGS)
 AC_SUBST(GANGLIA_LIBS)
-AM_CONDITIONAL(BUILD_WITH_LIBGANGLIA, test "x$with_libganglia" = "xyes")
 # }}}
 
 # --with-libgcrypt {{{
 GCRYPT_CPPFLAGS="$GCRYPT_CPPFLAGS"
 GCRYPT_LDFLAGS="$GCRYPT_LDFLAGS"
 GCRYPT_LIBS="$GCRYPT_LIBS"
-AC_ARG_WITH(libgcrypt, [AS_HELP_STRING([--with-libgcrypt@<:@=PREFIX@:>@], [Path to libgcrypt.])],
-[
- if test -f "$withval" && test -x "$withval"
- then
-        with_libgcrypt_config="$withval"
-        with_libgcrypt="yes"
- else if test -f "$withval/bin/gcrypt-config" && test -x "$withval/bin/gcrypt-config"
- then
-        with_libgcrypt_config="$withval/bin/gcrypt-config"
-        with_libgcrypt="yes"
- else if test -d "$withval"
- then
-        GCRYPT_CPPFLAGS="$GCRYPT_CPPFLAGS -I$withval/include"
-        GCRYPT_LDFLAGS="$GCRYPT_LDFLAGS -L$withval/lib"
-        with_libgcrypt="yes"
- else
-        with_libgcrypt_config="gcrypt-config"
-        with_libgcrypt="$withval"
- fi; fi; fi
-],
-[
- with_libgcrypt_config="libgcrypt-config"
- with_libgcrypt="yes"
-])
+AC_ARG_WITH([libgcrypt],
+  [AS_HELP_STRING([--with-libgcrypt@<:@=PREFIX@:>@], [Path to libgcrypt.])],
+  [
+    if test -f "$withval" && test -x "$withval"; then
+      with_libgcrypt_config="$withval"
+      with_libgcrypt="yes"
+    else if test -f "$withval/bin/gcrypt-config" && test -x "$withval/bin/gcrypt-config"; then
+      with_libgcrypt_config="$withval/bin/gcrypt-config"
+      with_libgcrypt="yes"
+    else if test -d "$withval"; then
+      GCRYPT_CPPFLAGS="$GCRYPT_CPPFLAGS -I$withval/include"
+      GCRYPT_LDFLAGS="$GCRYPT_LDFLAGS -L$withval/lib"
+      with_libgcrypt="yes"
+    else
+      with_libgcrypt_config="gcrypt-config"
+      with_libgcrypt="$withval"
+    fi; fi; fi
+  ],
+  [
+    with_libgcrypt_config="libgcrypt-config"
+    with_libgcrypt="yes"
+  ]
+)
 
-if test "x$with_libgcrypt" = "xyes" && test "x$with_libgcrypt_config" != "x"
-then
-       if test "x$GCRYPT_CPPFLAGS" = "x"
-       then
-               GCRYPT_CPPFLAGS=`"$with_libgcrypt_config" --cflags 2>/dev/null`
-       fi
+if test "x$with_libgcrypt" = "xyes" && test "x$with_libgcrypt_config" != "x"; then
+  if test "x$GCRYPT_CPPFLAGS" = "x"; then
+    GCRYPT_CPPFLAGS=`"$with_libgcrypt_config" --cflags 2>/dev/null`
+  fi
 
-       if test "x$GCRYPT_LIBS" = "x"
-       then
-               GCRYPT_LIBS=`"$with_libgcrypt_config" --libs 2>/dev/null`
-       fi
+  if test "x$GCRYPT_LIBS" = "x"; then
+    GCRYPT_LIBS=`"$with_libgcrypt_config" --libs 2>/dev/null`
+  fi
 fi
 
 SAVE_CPPFLAGS="$CPPFLAGS"
@@ -2342,118 +2440,108 @@ CPPFLAGS="$CPPFLAGS $GCRYPT_CPPFLAGS"
 LDFLAGS="$LDFLAGS $GCRYPT_LDFLAGS"
 LIBS="$LIBS $GCRYPT_LIBS"
 
-if test "x$with_libgcrypt" = "xyes"
-then
-       if test "x$GCRYPT_CPPFLAGS" != "x"
-       then
-               AC_MSG_NOTICE([gcrypt CPPFLAGS: $GCRYPT_CPPFLAGS])
-       fi
-       AC_CHECK_HEADERS(gcrypt.h,
-               [with_libgcrypt="yes"],
-               [with_libgcrypt="no (gcrypt.h not found)"])
+if test "x$with_libgcrypt" = "xyes"; then
+  if test "x$GCRYPT_CPPFLAGS" != "x"; then
+    AC_MSG_NOTICE([gcrypt CPPFLAGS: $GCRYPT_CPPFLAGS])
+  fi
+  AC_CHECK_HEADERS([gcrypt.h],
+    [with_libgcrypt="yes"],
+    [with_libgcrypt="no (gcrypt.h not found)"]
+  )
 fi
 
-if test "x$with_libgcrypt" = "xyes"
-then
-       AC_CHECK_LIB(gcrypt, gcry_md_hash_buffer,
-               [with_libgcrypt="yes"],
-               [with_libgcrypt="no (symbol gcry_md_hash_buffer not found)"])
+if test "x$with_libgcrypt" = "xyes"; then
+  AC_CHECK_LIB(gcrypt, gcry_md_hash_buffer,
+    [with_libgcrypt="yes"],
+    [with_libgcrypt="no (symbol gcry_md_hash_buffer not found)"]
+  )
 fi
 
 CPPFLAGS="$SAVE_CPPFLAGS"
 LDFLAGS="$SAVE_LDFLAGS"
 LIBS="$SAVE_LIBS"
 
-if test "x$with_libgcrypt" = "xyes"
-then
-       AC_DEFINE(HAVE_LIBGCRYPT, 1, [Define to 1 if you have the gcrypt library (-lgcrypt).])
-fi
-
-AC_SUBST(GCRYPT_CPPFLAGS)
-AC_SUBST(GCRYPT_LDFLAGS)
-AC_SUBST(GCRYPT_LIBS)
-AM_CONDITIONAL(BUILD_WITH_LIBGCRYPT, test "x$with_libgcrypt" = "xyes")
+AC_SUBST([GCRYPT_CPPFLAGS])
+AC_SUBST([GCRYPT_LDFLAGS])
+AC_SUBST([GCRYPT_LIBS])
+AM_CONDITIONAL([BUILD_WITH_LIBGCRYPT], [test "x$with_libgcrypt" = "xyes"])
 # }}}
 
 # --with-libgps {{{
-with_libgps_cflags=""
-with_libgps_ldflags=""
-AC_ARG_WITH(libgps, [AS_HELP_STRING([--with-libgps@<:@=PREFIX@:>@], [Path to libgps.])],
-[
-       if test "x$withval" != "xno" && test "x$withval" != "xyes"
-       then
-               with_libgps_cflags="-I$withval/include"
-               with_libgps_ldflags="-L$withval/lib"
-               with_libgps="yes"
-       else
-               with_libgps="$withval"
-       fi
-],
-[
-       with_libgps="yes"
-])
-if test "x$with_libgps" = "xyes"
-then
-       SAVE_CFLAGS="$CFLAGS"
-       CFLAGS="$CFLAGS $with_libgps_cflags"
+AC_ARG_WITH([libgps],
+  [AS_HELP_STRING([--with-libgps@<:@=PREFIX@:>@], [Path to libgps.])],
+  [
+    if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
+      with_libgps_cflags="-I$withval/include"
+      with_libgps_ldflags="-L$withval/lib"
+      with_libgps="yes"
+    else
+      with_libgps="$withval"
+    fi
+  ],
+  [with_libgps="yes"]
+)
+
+if test "x$with_libgps" = "xyes"; then
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS $with_libgps_cflags"
 
-       AC_CHECK_HEADERS(gps.h, [with_libgps="yes"], [with_libgps="no (gps.h not found)"])
+  AC_CHECK_HEADERS([gps.h],
+    [with_libgps="yes"],
+    [with_libgps="no (gps.h not found)"]
+  )
 
-       CFLAGS="$SAVE_CFLAGS"
+  CFLAGS="$SAVE_CFLAGS"
 fi
-if test "x$with_libgps" = "xyes"
-then
-       SAVE_CFLAGS="$CFLAGS"
-       SAVE_LDFLAGS="$LDFLAGS"
-       CFLAGS="$CFLAGS $with_libgps_cflags"
-       LDFLAGS="$LDFLAGS $with_libgps_ldflags"
 
-       AC_CHECK_LIB(gps, gps_open, [with_libgps="yes"], [with_libgps="no (symbol gps_open not found)"])
+if test "x$with_libgps" = "xyes"; then
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $with_libgps_ldflags"
 
-       CFLAGS="$SAVE_CFLAGS"
-       LDFLAGS="$SAVE_LDFLAGS"
+  AC_CHECK_LIB([gps], [gps_open],
+    [with_libgps="yes"],
+    [with_libgps="no (symbol gps_open not found)"]
+  )
+
+  LDFLAGS="$SAVE_LDFLAGS"
 fi
-if test "x$with_libgps" = "xyes"
-then
-       BUILD_WITH_LIBGPS_CFLAGS="$with_libgps_cflags"
-       BUILD_WITH_LIBGPS_LDFLAGS="$with_libgps_ldflags"
-       BUILD_WITH_LIBGPS_LIBS="-lgps"
-       AC_SUBST(BUILD_WITH_LIBGPS_CFLAGS)
-       AC_SUBST(BUILD_WITH_LIBGPS_LDFLAGS)
-       AC_SUBST(BUILD_WITH_LIBGPS_LIBS)
-fi
-AM_CONDITIONAL(BUILD_WITH_LIBGPS, test "x$with_libgps" = "xyes")
+
+if test "x$with_libgps" = "xyes"; then
+  BUILD_WITH_LIBGPS_CFLAGS="$with_libgps_cflags"
+  BUILD_WITH_LIBGPS_LDFLAGS="$with_libgps_ldflags"
+  BUILD_WITH_LIBGPS_LIBS="-lgps"
+fi
+
+AC_SUBST([BUILD_WITH_LIBGPS_CFLAGS])
+AC_SUBST([BUILD_WITH_LIBGPS_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBGPS_LIBS])
+
 # }}}
 
 # --with-libgrpc++ {{{
-with_libgrpcpp_cppflags=""
-with_libgrpcpp_ldflags=""
-AC_ARG_WITH([libgrpc++], [AS_HELP_STRING([--with-libgrpc++@<:@=PREFIX@:>@], [Path to libgrpc++.])],
+AC_ARG_WITH([libgrpc++],
+  [AS_HELP_STRING([--with-libgrpc++@<:@=PREFIX@:>@], [Path to libgrpc++.])],
   [
     with_grpcpp="$withval"
-    if test "x$withval" != "xno" && test "x$withval" != "xyes"
-    then
+    if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
       with_libgrpcpp_cppflags="-I$withval/include"
       with_libgrpcpp_ldflags="-L$withval/lib"
       with_libgrpcpp="yes"
     fi
-    if test "x$withval" = "xno"
-    then
+    if test "x$withval" = "xno"; then
       with_libgrpcpp="no (disabled on command line)"
     fi
   ],
   [withval="yes"]
 )
-if test "x$withval" = "xyes"
-then
+if test "x$withval" = "xyes"; then
 PKG_CHECK_MODULES([GRPCPP], [grpc++],
   [with_libgrpcpp="yes"],
   [with_libgrpcpp="no (pkg-config could not find libgrpc++)"]
 )
 fi
 
-if test "x$withval" != "xno"
-then
+if test "x$withval" != "xno"; then
   AC_MSG_CHECKING([whether $CXX accepts -std=c++11])
   if test_cxx_flags -std=c++11; then
     AC_MSG_RESULT([yes])
@@ -2463,40 +2551,40 @@ then
   fi
 fi
 
-if test "x$with_libgrpcpp" = "xyes"
-then
+if test "x$with_libgrpcpp" = "xyes"; then
   AC_LANG_PUSH(C++)
   SAVE_CPPFLAGS="$CPPFLAGS"
   CPPFLAGS="-std=c++11 $with_libgrpcpp_cppflags $GRPCPP_CFLAGS $CPPFLAGS"
-  AC_CHECK_HEADERS([grpc++/grpc++.h], [],
+  AC_CHECK_HEADERS([grpc++/grpc++.h],
+    [with_libgrpcpp="yes"],
     [with_libgrpcpp="no (<grpc++/grpc++.h> not found)"]
   )
   CPPFLAGS="$SAVE_CPPFLAGS"
   AC_LANG_POP(C++)
 fi
-if test "x$with_libgrpcpp" = "xyes"
-then
+
+if test "x$with_libgrpcpp" = "xyes"; then
   AC_LANG_PUSH(C++)
   SAVE_CPPFLAGS="$CPPFLAGS"
   SAVE_LDFLAGS="$LDFLAGS"
   SAVE_LIBS="$LIBS"
   CPPFLAGS="-std=c++11 $with_libgrpcpp_cppflags $GRPCPP_CFLAGS $CPPFLAGS"
   LDFLAGS="$with_libgrpcpp_ldflags"
-  if test "x$GRPCPP_LIBS" = "x"
-  then
+  if test "x$GRPCPP_LIBS" = "x"; then
     LIBS="-lgrpc++"
   else
     LIBS="$GRPCPP_LIBS"
   fi
   AC_LINK_IFELSE(
-    [AC_LANG_PROGRAM(
-      [[#include <grpc++/grpc++.h>]],
-      [[grpc::ServerBuilder sb;]]
-    )],
+    [
+      AC_LANG_PROGRAM(
+        [[#include <grpc++/grpc++.h>]],
+        [[grpc::ServerBuilder sb;]]
+      )
+    ],
     [
       with_libgrpcpp="yes"
-      if test "x$GRPCPP_LIBS" = "x"
-      then
+      if test "x$GRPCPP_LIBS" = "x"; then
         GRPCPP_LIBS="-lgrpc++"
       fi
     ],
@@ -2507,6 +2595,7 @@ then
   LIBS="$SAVE_LIBS"
   AC_LANG_POP(C++)
 fi
+
 BUILD_WITH_LIBGRPCPP_CPPFLAGS="-std=c++11 $with_libgrpcpp_cppflags $GRPCPP_CFLAGS"
 BUILD_WITH_LIBGRPCPP_LDFLAGS="$with_libgrpcpp_ldflags"
 BUILD_WITH_LIBGRPCPP_LIBS="$GRPCPP_LIBS"
@@ -2515,94 +2604,94 @@ AC_SUBST([BUILD_WITH_LIBGRPCPP_LDFLAGS])
 AC_SUBST([BUILD_WITH_LIBGRPCPP_LIBS])
 # }}}
 
+AC_ARG_VAR([GRPC_CPP_PLUGIN], [path to the grpc_cpp_plugin binary])
+AC_PATH_PROG([GRPC_CPP_PLUGIN], [grpc_cpp_plugin])
+AM_CONDITIONAL([HAVE_GRPC_CPP], [test "x$GRPC_CPP_PLUGIN" != "x"])
+
 # --with-libiptc {{{
-AC_ARG_WITH(libiptc, [AS_HELP_STRING([--with-libiptc@<:@=PREFIX@:>@], [Path to libiptc.])],
-[
-       if test "x$withval" = "xyes"
-       then
-               with_libiptc="pkgconfig"
-       else if test "x$withval" = "xno"
-       then
-               with_libiptc="no"
-       else
-               with_libiptc="yes"
-               with_libiptc_cflags="-I$withval/include"
-               with_libiptc_libs="-L$withval/lib"
-       fi; fi
-],
-[
-       if test "x$ac_system" = "xLinux"
-       then
-               with_libiptc="pkgconfig"
-       else
-               with_libiptc="no (Linux only)"
-       fi
-])
+AC_ARG_WITH([libiptc],
+  [AS_HELP_STRING([--with-libiptc@<:@=PREFIX@:>@], [Path to libiptc.])],
+  [
+    if test "x$withval" = "xyes"; then
+      with_libiptc="pkgconfig"
+    else if test "x$withval" = "xno"; then
+      with_libiptc="no"
+    else
+      with_libiptc="yes"
+      with_libiptc_cflags="-I$withval/include"
+      with_libiptc_libs="-L$withval/lib"
+    fi; fi
+  ],
+  [
+    if test "x$ac_system" = "xLinux"; then
+      with_libiptc="pkgconfig"
+    else
+      with_libiptc="no (Linux only)"
+    fi
+  ]
+)
 
-if test "x$with_libiptc" = "xpkgconfig"
-then
-       $PKG_CONFIG --exists 'libiptc' 2>/dev/null
-       if test $? -ne 0
-       then
-               with_libiptc="no (pkg-config doesn't know libiptc)"
-       fi
+if test "x$with_libiptc" = "xpkgconfig"; then
+  $PKG_CONFIG --exists 'libiptc' 2>/dev/null
+  if test $? -ne 0; then
+    with_libiptc="no (pkg-config doesn't know libiptc)"
+  fi
 fi
-if test "x$with_libiptc" = "xpkgconfig"
-then
-       with_libiptc_cflags="`$PKG_CONFIG --cflags 'libiptc'`"
-       if test $? -ne 0
-       then
-               with_libiptc="no ($PKG_CONFIG failed)"
-       fi
-       with_libiptc_libs="`$PKG_CONFIG --libs 'libiptc'`"
-       if test $? -ne 0
-       then
-               with_libiptc="no ($PKG_CONFIG failed)"
-       fi
+
+if test "x$with_libiptc" = "xpkgconfig"; then
+  with_libiptc_cflags="`$PKG_CONFIG --cflags 'libiptc'`"
+  if test $? -ne 0; then
+    with_libiptc="no ($PKG_CONFIG failed)"
+  fi
+
+  with_libiptc_libs="`$PKG_CONFIG --libs 'libiptc'`"
+  if test $? -ne 0; then
+    with_libiptc="no ($PKG_CONFIG failed)"
+  fi
 fi
 
 SAVE_CPPFLAGS="$CPPFLAGS"
 CPPFLAGS="$CPPFLAGS $with_libiptc_cflags"
 
 # check whether the header file for libiptc is available.
-if test "x$with_libiptc" = "xpkgconfig"
-then
-       AC_CHECK_HEADERS(libiptc/libiptc.h libiptc/libip6tc.h, ,
-                       [with_libiptc="no (header file missing)"])
+if test "x$with_libiptc" = "xpkgconfig"; then
+  AC_CHECK_HEADERS([libiptc/libiptc.h libiptc/libip6tc.h],
+    [],
+    [with_libiptc="no (header file missing)"]
+  )
 fi
+
 # If the header file is available, check for the required type declaractions.
 # They may be missing in old versions of libiptc. In that case, they will be
 # declared in the iptables plugin.
-if test "x$with_libiptc" = "xpkgconfig"
-then
-       AC_CHECK_TYPES([iptc_handle_t, ip6tc_handle_t], [], [])
+if test "x$with_libiptc" = "xpkgconfig"; then
+  AC_CHECK_TYPES([iptc_handle_t, ip6tc_handle_t], [], [])
 fi
+
 # Check for the iptc_init symbol in the library.
 # 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
-       with_libiptc="yes"
+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
+  with_libiptc="yes"
 fi
 
 CPPFLAGS="$SAVE_CPPFLAGS"
 
-AM_CONDITIONAL(BUILD_WITH_LIBIPTC, test "x$with_libiptc" = "xyes")
-if test "x$with_libiptc" = "xyes"
-then
-       BUILD_WITH_LIBIPTC_CPPFLAGS="$with_libiptc_cflags"
-       BUILD_WITH_LIBIPTC_LDFLAGS="$with_libiptc_libs"
-       AC_SUBST(BUILD_WITH_LIBIPTC_CPPFLAGS)
-       AC_SUBST(BUILD_WITH_LIBIPTC_LDFLAGS)
+if test "x$with_libiptc" = "xyes"; then
+  BUILD_WITH_LIBIPTC_CPPFLAGS="$with_libiptc_cflags"
+  BUILD_WITH_LIBIPTC_LDFLAGS="$with_libiptc_libs"
 fi
+AC_SUBST([BUILD_WITH_LIBIPTC_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBIPTC_LDFLAGS])
 # }}}
 
 # --with-libdpdk {{{
@@ -2611,171 +2700,170 @@ AC_ARG_VAR([LIBDPDK_LDFLAGS], [Linker flags for libdpdk])
 
 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
 
 # }}}
 
 # --with-java {{{
 with_java_home="$JAVA_HOME"
-if test "x$with_java_home" = "x"
-then
-       with_java_home="/usr/lib/jvm"
+if test "x$with_java_home" = "x"; then
+  with_java_home="/usr/lib/jvm"
 fi
+
 JAVAC="$JAVAC"
 JAR="$JAR"
-AC_ARG_WITH(java, [AS_HELP_STRING([--with-java@<:@=PREFIX@:>@], [Path to Java home.])],
-[
-       if test "x$withval" = "xno"
-       then
-               with_java="no"
-       else if test "x$withval" = "xyes"
-       then
-               with_java="yes"
-       else
-               with_java_home="$withval"
-               with_java="yes"
-       fi; fi
-],
-[with_java="yes"])
-if test "x$with_java" = "xyes"
-then
-       if test -d "$with_java_home"
-       then
-               AC_MSG_CHECKING([for jni.h])
-               TMPVAR=`find -L "$with_java_home" -name jni.h -type f -exec 'dirname' '{}' ';' 2>/dev/null | LC_ALL=C sort | head -n 1`
-               if test "x$TMPVAR" != "x"
-               then
-                       AC_MSG_RESULT([found in $TMPVAR])
-                       JAVA_CPPFLAGS="$JAVA_CPPFLAGS -I$TMPVAR"
-               else
-                       AC_MSG_RESULT([not found])
-               fi
-
-               AC_MSG_CHECKING([for jni_md.h])
-               TMPVAR=`find -L "$with_java_home" -name jni_md.h -type f -exec 'dirname' '{}' ';' 2>/dev/null | LC_ALL=C sort | head -n 1`
-               if test "x$TMPVAR" != "x"
-               then
-                       AC_MSG_RESULT([found in $TMPVAR])
-                       JAVA_CPPFLAGS="$JAVA_CPPFLAGS -I$TMPVAR"
-               else
-                       AC_MSG_RESULT([not found])
-               fi
-
-               AC_MSG_CHECKING([for libjvm.so])
-               TMPVAR=`find -L "$with_java_home" -type f \( -name libjvm.so -o -name libjvm.dylib \) -exec 'dirname' '{}' ';' 2>/dev/null | LC_ALL=C sort | head -n 1`
-               if test "x$TMPVAR" != "x"
-               then
-                       AC_MSG_RESULT([found in $TMPVAR])
-                       JAVA_LDFLAGS="$JAVA_LDFLAGS -L$TMPVAR -Wl,-rpath -Wl,$TMPVAR"
-               else
-                       AC_MSG_RESULT([not found])
-               fi
-
-               if test "x$JAVAC" = "x"
-               then
-                       AC_MSG_CHECKING([for javac])
-                       TMPVAR=`find -L "$with_java_home" -name javac -type f 2>/dev/null | LC_ALL=C sort | head -n 1`
-                       if test "x$TMPVAR" != "x"
-                       then
-                               JAVAC="$TMPVAR"
-                               AC_MSG_RESULT([$JAVAC])
-                       else
-                               AC_MSG_RESULT([not found])
-                       fi
-               fi
-               if test "x$JAR" = "x"
-               then
-                       AC_MSG_CHECKING([for jar])
-                       TMPVAR=`find -L "$with_java_home" -name jar -type f 2>/dev/null | LC_ALL=C sort | head -n 1`
-                       if test "x$TMPVAR" != "x"
-                       then
-                               JAR="$TMPVAR"
-                               AC_MSG_RESULT([$JAR])
-                       else
-                               AC_MSG_RESULT([not found])
-                       fi
-               fi
-       else if test "x$with_java_home" != "x"
-       then
-               AC_MSG_WARN([JAVA_HOME: No such directory: $with_java_home])
-       fi; fi
+AC_ARG_WITH([java],
+  [AS_HELP_STRING([--with-java@<:@=PREFIX@:>@], [Path to Java home.])],
+  [
+    if test "x$withval" = "xno"; then
+      with_java="no"
+    else if test "x$withval" = "xyes"; then
+      with_java="yes"
+    else
+      with_java_home="$withval"
+      with_java="yes"
+    fi; fi
+  ],
+  [with_java="yes"]
+)
+
+if test "x$with_java" = "xyes"; then
+  if test -d "$with_java_home"; then
+    AC_MSG_CHECKING([for jni.h])
+    TMPVAR=`find -L "$with_java_home" -name jni.h -type f -exec 'dirname' '{}' ';' 2>/dev/null | LC_ALL=C sort | head -n 1`
+    if test "x$TMPVAR" != "x"; then
+      AC_MSG_RESULT([found in $TMPVAR])
+      JAVA_CPPFLAGS="$JAVA_CPPFLAGS -I$TMPVAR"
+    else
+      AC_MSG_RESULT([not found])
+    fi
+
+    AC_MSG_CHECKING([for jni_md.h])
+    TMPVAR=`find -L "$with_java_home" -name jni_md.h -type f -exec 'dirname' '{}' ';' 2>/dev/null | LC_ALL=C sort | head -n 1`
+    if test "x$TMPVAR" != "x"; then
+      AC_MSG_RESULT([found in $TMPVAR])
+      JAVA_CPPFLAGS="$JAVA_CPPFLAGS -I$TMPVAR"
+    else
+      AC_MSG_RESULT([not found])
+    fi
+
+    AC_MSG_CHECKING([for libjvm.so])
+    TMPVAR=`find -L "$with_java_home" -type f \( -name libjvm.so -o -name libjvm.dylib \) -exec 'dirname' '{}' ';' 2>/dev/null | LC_ALL=C sort | head -n 1`
+    if test "x$TMPVAR" != "x"; then
+      AC_MSG_RESULT([found in $TMPVAR])
+      JAVA_LDFLAGS="$JAVA_LDFLAGS -L$TMPVAR -Wl,-rpath -Wl,$TMPVAR"
+    else
+      AC_MSG_RESULT([not found])
+    fi
+
+    if test "x$JAVAC" = "x"; then
+      AC_MSG_CHECKING([for javac])
+      TMPVAR=`find -L "$with_java_home" -name javac -type f 2>/dev/null | LC_ALL=C sort | head -n 1`
+      if test "x$TMPVAR" != "x"; then
+        JAVAC="$TMPVAR"
+        AC_MSG_RESULT([$JAVAC])
+      else
+        AC_MSG_RESULT([not found])
+      fi
+    fi
+
+    if test "x$JAR" = "x"; then
+      AC_MSG_CHECKING([for jar])
+      TMPVAR=`find -L "$with_java_home" -name jar -type f 2>/dev/null | LC_ALL=C sort | head -n 1`
+      if test "x$TMPVAR" != "x"; then
+        JAR="$TMPVAR"
+        AC_MSG_RESULT([$JAR])
+      else
+        AC_MSG_RESULT([not found])
+      fi
+    fi
+  else if test "x$with_java_home" != "x"; then
+    AC_MSG_WARN([JAVA_HOME: No such directory: $with_java_home])
+  fi; fi
 fi
 
-if test "x$JAVA_CPPFLAGS" != "x"
-then
-       AC_MSG_NOTICE([Building with JAVA_CPPFLAGS set to: $JAVA_CPPFLAGS])
+if test "x$JAVA_CPPFLAGS" != "x"; then
+  AC_MSG_NOTICE([Building with JAVA_CPPFLAGS set to: $JAVA_CPPFLAGS])
 fi
-if test "x$JAVA_CFLAGS" != "x"
-then
-       AC_MSG_NOTICE([Building with JAVA_CFLAGS set to: $JAVA_CFLAGS])
+if test "x$JAVA_CFLAGS" != "x"; then
+  AC_MSG_NOTICE([Building with JAVA_CFLAGS set to: $JAVA_CFLAGS])
 fi
-if test "x$JAVA_LDFLAGS" != "x"
-then
-       AC_MSG_NOTICE([Building with JAVA_LDFLAGS set to: $JAVA_LDFLAGS])
+if test "x$JAVA_LDFLAGS" != "x"; then
+  AC_MSG_NOTICE([Building with JAVA_LDFLAGS set to: $JAVA_LDFLAGS])
 fi
-if test "x$JAVA_LIBS" != "x"
-then
-       AC_MSG_NOTICE([Building with JAVA_LIBS set to: $JAVA_LIBS])
+if test "x$JAVA_LIBS" != "x"; then
+  AC_MSG_NOTICE([Building with JAVA_LIBS set to: $JAVA_LIBS])
 fi
-if test "x$JAVAC" = "x"
-then
-       with_javac_path="$PATH"
-       if test "x$with_java_home" != "x"
-       then
-               with_javac_path="$with_java_home:with_javac_path"
-               if test -d "$with_java_home/bin"
-               then
-                       with_javac_path="$with_java_home/bin:with_javac_path"
-               fi
-       fi
+if test "x$JAVAC" = "x"; then
+  with_javac_path="$PATH"
+  if test "x$with_java_home" != "x"; then
+    with_javac_path="$with_java_home:with_javac_path"
+    if test -d "$with_java_home/bin"; then
+      with_javac_path="$with_java_home/bin:with_javac_path"
+    fi
+  fi
 
-       AC_PATH_PROG(JAVAC, javac, [], "$with_javac_path")
+  AC_PATH_PROG([JAVAC], [javac], [], "$with_javac_path")
 fi
-if test "x$JAVAC" = "x"
-then
-       with_java="no (javac not found)"
+
+if test "x$JAVAC" = "x"; then
+  with_java="no (javac not found)"
 fi
-if test "x$JAR" = "x"
-then
-       with_jar_path="$PATH"
-       if test "x$with_java_home" != "x"
-       then
-               with_jar_path="$with_java_home:$with_jar_path"
-               if test -d "$with_java_home/bin"
-               then
-                       with_jar_path="$with_java_home/bin:$with_jar_path"
-               fi
-       fi
 
-       AC_PATH_PROG(JAR, jar, [], "$with_jar_path")
+if test "x$JAR" = "x"; then
+  with_jar_path="$PATH"
+  if test "x$with_java_home" != "x"; then
+    with_jar_path="$with_java_home:$with_jar_path"
+    if test -d "$with_java_home/bin"; then
+      with_jar_path="$with_java_home/bin:$with_jar_path"
+    fi
+  fi
+
+  AC_PATH_PROG([JAR], [jar], [], "$with_jar_path")
 fi
-if test "x$JAR" = "x"
-then
-       with_java="no (jar not found)"
+
+if test "x$JAR" = "x"; then
+  with_java="no (jar not found)"
 fi
 
 SAVE_CPPFLAGS="$CPPFLAGS"
@@ -2787,21 +2875,23 @@ CFLAGS="$CFLAGS $JAVA_CFLAGS"
 LDFLAGS="$LDFLAGS $JAVA_LDFLAGS"
 LIBS="$LIBS $JAVA_LIBS"
 
-if test "x$with_java" = "xyes"
-then
-       AC_CHECK_HEADERS(jni.h, [], [with_java="no (jni.h not found)"])
+if test "x$with_java" = "xyes"; then
+  AC_CHECK_HEADERS([jni.h],
+    [with_jave="yes"],
+    [with_java="no (jni.h not found)"])
 fi
-if test "x$with_java" = "xyes"
-then
-       AC_CHECK_LIB(jvm, JNI_CreateJavaVM,
-       [with_java="yes"],
-       [with_java="no (Symbol 'JNI_CreateJavaVM' not found)"],
-       [$JAVA_LIBS $PTHREAD_LIBS])
+
+if test "x$with_java" = "xyes"; then
+  AC_CHECK_LIB([jvm], [JNI_CreateJavaVM],
+    [with_java="yes"],
+    [with_java="no (Symbol 'JNI_CreateJavaVM' not found)"],
+    [$JAVA_LIBS $PTHREAD_LIBS]
+  )
 fi
-if test "x$with_java" = "xyes"
-then
-       JAVA_LIBS="$JAVA_LIBS -ljvm"
-       AC_MSG_NOTICE([Building with JAVA_LIBS set to: $JAVA_LIBS])
+
+if test "x$with_java" = "xyes"; then
+  JAVA_LIBS="$JAVA_LIBS -ljvm"
+  AC_MSG_NOTICE([Building with JAVA_LIBS set to: $JAVA_LIBS])
 fi
 
 CPPFLAGS="$SAVE_CPPFLAGS"
@@ -2809,29 +2899,29 @@ CFLAGS="$SAVE_CFLAGS"
 LDFLAGS="$SAVE_LDFLAGS"
 LIBS="$SAVE_LIBS"
 
-AC_SUBST(JAVA_CPPFLAGS)
-AC_SUBST(JAVA_CFLAGS)
-AC_SUBST(JAVA_LDFLAGS)
-AC_SUBST(JAVA_LIBS)
-AM_CONDITIONAL(BUILD_WITH_JAVA, test "x$with_java" = "xyes")
+AC_SUBST([JAVA_CPPFLAGS])
+AC_SUBST([JAVA_CFLAGS])
+AC_SUBST([JAVA_LDFLAGS])
+AC_SUBST([JAVA_LIBS])
+AM_CONDITIONAL([BUILD_WITH_JAVA], [test "x$with_java" = "xyes"])
 # }}}
 
 # --with-libldap {{{
-AC_ARG_WITH(libldap, [AS_HELP_STRING([--with-libldap@<:@=PREFIX@:>@], [Path to libldap.])],
-[
- if test "x$withval" = "xyes"
- then
-        with_libldap="yes"
- else if test "x$withval" = "xno"
- then
-        with_libldap="no"
- else
-        with_libldap="yes"
-        LIBLDAP_CPPFLAGS="$LIBLDAP_CPPFLAGS -I$withval/include"
-        LIBLDAP_LDFLAGS="$LIBLDAP_LDFLAGS -L$withval/lib"
- fi; fi
-],
-[with_libldap="yes"])
+AC_ARG_WITH([libldap],
+  [AS_HELP_STRING([--with-libldap@<:@=PREFIX@:>@], [Path to libldap.])],
+  [
   if test "x$withval" = "xyes"; then
+      with_libldap="yes"
+    else if test "x$withval" = "xno"; then
+      with_libldap="no"
+    else
+      with_libldap="yes"
+      LIBLDAP_CPPFLAGS="$LIBLDAP_CPPFLAGS -I$withval/include"
+      LIBLDAP_LDFLAGS="$LIBLDAP_LDFLAGS -L$withval/lib"
+    fi; fi
+  ],
+  [with_libldap="yes"]
+)
 
 SAVE_CPPFLAGS="$CPPFLAGS"
 SAVE_LDFLAGS="$LDFLAGS"
@@ -2839,26 +2929,26 @@ SAVE_LDFLAGS="$LDFLAGS"
 CPPFLAGS="$CPPFLAGS $LIBLDAP_CPPFLAGS"
 LDFLAGS="$LDFLAGS $LIBLDAP_LDFLAGS"
 
-if test "x$with_libldap" = "xyes"
-then
-       if test "x$LIBLDAP_CPPFLAGS" != "x"
-       then
-               AC_MSG_NOTICE([libldap CPPFLAGS: $LIBLDAP_CPPFLAGS])
-       fi
-       AC_CHECK_HEADERS(ldap.h,
-       [with_libldap="yes"],
-       [with_libldap="no ('ldap.h' not found)"])
+if test "x$with_libldap" = "xyes"; then
+  if test "x$LIBLDAP_CPPFLAGS" != "x"; then
+    AC_MSG_NOTICE([libldap CPPFLAGS: $LIBLDAP_CPPFLAGS])
+  fi
+
+  AC_CHECK_HEADERS([ldap.h],
+    [with_libldap="yes"],
+    [with_libldap="no ('ldap.h' not found)"]
+  )
 fi
-if test "x$with_libldap" = "xyes"
-then
-       if test "x$LIBLDAP_LDFLAGS" != "x"
-       then
-               AC_MSG_NOTICE([libldap LDFLAGS: $LIBLDAP_LDFLAGS])
-       fi
-       AC_CHECK_LIB(ldap, ldap_initialize,
-       [with_libldap="yes"],
-       [with_libldap="no (symbol 'ldap_initialize' not found)"])
 
+if test "x$with_libldap" = "xyes"; then
+  if test "x$LIBLDAP_LDFLAGS" != "x"; then
+    AC_MSG_NOTICE([libldap LDFLAGS: $LIBLDAP_LDFLAGS])
+  fi
+
+  AC_CHECK_LIB([ldap], [ldap_initialize],
+    [with_libldap="yes"],
+    [with_libldap="no (symbol 'ldap_initialize' not found)"]
+  )
 fi
 
 CPPFLAGS="$SAVE_CPPFLAGS"
@@ -2866,12 +2956,11 @@ LDFLAGS="$SAVE_LDFLAGS"
 
 if test "x$with_libldap" = "xyes"
 then
-       BUILD_WITH_LIBLDAP_CPPFLAGS="$LIBLDAP_CPPFLAGS"
-       BUILD_WITH_LIBLDAP_LDFLAGS="$LIBLDAP_LDFLAGS"
-       AC_SUBST(BUILD_WITH_LIBLDAP_CPPFLAGS)
-       AC_SUBST(BUILD_WITH_LIBLDAP_LDFLAGS)
+  BUILD_WITH_LIBLDAP_CPPFLAGS="$LIBLDAP_CPPFLAGS"
+  BUILD_WITH_LIBLDAP_LDFLAGS="$LIBLDAP_LDFLAGS"
 fi
-AM_CONDITIONAL(BUILD_WITH_LIBLDAP, test "x$with_libldap" = "xyes")
+AC_SUBST([BUILD_WITH_LIBLDAP_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBLDAP_LDFLAGS])
 # }}}
 
 # --with-liblua {{{
@@ -2889,7 +2978,7 @@ else
       PKG_CHECK_MODULES([LUA], [lua-5.3],
         [with_liblua="yes"],
         [
-         PKG_CHECK_MODULES([LUA], [lua5.3],
+          PKG_CHECK_MODULES([LUA], [lua5.3],
             [with_liblua="yes"],
             [
               PKG_CHECK_MODULES([LUA], [lua-5.2],
@@ -2955,114 +3044,117 @@ AC_SUBST(BUILD_WITH_LIBLUA_LIBS)
 # }}}
 
 # --with-liblvm2app {{{
-with_liblvm2app_cppflags=""
-with_liblvm2app_ldflags=""
-AC_ARG_WITH(liblvm2app, [AS_HELP_STRING([--with-liblvm2app@<:@=PREFIX@:>@], [Path to liblvm2app.])],
-[
-       if test "x$withval" = "xno"
-       then
-               with_liblvm2app="no"
-       else
-               with_liblvm2app="yes"
-               if test "x$withval" != "xyes"
-               then
-                       with_liblvm2app_cppflags="-I$withval/include"
-                       with_liblvm2app_ldflags="-L$withval/lib"
-               fi
-        fi
-],
-[
-       if test "x$ac_system" = "xLinux"
-       then
-               with_liblvm2app="yes"
-       else
-               with_liblvm2app="no (Linux only library)"
-       fi
-])
-if test "x$with_liblvm2app" = "xyes"
-then
-        SAVE_CPPFLAGS="$CPPFLAGS"
-        CPPFLAGS="$CPPFLAGS $with_liblvm2app_cppflags"
+AC_ARG_WITH([liblvm2app],
+  [AS_HELP_STRING([--with-liblvm2app@<:@=PREFIX@:>@], [Path to liblvm2app.])],
+  [
+    if test "x$withval" = "xno"; then
+      with_liblvm2app="no"
+    else
+      with_liblvm2app="yes"
+      if test "x$withval" != "xyes"; then
+        with_liblvm2app_cppflags="-I$withval/include"
+        with_liblvm2app_ldflags="-L$withval/lib"
+      fi
+    fi
+  ],
+  [
+    if test "x$ac_system" = "xLinux"; then
+      with_liblvm2app="yes"
+    else
+      with_liblvm2app="no (Linux only library)"
+    fi
+  ]
+)
 
-        AC_CHECK_HEADERS(lvm2app.h, [with_liblvm2app="yes"], [with_liblvm2app="no (lvm2app.h not found)"])
+if test "x$with_liblvm2app" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_liblvm2app_cppflags"
+
+  AC_CHECK_HEADERS([lvm2app.h],
+    [with_liblvm2app="yes"],
+    [with_liblvm2app="no (lvm2app.h not found)"]
+  )
 
-        CPPFLAGS="$SAVE_CPPFLAGS"
+  CPPFLAGS="$SAVE_CPPFLAGS"
 fi
 
-if test "x$with_liblvm2app" = "xyes"
-then
-        SAVE_CPPFLAGS="$CPPFLAGS"
-        SAVE_LDFLAGS="$LDFLAGS"
-        CPPFLAGS="$CPPFLAGS $with_liblvm2app_cppflags"
-        LDFLAGS="$LDFLAGS $with_liblvm2app_ldflags"
+if test "x$with_liblvm2app" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  SAVE_LDFLAGS="$LDFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_liblvm2app_cppflags"
+  LDFLAGS="$LDFLAGS $with_liblvm2app_ldflags"
 
-        AC_CHECK_LIB(lvm2app, lvm_lv_get_property, [with_liblvm2app="yes"], [with_liblvm2app="no (Symbol 'lvm_lv_get_property' not found)"])
+  AC_CHECK_LIB([lvm2app], [lvm_lv_get_property],
+    [with_liblvm2app="yes"],
+    [with_liblvm2app="no (Symbol 'lvm_lv_get_property' not found)"]
+  )
 
-        CPPFLAGS="$SAVE_CPPFLAGS"
-        LDFLAGS="$SAVE_LDFLAGS"
+  CPPFLAGS="$SAVE_CPPFLAGS"
+  LDFLAGS="$SAVE_LDFLAGS"
 fi
-if test "x$with_liblvm2app" = "xyes"
-then
-        BUILD_WITH_LIBLVM2APP_CPPFLAGS="$with_liblvm2app_cppflags"
-        BUILD_WITH_LIBLVM2APP_LDFLAGS="$with_liblvm2app_ldflags"
-        BUILD_WITH_LIBLVM2APP_LIBS="-llvm2app"
-        AC_SUBST(BUILD_WITH_LIBLVM2APP_CPPFLAGS)
-        AC_SUBST(BUILD_WITH_LIBLVM2APP_LDFLAGS)
-        AC_SUBST(BUILD_WITH_LIBLVM2APP_LIBS)
-        AC_DEFINE(HAVE_LIBLVM2APP, 1, [Define if liblvm2app is present and usable.])
-fi
-AM_CONDITIONAL(BUILD_WITH_LIBLVM2APP, test "x$with_liblvm2app" = "xyes")
+
+if test "x$with_liblvm2app" = "xyes"; then
+  BUILD_WITH_LIBLVM2APP_CPPFLAGS="$with_liblvm2app_cppflags"
+  BUILD_WITH_LIBLVM2APP_LDFLAGS="$with_liblvm2app_ldflags"
+  BUILD_WITH_LIBLVM2APP_LIBS="-llvm2app"
+fi
+
+AC_SUBST([BUILD_WITH_LIBLVM2APP_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBLVM2APP_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBLVM2APP_LIBS])
 # }}}
 
 # --with-libmemcached {{{
-with_libmemcached_cppflags=""
-with_libmemcached_ldflags=""
-AC_ARG_WITH(libmemcached, [AS_HELP_STRING([--with-libmemcached@<:@=PREFIX@:>@], [Path to libmemcached.])],
-[
-       if test "x$withval" != "xno" && test "x$withval" != "xyes"
-       then
-               with_libmemcached_cppflags="-I$withval/include"
-               with_libmemcached_ldflags="-L$withval/lib"
-               with_libmemcached="yes"
-       else
-               with_libmemcached="$withval"
-       fi
-],
-[
-       with_libmemcached="yes"
-])
-if test "x$with_libmemcached" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_libmemcached_cppflags"
+AC_ARG_WITH([libmemcached],
+  [AS_HELP_STRING([--with-libmemcached@<:@=PREFIX@:>@], [Path to libmemcached.])],
+  [
+    if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
+      with_libmemcached_cppflags="-I$withval/include"
+      with_libmemcached_ldflags="-L$withval/lib"
+      with_libmemcached="yes"
+    else
+      with_libmemcached="$withval"
+    fi
+  ],
+  [with_libmemcached="yes"]
+)
 
-       AC_CHECK_HEADERS(libmemcached/memcached.h, [with_libmemcached="yes"], [with_libmemcached="no (libmemcached/memcached.h not found)"])
+if test "x$with_libmemcached" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_libmemcached_cppflags"
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
+  AC_CHECK_HEADERS([libmemcached/memcached.h],
+    [with_libmemcached="yes"],
+    [with_libmemcached="no (libmemcached/memcached.h not found)"]
+  )
+
+  CPPFLAGS="$SAVE_CPPFLAGS"
 fi
-if test "x$with_libmemcached" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       SAVE_LDFLAGS="$LDFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_libmemcached_cppflags"
-       LDFLAGS="$LDFLAGS $with_libmemcached_ldflags"
 
-       AC_CHECK_LIB(memcached, memcached_create, [with_libmemcached="yes"], [with_libmemcached="no (Symbol 'memcached_create' not found)"])
+if test "x$with_libmemcached" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  SAVE_LDFLAGS="$LDFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_libmemcached_cppflags"
+  LDFLAGS="$LDFLAGS $with_libmemcached_ldflags"
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
-       LDFLAGS="$SAVE_LDFLAGS"
+  AC_CHECK_LIB([memcached], [memcached_create],
+    [with_libmemcached="yes"],
+    [with_libmemcached="no (Symbol 'memcached_create' not found)"]
+  )
+
+  CPPFLAGS="$SAVE_CPPFLAGS"
+  LDFLAGS="$SAVE_LDFLAGS"
 fi
-if test "x$with_libmemcached" = "xyes"
-then
-       BUILD_WITH_LIBMEMCACHED_CPPFLAGS="$with_libmemcached_cppflags"
-       BUILD_WITH_LIBMEMCACHED_LDFLAGS="$with_libmemcached_ldflags"
-       BUILD_WITH_LIBMEMCACHED_LIBS="-lmemcached"
-       AC_SUBST(BUILD_WITH_LIBMEMCACHED_CPPFLAGS)
-       AC_SUBST(BUILD_WITH_LIBMEMCACHED_LDFLAGS)
-       AC_SUBST(BUILD_WITH_LIBMEMCACHED_LIBS)
-       AC_DEFINE(HAVE_LIBMEMCACHED, 1, [Define if libmemcached is present and usable.])
-fi
-AM_CONDITIONAL(BUILD_WITH_LIBMEMCACHED, test "x$with_libmemcached" = "xyes")
+
+if test "x$with_libmemcached" = "xyes"; then
+  BUILD_WITH_LIBMEMCACHED_CPPFLAGS="$with_libmemcached_cppflags"
+  BUILD_WITH_LIBMEMCACHED_LDFLAGS="$with_libmemcached_ldflags"
+  BUILD_WITH_LIBMEMCACHED_LIBS="-lmemcached"
+fi
+
+AC_SUBST([BUILD_WITH_LIBMEMCACHED_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBMEMCACHED_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBMEMCACHED_LIBS])
 # }}}
 
 # --with-libmicrohttpd {{{
@@ -3070,29 +3162,25 @@ with_libmicrohttpd_cppflags=""
 with_libmicrohttpd_ldflags=""
 AC_ARG_WITH([libmicrohttpd], [AS_HELP_STRING([--with-libmicrohttpd@<:@=PREFIX@:>@], [Path to libmicrohttpd.])],
   [
-    if test "x$withval" != "xno" && test "x$withval" != "xyes"
-    then
+    if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
       with_libmicrohttpd_cppflags="-I$withval/include"
       with_libmicrohttpd_ldflags="-L$withval/lib"
       with_libmicrohttpd="yes"
     fi
-    if test "x$withval" = "xno"
-    then
+    if test "x$withval" = "xno"; then
       with_libmicrohttpd="no (disabled on command line)"
     fi
   ],
   [withval="yes"]
 )
-if test "x$withval" = "xyes"
-then
-PKG_CHECK_MODULES([MICROHTTPD], [libmicrohttpd],
-  [with_libmicrohttpd="yes"],
-  [with_libmicrohttpd="no (pkg-config could not find libmicrohttpd)"]
-)
+if test "x$withval" = "xyes"; then
+  PKG_CHECK_MODULES([MICROHTTPD], [libmicrohttpd],
+    [with_libmicrohttpd="yes"],
+    [with_libmicrohttpd="no (pkg-config could not find libmicrohttpd)"]
+  )
 fi
 
-if test "x$MICROHTTPD_LIBS" = "x"
-then
+if test "x$MICROHTTPD_LIBS" = "x"; then
   MICROHTTPD_LIBS="-lmicrohttpd"
 fi
 
@@ -3103,18 +3191,18 @@ CPPFLAGS="$with_libmicrohttpd_cppflags $MICROHTTPD_CFLAGS"
 LDFLAGS="$with_libmicrohttpd_ldflags $LDFLAGS"
 LIBS="$LIBS $MICROHTTPD_LIBS"
 
-if test "x$with_libmicrohttpd" = "xyes"
-then
+if test "x$with_libmicrohttpd" = "xyes"; then
   AC_CHECK_HEADERS([microhttpd.h],
-                   [with_libmicrohttpd="yes"],
-                   [with_libmicrohttpd="no (<microhttpd.h> not found)"])
+   [with_libmicrohttpd="yes"],
+   [with_libmicrohttpd="no (<microhttpd.h> not found)"]
+  )
 fi
 
-if test "x$with_libmicrohttpd" = "xyes"
-then
+if test "x$with_libmicrohttpd" = "xyes"; then
   AC_CHECK_LIB([microhttpd], [MHD_start_daemon],
-               [with_libmicrohttpd="yes"],
-               [with_libmicrohttpd="no (libmicrohttpd not found)"])
+    [with_libmicrohttpd="yes"],
+    [with_libmicrohttpd="no (libmicrohttpd not found)"]
+  )
 fi
 
 CPPFLAGS="$SAVE_CPPFLAGS"
@@ -3130,106 +3218,97 @@ AC_SUBST([BUILD_WITH_LIBMICROHTTPD_LIBS])
 # }}}
 
 # --with-libmodbus {{{
-with_libmodbus_config=""
-with_libmodbus_cflags=""
-with_libmodbus_libs=""
-AC_ARG_WITH(libmodbus, [AS_HELP_STRING([--with-libmodbus@<:@=PREFIX@:>@], [Path to the modbus library.])],
-[
-       if test "x$withval" = "xno"
-       then
-               with_libmodbus="no"
-       else if test "x$withval" = "xyes"
-       then
-               with_libmodbus="use_pkgconfig"
-       else if test -d "$with_libmodbus/lib"
-       then
-               AC_MSG_NOTICE([Not checking for libmodbus: Manually configured])
-               with_libmodbus_cflags="-I$withval/include"
-               with_libmodbus_libs="-L$withval/lib -lmodbus"
-               with_libmodbus="yes"
-       fi; fi; fi
-],
-[with_libmodbus="use_pkgconfig"])
+AC_ARG_WITH([libmodbus],
+  [AS_HELP_STRING([--with-libmodbus@<:@=PREFIX@:>@], [Path to the modbus library.])],
+  [
+    if test "x$withval" = "xno"; then
+      with_libmodbus="no"
+    else if test "x$withval" = "xyes"; then
+      with_libmodbus="use_pkgconfig"
+    else if test -d "$with_libmodbus/lib"; then
+      AC_MSG_NOTICE([Not checking for libmodbus: Manually configured])
+      with_libmodbus_cflags="-I$withval/include"
+      with_libmodbus_libs="-L$withval/lib -lmodbus"
+      with_libmodbus="yes"
+    fi; fi; fi
+  ],
+  [with_libmodbus="use_pkgconfig"]
+)
 
 # configure using pkg-config
-if test "x$with_libmodbus" = "xuse_pkgconfig"
-then
-       AC_MSG_NOTICE([Checking for libmodbus using $PKG_CONFIG])
-       $PKG_CONFIG --exists 'libmodbus' 2>/dev/null
-       if test $? -ne 0
-       then
-               with_libmodbus="no (pkg-config doesn't know libmodbus)"
-       fi
+if test "x$with_libmodbus" = "xuse_pkgconfig"; then
+  AC_MSG_NOTICE([Checking for libmodbus using $PKG_CONFIG])
+  $PKG_CONFIG --exists 'libmodbus' 2>/dev/null
+  if test $? -ne 0; then
+    with_libmodbus="no (pkg-config doesn't know libmodbus)"
+  fi
 fi
-if test "x$with_libmodbus" = "xuse_pkgconfig"
-then
-       with_libmodbus_cflags="`$PKG_CONFIG --cflags 'libmodbus'`"
-       if test $? -ne 0
-       then
-               with_libmodbus="no ($PKG_CONFIG failed)"
-       fi
-       with_libmodbus_libs="`$PKG_CONFIG --libs 'libmodbus'`"
-       if test $? -ne 0
-       then
-               with_libmodbus="no ($PKG_CONFIG failed)"
-       fi
+
+if test "x$with_libmodbus" = "xuse_pkgconfig"; then
+  with_libmodbus_cflags="`$PKG_CONFIG --cflags 'libmodbus'`"
+  if test $? -ne 0; then
+    with_libmodbus="no ($PKG_CONFIG failed)"
+  fi
+
+  with_libmodbus_libs="`$PKG_CONFIG --libs 'libmodbus'`"
+  if test $? -ne 0; then
+    with_libmodbus="no ($PKG_CONFIG failed)"
+  fi
 fi
-if test "x$with_libmodbus" = "xuse_pkgconfig"
-then
-       with_libmodbus="yes"
+
+if test "x$with_libmodbus" = "xuse_pkgconfig"; then
+  with_libmodbus="yes"
 fi
 
-# with_libmodbus_cflags and with_libmodbus_libs are set up now, let's do
-# the actual checks.
-if test "x$with_libmodbus" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_libmodbus_cflags"
+if test "x$with_libmodbus" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_libmodbus_cflags"
 
-       AC_CHECK_HEADERS(modbus.h, [], [with_libmodbus="no (modbus.h not found)"])
+  AC_CHECK_HEADERS([modbus.h],
+    [with_libmodbus="yes"],
+    [with_libmodbus="no (modbus.h not found)"]
+  )
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
+  CPPFLAGS="$SAVE_CPPFLAGS"
 fi
-if test "x$with_libmodbus" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       SAVE_LDFLAGS="$LDFLAGS"
 
-       CPPFLAGS="$CPPFLAGS $with_libmodbus_cflags"
-       LDFLAGS="$LDFLAGS $with_libmodbus_libs"
+if test "x$with_libmodbus" = "xyes"; then
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $with_libmodbus_libs"
 
-       AC_CHECK_LIB(modbus, modbus_connect,
-                    [with_libmodbus="yes"],
-                    [with_libmodbus="no (symbol modbus_connect not found)"])
+  AC_CHECK_LIB([modbus], [modbus_connect],
+    [with_libmodbus="yes"],
+    [with_libmodbus="no (symbol modbus_connect not found)"]
+  )
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
-       LDFLAGS="$SAVE_LDFLAGS"
+  LDFLAGS="$SAVE_LDFLAGS"
 fi
-if test "x$with_libmodbus" = "xyes"
-then
-       BUILD_WITH_LIBMODBUS_CFLAGS="$with_libmodbus_cflags"
-       BUILD_WITH_LIBMODBUS_LIBS="$with_libmodbus_libs"
-       AC_SUBST(BUILD_WITH_LIBMODBUS_CFLAGS)
-       AC_SUBST(BUILD_WITH_LIBMODBUS_LIBS)
+
+if test "x$with_libmodbus" = "xyes"; then
+  BUILD_WITH_LIBMODBUS_CFLAGS="$with_libmodbus_cflags"
+  BUILD_WITH_LIBMODBUS_LIBS="$with_libmodbus_libs"
 fi
+
+AC_SUBST([BUILD_WITH_LIBMODBUS_CFLAGS])
+AC_SUBST([BUILD_WITH_LIBMODBUS_LIBS])
 # }}}
 
 # --with-libmongoc {{{
-AC_ARG_WITH(libmongoc, [AS_HELP_STRING([--with-libmongoc@<:@=PREFIX@:>@], [Path to libmongoc.])],
-[
- if test "x$withval" = "xyes"
- then
-        with_libmongoc="yes"
- 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"
- fi; fi
-],
-[with_libmongoc="yes"])
+AC_ARG_WITH([libmongoc],
+  [AS_HELP_STRING([--with-libmongoc@<:@=PREFIX@:>@], [Path to libmongoc.])],
+  [
   if test "x$withval" = "xyes"; then
+      with_libmongoc="yes"
+    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"
+    fi; fi
+  ],
+  [with_libmongoc="yes"]
+)
 
 SAVE_CPPFLAGS="$CPPFLAGS"
 SAVE_LDFLAGS="$LDFLAGS"
@@ -3237,366 +3316,346 @@ SAVE_LDFLAGS="$LDFLAGS"
 CPPFLAGS="$CPPFLAGS $LIBMONGOC_CPPFLAGS"
 LDFLAGS="$LDFLAGS $LIBMONGOC_LDFLAGS"
 
-if test "x$with_libmongoc" = "xyes"
-then
-       if test "x$LIBMONGOC_CPPFLAGS" != "x"
-       then
-               AC_MSG_NOTICE([libmongoc CPPFLAGS: $LIBMONGOC_CPPFLAGS])
-       fi
-       AC_CHECK_HEADERS(mongo.h,
-       [with_libmongoc="yes"],
-       [with_libmongoc="no ('mongo.h' not found)"],
-[#if HAVE_STDINT_H
-# define MONGO_HAVE_STDINT 1
-#else
-# define MONGO_USE_LONG_LONG_INT 1
-#endif
-])
+if test "x$with_libmongoc" = "xyes"; then
+  if test "x$LIBMONGOC_CPPFLAGS" != "x"; then
+    AC_MSG_NOTICE([libmongoc CPPFLAGS: $LIBMONGOC_CPPFLAGS])
+  fi
+
+  AC_CHECK_HEADERS([mongo.h],
+    [with_libmongoc="yes"],
+    [with_libmongoc="no ('mongo.h' not found)"],
+    [[#define MONGO_HAVE_STDINT 1]]
+  )
 fi
-if test "x$with_libmongoc" = "xyes"
-then
-       if test "x$LIBMONGOC_LDFLAGS" != "x"
-       then
-               AC_MSG_NOTICE([libmongoc LDFLAGS: $LIBMONGOC_LDFLAGS])
-       fi
-       AC_CHECK_LIB(mongoc, mongo_run_command,
-       [with_libmongoc="yes"],
-       [with_libmongoc="no (symbol 'mongo_run_command' not found)"])
+
+if test "x$with_libmongoc" = "xyes"; then
+  if test "x$LIBMONGOC_LDFLAGS" != "x"; then
+    AC_MSG_NOTICE([libmongoc LDFLAGS: $LIBMONGOC_LDFLAGS])
+  fi
+
+  AC_CHECK_LIB([mongoc], [mongo_run_command],
+    [with_libmongoc="yes"],
+    [with_libmongoc="no (symbol 'mongo_run_command' not found)"]
+  )
 fi
 
 CPPFLAGS="$SAVE_CPPFLAGS"
 LDFLAGS="$SAVE_LDFLAGS"
 
-if test "x$with_libmongoc" = "xyes"
-then
-       BUILD_WITH_LIBMONGOC_CPPFLAGS="$LIBMONGOC_CPPFLAGS"
-       BUILD_WITH_LIBMONGOC_LDFLAGS="$LIBMONGOC_LDFLAGS"
-       AC_SUBST(BUILD_WITH_LIBMONGOC_CPPFLAGS)
-       AC_SUBST(BUILD_WITH_LIBMONGOC_LDFLAGS)
+if test "x$with_libmongoc" = "xyes"; then
+  BUILD_WITH_LIBMONGOC_CPPFLAGS="$LIBMONGOC_CPPFLAGS"
+  BUILD_WITH_LIBMONGOC_LDFLAGS="$LIBMONGOC_LDFLAGS"
 fi
-AM_CONDITIONAL(BUILD_WITH_LIBMONGOC, test "x$with_libmongoc" = "xyes")
+
+AC_SUBST([BUILD_WITH_LIBMONGOC_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBMONGOC_LDFLAGS])
 # }}}
 
 # --with-libmosquitto {{{
-with_libmosquitto_cppflags=""
-with_libmosquitto_ldflags=""
-AC_ARG_WITH(libmosquitto, [AS_HELP_STRING([--with-libmosquitto@<:@=PREFIX@:>@], [Path to libmosquitto.])],
-[
-       if test "x$withval" != "xno" && test "x$withval" != "xyes"
-       then
-               with_libmosquitto_cppflags="-I$withval/include"
-               with_libmosquitto_ldflags="-L$withval/lib"
-               with_libmosquitto="yes"
-       else
-               with_libmosquitto="$withval"
-       fi
-],
-[
-       with_libmosquitto="yes"
-])
-if test "x$with_libmosquitto" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_libmosquitto_cppflags"
+AC_ARG_WITH([libmosquitto],
+  [AS_HELP_STRING([--with-libmosquitto@<:@=PREFIX@:>@], [Path to libmosquitto.])],
+  [
+    if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
+      with_libmosquitto_cppflags="-I$withval/include"
+      with_libmosquitto_ldflags="-L$withval/lib"
+      with_libmosquitto="yes"
+    else
+      with_libmosquitto="$withval"
+    fi
+  ],
+  [with_libmosquitto="yes"]
+)
+
+if test "x$with_libmosquitto" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_libmosquitto_cppflags"
 
-       AC_CHECK_HEADERS(mosquitto.h, [with_libmosquitto="yes"], [with_libmosquitto="no (mosquitto.h not found)"])
+  AC_CHECK_HEADERS([mosquitto.h],
+    [with_libmosquitto="yes"],
+    [with_libmosquitto="no (mosquitto.h not found)"]
+  )
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
+  CPPFLAGS="$SAVE_CPPFLAGS"
 fi
-if test "x$with_libmosquitto" = "xyes"
-then
-       SAVE_LDFLAGS="$LDFLAGS"
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       LDFLAGS="$LDFLAGS $with_libmosquitto_ldflags"
-       CPPFLAGS="$CPPFLAGS $with_libmosquitto_cppflags"
 
-       AC_CHECK_LIB(mosquitto, mosquitto_connect, [with_libmosquitto="yes"], [with_libmosquitto="no (libmosquitto not found)"])
+if test "x$with_libmosquitto" = "xyes"; then
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $with_libmosquitto_ldflags"
+
+  AC_CHECK_LIB([mosquitto], [mosquitto_connect],
+    [with_libmosquitto="yes"],
+    [with_libmosquitto="no (libmosquitto not found)"]
+  )
 
-       LDFLAGS="$SAVE_LDFLAGS"
-       CPPFLAGS="$SAVE_CPPFLAGS"
+  LDFLAGS="$SAVE_LDFLAGS"
 fi
-if test "x$with_libmosquitto" = "xyes"
-then
-       BUILD_WITH_LIBMOSQUITTO_CPPFLAGS="$with_libmosquitto_cppflags"
-       BUILD_WITH_LIBMOSQUITTO_LDFLAGS="$with_libmosquitto_ldflags"
-       BUILD_WITH_LIBMOSQUITTO_LIBS="-lmosquitto"
-       AC_SUBST(BUILD_WITH_LIBMOSQUITTO_CPPFLAGS)
-       AC_SUBST(BUILD_WITH_LIBMOSQUITTO_LDFLAGS)
-       AC_SUBST(BUILD_WITH_LIBMOSQUITTO_LIBS)
+
+if test "x$with_libmosquitto" = "xyes"; then
+  BUILD_WITH_LIBMOSQUITTO_CPPFLAGS="$with_libmosquitto_cppflags"
+  BUILD_WITH_LIBMOSQUITTO_LDFLAGS="$with_libmosquitto_ldflags"
+  BUILD_WITH_LIBMOSQUITTO_LIBS="-lmosquitto"
 fi
+
+AC_SUBST([BUILD_WITH_LIBMOSQUITTO_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBMOSQUITTO_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBMOSQUITTO_LIBS])
 # }}}
 
 # --with-libmysql {{{
 with_mysql_config="mysql_config"
-with_mysql_cflags=""
-with_mysql_libs=""
-AC_ARG_WITH(libmysql, [AS_HELP_STRING([--with-libmysql@<:@=PREFIX@:>@], [Path to libmysql.])],
-[
-       if test "x$withval" = "xno"
-       then
-               with_libmysql="no"
-       else if test "x$withval" = "xyes"
-       then
-               with_libmysql="yes"
-       else
-               if test -f "$withval" && test -x "$withval";
-               then
-                       with_mysql_config="$withval"
-               else if test -x "$withval/bin/mysql_config"
-               then
-                       with_mysql_config="$withval/bin/mysql_config"
-               fi; fi
-               with_libmysql="yes"
-       fi; fi
-],
-[
-       with_libmysql="yes"
-])
-if test "x$with_libmysql" = "xyes"
-then
-       with_mysql_cflags=`$with_mysql_config --include 2>/dev/null`
-       mysql_config_status=$?
+AC_ARG_WITH([libmysql],
+  [AS_HELP_STRING([--with-libmysql@<:@=PREFIX@:>@], [Path to libmysql.])],
+  [
+    if test "x$withval" = "xno"; then
+      with_libmysql="no"
+    else if test "x$withval" = "xyes"; then
+      with_libmysql="yes"
+    else
+      if test -f "$withval" && test -x "$withval"; then
+        with_mysql_config="$withval"
+      else if test -x "$withval/bin/mysql_config"; then
+        with_mysql_config="$withval/bin/mysql_config"
+      fi; fi
+      with_libmysql="yes"
+    fi; fi
+  ],
+  [with_libmysql="yes"]
+)
 
-       if test $mysql_config_status -ne 0
-       then
-               with_libmysql="no ($with_mysql_config failed)"
-       else
-               SAVE_CPPFLAGS="$CPPFLAGS"
-               CPPFLAGS="$CPPFLAGS $with_mysql_cflags"
+if test "x$with_libmysql" = "xyes"; then
+  with_mysql_cflags=`$with_mysql_config --include 2>/dev/null`
+  if test $? -ne 0; then
+    with_libmysql="no ($with_mysql_config failed)"
+  else
+    SAVE_CPPFLAGS="$CPPFLAGS"
+    CPPFLAGS="$CPPFLAGS $with_mysql_cflags"
 
-               have_mysql_h="no"
-               have_mysql_mysql_h="no"
-               AC_CHECK_HEADERS(mysql.h, [have_mysql_h="yes"])
+    AC_CHECK_HEADERS([mysql.h],
+      [have_mysql_h="yes"],
+      [have_mysql_h="no"]
+    )
 
-               if test "x$have_mysql_h" = "xno"
-               then
-                       AC_CHECK_HEADERS(mysql/mysql.h, [have_mysql_mysql_h="yes"])
-               fi
+    if test "x$have_mysql_h" != "xyes"; then
+      AC_CHECK_HEADERS([mysql/mysql.h],
+        [have_mysql_mysql_h="yes"],
+        [],
+      )
+    fi
 
-               if test "x$have_mysql_h$have_mysql_mysql_h" = "xnono"
-               then
-                       with_libmysql="no (mysql.h not found)"
-               fi
+    if test "x$have_mysql_h" != "xyes" && test "x$have_mysql_mysql_h" != "xyes"; then
+      with_libmysql="no (mysql.h not found)"
+    fi
 
-               CPPFLAGS="$SAVE_CPPFLAGS"
-       fi
+    CPPFLAGS="$SAVE_CPPFLAGS"
+  fi
 fi
-if test "x$with_libmysql" = "xyes"
-then
-       with_mysql_libs=`$with_mysql_config --libs_r 2>/dev/null`
-       mysql_config_status=$?
 
-       if test $mysql_config_status -ne 0
-       then
-               with_libmysql="no ($with_mysql_config failed)"
-       else
-               SAVE_CPPFLAGS="$CPPFLAGS"
-               CPPFLAGS="$CPPFLAGS $with_mysql_cflags"
-               SAVE_LIBS="$LIBS"
-               LIBS="$with_mysql_libs"
-               AC_SEARCH_LIBS([mysql_get_server_version],
-                [],
-                [with_libmysql="yes"],
-                [with_libmysql="no (symbol 'mysql_get_server_version' not found)"],
-                [])
-               CPPFLAGS="$SAVE_CPPFLAGS"
-               LIBS="$SAVE_LIBS"
-       fi
+if test "x$with_libmysql" = "xyes"; then
+  with_mysql_libs=`$with_mysql_config --libs_r 2>/dev/null`
+  if test $? -ne 0; then
+    with_libmysql="no ($with_mysql_config failed)"
+  else
+    SAVE_LIBS="$LIBS"
+    LIBS="$with_mysql_libs"
+
+    AC_SEARCH_LIBS([mysql_get_server_version],
+      [],
+      [with_libmysql="yes"],
+      [with_libmysql="no (symbol 'mysql_get_server_version' not found in ${LIBS})"],
+      []
+    )
+    LIBS="$SAVE_LIBS"
+  fi
 fi
-if test "x$with_libmysql" = "xyes"
-then
-       BUILD_WITH_LIBMYSQL_CFLAGS="$with_mysql_cflags"
-       BUILD_WITH_LIBMYSQL_LIBS="$with_mysql_libs"
-       AC_SUBST(BUILD_WITH_LIBMYSQL_CFLAGS)
-       AC_SUBST(BUILD_WITH_LIBMYSQL_LIBS)
+
+if test "x$with_libmysql" = "xyes"; then
+  BUILD_WITH_LIBMYSQL_CFLAGS="$with_mysql_cflags"
+  BUILD_WITH_LIBMYSQL_LIBS="$with_mysql_libs"
 fi
-AM_CONDITIONAL(BUILD_WITH_LIBMYSQL, test "x$with_libmysql" = "xyes")
+
+AC_SUBST([BUILD_WITH_LIBMYSQL_CFLAGS])
+AC_SUBST([BUILD_WITH_LIBMYSQL_LIBS])
 # }}}
 
 # --with-libmnl {{{
-with_libmnl_cflags=""
-with_libmnl_libs=""
-AC_ARG_WITH(libmnl, [AS_HELP_STRING([--with-libmnl@<:@=PREFIX@:>@], [Path to libmnl.])],
-[
- echo "libmnl: withval = $withval"
- if test "x$withval" = "xyes"
- then
-        with_libmnl="yes"
- else if test "x$withval" = "xno"
- then
-        with_libmnl="no"
- else
-        if test -d "$withval/include"
-        then
-                with_libmnl_cflags="-I$withval/include"
-                with_libmnl_libs="-L$withval/lib -lmnl"
-                with_libmnl="yes"
-        else
-                AC_MSG_ERROR("no such directory: $withval/include")
-        fi
- fi; fi
-],
-[
- if test "x$ac_system" = "xLinux"
- then
-        with_libmnl="yes"
- else
-        with_libmnl="no (Linux only library)"
- fi
-])
-if test "x$with_libmnl" = "xyes"
-then
-       if $PKG_CONFIG --exists libmnl 2>/dev/null; then
-         with_libmnl_cflags="$with_libmnl_ldflags `$PKG_CONFIG --cflags libmnl`"
-         with_libmnl_libs="$with_libmnl_libs `$PKG_CONFIG --libs libmnl`"
-       fi
-
-       AC_CHECK_HEADERS(libmnl.h libmnl/libmnl.h,
-       [
-        with_libmnl="yes"
-        break
-       ], [],
-[#include <stdio.h>
-#include <sys/types.h>
-#include <asm/types.h>
-#include <sys/socket.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>])
-       AC_CHECK_HEADERS(linux/gen_stats.h linux/pkt_sched.h, [], [],
-[#include <stdio.h>
-#include <sys/types.h>
-#include <asm/types.h>
-#include <sys/socket.h>])
-
-        AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
-[[
-#include <stdio.h>
-#include <sys/types.h>
-#include <asm/types.h>
-#include <sys/socket.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-]],
-[[
-int retval = TCA_STATS2;
-return (retval);
-]]
-       )],
-       [AC_DEFINE([HAVE_TCA_STATS2], [1], [True if the enum-member TCA_STATS2 exists])])
-
-       AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
-[[
-#include <stdio.h>
-#include <sys/types.h>
-#include <asm/types.h>
-#include <sys/socket.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-]],
-[[
-int retval = TCA_STATS;
-return (retval);
-]]
-       )],
-       [AC_DEFINE([HAVE_TCA_STATS], 1, [True if the enum-member TCA_STATS exists])])
-fi
-if test "x$with_libmnl" = "xyes"
-then
-       AC_CHECK_MEMBERS([struct rtnl_link_stats64.tx_window_errors],
-       [AC_DEFINE(HAVE_RTNL_LINK_STATS64, 1, [Define if struct rtnl_link_stats64 exists and is usable.])],
-       [],
-       [
-       #include <linux/if_link.h>
-       ])
-fi
-if test "x$with_libmnl" = "xyes"
-then
-       AC_CHECK_LIB(mnl, mnl_nlmsg_get_payload,
-                    [with_libmnl="yes"],
-                    [with_libmnl="no (symbol 'mnl_nlmsg_get_payload' not found)"],
-                    [$with_libmnl_libs])
-fi
-if test "x$with_libmnl" = "xyes"
-then
-       AC_DEFINE(HAVE_LIBMNL, 1, [Define if libmnl is present and usable.])
-       BUILD_WITH_LIBMNL_CFLAGS="$with_libmnl_cflags"
-       BUILD_WITH_LIBMNL_LIBS="$with_libmnl_libs"
-       AC_SUBST(BUILD_WITH_LIBMNL_CFLAGS)
-       AC_SUBST(BUILD_WITH_LIBMNL_LIBS)
-fi
-AM_CONDITIONAL(BUILD_WITH_LIBMNL, test "x$with_libmnl" = "xyes")
-# }}}
+AC_ARG_WITH([libmnl],
+  [AS_HELP_STRING([--with-libmnl@<:@=PREFIX@:>@], [Path to libmnl.])],
+  [
+    if test "x$withval" = "xyes"; then
+      with_libmnl="yes"
+     else if test "x$withval" = "xno"; then
+       with_libmnl="no"
+     else
+       if test -d "$withval/include"; then
+         with_libmnl_cflags="-I$withval/include"
+         with_libmnl_libs="-L$withval/lib -lmnl"
+         with_libmnl="yes"
+       else
+         AC_MSG_ERROR("no such directory: $withval/include")
+       fi
+     fi; fi
+  ],
+  [
+    if test "x$ac_system" = "xLinux"; then
+      with_libmnl="yes"
+    else
+      with_libmnl="no (Linux only library)"
+    fi
+  ]
+)
 
-# --with-libnetapp {{{
-AC_ARG_VAR([LIBNETAPP_CPPFLAGS], [C preprocessor flags required to build with libnetapp])
-AC_ARG_VAR([LIBNETAPP_LDFLAGS],  [Linker flags required to build with libnetapp])
-AC_ARG_VAR([LIBNETAPP_LIBS],     [Other libraries required to link against libnetapp])
-LIBNETAPP_CPPFLAGS="$LIBNETAPP_CPPFLAGS"
-LIBNETAPP_LDFLAGS="$LIBNETAPP_LDFLAGS"
-LIBNETAPP_LIBS="$LIBNETAPP_LIBS"
-AC_ARG_WITH(libnetapp, [AS_HELP_STRING([--with-libnetapp@<:@=PREFIX@:>@], [Path to libnetapp.])],
-[
- if test -d "$withval"
- then
-        LIBNETAPP_CPPFLAGS="$LIBNETAPP_CPPFLAGS -I$withval/include"
-        LIBNETAPP_LDFLAGS="$LIBNETAPP_LDFLAGS -L$withval/lib"
-        with_libnetapp="yes"
- else
-        with_libnetapp="$withval"
- fi
-],
-[
- with_libnetapp="yes"
-])
+if test "x$with_libmnl" = "xyes"; then
+  if $PKG_CONFIG --exists libmnl 2>/dev/null; then
+    with_libmnl_cflags="$with_libmnl_ldflags `$PKG_CONFIG --cflags libmnl`"
+    with_libmnl_libs="$with_libmnl_libs `$PKG_CONFIG --libs libmnl`"
+  fi
 
-SAVE_CPPFLAGS="$CPPFLAGS"
-SAVE_LDFLAGS="$LDFLAGS"
-CPPFLAGS="$CPPFLAGS $LIBNETAPP_CPPFLAGS"
-LDFLAGS="$LDFLAGS $LIBNETAPP_LDFLAGS"
+  AC_CHECK_HEADERS([libmnl.h libmnl/libmnl.h],
+    [
+      with_libmnl="yes"
+      break
+    ],
+    [],
+    [[
+      #include <stdio.h>
+      #include <sys/types.h>
+      #include <asm/types.h>
+      #include <sys/socket.h>
+      #include <linux/netlink.h>
+      #include <linux/rtnetlink.h>]]
+  )
 
-if test "x$with_libnetapp" = "xyes"
-then
-       if test "x$LIBNETAPP_CPPFLAGS" != "x"
-       then
-               AC_MSG_NOTICE([netapp CPPFLAGS: $LIBNETAPP_CPPFLAGS])
-       fi
-       AC_CHECK_HEADERS(netapp_api.h,
-               [with_libnetapp="yes"],
-               [with_libnetapp="no (netapp_api.h not found)"])
+  AC_CHECK_HEADERS([linux/gen_stats.h linux/pkt_sched.h],
+    [],
+    [],
+    [[
+      #include <stdio.h>
+      #include <sys/types.h>
+      #include <asm/types.h>
+      #include <sys/socket.h>
+    ]]
+  )
+
+  AC_COMPILE_IFELSE(
+    [
+      AC_LANG_PROGRAM(
+        [[
+          #include <stdio.h>
+          #include <sys/types.h>
+          #include <asm/types.h>
+          #include <sys/socket.h>
+          #include <linux/netlink.h>
+          #include <linux/rtnetlink.h>
+        ]],
+        [[
+          int retval = TCA_STATS2;
+          return (retval);
+        ]]
+      )
+    ],
+    [AC_DEFINE([HAVE_TCA_STATS2], [1], [True if the enum-member TCA_STATS2 exists])]
+  )
+
+  AC_COMPILE_IFELSE(
+    [
+      AC_LANG_PROGRAM(
+        [[
+          #include <stdio.h>
+          #include <sys/types.h>
+          #include <asm/types.h>
+          #include <sys/socket.h>
+          #include <linux/netlink.h>
+          #include <linux/rtnetlink.h>
+        ]],
+        [[
+          int retval = TCA_STATS;
+          return (retval);
+        ]]
+      )
+    ],
+    [AC_DEFINE([HAVE_TCA_STATS], 1, [True if the enum-member TCA_STATS exists])]
+  )
+
+  AC_CHECK_MEMBERS([struct rtnl_link_stats64.tx_window_errors],
+    [AC_DEFINE(HAVE_RTNL_LINK_STATS64, 1, [Define if struct rtnl_link_stats64 exists and is usable.])],
+    [],
+    [[#include <linux/if_link.h>]]
+  )
+
+  AC_CHECK_LIB([mnl], [mnl_nlmsg_get_payload],
+    [with_libmnl="yes"],
+    [with_libmnl="no (symbol 'mnl_nlmsg_get_payload' not found)"],
+    [$with_libmnl_libs]
+  )
 fi
 
-if test "x$with_libnetapp" = "xyes"
-then
-       if test "x$LIBNETAPP_LDFLAGS" != "x"
-       then
-               AC_MSG_NOTICE([netapp LDFLAGS: $LIBNETAPP_LDFLAGS])
-       fi
+if test "x$with_libmnl" = "xyes"; then
+  BUILD_WITH_LIBMNL_CFLAGS="$with_libmnl_cflags"
+  BUILD_WITH_LIBMNL_LIBS="$with_libmnl_libs"
+fi
+AC_SUBST([BUILD_WITH_LIBMNL_CFLAGS])
+AC_SUBST([BUILD_WITH_LIBMNL_LIBS])
+# }}}
 
-       if test "x$LIBNETAPP_LIBS" = "x"
-       then
-               LIBNETAPP_LIBS="$PTHREAD_LIBS -lxml -ladt -lssl -lm -lcrypto -lz"
-       fi
-       AC_MSG_NOTICE([netapp LIBS: $LIBNETAPP_LIBS])
+# --with-libnetapp {{{
+AC_ARG_VAR([LIBNETAPP_CPPFLAGS], [C preprocessor flags required to build with libnetapp])
+AC_ARG_VAR([LIBNETAPP_LDFLAGS],  [Linker flags required to build with libnetapp])
+AC_ARG_VAR([LIBNETAPP_LIBS],     [Other libraries required to link against libnetapp])
+AC_ARG_WITH([libnetapp],
+  [AS_HELP_STRING([--with-libnetapp@<:@=PREFIX@:>@], [Path to libnetapp.])],
+  [
+   if test -d "$withval"; then
+     LIBNETAPP_CPPFLAGS="$LIBNETAPP_CPPFLAGS -I$withval/include"
+     LIBNETAPP_LDFLAGS="$LIBNETAPP_LDFLAGS -L$withval/lib"
+     with_libnetapp="yes"
+   else
+     with_libnetapp="$withval"
+   fi
+  ],
+  [with_libnetapp="yes"]
+)
+
+SAVE_CPPFLAGS="$CPPFLAGS"
+SAVE_LDFLAGS="$LDFLAGS"
+CPPFLAGS="$CPPFLAGS $LIBNETAPP_CPPFLAGS"
+LDFLAGS="$LDFLAGS $LIBNETAPP_LDFLAGS"
 
-       AC_CHECK_LIB(netapp, na_server_invoke_elem,
-               [with_libnetapp="yes"],
-               [with_libnetapp="no (symbol na_server_invoke_elem not found)"],
-               [$LIBNETAPP_LIBS])
-       LIBNETAPP_LIBS="-lnetapp $LIBNETAPP_LIBS"
+if test "x$with_libnetapp" = "xyes"; then
+  if test "x$LIBNETAPP_CPPFLAGS" != "x"; then
+    AC_MSG_NOTICE([netapp CPPFLAGS: $LIBNETAPP_CPPFLAGS])
+  fi
+  AC_CHECK_HEADERS([netapp_api.h],
+    [with_libnetapp="yes"],
+    [with_libnetapp="no (netapp_api.h not found)"]
+  )
 fi
 
-CPPFLAGS="$SAVE_CPPFLAGS"
-LDFLAGS="$SAVE_LDFLAGS"
+if test "x$with_libnetapp" = "xyes"; then
+  if test "x$LIBNETAPP_LDFLAGS" != "x"; then
+    AC_MSG_NOTICE([netapp LDFLAGS: $LIBNETAPP_LDFLAGS])
+  fi
 
-if test "x$with_libnetapp" = "xyes"
-then
-       AC_DEFINE(HAVE_LIBNETAPP, 1, [Define to 1 if you have the netapp library (-lnetapp).])
+  if test "x$LIBNETAPP_LIBS" = "x"; then
+    LIBNETAPP_LIBS="$PTHREAD_LIBS -lxml -ladt -lssl -lm -lcrypto -lz"
+  fi
+
+  AC_MSG_NOTICE([netapp LIBS: $LIBNETAPP_LIBS])
+
+  AC_CHECK_LIB([netapp], [na_server_invoke_elem],
+    [with_libnetapp="yes"],
+    [with_libnetapp="no (symbol na_server_invoke_elem not found)"],
+    [$LIBNETAPP_LIBS]
+  )
+
+  LIBNETAPP_LIBS="-lnetapp $LIBNETAPP_LIBS"
 fi
 
-AC_SUBST(LIBNETAPP_CPPFLAGS)
-AC_SUBST(LIBNETAPP_LDFLAGS)
-AC_SUBST(LIBNETAPP_LIBS)
-AM_CONDITIONAL(BUILD_WITH_LIBNETAPP, test "x$with_libnetapp" = "xyes")
+CPPFLAGS="$SAVE_CPPFLAGS"
+LDFLAGS="$SAVE_LDFLAGS"
+
+AC_SUBST([LIBNETAPP_CPPFLAGS])
+AC_SUBST([LIBNETAPP_LDFLAGS])
+AC_SUBST([LIBNETAPP_LIBS])
 # }}}
 
 # --with-libnetsnmp {{{
@@ -3620,7 +3679,10 @@ then
        SAVE_CPPFLAGS="$CPPFLAGS"
        CPPFLAGS="$CPPFLAGS $with_libnetsnmp_cppflags"
 
-       AC_CHECK_HEADERS(net-snmp/net-snmp-config.h, [], [with_libnetsnmp="no (net-snmp/net-snmp-config.h not found)"])
+    AC_CHECK_HEADERS([net-snmp/net-snmp-config.h],
+      [with_libnetsnmp="yes"],
+      [with_libnetsnmp="no (net-snmp/net-snmp-config.h not found)"]
+    )
 
        CPPFLAGS="$SAVE_CPPFLAGS"
 fi
@@ -3647,552 +3709,496 @@ AC_SUBST(BUILD_WITH_LIBNETSNMP_LDFLAGS)
 AC_SUBST(BUILD_WITH_LIBNETSNMP_LIBS)
 # }}}
 
-# --with-liboconfig {{{
-with_own_liboconfig="no"
-liboconfig_LDFLAGS="$LDFLAGS"
-liboconfig_CPPFLAGS="$CPPFLAGS"
-AC_ARG_WITH(liboconfig, [AS_HELP_STRING([--with-liboconfig@<:@=PREFIX@:>@], [Path to liboconfig.])],
-[
-       if test "x$withval" != "xno" && test "x$withval" != "xyes"
-       then
-               if test -d "$withval/lib"
-               then
-                       liboconfig_LDFLAGS="$LDFLAGS -L$withval/lib"
-               fi
-               if test -d "$withval/include"
-               then
-                       liboconfig_CPPFLAGS="$CPPFLAGS -I$withval/include"
-               fi
-       fi
-       if test "x$withval" = "xno"
-       then
-               AC_MSG_ERROR("liboconfig is required")
-       fi
-],
-[
-       with_liboconfig="yes"
-])
-
-save_LDFLAGS="$LDFLAGS"
-save_CPPFLAGS="$CPPFLAGS"
-LDFLAGS="$liboconfig_LDFLAGS"
-CPPFLAGS="$liboconfig_CPPFLAGS"
-AC_CHECK_LIB(oconfig, oconfig_parse_file,
-[
-       with_liboconfig="yes"
-       with_own_liboconfig="no"
-],
-[
-       with_liboconfig="yes"
-       with_own_liboconfig="yes"
-       LDFLAGS="$save_LDFLAGS"
-       CPPFLAGS="$save_CPPFLAGS"
-])
-
-AM_CONDITIONAL(BUILD_WITH_OWN_LIBOCONFIG, test "x$with_own_liboconfig" = "xyes")
-if test "x$with_own_liboconfig" = "xyes"
-then
-       with_liboconfig="yes (shipped version)"
-fi
-# }}}
-
 # --with-liboping {{{
-AC_ARG_WITH(liboping, [AS_HELP_STRING([--with-liboping@<:@=PREFIX@:>@], [Path to liboping.])],
-[
- if test "x$withval" = "xyes"
- then
-        with_liboping="yes"
- else if test "x$withval" = "xno"
- then
-        with_liboping="no"
- else
-        with_liboping="yes"
-        LIBOPING_CPPFLAGS="$LIBOPING_CPPFLAGS -I$withval/include"
-        LIBOPING_LDFLAGS="$LIBOPING_LDFLAGS -L$withval/lib"
- fi; fi
-],
-[with_liboping="yes"])
+AC_ARG_WITH([liboping],
+  [AS_HELP_STRING([--with-liboping@<:@=PREFIX@:>@], [Path to liboping.])],
+  [
   if test "x$withval" = "xyes"; then
+      with_liboping="yes"
+    else if test "x$withval" = "xno"; then
+      with_liboping="no"
+    else
+      with_liboping="yes"
+      LIBOPING_CPPFLAGS="-I$withval/include"
+      LIBOPING_LDFLAGS="-L$withval/lib"
+    fi; fi
+  ],
+  [with_liboping="yes"]
+)
 
 SAVE_CPPFLAGS="$CPPFLAGS"
 SAVE_LDFLAGS="$LDFLAGS"
-
 CPPFLAGS="$CPPFLAGS $LIBOPING_CPPFLAGS"
 LDFLAGS="$LDFLAGS $LIBOPING_LDFLAGS"
 
-if test "x$with_liboping" = "xyes"
-then
-       if test "x$LIBOPING_CPPFLAGS" != "x"
-       then
-               AC_MSG_NOTICE([liboping CPPFLAGS: $LIBOPING_CPPFLAGS])
-       fi
-       AC_CHECK_HEADERS(oping.h,
-       [with_liboping="yes"],
-       [with_liboping="no (oping.h not found)"])
+if test "x$with_liboping" = "xyes"; then
+  AC_CHECK_HEADERS([oping.h],
+    [with_liboping="yes"],
+    [with_liboping="no (oping.h not found)"]
+  )
 fi
-if test "x$with_liboping" = "xyes"
-then
-       if test "x$LIBOPING_LDFLAGS" != "x"
-       then
-               AC_MSG_NOTICE([liboping LDFLAGS: $LIBOPING_LDFLAGS])
-       fi
-       AC_CHECK_LIB(oping, ping_construct,
-       [with_liboping="yes"],
-       [with_liboping="no (symbol 'ping_construct' not found)"])
+
+if test "x$with_liboping" = "xyes"; then
+  AC_CHECK_LIB([oping], [ping_construct],
+    [with_liboping="yes"],
+    [with_liboping="no (symbol 'ping_construct' not found)"]
+  )
 fi
 
 CPPFLAGS="$SAVE_CPPFLAGS"
 LDFLAGS="$SAVE_LDFLAGS"
 
-if test "x$with_liboping" = "xyes"
-then
-       BUILD_WITH_LIBOPING_CPPFLAGS="$LIBOPING_CPPFLAGS"
-       BUILD_WITH_LIBOPING_LDFLAGS="$LIBOPING_LDFLAGS"
-       AC_SUBST(BUILD_WITH_LIBOPING_CPPFLAGS)
-       AC_SUBST(BUILD_WITH_LIBOPING_LDFLAGS)
+if test "x$with_liboping" = "xyes"; then
+  BUILD_WITH_LIBOPING_CPPFLAGS="$LIBOPING_CPPFLAGS"
+  BUILD_WITH_LIBOPING_LDFLAGS="$LIBOPING_LDFLAGS"
 fi
-AM_CONDITIONAL(BUILD_WITH_LIBOPING, test "x$with_liboping" = "xyes")
+
+AC_SUBST([BUILD_WITH_LIBOPING_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBOPING_LDFLAGS])
 # }}}
 
 # --with-oracle {{{
-with_oracle_cppflags=""
-with_oracle_libs=""
-AC_ARG_WITH(oracle, [AS_HELP_STRING([--with-oracle@<:@=ORACLE_HOME@:>@], [Path to Oracle.])],
-[
-       if test "x$withval" = "xyes"
-       then
-               if test "x$ORACLE_HOME" = "x"
-               then
-                       AC_MSG_WARN([Use of the Oracle library has been forced, but the environment variable ORACLE_HOME is not set.])
-               fi
-               with_oracle="yes"
-       else if test "x$withval" = "xno"
-       then
-               with_oracle="no"
-       else
-               with_oracle="yes"
-               ORACLE_HOME="$withval"
-       fi; fi
-],
-[
-       if test "x$ORACLE_HOME" = "x"
-       then
-               with_oracle="no (ORACLE_HOME is not set)"
-       else
-               with_oracle="yes"
-       fi
-])
-if test "x$ORACLE_HOME" != "x"
-then
-       with_oracle_cppflags="-I$ORACLE_HOME/rdbms/public"
+AC_ARG_WITH([oracle],
+  [AS_HELP_STRING([--with-oracle@<:@=ORACLE_HOME@:>@], [Path to Oracle.])],
+  [
+    if test "x$withval" = "xyes"; then
+      if test "x$ORACLE_HOME" = "x"; then
+        AC_MSG_WARN([Use of the Oracle library has been forced, but the environment variable ORACLE_HOME is not set.])
+      fi
+      with_oracle="yes"
+    else if test "x$withval" = "xno"; then
+      with_oracle="no"
+    else
+      with_oracle="yes"
+      ORACLE_HOME="$withval"
+    fi; fi
+  ],
+  [
+    if test "x$ORACLE_HOME" = "x"; then
+      with_oracle="no (ORACLE_HOME is not set)"
+    else
+      with_oracle="yes"
+    fi
+  ]
+)
 
-       if test -e "$ORACLE_HOME/lib/ldflags"
-       then
-               with_oracle_libs=`cat "$ORACLE_HOME/lib/ldflags"`
-       fi
-       #with_oracle_libs="-L$ORACLE_HOME/lib $with_oracle_libs -lclntsh"
-       with_oracle_libs="-L$ORACLE_HOME/lib -lclntsh"
+if test "x$ORACLE_HOME" != "x"; then
+  with_oracle_cppflags="-I$ORACLE_HOME/rdbms/public"
+  if test -e "$ORACLE_HOME/lib/ldflags"; then
+    with_oracle_libs=`cat "$ORACLE_HOME/lib/ldflags"`
+  fi
+  with_oracle_libs="-L$ORACLE_HOME/lib -lclntsh"
 fi
-if test "x$with_oracle" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_oracle_cppflags"
 
-       AC_CHECK_HEADERS(oci.h, [with_oracle="yes"], [with_oracle="no (oci.h not found)"])
+if test "x$with_oracle" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_oracle_cppflags"
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
+  AC_CHECK_HEADERS([oci.h],
+    [with_oracle="yes"],
+    [with_oracle="no (oci.h not found)"]
+  )
+
+  CPPFLAGS="$SAVE_CPPFLAGS"
 fi
-if test "x$with_oracle" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       SAVE_LIBS="$LIBS"
-       CPPFLAGS="$CPPFLAGS $with_oracle_cppflags"
-       LIBS="$LIBS $with_oracle_libs"
 
-       AC_CHECK_FUNC(OCIEnvCreate, [with_oracle="yes"], [with_oracle="no (Symbol 'OCIEnvCreate' not found)"])
+if test "x$with_oracle" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  SAVE_LIBS="$LIBS"
+  CPPFLAGS="$CPPFLAGS $with_oracle_cppflags"
+  LIBS="$LIBS $with_oracle_libs"
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
-       LIBS="$SAVE_LIBS"
+  AC_CHECK_FUNC([OCIEnvCreate],
+    [with_oracle="yes"],
+    [with_oracle="no (Symbol 'OCIEnvCreate' not found)"]
+  )
+
+  CPPFLAGS="$SAVE_CPPFLAGS"
+  LIBS="$SAVE_LIBS"
 fi
-if test "x$with_oracle" = "xyes"
-then
-       BUILD_WITH_ORACLE_CPPFLAGS="$with_oracle_cppflags"
-       BUILD_WITH_ORACLE_LIBS="$with_oracle_libs"
-       AC_SUBST(BUILD_WITH_ORACLE_CPPFLAGS)
-       AC_SUBST(BUILD_WITH_ORACLE_LIBS)
+
+if test "x$with_oracle" = "xyes"; then
+  BUILD_WITH_ORACLE_CPPFLAGS="$with_oracle_cppflags"
+  BUILD_WITH_ORACLE_LIBS="$with_oracle_libs"
 fi
+
+AC_SUBST([BUILD_WITH_ORACLE_CPPFLAGS])
+AC_SUBST([BUILD_WITH_ORACLE_LIBS])
 # }}}
 
 # --with-libowcapi {{{
-with_libowcapi_cppflags=""
-with_libowcapi_ldflags=""
-AC_ARG_WITH(libowcapi, [AS_HELP_STRING([--with-libowcapi@<:@=PREFIX@:>@], [Path to libowcapi.])],
-[
-       if test "x$withval" != "xno" && test "x$withval" != "xyes"
-       then
-               with_libowcapi_cppflags="-I$withval/include"
-               with_libowcapi_ldflags="-L$withval/lib"
-               with_libowcapi="yes"
-       else
-               with_libowcapi="$withval"
-       fi
-],
-[
-       with_libowcapi="yes"
-])
-if test "x$with_libowcapi" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_libowcapi_cppflags"
+AC_ARG_WITH([libowcapi],
+  [AS_HELP_STRING([--with-libowcapi@<:@=PREFIX@:>@], [Path to libowcapi.])],
+  [
+    if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
+      with_libowcapi_cppflags="-I$withval/include"
+      with_libowcapi_ldflags="-L$withval/lib"
+      with_libowcapi="yes"
+    else
+      with_libowcapi="$withval"
+    fi
+  ],
+  [with_libowcapi="yes"]
+)
 
-       AC_CHECK_HEADERS(owcapi.h, [with_libowcapi="yes"], [with_libowcapi="no (owcapi.h not found)"])
+if test "x$with_libowcapi" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_libowcapi_cppflags"
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
+  AC_CHECK_HEADERS([owcapi.h],
+    [with_libowcapi="yes"],
+    [with_libowcapi="no (owcapi.h not found)"]
+  )
+
+  CPPFLAGS="$SAVE_CPPFLAGS"
 fi
-if test "x$with_libowcapi" = "xyes"
-then
-       SAVE_LDFLAGS="$LDFLAGS"
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       LDFLAGS="$LDFLAGS $with_libowcapi_ldflags"
-       CPPFLAGS="$with_libowcapi_cppflags"
 
-       AC_CHECK_LIB(owcapi, OW_get, [with_libowcapi="yes"], [with_libowcapi="no (libowcapi not found)"])
+if test "x$with_libowcapi" = "xyes"; then
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $with_libowcapi_ldflags"
 
-       LDFLAGS="$SAVE_LDFLAGS"
-       CPPFLAGS="$SAVE_CPPFLAGS"
+  AC_CHECK_LIB([owcapi], [OW_get],
+    [with_libowcapi="yes"],
+    [with_libowcapi="no (libowcapi not found)"]
+  )
+
+  LDFLAGS="$SAVE_LDFLAGS"
 fi
-if test "x$with_libowcapi" = "xyes"
-then
-       BUILD_WITH_LIBOWCAPI_CPPFLAGS="$with_libowcapi_cppflags"
-       BUILD_WITH_LIBOWCAPI_LDFLAGS="$with_libowcapi_ldflags"
-       BUILD_WITH_LIBOWCAPI_LIBS="-lowcapi"
-       AC_SUBST(BUILD_WITH_LIBOWCAPI_CPPFLAGS)
-       AC_SUBST(BUILD_WITH_LIBOWCAPI_LDFLAGS)
-       AC_SUBST(BUILD_WITH_LIBOWCAPI_LIBS)
+
+if test "x$with_libowcapi" = "xyes"; then
+  BUILD_WITH_LIBOWCAPI_CPPFLAGS="$with_libowcapi_cppflags"
+  BUILD_WITH_LIBOWCAPI_LDFLAGS="$with_libowcapi_ldflags"
+  BUILD_WITH_LIBOWCAPI_LIBS="-lowcapi"
 fi
+
+AC_SUBST([BUILD_WITH_LIBOWCAPI_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBOWCAPI_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBOWCAPI_LIBS])
 # }}}
 
 # --with-libpcap {{{
-AC_ARG_WITH(libpcap, [AS_HELP_STRING([--with-libpcap@<:@=PREFIX@:>@], [Path to libpcap.])],
-[
-       if test "x$withval" != "xno" && test "x$withval" != "xyes"
-       then
-               LDFLAGS="$LDFLAGS -L$withval/lib"
-               CPPFLAGS="$CPPFLAGS -I$withval/include"
-               with_libpcap="yes"
-       else
-               with_libpcap="$withval"
-       fi
-],
-[
-       with_libpcap="yes"
-])
-if test "x$with_libpcap" = "xyes"
-then
-       AC_CHECK_LIB(pcap, pcap_open_live,
-       [
-               AC_DEFINE(HAVE_LIBPCAP, 1, [Define to 1 if you have the pcap library (-lpcap).])
-       ], [with_libpcap="no (libpcap not found)"])
+AC_ARG_WITH([libpcap],
+  [AS_HELP_STRING([--with-libpcap@<:@=PREFIX@:>@], [Path to libpcap.])],
+  [
+    if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
+      with_libpcap_cppflags="-I$withval/include"
+      with_libpcap_ldflags="$LDFLAGS -L$withval/lib"
+      with_libpcap="yes"
+    else
+      with_libpcap="$withval"
+    fi
+  ],
+  [with_libpcap="yes"]
+)
+
+if test "x$with_libpcap" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_libpcap_cppflags"
+
+  AC_CHECK_HEADERS([pcap.h],
+    [with_libpcap="yes"],
+    [with_libpcap="no (pcap.h not found)"]
+  )
+
+  CPPFLAGS="$SAVE_CPPFLAGS"
 fi
-if test "x$with_libpcap" = "xyes"
-then
-       AC_CHECK_HEADERS(pcap.h,,
-                        [with_libpcap="no (pcap.h not found)"])
+
+if test "x$with_libpcap" = "xyes"; then
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $with_libpcap_ldflags"
+
+  AC_CHECK_LIB([pcap], [pcap_open_live],
+    [with_libpcap="yes"],
+    [with_libpcap="no (libpcap not found)"]
+  )
+
+  LDFLAGS="$SAVE_LDFLAGS"
 fi
-if test "x$with_libpcap" = "xyes"
-then
-       AC_CACHE_CHECK([whether libpcap has PCAP_ERROR_IFACE_NOT_UP],
-                      [c_cv_libpcap_have_pcap_error_iface_not_up],
-                      AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
-[[[
-#include <pcap.h>
-]]],
-[[[
-  int val = PCAP_ERROR_IFACE_NOT_UP;
-  return(val);
-]]]
-                      )],
-                      [c_cv_libpcap_have_pcap_error_iface_not_up="yes"],
-                      [c_cv_libpcap_have_pcap_error_iface_not_up="no"]))
-fi
-if test "x$c_cv_libpcap_have_pcap_error_iface_not_up" != "xyes"
-then
-               with_libpcap="no (pcap.h misses PCAP_ERROR_IFACE_NOT_UP)"
+
+if test "x$with_libpcap" = "xyes"; then
+  AC_CACHE_CHECK([whether libpcap has PCAP_ERROR_IFACE_NOT_UP],
+    [c_cv_libpcap_have_pcap_error_iface_not_up],
+    [
+      AC_COMPILE_IFELSE(
+        [
+          AC_LANG_PROGRAM(
+            [[#include <pcap.h>]],
+            [[
+              int val = PCAP_ERROR_IFACE_NOT_UP;
+              return(val);
+            ]]
+          )
+        ],
+        [c_cv_libpcap_have_pcap_error_iface_not_up="yes"],
+        [c_cv_libpcap_have_pcap_error_iface_not_up="no"]
+      )
+    ]
+  )
+fi
+
+if test "x$c_cv_libpcap_have_pcap_error_iface_not_up" != "xyes"; then
+  with_libpcap="no (pcap.h misses PCAP_ERROR_IFACE_NOT_UP)"
+fi
+
+if test "x$with_libpcap" = "xyes"; then
+  BUILD_WITH_LIBPCAP_CPPFLAGS="$with_libpcap_cppflags"
+  BUILD_WITH_LIBPCAP_LDFLAGS="$with_libpcap_ldflags"
+  BUILD_WITH_LIBPCAP_LIBS="-lpcap"
 fi
-AM_CONDITIONAL(BUILD_WITH_LIBPCAP, test "x$with_libpcap" = "xyes")
+
+AC_SUBST([BUILD_WITH_LIBPCAP_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBPCAP_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBPCAP_LIBS])
 # }}}
 
 # --with-libperl {{{
-perl_interpreter="perl"
-AC_ARG_WITH(libperl, [AS_HELP_STRING([--with-libperl@<:@=PREFIX@:>@], [Path to libperl.])],
-[
-       if test -f "$withval" && test -x "$withval"
-       then
-               perl_interpreter="$withval"
-               with_libperl="yes"
-       else if test "x$withval" != "xno" && test "x$withval" != "xyes"
-       then
-               LDFLAGS="$LDFLAGS -L$withval/lib"
-               CPPFLAGS="$CPPFLAGS -I$withval/include"
-               perl_interpreter="$withval/bin/perl"
-               with_libperl="yes"
-       else
-               with_libperl="$withval"
-       fi; fi
-],
-[
-       with_libperl="yes"
-])
+AC_ARG_WITH([libperl],
+  [AS_HELP_STRING([--with-libperl@<:@=PREFIX@:>@], [Path to libperl.])],
+  [
+    if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
+      LDFLAGS="$LDFLAGS -L$withval/lib"
+      CPPFLAGS="$CPPFLAGS -I$withval/include"
+      with_libperl="yes"
+    else
+      with_libperl="$withval"
+    fi
+  ],
+  [with_libperl="yes"]
+)
 
-AC_MSG_CHECKING([for perl])
-perl_interpreter=`which "$perl_interpreter" 2> /dev/null`
-if test -x "$perl_interpreter"
-then
-       AC_MSG_RESULT([yes ($perl_interpreter)])
-else
-       perl_interpreter=""
-       AC_MSG_RESULT([no])
-fi
+AC_ARG_VAR([PERL], [path to Perl interpreter])
+AC_PATH_PROG([PERL], [perl])
 
-AC_SUBST(PERL, "$perl_interpreter")
+if test "x$PERL" = "x"; then
+  with_libperl="no (no Perl interpreter found)"
+fi
 
-if test "x$with_libperl" = "xyes" \
-       && test -n "$perl_interpreter"
-then
+if test "x$with_libperl" = "xyes"; then
   SAVE_CFLAGS="$CFLAGS"
   SAVE_LIBS="$LIBS"
-dnl ARCHFLAGS="" -> disable multi -arch on OSX (see Config_heavy.pl:fetch_string)
-  PERL_CFLAGS=`ARCHFLAGS="" $perl_interpreter -MExtUtils::Embed -e perl_inc`
-  PERL_LIBS=`ARCHFLAGS="" $perl_interpreter -MExtUtils::Embed -e ldopts`
+  dnl ARCHFLAGS="" -> disable multi -arch on OSX (see Config_heavy.pl:fetch_string)
+  PERL_CFLAGS=`ARCHFLAGS="" $PERL -MExtUtils::Embed -e perl_inc`
+  PERL_LIBS=`ARCHFLAGS="" $PERL -MExtUtils::Embed -e ldopts`
   CFLAGS="$CFLAGS $PERL_CFLAGS"
   LIBS="$LIBS $PERL_LIBS"
 
   AC_CACHE_CHECK([for libperl],
     [c_cv_have_libperl],
-    AC_LINK_IFELSE([AC_LANG_PROGRAM(
-[[[
-#define PERL_NO_GET_CONTEXT
-#include <EXTERN.h>
-#include <perl.h>
-#include <XSUB.h>
-]]],
-[[[
-       dTHX;
-       load_module (PERL_LOADMOD_NOIMPORT,
-                        newSVpv ("Collectd::Plugin::FooBar", 24),
-                        Nullsv);
-]]]
-      )],
-      [c_cv_have_libperl="yes"],
-      [c_cv_have_libperl="no"]
-    )
+    [
+      AC_LINK_IFELSE(
+        [
+          AC_LANG_PROGRAM(
+            [[
+              #define PERL_NO_GET_CONTEXT
+              #include <EXTERN.h>
+              #include <perl.h>
+              #include <XSUB.h>
+            ]],
+            [[
+              dTHX;
+              load_module (PERL_LOADMOD_NOIMPORT,
+                newSVpv ("Collectd::Plugin::FooBar", 24),
+                Nullsv);
+            ]]
+          )
+        ],
+        [c_cv_have_libperl="yes"],
+        [c_cv_have_libperl="no"]
+      )
+    ]
   )
 
-  if test "x$c_cv_have_libperl" = "xyes"
-  then
-         AC_DEFINE(HAVE_LIBPERL, 1, [Define if libperl is present and usable.])
-         AC_SUBST(PERL_CFLAGS)
-         AC_SUBST(PERL_LIBS)
-  else
-         with_libperl="no"
-  fi
-
   CFLAGS="$SAVE_CFLAGS"
   LIBS="$SAVE_LIBS"
-else if test -z "$perl_interpreter"; then
-  with_libperl="no (no perl interpreter found)"
-  c_cv_have_libperl="no"
-fi; fi
-AM_CONDITIONAL(BUILD_WITH_LIBPERL, test "x$with_libperl" = "xyes")
-
-if test "x$with_libperl" = "xyes"
-then
-       SAVE_CFLAGS="$CFLAGS"
-       SAVE_LIBS="$LIBS"
-       CFLAGS="$CFLAGS $PERL_CFLAGS"
-       LIBS="$LIBS $PERL_LIBS"
-
-       AC_CACHE_CHECK([if perl supports ithreads],
-               [c_cv_have_perl_ithreads],
-               AC_LINK_IFELSE([AC_LANG_PROGRAM(
-[[[
-#include <EXTERN.h>
-#include <perl.h>
-#include <XSUB.h>
-
-#if !defined(USE_ITHREADS)
-# error "Perl does not support ithreads!"
-#endif /* !defined(USE_ITHREADS) */
-]]],
-[[[ ]]]
-                       )],
-                       [c_cv_have_perl_ithreads="yes"],
-                       [c_cv_have_perl_ithreads="no"]
-               )
-       )
-
-       if test "x$c_cv_have_perl_ithreads" = "xyes"
-       then
-               AC_DEFINE(HAVE_PERL_ITHREADS, 1, [Define if Perl supports ithreads.])
-       fi
 
-       CFLAGS="$SAVE_CFLAGS"
-       LIBS="$SAVE_LIBS"
+  if test "x$c_cv_have_libperl" = "xno"; then
+    with_libperl="no"
+  fi
 fi
 
-if test "x$with_libperl" = "xyes"
-then
-       SAVE_CFLAGS="$CFLAGS"
-       SAVE_LIBS="$LIBS"
-       # trigger an error if Perl_load_module*() uses __attribute__nonnull__(3)
-       # (see issues #41 and #42)
-       CFLAGS="$CFLAGS $PERL_CFLAGS -Wall -Werror"
-       LIBS="$LIBS $PERL_LIBS"
-
-       AC_CACHE_CHECK([for broken Perl_load_module()],
-               [c_cv_have_broken_perl_load_module],
-               AC_LINK_IFELSE([AC_LANG_PROGRAM(
-[[[
-#define PERL_NO_GET_CONTEXT
-#include <EXTERN.h>
-#include <perl.h>
-#include <XSUB.h>
-]]],
-[[[
-                        dTHX;
-                        load_module (PERL_LOADMOD_NOIMPORT,
-                            newSVpv ("Collectd::Plugin::FooBar", 24),
-                            Nullsv);
-]]]
-                       )],
-                       [c_cv_have_broken_perl_load_module="no"],
-                       [c_cv_have_broken_perl_load_module="yes"]
-               )
-       )
-
-       CFLAGS="$SAVE_CFLAGS"
-       LIBS="$SAVE_LIBS"
-fi
-AM_CONDITIONAL(HAVE_BROKEN_PERL_LOAD_MODULE,
-               test "x$c_cv_have_broken_perl_load_module" = "xyes")
-
-if test "x$with_libperl" = "xyes"
-then
-       SAVE_CFLAGS="$CFLAGS"
-       SAVE_LIBS="$LIBS"
-       CFLAGS="$CFLAGS $PERL_CFLAGS"
-       LIBS="$LIBS $PERL_LIBS"
-
-       AC_CHECK_MEMBER(
-               [struct mgvtbl.svt_local],
-               [have_struct_mgvtbl_svt_local="yes"],
-               [have_struct_mgvtbl_svt_local="no"],
-               [
-#include <EXTERN.h>
-#include <perl.h>
-#include <XSUB.h>
-               ])
-
-       if test "x$have_struct_mgvtbl_svt_local" = "xyes"
-       then
-               AC_DEFINE(HAVE_PERL_STRUCT_MGVTBL_SVT_LOCAL, 1,
-                                 [Define if Perl's struct mgvtbl has member svt_local.])
-       fi
-
-       CFLAGS="$SAVE_CFLAGS"
-       LIBS="$SAVE_LIBS"
-fi
-# }}}
+if test "x$with_libperl" = "xyes"; then
+  SAVE_CFLAGS="$CFLAGS"
+  SAVE_LIBS="$LIBS"
+  CFLAGS="$CFLAGS $PERL_CFLAGS"
+  LIBS="$LIBS $PERL_LIBS"
 
-# --with-libpq {{{
-with_pg_config="pg_config"
-with_libpq_includedir=""
-with_libpq_libdir=""
-with_libpq_cppflags=""
-with_libpq_ldflags=""
-AC_ARG_WITH(libpq, [AS_HELP_STRING([--with-libpq@<:@=PREFIX@:>@],
-       [Path to libpq.])],
-[
-       if test "x$withval" = "xno"
-       then
-               with_libpq="no"
-       else if test "x$withval" = "xyes"
-       then
-               with_libpq="yes"
-       else
-               if test -f "$withval" && test -x "$withval";
-               then
-                       with_pg_config="$withval"
-               else if test -x "$withval/bin/pg_config"
-               then
-                       with_pg_config="$withval/bin/pg_config"
-               fi; fi
-               with_libpq="yes"
-       fi; fi
-],
-[
-       with_libpq="yes"
-])
-if test "x$with_libpq" = "xyes"
-then
-       with_libpq_includedir=`$with_pg_config --includedir 2> /dev/null`
-       pg_config_status=$?
+  AC_CACHE_CHECK([if Perl supports ithreads],
+    [c_cv_have_perl_ithreads],
+    [
+      AC_LINK_IFELSE(
+        [
+          AC_LANG_PROGRAM(
+            [[
+              #include <EXTERN.h>
+              #include <perl.h>
+              #include <XSUB.h>
+
+              #if !defined(USE_ITHREADS)
+              # error "Perl does not support ithreads!"
+              #endif /* !defined(USE_ITHREADS) */
+            ]],
+            []
+          )
+        ],
+        [c_cv_have_perl_ithreads="yes"],
+        [c_cv_have_perl_ithreads="no"]
+      )
+    ]
+  )
 
-       if test $pg_config_status -eq 0
-       then
-               if test -n "$with_libpq_includedir"; then
-                       for dir in $with_libpq_includedir; do
-                               with_libpq_cppflags="$with_libpq_cppflags -I$dir"
-                       done
-               fi
-       else
-               AC_MSG_WARN([$with_pg_config returned with status $pg_config_status])
-       fi
+  CFLAGS="$SAVE_CFLAGS"
+  LIBS="$SAVE_LIBS"
+fi
 
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_libpq_cppflags"
+if test "x$with_libperl" = "xyes"; then
+  # trigger an error if Perl_load_module*() uses __attribute__nonnull__(3)
+  # (see issues #41 and #42)
+  SAVE_CFLAGS="$CFLAGS"
+  SAVE_LIBS="$LIBS"
+  CFLAGS="$CFLAGS $PERL_CFLAGS -Wall -Werror"
+  LIBS="$LIBS $PERL_LIBS"
 
-       AC_CHECK_HEADERS(libpq-fe.h, [],
-               [with_libpq="no (libpq-fe.h not found)"], [])
+  AC_CACHE_CHECK([for broken Perl_load_module()],
+    [c_cv_have_broken_perl_load_module],
+    [
+      AC_LINK_IFELSE(
+        [
+          AC_LANG_PROGRAM(
+            [[
+              #define PERL_NO_GET_CONTEXT
+              #include <EXTERN.h>
+              #include <perl.h>
+              #include <XSUB.h>
+            ]],
+            [[
+              dTHX;
+              load_module (PERL_LOADMOD_NOIMPORT,
+                newSVpv ("Collectd::Plugin::FooBar", 24),
+                Nullsv);
+            ]]
+          )
+        ],
+        [c_cv_have_broken_perl_load_module="no"],
+        [c_cv_have_broken_perl_load_module="yes"]
+      )
+    ]
+  )
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
+  CFLAGS="$SAVE_CFLAGS"
+  LIBS="$SAVE_LIBS"
 fi
-if test "x$with_libpq" = "xyes"
-then
-       with_libpq_libdir=`$with_pg_config --libdir 2> /dev/null`
-       pg_config_status=$?
 
-       if test $pg_config_status -eq 0
-       then
-               if test -n "$with_libpq_libdir"; then
-                       for dir in $with_libpq_libdir; do
-                               with_libpq_ldflags="$with_libpq_ldflags -L$dir"
-                       done
-               fi
-       else
-               AC_MSG_WARN([$with_pg_config returned with status $pg_config_status])
-       fi
+if test "x$c_cv_have_broken_perl_load_module" = "xyes"; then
+  PERL_CFLAGS="$PERL_CFLAGS -Wno-nonnull"
+fi
 
-       SAVE_LDFLAGS="$LDFLAGS"
-       LDFLAGS="$LDFLAGS $with_libpq_ldflags"
+if test "x$with_libperl" = "xyes"; then
+  SAVE_CFLAGS="$CFLAGS"
+  SAVE_LIBS="$LIBS"
+  CFLAGS="$CFLAGS $PERL_CFLAGS"
+  LIBS="$LIBS $PERL_LIBS"
 
-       AC_CHECK_LIB(pq, PQconnectdb,
-               [with_libpq="yes"],
-               [with_libpq="no (symbol 'PQconnectdb' not found)"])
+  AC_CHECK_MEMBER(
+    [struct mgvtbl.svt_local],
+    [have_struct_mgvtbl_svt_local="yes"],
+    [have_struct_mgvtbl_svt_local="no"],
+    [[
+      #include <EXTERN.h>
+      #include <perl.h>
+      #include <XSUB.h>
+    ]]
+  )
 
-       AC_CHECK_LIB(pq, PQserverVersion,
-               [with_libpq="yes"],
-               [with_libpq="no (symbol 'PQserverVersion' not found)"])
+  if test "x$have_struct_mgvtbl_svt_local" = "xyes"; then
+    AC_DEFINE([HAVE_PERL_STRUCT_MGVTBL_SVT_LOCAL], [1], [Define if Perls struct mgvtbl has member svt_local.])
+  fi
 
-       LDFLAGS="$SAVE_LDFLAGS"
+  CFLAGS="$SAVE_CFLAGS"
+  LIBS="$SAVE_LIBS"
 fi
-if test "x$with_libpq" = "xyes"
-then
-       BUILD_WITH_LIBPQ_CPPFLAGS="$with_libpq_cppflags"
-       BUILD_WITH_LIBPQ_LDFLAGS="$with_libpq_ldflags"
-       AC_SUBST(BUILD_WITH_LIBPQ_CPPFLAGS)
-       AC_SUBST(BUILD_WITH_LIBPQ_LDFLAGS)
+AC_SUBST([PERL_CFLAGS])
+AC_SUBST([PERL_LIBS])
+
+# }}}
+
+# --with-libpq {{{
+with_pg_config="pg_config"
+AC_ARG_WITH([libpq],
+  [AS_HELP_STRING([--with-libpq@<:@=PREFIX@:>@], [Path to libpq.])],
+  [
+    if test "x$withval" = "xno" || test "x$withval" = "xyes"; then
+      with_libpq="$withval"
+    else
+      if test -f "$withval" && test -x "$withval"; then
+        with_pg_config="$withval"
+      else if test -x "$withval/bin/pg_config"; then
+        with_pg_config="$withval/bin/pg_config"
+      fi; fi
+      with_libpq="yes"
+    fi
+  ],
+  [with_libpq="yes"]
+)
+
+if test "x$with_libpq" = "xyes"; then
+  with_libpq_includedir=`$with_pg_config --includedir 2> /dev/null`
+  pg_config_status=$?
+
+  if test $pg_config_status -eq 0; then
+    if test -n "$with_libpq_includedir"; then
+      for dir in $with_libpq_includedir; do
+        with_libpq_cppflags="$with_libpq_cppflags -I$dir"
+      done
+    fi
+  else
+    AC_MSG_WARN([$with_pg_config returned with status $pg_config_status])
+  fi
+
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_libpq_cppflags"
+
+  AC_CHECK_HEADERS([libpq-fe.h],
+    [with_libpq="yes"],
+    [with_libpq="no (libpq-fe.h not found)"]
+  )
+
+  CPPFLAGS="$SAVE_CPPFLAGS"
+fi
+
+if test "x$with_libpq" = "xyes"; then
+  with_libpq_libdir=`$with_pg_config --libdir 2> /dev/null`
+  pg_config_status=$?
+
+  if test $pg_config_status -eq 0
+  then
+    if test -n "$with_libpq_libdir"; then
+      for dir in $with_libpq_libdir; do
+        with_libpq_ldflags="$with_libpq_ldflags -L$dir"
+      done
+    fi
+  else
+    AC_MSG_WARN([$with_pg_config returned with status $pg_config_status])
+  fi
+
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $with_libpq_ldflags"
+
+  AC_CHECK_LIB([pq], [PQserverVersion],
+    [with_libpq="yes"],
+    [with_libpq="no (symbol 'PQserverVersion' not found)"])
+
+  LDFLAGS="$SAVE_LDFLAGS"
+fi
+
+if test "x$with_libpq" = "xyes"; then
+  BUILD_WITH_LIBPQ_CPPFLAGS="$with_libpq_cppflags"
+  BUILD_WITH_LIBPQ_LDFLAGS="$with_libpq_ldflags"
+  BUILD_WITH_LIBPQ_LIBS="-lpq"
 fi
-AM_CONDITIONAL(BUILD_WITH_LIBPQ, test "x$with_libpq" = "xyes")
+
+AC_SUBST([BUILD_WITH_LIBPQ_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBPQ_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBPQ_LIBS])
 # }}}
 
 # --with-libpqos {{{
@@ -4257,31 +4263,29 @@ fi
 # --with-libprotobuf {{{
 with_libprotobuf_cppflags=""
 with_libprotobuf_ldflags=""
-AC_ARG_WITH([libprotobuf], [AS_HELP_STRING([--with-libprotobuf@<:@=PREFIX@:>@], [Path to libprotobuf.])],
+AC_ARG_WITH([libprotobuf],
+  [AS_HELP_STRING([--with-libprotobuf@<:@=PREFIX@:>@], [Path to libprotobuf.])],
   [
-    if test "x$withval" != "xno" && test "x$withval" != "xyes"
-    then
+    if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
       with_libprotobuf_cppflags="-I$withval/include"
       with_libprotobuf_ldflags="-L$withval/lib"
       with_libprotobuf="yes"
     fi
-    if test "x$withval" = "xno"
-    then
+    if test "x$withval" = "xno"; then
       with_libprotobuf="no (disabled on command line)"
     fi
   ],
   [withval="yes"]
 )
-if test "x$withval" = "xyes"
-then
-PKG_CHECK_MODULES([PROTOBUF], [protobuf],
-  [with_libprotobuf="yes"],
-  [with_libprotobuf="no (pkg-config could not find libprotobuf)"]
-)
+
+if test "x$withval" = "xyes"; then
+  PKG_CHECK_MODULES([PROTOBUF], [protobuf],
+    [with_libprotobuf="yes"],
+    [with_libprotobuf="no (pkg-config could not find libprotobuf)"]
+  )
 fi
 
-if test "x$withval" != "xno"
-then
+if test "x$withval" != "xno"; then
   SAVE_LDFLAGS="$LDFLAGS"
   SAVE_LIBS="$LIBS"
   LDFLAGS="$with_libprotobuf_ldflags"
@@ -4307,6 +4311,7 @@ then
   LDFLAGS="$SAVE_LDFLAGS"
   LIBS="$SAVE_LIBS"
 fi
+
 BUILD_WITH_LIBPROTOBUF_CPPFLAGS="$with_libprotobuf_cppflags $PROTOBUF_CFLAGS"
 BUILD_WITH_LIBPROTOBUF_LDFLAGS="$with_libprotobuf_ldflags"
 BUILD_WITH_LIBPROTOBUF_LIBS="$PROTOBUF_LIBS"
@@ -4315,34 +4320,46 @@ AC_SUBST([BUILD_WITH_LIBPROTOBUF_LDFLAGS])
 AC_SUBST([BUILD_WITH_LIBPROTOBUF_LIBS])
 # }}}
 
+AC_ARG_VAR([PROTOC], [path to the protoc binary])
+AC_PATH_PROG([PROTOC], [protoc])
+have_protoc3="no"
+if test "x$PROTOC" != "x"; then
+  AC_MSG_CHECKING([for protoc 3.0.0+])
+  if $PROTOC --version | $EGREP libprotoc.3 >/dev/null; then
+    protoc3="yes (`$PROTOC --version`)"
+    have_protoc3="yes"
+  else
+    protoc3="no (`$PROTOC --version`)"
+  fi
+  AC_MSG_RESULT([$protoc3])
+fi
+AM_CONDITIONAL([HAVE_PROTOC3], [test "x$have_protoc3" = "xyes"])
+
 # --with-libprotobuf-c {{{
-with_libprotobuf_c_cppflags=""
-with_libprotobuf_c_ldflags=""
-AC_ARG_WITH([libprotobuf-c], [AS_HELP_STRING([--with-libprotobuf-c@<:@=PREFIX@:>@], [Path to libprotobuf-c.])],
+AC_ARG_WITH([libprotobuf-c],
+  [AS_HELP_STRING([--with-libprotobuf-c@<:@=PREFIX@:>@], [Path to libprotobuf-c.])],
   [
-    if test "x$withval" != "xno" && test "x$withval" != "xyes"
-    then
+    if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
       with_libprotobuf_c_cppflags="-I$withval/include"
       with_libprotobuf_c_ldflags="-L$withval/lib"
       with_libprotobuf_c="yes"
     fi
-    if test "x$withval" = "xno"
-    then
+
+    if test "x$withval" = "xno"; then
       with_libprotobuf_c="no (disabled on command line)"
     fi
   ],
   [withval="yes"]
 )
-if test "x$withval" = "xyes"
-then
-PKG_CHECK_MODULES([PROTOBUF_C], [libprotobuf-c],
-  [with_libprotobuf_c="yes"],
-  [with_libprotobuf_c="no (pkg-config could not find libprotobuf-c)"]
-)
+
+if test "x$withval" = "xyes"; then
+  PKG_CHECK_MODULES([PROTOBUF_C], [libprotobuf-c],
+    [with_libprotobuf_c="yes"],
+    [with_libprotobuf_c="no (pkg-config could not find libprotobuf-c)"]
+  )
 fi
 
-if test "x$withval" != "xno"
-then
+if test "x$withval" != "xno"; then
   SAVE_LDFLAGS="$LDFLAGS"
   SAVE_LIBS="$LIBS"
   LDFLAGS="$with_libprotobuf_c_ldflags"
@@ -4351,10 +4368,10 @@ then
     [
       SAVE_CPPFLAGS="$CPPFLAGS"
       CPPFLAGS="$with_libprotobuf_c_cppflags $PROTOBUF_C_CFLAGS"
-      if test "x$PROTOBUF_C_LIBS" = "x"
-      then
+      if test "x$PROTOBUF_C_LIBS" = "x"; then
         PROTOBUF_C_LIBS="-lprotobuf-c"
       fi
+
       AC_CHECK_HEADERS([protobuf-c/protobuf-c.h google/protobuf-c/protobuf-c.h],
         [
           with_libprotobuf_c="yes"
@@ -4362,6 +4379,7 @@ then
         ],
         [with_libprotobuf_c="no (<protobuf-c.h> not found)"]
       )
+
       CPPFLAGS="$SAVE_CPPFLAGS"
     ],
     [with_libprotobuf_c="no (libprotobuf-c not found)"]
@@ -4369,6 +4387,7 @@ then
   LDFLAGS="$SAVE_LDFLAGS"
   LIBS="$SAVE_LIBS"
 fi
+
 BUILD_WITH_LIBPROTOBUF_C_CPPFLAGS="$with_libprotobuf_c_cppflags $PROTOBUF_C_CFLAGS"
 BUILD_WITH_LIBPROTOBUF_C_LDFLAGS="$with_libprotobuf_c_ldflags"
 BUILD_WITH_LIBPROTOBUF_C_LIBS="$PROTOBUF_C_LIBS"
@@ -4377,18 +4396,26 @@ AC_SUBST([BUILD_WITH_LIBPROTOBUF_C_LDFLAGS])
 AC_SUBST([BUILD_WITH_LIBPROTOBUF_C_LIBS])
 # }}}
 
+AC_ARG_VAR([PROTOC_C], [path to the protoc-c binary])
+AC_PATH_PROG([PROTOC_C], [protoc-c])
+if test "x$PROTOC_C" = "x"
+then
+  have_protoc_c="no (protoc-c compiler not found)"
+else
+  have_protoc_c="yes"
+fi
+
 # --with-libpython {{{
 AC_ARG_VAR([LIBPYTHON_CPPFLAGS], [Preprocessor flags for libpython])
 AC_ARG_VAR([LIBPYTHON_LDFLAGS], [Linker flags for libpython])
 AC_ARG_VAR([LIBPYTHON_LIBS], [Libraries for libpython])
 
 AC_ARG_WITH([libpython],
-  [AS_HELP_STRING([--with-libpython],
-    [if we should build with libpython @<:@default=yes@:>@])
-  ],
+  [AS_HELP_STRING([--with-libpython], [if we should build with libpython @<:@default=yes@:>@])],
   [with_libpython="$withval"],
   [with_libpython="check"]
 )
+
 if test "$with_libpython" != "no"; then
   if test "$LIBPYTHON_CPPFLAGS" = "" && test "$LIBPYTHON_LDFLAGS" = ""; then
     AC_ARG_VAR([PYTHON_CONFIG], [path to python-config])
@@ -4426,6 +4453,7 @@ if test "$with_libpython" != "xno"; then
   CPPFLAGS="$LIBPYTHON_CPPFLAGS $CPPFLAGS"
   LDFLAGS="$LIBPYTHON_LDFLAGS $LDFLAGS"
   LIBS="$LIBPYTHON_LIBS $LIBS"
+
   AC_CHECK_HEADERS([Python.h],
     [
       AC_MSG_CHECKING([for libpython])
@@ -4440,6 +4468,7 @@ if test "$with_libpython" != "xno"; then
     ],
     [with_libpython="no"]
   )
+
   CPPFLAGS="$SAVE_CPPFLAGS"
   LDFLAGS="$SAVE_LDFLAGS"
   LIBS="$SAVE_LIBS"
 # }}} --with-libpython
 
 # --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")
+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"]
+)
 
-with_amqp_tcp_socket="no"
-if test "x$with_librabbitmq" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       SAVE_LDFLAGS="$LDFLAGS"
-       SAVE_LIBS="$LIBS"
-       CPPFLAGS="$CPPFLAGS $with_librabbitmq_cppflags"
-       LDFLAGS="$LDFLAGS $with_librabbitmq_ldflags"
-       LIBS="-lrabbitmq"
-
-       AC_CHECK_HEADERS(amqp_tcp_socket.h amqp_socket.h)
-       AC_CHECK_FUNC(amqp_tcp_socket_new, [with_amqp_tcp_socket="yes"], [with_amqp_tcp_socket="no"])
-       if test "x$with_amqp_tcp_socket" = "xyes"
-       then
-               AC_DEFINE(HAVE_AMQP_TCP_SOCKET, 1,
-                               [Define if librabbitmq provides the new TCP socket interface.])
-       fi
+if test "x$with_librabbitmq" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_librabbitmq_cppflags"
 
-       AC_CHECK_DECLS(amqp_socket_close,
-                               [amqp_socket_close_decl="yes"], [amqp_socket_close_decl="no"],
-                               [[
-#include <amqp.h>
-#ifdef HAVE_AMQP_TCP_SOCKET_H
-# include <amqp_tcp_socket.h>
-#endif
-#ifdef HAVE_AMQP_SOCKET_H
-# include <amqp_socket.h>
-#endif
-                               ]])
+  AC_CHECK_HEADERS([amqp.h],
+    [with_librabbitmq="yes"],
+    [with_librabbitmq="no (amqp.h not found)"]
+  )
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
-       LDFLAGS="$SAVE_LDFLAGS"
-       LIBS="$SAVE_LIBS"
+  CPPFLAGS="$SAVE_CPPFLAGS"
 fi
-# }}}
 
-# --with-librdkafka {{{
-AC_ARG_WITH(librdkafka, [AS_HELP_STRING([--with-librdkafka@<:@=PREFIX@:>@], [Path to librdkafka.])],
-[
-  if test "x$withval" != "xno" && test "x$withval" != "xyes"
-  then
-    with_librdkafka_cppflags="-I$withval/include"
-    with_librdkafka_ldflags="-L$withval/lib"
-    with_librdkafka_rpath="$withval/lib"
-    with_librdkafka="yes"
-  else
-    with_librdkafka="$withval"
-  fi
-],
-[
-  with_librdkafka="yes"
-])
-SAVE_CPPFLAGS="$CPPFLAGS"
-SAVE_LDFLAGS="$LDFLAGS"
+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 :(.
 
-CPPFLAGS="$CPPFLAGS $with_librdkafka_cppflags"
-LDFLAGS="$LDFLAGS $with_librdkafka_ldflags"
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_librabbitmq_cppflags"
 
-if test "x$with_librdkafka" = "xyes"
-then
-       AC_CHECK_HEADERS(librdkafka/rdkafka.h, [with_librdkafka="yes"], [with_librdkafka="no (librdkafka/rdkafka.h not found)"])
-fi
+  AC_CHECK_MEMBERS([amqp_rpc_reply_t.library_errno],
+    [],
+    [],
+    [[
+      #include <stdlib.h>
+      #include <stdio.h>
+      #include <stdint.h>
+      #include <inttypes.h>
+      #include <amqp.h>
+    ]]
+  )
+  CPPFLAGS="$SAVE_CPPFLAGS"
 
-if test "x$with_librdkafka" = "xyes"
-then
-       AC_CHECK_LIB(rdkafka, rd_kafka_new, [with_librdkafka="yes"], [with_librdkafka="no (Symbol 'rd_kafka_new' not found)"])
-  AC_CHECK_LIB(rdkafka, rd_kafka_conf_set_log_cb, [with_librdkafka_log_cb="yes"], [with_librdkafka_log_cb="no"])
-  AC_CHECK_LIB(rdkafka, rd_kafka_set_logger, [with_librdkafka_logger="yes"], [with_librdkafka_logger="no"])
-fi
-if test "x$with_librdkafka" = "xyes"
-then
-       BUILD_WITH_LIBRDKAFKA_CPPFLAGS="$with_librdkafka_cppflags"
-       BUILD_WITH_LIBRDKAFKA_LDFLAGS="$with_librdkafka_ldflags"
-       if test "x$with_librdkafka_rpath" != "x"
-       then
-               BUILD_WITH_LIBRDKAFKA_LIBS="-Wl,-rpath,$with_librdkafka_rpath -lrdkafka"
-       else
-               BUILD_WITH_LIBRDKAFKA_LIBS="-lrdkafka"
-       fi
-       AC_SUBST(BUILD_WITH_LIBRDKAFKA_CPPFLAGS)
-       AC_SUBST(BUILD_WITH_LIBRDKAFKA_LDFLAGS)
-       AC_SUBST(BUILD_WITH_LIBRDKAFKA_LIBS)
-       AC_DEFINE(HAVE_LIBRDKAFKA, 1, [Define if librdkafka is present and usable.])
-  if test "x$with_librdkafka_log_cb" = "xyes"
-  then
-        AC_DEFINE(HAVE_LIBRDKAFKA_LOG_CB, 1, [Define if librdkafka log facility is present and usable.])
-  else if test "x$with_librdkafka_logger" = "xyes"
-  then
-        AC_DEFINE(HAVE_LIBRDKAFKA_LOGGER, 1, [Define if librdkafka log facility is present and usable.])
-  fi; fi
-fi
-CPPFLAGS="$SAVE_CPPFLAGS"
-LDFLAGS="$SAVE_LDFLAGS"
-AM_CONDITIONAL(BUILD_WITH_LIBRDKAFKA, test "x$with_librdkafka" = "xyes")
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $with_librabbitmq_ldflags"
 
-# }}}
+  AC_CHECK_LIB([rabbitmq], [amqp_basic_publish],
+    [with_librabbitmq="yes"],
+    [with_librabbitmq="no (Symbol 'amqp_basic_publish' not found)"]
+  )
 
-# --with-librouteros {{{
-AC_ARG_WITH(librouteros, [AS_HELP_STRING([--with-librouteros@<:@=PREFIX@:>@], [Path to librouteros.])],
-[
- if test "x$withval" = "xyes"
- then
-        with_librouteros="yes"
- else if test "x$withval" = "xno"
- then
-        with_librouteros="no"
- else
-        with_librouteros="yes"
-        LIBROUTEROS_CPPFLAGS="$LIBROUTEROS_CPPFLAGS -I$withval/include"
-        LIBROUTEROS_LDFLAGS="$LIBROUTEROS_LDFLAGS -L$withval/lib"
- fi; fi
-],
-[with_librouteros="yes"])
+  LDFLAGS="$SAVE_LDFLAGS"
+fi
 
-SAVE_CPPFLAGS="$CPPFLAGS"
-SAVE_LDFLAGS="$LDFLAGS"
+if test "x$with_librabbitmq" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  SAVE_LDFLAGS="$LDFLAGS"
+  SAVE_LIBS="$LIBS"
+  CPPFLAGS="$CPPFLAGS $with_librabbitmq_cppflags"
+  LDFLAGS="$LDFLAGS $with_librabbitmq_ldflags"
+  LIBS="-lrabbitmq"
+
+  AC_CHECK_HEADERS([amqp_tcp_socket.h amqp_socket.h])
+  AC_CHECK_FUNC([amqp_tcp_socket_new],
+    [
+      AC_DEFINE([HAVE_AMQP_TCP_SOCKET], [1],
+        [Define if librabbitmq provides the new TCP socket interface.])
+    ]
+  )
 
-CPPFLAGS="$CPPFLAGS $LIBROUTEROS_CPPFLAGS"
-LDFLAGS="$LDFLAGS $LIBROUTEROS_LDFLAGS"
+  AC_CHECK_DECLS([amqp_socket_close],
+    [],
+    [],
+    [[
+      #include <amqp.h>
+      #ifdef HAVE_AMQP_TCP_SOCKET_H
+      # include <amqp_tcp_socket.h>
+      #endif
+      #ifdef HAVE_AMQP_SOCKET_H
+      # include <amqp_socket.h>
+      #endif
+    ]]
+  )
 
-if test "x$with_librouteros" = "xyes"
-then
-       if test "x$LIBROUTEROS_CPPFLAGS" != "x"
-       then
-               AC_MSG_NOTICE([librouteros CPPFLAGS: $LIBROUTEROS_CPPFLAGS])
-       fi
-       AC_CHECK_HEADERS(routeros_api.h,
-       [with_librouteros="yes"],
-       [with_librouteros="no (routeros_api.h not found)"])
+  CPPFLAGS="$SAVE_CPPFLAGS"
+  LDFLAGS="$SAVE_LDFLAGS"
+  LIBS="$SAVE_LIBS"
 fi
-if test "x$with_librouteros" = "xyes"
-then
-       if test "x$LIBROUTEROS_LDFLAGS" != "x"
-       then
-               AC_MSG_NOTICE([librouteros LDFLAGS: $LIBROUTEROS_LDFLAGS])
-       fi
-       AC_CHECK_LIB(routeros, ros_interface,
-       [with_librouteros="yes"],
-       [with_librouteros="no (symbol 'ros_interface' not found)"])
+
+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"
 fi
 
-CPPFLAGS="$SAVE_CPPFLAGS"
-LDFLAGS="$SAVE_LDFLAGS"
+AC_SUBST(BUILD_WITH_LIBRABBITMQ_CPPFLAGS)
+AC_SUBST(BUILD_WITH_LIBRABBITMQ_LDFLAGS)
+AC_SUBST(BUILD_WITH_LIBRABBITMQ_LIBS)
 
-if test "x$with_librouteros" = "xyes"
-then
-       BUILD_WITH_LIBROUTEROS_CPPFLAGS="$LIBROUTEROS_CPPFLAGS"
-       BUILD_WITH_LIBROUTEROS_LDFLAGS="$LIBROUTEROS_LDFLAGS"
-       AC_SUBST(BUILD_WITH_LIBROUTEROS_CPPFLAGS)
-       AC_SUBST(BUILD_WITH_LIBROUTEROS_LDFLAGS)
-fi
-AM_CONDITIONAL(BUILD_WITH_LIBROUTEROS, test "x$with_librouteros" = "xyes")
 # }}}
 
-# --with-librrd {{{
-librrd_cflags=""
-librrd_ldflags=""
-librrd_threadsafe="no"
-librrd_rrdc_update="no"
-AC_ARG_WITH(librrd,
-  [AS_HELP_STRING([--with-librrd@<:@=PREFIX@:>@], [Path to rrdtool.])],
+# --with-librdkafka {{{
+AC_ARG_WITH([librdkafka],
+  [AS_HELP_STRING([--with-librdkafka@<:@=PREFIX@:>@], [Path to librdkafka.])],
   [
-    if test "x$withval" != "xno" && test "x$withval" != "xyes"
-    then
-      librrd_cflags="-I$withval/include"
-      librrd_ldflags="-L$withval/lib"
-      with_librrd="yes"
+    if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
+      with_librdkafka_cppflags="-I$withval/include"
+      with_librdkafka_ldflags="-L$withval/lib"
+      with_librdkafka_rpath="$withval/lib"
+      with_librdkafka="yes"
     else
-      with_librrd="$withval"
+      with_librdkafka="$withval"
     fi
   ],
-  [with_librrd="yes"]
+  [with_librdkafka="yes"]
 )
 
-if test "x$with_librrd" = "xyes"
-then
-  SAVE_LDFLAGS="$LDFLAGS"
-  LDFLAGS="$LDFLAGS $librrd_ldflags"
-  PKG_CHECK_MODULES([RRD], [librrd >= 1.6.0],
-    [
-      AC_CHECK_LIB([rrd], [rrd_update_r],
-        [librrd_threadsafe="yes"],
-        [:]
-      )
-      AC_CHECK_LIB([rrd], [rrdc_update],
-        [librrd_rrdc_update="yes"],
-        [:]
-      )
-    ],[:]
-  )
-  LDFLAGS="$SAVE_LDFLAGS"
-
+if test "x$with_librdkafka" = "xyes"; then
   SAVE_CPPFLAGS="$CPPFLAGS"
-  CPPFLAGS="$CPPFLAGS $RRD_CFLAGS $librrd_cflags"
+  CPPFLAGS="$CPPFLAGS $with_librdkafka_cppflags"
 
-  AC_CHECK_HEADERS([rrd.h],, [with_librrd="no (rrd.h not found)"])
+  AC_CHECK_HEADERS([librdkafka/rdkafka.h],
+    [with_librdkafka="yes"],
+    [with_librdkafka="no (librdkafka/rdkafka.h not found)"]
+  )
 
   CPPFLAGS="$SAVE_CPPFLAGS"
 fi
 
-if test "x$with_librrd" = "xyes" && test "x$librrd_threadsafe" = "xno"
-then
+if test "x$with_librdkafka" = "xyes"; then
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $with_librdkafka_ldflags"
+
+  AC_CHECK_LIB([rdkafka], [rd_kafka_new],
+    [with_librdkafka="yes"],
+    [with_librdkafka="no (Symbol 'rd_kafka_new' not found)"])
+
+  AC_CHECK_LIB([rdkafka], [rd_kafka_conf_set_log_cb],
+    [with_librdkafka_log_cb="yes"],
+    [with_librdkafka_log_cb="no"])
+
+  AC_CHECK_LIB([rdkafka], [rd_kafka_set_logger],
+    [with_librdkafka_logger="yes"],
+    [with_librdkafka_logger="no"]
+  )
+
+  LDFLAGS="$SAVE_LDFLAGS"
+fi
+
+if test "x$with_librdkafka" = "xyes"; then
+  BUILD_WITH_LIBRDKAFKA_CPPFLAGS="$with_librdkafka_cppflags"
+  BUILD_WITH_LIBRDKAFKA_LDFLAGS="$with_librdkafka_ldflags"
+
+  if test "x$with_librdkafka_rpath" != "x"; then
+    BUILD_WITH_LIBRDKAFKA_LIBS="-Wl,-rpath,$with_librdkafka_rpath -lrdkafka"
+  else
+    BUILD_WITH_LIBRDKAFKA_LIBS="-lrdkafka"
+  fi
+
+  if test "x$with_librdkafka_log_cb" = "xyes"; then
+    AC_DEFINE(HAVE_LIBRDKAFKA_LOG_CB, 1, [Define if librdkafka log facility is present and usable.])
+  else if test "x$with_librdkafka_logger" = "xyes"; then
+    AC_DEFINE(HAVE_LIBRDKAFKA_LOGGER, 1, [Define if librdkafka log facility is present and usable.])
+  fi; fi
+fi
+
+AC_SUBST([BUILD_WITH_LIBRDKAFKA_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBRDKAFKA_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBRDKAFKA_LIBS])
+# }}}
+
+# --with-librouteros {{{
+AC_ARG_WITH([librouteros],
+  [AS_HELP_STRING([--with-librouteros@<:@=PREFIX@:>@], [Path to librouteros.])],
+  [
+    if test "x$withval" = "xyes" || test "x$withval" = "xno"; then
+      with_librouteros="$witval"
+    else
+      with_librouteros_cppflags="-I$withval/include"
+      with_librouteros_ldflags="-L$withval/lib"
+      with_librouteros="yes"
+   fi
+  ],
+  [with_librouteros="yes"]
+)
+
+if test "x$with_librouteros" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_librouteros_cppflags"
+
+  AC_CHECK_HEADERS([routeros_api.h],
+    [with_librouteros="yes"],
+    [with_librouteros="no (routeros_api.h not found)"]
+  )
+
+  CPPFLAGS="$SAVE_CPPFLAGS"
+fi
+
+if test "x$with_librouteros" = "xyes"; then
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $with_librouteros_ldflags"
+
+  AC_CHECK_LIB([routeros], [ros_interface],
+    [with_librouteros="yes"],
+    [with_librouteros="no (symbol 'ros_interface' not found)"]
+  )
+
+  LDFLAGS="$SAVE_LDFLAGS"
+fi
+
+if test "x$with_librouteros" = "xyes"; then
+  BUILD_WITH_LIBROUTEROS_CPPFLAGS="$with_librouteros_cppflags"
+  BUILD_WITH_LIBROUTEROS_LDFLAGS="$with_librouteros_ldflags"
+fi
+
+AC_SUBST([BUILD_WITH_LIBROUTEROS_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBROUTEROS_LDFLAGS])
+# }}}
+
+# --with-librrd {{{
+librrd_threadsafe="no"
+librrd_rrdc_update="no"
+AC_ARG_WITH([librrd],
+  [AS_HELP_STRING([--with-librrd@<:@=PREFIX@:>@], [Path to rrdtool.])],
+  [
+    if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
+      librrd_cflags="-I$withval/include"
+      librrd_ldflags="-L$withval/lib"
+      with_librrd="yes"
+    else
+      with_librrd="$withval"
+    fi
+  ],
+  [with_librrd="yes"]
+)
+
+if test "x$with_librrd" = "xyes"; then
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $librrd_ldflags"
+  PKG_CHECK_MODULES([RRD], [librrd >= 1.6.0],
+    [
+      AC_CHECK_LIB([rrd], [rrd_update_r],
+        [librrd_threadsafe="yes"],
+        [:]
+      )
+      AC_CHECK_LIB([rrd], [rrdc_update],
+        [librrd_rrdc_update="yes"],
+        [:]
+      )
+    ],[:]
+  )
+  LDFLAGS="$SAVE_LDFLAGS"
+
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $RRD_CFLAGS $librrd_cflags"
+
+  AC_CHECK_HEADERS([rrd.h],, [with_librrd="no (rrd.h not found)"])
+
+  CPPFLAGS="$SAVE_CPPFLAGS"
+fi
+
+if test "x$with_librrd" = "xyes" && test "x$librrd_threadsafe" = "xno"; then
   SAVE_LDFLAGS="$LDFLAGS"
   LDFLAGS="$LDFLAGS $librrd_ldflags"
 
@@ -4730,8 +4759,7 @@ then
   LDFLAGS="$SAVE_LDFLAGS"
 fi
 
-if test "x$with_librrd" = "xyes" && test "x$librrd_threadsafe" = "xno"
-then
+if test "x$with_librrd" = "xyes" && test "x$librrd_threadsafe" = "xno"; then
   SAVE_LDFLAGS="$LDFLAGS"
   LDFLAGS="$LDFLAGS $librrd_ldflags"
 
@@ -4748,82 +4776,78 @@ then
   LDFLAGS="$SAVE_LDFLAGS"
 fi
 
-if test "x$with_librrd" = "xyes"
-then
+if test "x$with_librrd" = "xyes"; then
   BUILD_WITH_LIBRRD_CFLAGS="$RRD_CFLAGS $librrd_cflags"
   BUILD_WITH_LIBRRD_LDFLAGS="$librrd_ldflags"
   BUILD_WITH_LIBRRD_LIBS="$RRD_LIBS"
-  AC_SUBST(BUILD_WITH_LIBRRD_CFLAGS)
-  AC_SUBST(BUILD_WITH_LIBRRD_LDFLAGS)
-  AC_SUBST(BUILD_WITH_LIBRRD_LIBS)
 fi
-if test "x$librrd_threadsafe" = "xyes"
-then
+
+if test "x$librrd_threadsafe" = "xyes"; then
   AC_DEFINE([HAVE_THREADSAFE_LIBRRD], [1],
     [Define to 1 if the rrd library is thread-safe]
   )
 fi
+
+AC_SUBST([BUILD_WITH_LIBRRD_CFLAGS])
+AC_SUBST([BUILD_WITH_LIBRRD_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBRRD_LIBS])
 # }}}
 
 # --with-libsensors {{{
-with_sensors_cflags=""
-with_sensors_ldflags=""
-AC_ARG_WITH(libsensors, [AS_HELP_STRING([--with-libsensors@<:@=PREFIX@:>@], [Path to lm_sensors.])],
-[
-       if test "x$withval" = "xno"
-       then
-               with_libsensors="no"
-       else
-               with_libsensors="yes"
-               if test "x$withval" != "xyes"
-               then
-                       with_sensors_cflags="-I$withval/include"
-                       with_sensors_ldflags="-L$withval/lib"
-                       with_libsensors="yes"
-               fi
-       fi
-],
-[
-       if test "x$ac_system" = "xLinux"
-       then
-               with_libsensors="yes"
-       else
-               with_libsensors="no (Linux only library)"
-       fi
-])
-if test "x$with_libsensors" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_sensors_cflags"
+AC_ARG_WITH([libsensors],
+  [AS_HELP_STRING([--with-libsensors@<:@=PREFIX@:>@], [Path to lm_sensors.])],
+  [
+    if test "x$withval" = "xno" || test "x$withval" = "xyes"; then
+      with_libsensors="$withval"
+    else
+      with_sensors_cppflags="-I$withval/include"
+      with_sensors_ldflags="-L$withval/lib"
+      with_libsensors="yes"
+    fi
+  ],
+  [
+    if test "x$ac_system" = "xLinux"; then
+      with_libsensors="yes"
+    else
+      with_libsensors="no (Linux only library)"
+    fi
+  ]
+)
 
-       AC_CHECK_HEADERS(sensors/sensors.h, [], [with_libsensors="no (sensors/sensors.h not found)"])
+if test "x$with_libsensors" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_sensors_cppflags"
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
+  AC_CHECK_HEADERS([sensors/sensors.h],
+    [with_libsensors="yes"],
+    [with_libsensors="no (sensors/sensors.h not found)"]
+  )
+
+  CPPFLAGS="$SAVE_CPPFLAGS"
 fi
-if test "x$with_libsensors" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       SAVE_LDFLAGS="$LDFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_sensors_cflags"
-       LDFLAGS="$LDFLAGS $with_sensors_ldflags"
 
-       AC_CHECK_LIB(sensors, sensors_init,
-       [
-               AC_DEFINE(HAVE_LIBSENSORS, 1, [Define to 1 if you have the sensors library (-lsensors).])
-       ],
-       [with_libsensors="no (libsensors not found)"])
+if test "x$with_libsensors" = "xyes"; then
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $with_sensors_ldflags"
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
-       LDFLAGS="$SAVE_LDFLAGS"
+  AC_CHECK_LIB([sensors], [sensors_init],
+    [with_libsensors="yes"],
+    [with_libsensors="no (libsensors not found)"]
+  )
+
+  LDFLAGS="$SAVE_LDFLAGS"
 fi
-if test "x$with_libsensors" = "xyes"
-then
-       BUILD_WITH_LIBSENSORS_CFLAGS="$with_sensors_cflags"
-       BUILD_WITH_LIBSENSORS_LDFLAGS="$with_sensors_ldflags"
-       AC_SUBST(BUILD_WITH_LIBSENSORS_CFLAGS)
-       AC_SUBST(BUILD_WITH_LIBSENSORS_LDFLAGS)
+
+if test "x$with_libsensors" = "xyes"; then
+  BUILD_WITH_LIBSENSORS_CPPFLAGS="$with_sensors_cppflags"
+  BUILD_WITH_LIBSENSORS_LDFLAGS="$with_sensors_ldflags"
+  BUILD_WITH_LIBSENSORS_LIBS="-lsensors"
 fi
-AM_CONDITIONAL(BUILD_WITH_LM_SENSORS, test "x$with_libsensors" = "xyes")
+
+AC_SUBST([BUILD_WITH_LIBSENSORS_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBSENSORS_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBSENSORS_LIBS])
+
 # }}}
 
 # libsigrok {{{
@@ -4836,35 +4860,29 @@ PKG_CHECK_MODULES([LIBSIGROK], [libsigrok < 0.4],
 # }}}
 
 # --with-libstatgrab {{{
-with_libstatgrab_cflags=""
-with_libstatgrab_ldflags=""
-AC_ARG_WITH(libstatgrab, [AS_HELP_STRING([--with-libstatgrab@<:@=PREFIX@:>@], [Path to libstatgrab.])],
-[
- if test "x$withval" != "xno" \
-   && test "x$withval" != "xyes"
- then
-   with_libstatgrab_cflags="-I$withval/include"
-   with_libstatgrab_ldflags="-L$withval/lib -lstatgrab"
-   with_libstatgrab="yes"
-   with_libstatgrab_pkg_config="no"
- else
-   with_libstatgrab="$withval"
-   with_libstatgrab_pkg_config="yes"
- fi
- ],
-[
- with_libstatgrab="yes"
- with_libstatgrab_pkg_config="yes"
-])
+AC_ARG_WITH([libstatgrab],
+  [AS_HELP_STRING([--with-libstatgrab@<:@=PREFIX@:>@], [Path to libstatgrab.])],
+  [
+    if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
+      with_libstatgrab_cflags="-I$withval/include"
+      with_libstatgrab_ldflags="-L$withval/lib -lstatgrab"
+      with_libstatgrab="yes"
+      with_libstatgrab_pkg_config="no"
+    else
+      with_libstatgrab="$withval"
+      with_libstatgrab_pkg_config="yes"
+    fi
+  ],
+  [
+    with_libstatgrab="yes"
+    with_libstatgrab_pkg_config="yes"
+  ])
 
-if test "x$with_libstatgrab" = "xyes" \
-  && test "x$with_libstatgrab_pkg_config" = "xyes"
-then
+if test "x$with_libstatgrab" = "xyes" && test "x$with_libstatgrab_pkg_config" = "xyes"; then
   AC_MSG_CHECKING([pkg-config for libstatgrab])
   temp_result="found"
   $PKG_CONFIG --exists libstatgrab 2>/dev/null
-  if test "$?" != "0"
-  then
+  if test "$?" != "0"; then
     with_libstatgrab_pkg_config="no"
     with_libstatgrab="no (pkg-config doesn't know libstatgrab)"
     temp_result="not found"
@@ -4872,14 +4890,10 @@ then
   AC_MSG_RESULT([$temp_result])
 fi
 
-if test "x$with_libstatgrab" = "xyes" \
-  && test "x$with_libstatgrab_pkg_config" = "xyes" \
-  && test "x$with_libstatgrab_cflags" = "x"
-then
+if test "x$with_libstatgrab" = "xyes" && test "x$with_libstatgrab_pkg_config" = "xyes" && test "x$with_libstatgrab_cflags" = "x"; then
   AC_MSG_CHECKING([for libstatgrab CFLAGS])
   temp_result="`$PKG_CONFIG --cflags libstatgrab`"
-  if test "$?" = "0"
-  then
+  if test "$?" = "0"; then
     with_libstatgrab_cflags="$temp_result"
   else
     with_libstatgrab="no ($PKG_CONFIG --cflags libstatgrab failed)"
@@ -4888,10 +4902,7 @@ then
   AC_MSG_RESULT([$temp_result])
 fi
 
-if test "x$with_libstatgrab" = "xyes" \
-  && test "x$with_libstatgrab_pkg_config" = "xyes" \
-  && test "x$with_libstatgrab_ldflags" = "x"
-then
+if test "x$with_libstatgrab" = "xyes" && test "x$with_libstatgrab_pkg_config" = "xyes" && test "x$with_libstatgrab_ldflags" = "x"; then
   AC_MSG_CHECKING([for libstatgrab LDFLAGS])
   temp_result="`$PKG_CONFIG --libs libstatgrab`"
   if test "$?" = "0"
@@ -4904,36 +4915,31 @@ then
   AC_MSG_RESULT([$temp_result])
 fi
 
-if test "x$with_libstatgrab" = "xyes"
-then
+if test "x$with_libstatgrab" = "xyes"; then
   SAVE_CPPFLAGS="$CPPFLAGS"
   CPPFLAGS="$CPPFLAGS $with_libstatgrab_cflags"
 
-  AC_CHECK_HEADERS(statgrab.h,
-                  [with_libstatgrab="yes"],
-                  [with_libstatgrab="no (statgrab.h not found)"])
+  AC_CHECK_HEADERS([statgrab.h],
+    [with_libstatgrab="yes"],
+    [with_libstatgrab="no (statgrab.h not found)"]
+  )
 
   CPPFLAGS="$SAVE_CPPFLAGS"
 fi
 
-if test "x$with_libstatgrab" = "xyes"
-then
-  SAVE_CFLAGS="$CFLAGS"
+if test "x$with_libstatgrab" = "xyes"; then
   SAVE_LDFLAGS="$LDFLAGS"
-
-  CFLAGS="$CFLAGS $with_libstatgrab_cflags"
   LDFLAGS="$LDFLAGS $with_libstatgrab_ldflags"
 
-  AC_CHECK_LIB(statgrab, sg_init,
-              [with_libstatgrab="yes"],
-              [with_libstatgrab="no (symbol sg_init not found)"])
+  AC_CHECK_LIB([statgrab], [sg_init],
+    [with_libstatgrab="yes"],
+    [with_libstatgrab="no (symbol sg_init not found)"]
+  )
 
-  CFLAGS="$SAVE_CFLAGS"
   LDFLAGS="$SAVE_LDFLAGS"
 fi
 
-if test "x$with_libstatgrab" = "xyes"
-then
+if test "x$with_libstatgrab" = "xyes"; then
   SAVE_CFLAGS="$CFLAGS"
   SAVE_LDFLAGS="$LDFLAGS"
   SAVE_LIBS="$LIBS"
@@ -4943,19 +4949,24 @@ then
   LIBS="-lstatgrab $LIBS"
 
   AC_CACHE_CHECK([if libstatgrab >= 0.90],
-          [c_cv_have_libstatgrab_0_90],
-          AC_LINK_IFELSE([AC_LANG_PROGRAM(
-[[[
-#include <stdio.h>
-#include <statgrab.h>
-]]],
-[[[
-      if (sg_init()) return 0;
-]]]
-    )],
-    [c_cv_have_libstatgrab_0_90="no"],
-    [c_cv_have_libstatgrab_0_90="yes"]
+    [c_cv_have_libstatgrab_0_90],
+    [
+      AC_LINK_IFELSE(
+        [
+          AC_LANG_PROGRAM(
+            [[
+              #include <stdio.h>
+              #include <statgrab.h>
+            ]],
+            [[
+              if (sg_init()) return 0;
+            ]]
           )
+        ],
+        [c_cv_have_libstatgrab_0_90="no"],
+        [c_cv_have_libstatgrab_0_90="yes"]
+      )
+    ]
   )
 
   CFLAGS="$SAVE_CFLAGS"
@@ -4963,832 +4974,797 @@ then
   LIBS="$SAVE_LIBS"
 fi
 
-AM_CONDITIONAL(BUILD_WITH_LIBSTATGRAB, test "x$with_libstatgrab" = "xyes")
-if test "x$with_libstatgrab" = "xyes"
-then
-  AC_DEFINE(HAVE_LIBSTATGRAB, 1, [Define to 1 if you have the 'statgrab' library (-lstatgrab)])
+AM_CONDITIONAL([BUILD_WITH_LIBSTATGRAB], [test "x$with_libstatgrab" = "xyes"])
+
+if test "x$with_libstatgrab" = "xyes"; then
+  AC_DEFINE([HAVE_LIBSTATGRAB], [1],
+    [Define to 1 if you have the 'statgrab' library (-lstatgrab)]
+  )
+
+  if test "x$c_cv_have_libstatgrab_0_90" = "xyes"; then
+    AC_DEFINE([HAVE_LIBSTATGRAB_0_90], [1],
+      [Define to 1 if libstatgrab version >= 0.90]
+    )
+  fi
+
   BUILD_WITH_LIBSTATGRAB_CFLAGS="$with_libstatgrab_cflags"
   BUILD_WITH_LIBSTATGRAB_LDFLAGS="$with_libstatgrab_ldflags"
-  AC_SUBST(BUILD_WITH_LIBSTATGRAB_CFLAGS)
-  AC_SUBST(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
-  if test "x$c_cv_have_libstatgrab_0_90" = "xyes"
-  then
-        AC_DEFINE(HAVE_LIBSTATGRAB_0_90, 1, [Define to 1 if libstatgrab version >= 0.90])
-  fi
+
 fi
+
+AC_SUBST([BUILD_WITH_LIBSTATGRAB_CFLAGS])
+AC_SUBST([BUILD_WITH_LIBSTATGRAB_LDFLAGS])
 # }}}
 
 # --with-libtokyotyrant {{{
-with_libtokyotyrant_cppflags=""
-with_libtokyotyrant_ldflags=""
-with_libtokyotyrant_libs=""
-AC_ARG_WITH(libtokyotyrant, [AS_HELP_STRING([--with-libtokyotyrant@<:@=PREFIX@:>@], [Path to libtokyotyrant.])],
-[
-  if test "x$withval" = "xno"
-  then
-    with_libtokyotyrant="no"
-  else if test "x$withval" = "xyes"
-  then
-    with_libtokyotyrant="yes"
-  else
-    with_libtokyotyrant_cppflags="-I$withval/include"
-    with_libtokyotyrant_ldflags="-L$withval/include"
-    with_libtokyotyrant_libs="-ltokyotyrant"
-    with_libtokyotyrant="yes"
-  fi; fi
-],
-[
-  with_libtokyotyrant="yes"
-])
+AC_ARG_WITH([libtokyotyrant],
+  [AS_HELP_STRING([--with-libtokyotyrant@<:@=PREFIX@:>@], [Path to libtokyotyrant.])],
+  [
+    if test "x$withval" = "xno" || test "x$withval" = "xyes"; then
+      with_libtokyotyrant="$withval"
+    else
+      with_libtokyotyrant_cppflags="-I$withval/include"
+      with_libtokyotyrant_ldflags="-L$withval/include"
+      with_libtokyotyrant_libs="-ltokyotyrant"
+      with_libtokyotyrant="yes"
+    fi
+  ],
+  [with_libtokyotyrant="yes"]
+)
 
-if test "x$with_libtokyotyrant" = "xyes"
-then
-  if $PKG_CONFIG --exists tokyotyrant
-  then
+if test "x$with_libtokyotyrant" = "xyes"; then
+  if $PKG_CONFIG --exists tokyotyrant; then
     with_libtokyotyrant_cppflags="$with_libtokyotyrant_cppflags `$PKG_CONFIG --cflags tokyotyrant`"
     with_libtokyotyrant_ldflags="$with_libtokyotyrant_ldflags `$PKG_CONFIG --libs-only-L tokyotyrant`"
     with_libtokyotyrant_libs="$with_libtokyotyrant_libs `$PKG_CONFIG --libs-only-l tokyotyrant`"
   fi
 fi
 
-SAVE_CPPFLAGS="$CPPFLAGS"
-SAVE_LDFLAGS="$LDFLAGS"
-CPPFLAGS="$CPPFLAGS $with_libtokyotyrant_cppflags"
-LDFLAGS="$LDFLAGS $with_libtokyotyrant_ldflags"
+if test "x$with_libtokyotyrant" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_libtokyotyrant_cppflags"
 
-if test "x$with_libtokyotyrant" = "xyes"
-then
-  AC_CHECK_HEADERS(tcrdb.h,
-  [
-          AC_DEFINE(HAVE_TCRDB_H, 1,
-                    [Define to 1 if you have the <tcrdb.h> header file.])
-  ], [with_libtokyotyrant="no (tcrdb.h not found)"])
-fi
+  AC_CHECK_HEADERS([tcrdb.h],
+    [with_libtokyotyrant="yes"],
+    [with_libtokyotyrant="no (tcrdb.h not found)"]
+  )
 
-if test "x$with_libtokyotyrant" = "xyes"
-then
-  AC_CHECK_LIB(tokyotyrant, tcrdbrnum,
-  [
-          AC_DEFINE(HAVE_LIBTOKYOTYRANT, 1,
-                    [Define to 1 if you have the tokyotyrant library (-ltokyotyrant).])
-  ],
-  [with_libtokyotyrant="no (symbol tcrdbrnum not found)"],
-  [$with_libtokyotyrant_libs])
+  CPPFLAGS="$SAVE_CPPFLAGS"
 fi
 
-CPPFLAGS="$SAVE_CPPFLAGS"
-LDFLAGS="$SAVE_LDFLAGS"
+if test "x$with_libtokyotyrant" = "xyes"; then
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $with_libtokyotyrant_ldflags"
 
-if test "x$with_libtokyotyrant" = "xyes"
-then
+  AC_CHECK_LIB([tokyotyrant], [tcrdbrnum],
+    [with_libtokyotyrant="yes"],
+    [with_libtokyotyrant="no (symbol tcrdbrnum not found)"],
+    [$with_libtokyotyrant_libs]
+  )
+
+  LDFLAGS="$SAVE_LDFLAGS"
+fi
+
+if test "x$with_libtokyotyrant" = "xyes"; then
   BUILD_WITH_LIBTOKYOTYRANT_CPPFLAGS="$with_libtokyotyrant_cppflags"
   BUILD_WITH_LIBTOKYOTYRANT_LDFLAGS="$with_libtokyotyrant_ldflags"
   BUILD_WITH_LIBTOKYOTYRANT_LIBS="$with_libtokyotyrant_libs"
-  AC_SUBST(BUILD_WITH_LIBTOKYOTYRANT_CPPFLAGS)
-  AC_SUBST(BUILD_WITH_LIBTOKYOTYRANT_LDFLAGS)
-  AC_SUBST(BUILD_WITH_LIBTOKYOTYRANT_LIBS)
 fi
-AM_CONDITIONAL(BUILD_WITH_LIBTOKYOTYRANT, test "x$with_libtokyotyrant" = "xyes")
+AC_SUBST([BUILD_WITH_LIBTOKYOTYRANT_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBTOKYOTYRANT_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBTOKYOTYRANT_LIBS])
 # }}}
 
 # --with-libudev {{{
-with_libudev_cflags=""
-with_libudev_ldflags=""
-AC_ARG_WITH(libudev, [AS_HELP_STRING([--with-libudev@<:@=PREFIX@:>@], [Path to libudev.])],
-[
-       if test "x$withval" = "xno"
-       then
-               with_libudev="no"
-       else
-               with_libudev="yes"
-               if test "x$withval" != "xyes"
-               then
-                       with_libudev_cflags="-I$withval/include"
-                       with_libudev_ldflags="-L$withval/lib"
-                       with_libudev="yes"
-               fi
-       fi
-],
-[
-       if test "x$ac_system" = "xLinux"
-       then
-               with_libudev="yes"
-       else
-               with_libudev="no (Linux only library)"
-       fi
-])
-if test "x$with_libudev" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_libudev_cflags"
+AC_ARG_WITH([libudev],
+  [AS_HELP_STRING([--with-libudev@<:@=PREFIX@:>@], [Path to libudev.])],
+  [
+    if test "x$withval" = "xno" || test "x$withval" = "xyes"; then
+      with_libudev="$withval"
+    else
+      with_libudev_cppflags="-I$withval/include"
+      with_libudev_ldflags="-L$withval/lib"
+      with_libudev="yes"
+    fi
+  ],
+  [
+    if test "x$ac_system" = "xLinux"; then
+      with_libudev="yes"
+    else
+      with_libudev="no (Linux only library)"
+    fi
+  ]
+)
+
+if test "x$with_libudev" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_libudev_cppflags"
 
-       AC_CHECK_HEADERS(libudev.h, [], [with_libudev="no (libudev.h not found)"])
+  AC_CHECK_HEADERS([libudev.h],
+    [with_libudev="yes"],
+    [with_libudev="no (libudev.h not found)"]
+  )
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
+  CPPFLAGS="$SAVE_CPPFLAGS"
 fi
-if test "x$with_libudev" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       SAVE_LDFLAGS="$LDFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_libudev_cflags"
-       LDFLAGS="$LDFLAGS $with_libudev_ldflags"
 
-       AC_CHECK_LIB(udev, udev_new,
-       [
-               AC_DEFINE(HAVE_LIBUDEV, 1, [Define to 1 if you have the udev library (-ludev).])
-       ],
-       [with_libudev="no (libudev not found)"])
+if test "x$with_libudev" = "xyes"; then
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $with_libudev_ldflags"
+
+  AC_CHECK_LIB([udev], [udev_new],
+    [with_libudev="yes"],
+    [with_libudev="no (libudev not found)"]
+  )
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
-       LDFLAGS="$SAVE_LDFLAGS"
+  LDFLAGS="$SAVE_LDFLAGS"
 fi
-if test "x$with_libudev" = "xyes"
-then
-       BUILD_WITH_LIBUDEV_CFLAGS="$with_libudev_cflags"
-       BUILD_WITH_LIBUDEV_LDFLAGS="$with_libudev_ldflags"
-       BUILD_WITH_LIBUDEV_LIBS="-ludev"
-       AC_SUBST(BUILD_WITH_LIBUDEV_CFLAGS)
-       AC_SUBST(BUILD_WITH_LIBUDEV_LDFLAGS)
-       AC_SUBST(BUILD_WITH_LIBUDEV_LIBS)
-fi
-AM_CONDITIONAL(BUILD_WITH_LIBUDEV, test "x$with_libudev" = "xyes")
+
+if test "x$with_libudev" = "xyes"; then
+  BUILD_WITH_LIBUDEV_CPPFLAGS="$with_libudev_cppflags"
+  BUILD_WITH_LIBUDEV_LDFLAGS="$with_libudev_ldflags"
+  BUILD_WITH_LIBUDEV_LIBS="-ludev"
+fi
+
+AC_SUBST([BUILD_WITH_LIBUDEV_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBUDEV_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBUDEV_LIBS])
+
+AM_CONDITIONAL([BUILD_WITH_LIBUDEV], [test "x$with_libudev" = "xyes"])
 # }}}
 
 # --with-libupsclient {{{
 with_libupsclient_config=""
-with_libupsclient_cflags=""
-with_libupsclient_libs=""
-AC_ARG_WITH(libupsclient, [AS_HELP_STRING([--with-libupsclient@<:@=PREFIX@:>@], [Path to the upsclient library.])],
-[
-       if test "x$withval" = "xno"
-       then
-               with_libupsclient="no"
-       else if test "x$withval" = "xyes"
-       then
-               with_libupsclient="use_pkgconfig"
-       else
-               if test -x "$withval"
-               then
-                       with_libupsclient_config="$withval"
-                       with_libupsclient="use_libupsclient_config"
-               else if test -x "$withval/bin/libupsclient-config"
-               then
-                       with_libupsclient_config="$withval/bin/libupsclient-config"
-                       with_libupsclient="use_libupsclient_config"
-               else
-                       AC_MSG_NOTICE([Not checking for libupsclient: Manually configured])
-                       with_libupsclient_cflags="-I$withval/include"
-                       with_libupsclient_libs="-L$withval/lib -lupsclient"
-                       with_libupsclient="yes"
-               fi; fi
-       fi; fi
-],
-[with_libupsclient="use_pkgconfig"])
+AC_ARG_WITH([libupsclient],
+  [AS_HELP_STRING([--with-libupsclient@<:@=PREFIX@:>@], [Path to the upsclient library.])],
+  [
+    if test "x$withval" = "xno"; then
+      with_libupsclient="no"
+    else if test "x$withval" = "xyes"; then
+      with_libupsclient="use_pkgconfig"
+    else
+      if test -x "$withval"; then
+        with_libupsclient_config="$withval"
+        with_libupsclient="use_libupsclient_config"
+      else if test -x "$withval/bin/libupsclient-config"; then
+        with_libupsclient_config="$withval/bin/libupsclient-config"
+        with_libupsclient="use_libupsclient_config"
+      else
+        AC_MSG_NOTICE([Not checking for libupsclient: Manually configured])
+        with_libupsclient_cflags="-I$withval/include"
+        with_libupsclient_libs="-L$withval/lib -lupsclient"
+        with_libupsclient="yes"
+      fi; fi
+    fi; fi
+  ],
+  [with_libupsclient="use_pkgconfig"]
+)
 
 # configure using libupsclient-config
-if test "x$with_libupsclient" = "xuse_libupsclient_config"
-then
-       AC_MSG_NOTICE([Checking for libupsclient using $with_libupsclient_config])
-       with_libupsclient_cflags="`$with_libupsclient_config --cflags`"
-       if test $? -ne 0
-       then
-               with_libupsclient="no ($with_libupsclient_config failed)"
-       fi
-       with_libupsclient_libs="`$with_libupsclient_config --libs`"
-       if test $? -ne 0
-       then
-               with_libupsclient="no ($with_libupsclient_config failed)"
-       fi
+if test "x$with_libupsclient" = "xuse_libupsclient_config"; then
+  with_libupsclient_cflags="`$with_libupsclient_config --cflags`"
+  if test $? -ne 0; then
+    with_libupsclient="no ($with_libupsclient_config failed)"
+  fi
+  with_libupsclient_libs="`$with_libupsclient_config --libs`"
+  if test $? -ne 0; then
+    with_libupsclient="no ($with_libupsclient_config failed)"
+  fi
 fi
-if test "x$with_libupsclient" = "xuse_libupsclient_config"
-then
-       with_libupsclient="yes"
+
+if test "x$with_libupsclient" = "xuse_libupsclient_config"; then
+  with_libupsclient="yes"
 fi
 
 # configure using pkg-config
-if test "x$with_libupsclient" = "xuse_pkgconfig"
-then
-       AC_MSG_NOTICE([Checking for libupsclient using $PKG_CONFIG])
-       $PKG_CONFIG --exists 'libupsclient' 2>/dev/null
-       if test $? -ne 0
-       then
-               with_libupsclient="no (pkg-config doesn't know libupsclient)"
-       fi
+if test "x$with_libupsclient" = "xuse_pkgconfig"; then
+  AC_MSG_NOTICE([Checking for libupsclient using $PKG_CONFIG])
+  $PKG_CONFIG --exists 'libupsclient' 2>/dev/null
+  if test $? -ne 0; then
+    with_libupsclient="no (pkg-config doesn't know libupsclient)"
+  fi
 fi
-if test "x$with_libupsclient" = "xuse_pkgconfig"
-then
-       with_libupsclient_cflags="`$PKG_CONFIG --cflags 'libupsclient'`"
-       if test $? -ne 0
-       then
-               with_libupsclient="no ($PKG_CONFIG failed)"
-       fi
-       with_libupsclient_libs="`$PKG_CONFIG --libs 'libupsclient'`"
-       if test $? -ne 0
-       then
-               with_libupsclient="no ($PKG_CONFIG failed)"
-       fi
+
+if test "x$with_libupsclient" = "xuse_pkgconfig"; then
+  with_libupsclient_cflags="`$PKG_CONFIG --cflags 'libupsclient'`"
+  if test $? -ne 0; then
+    with_libupsclient="no ($PKG_CONFIG failed)"
+  fi
+
+  with_libupsclient_libs="`$PKG_CONFIG --libs 'libupsclient'`"
+  if test $? -ne 0; then
+    with_libupsclient="no ($PKG_CONFIG failed)"
+  fi
 fi
-if test "x$with_libupsclient" = "xuse_pkgconfig"
-then
-       with_libupsclient="yes"
+
+if test "x$with_libupsclient" = "xuse_pkgconfig"; then
+  with_libupsclient="yes"
 fi
 
-# with_libupsclient_cflags and with_libupsclient_libs are set up now, let's do
-# the actual checks.
-if test "x$with_libupsclient" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_libupsclient_cflags"
+if test "x$with_libupsclient" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_libupsclient_cflags"
 
-       AC_CHECK_HEADERS(upsclient.h, [], [with_libupsclient="no (upsclient.h not found)"])
+  AC_CHECK_HEADERS([upsclient.h],
+    [with_libupsclient="yes"],
+    [with_libupsclient="no (upsclient.h not found)"]
+  )
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
+  CPPFLAGS="$SAVE_CPPFLAGS"
 fi
-if test "x$with_libupsclient" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       SAVE_LDFLAGS="$LDFLAGS"
 
-       CPPFLAGS="$CPPFLAGS $with_libupsclient_cflags"
-       LDFLAGS="$LDFLAGS $with_libupsclient_libs"
+if test "x$with_libupsclient" = "xyes"; then
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $with_libupsclient_libs"
 
-       AC_CHECK_LIB(upsclient, upscli_connect,
-                    [with_libupsclient="yes"],
-                    [with_libupsclient="no (symbol upscli_connect not found)"])
+  AC_CHECK_LIB([upsclient], [upscli_connect],
+    [with_libupsclient="yes"],
+    [with_libupsclient="no (symbol upscli_connect not found)"]
+  )
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
-       LDFLAGS="$SAVE_LDFLAGS"
+  AC_CHECK_LIB([upsclient], [upscli_init],
+    [AC_DEFINE([WITH_UPSCLIENT_27], [1], [At least version 2-7])],
+    []
+  )
+
+  LDFLAGS="$SAVE_LDFLAGS"
 fi
-if test "x$with_libupsclient" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_libupsclient_cflags"
 
-       AC_CHECK_TYPES([UPSCONN_t, UPSCONN], [], [],
-[#include <stdlib.h>
-#include <stdio.h>
-#include <upsclient.h>])
+if test "x$with_libupsclient" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_libupsclient_cflags"
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
+  AC_CHECK_TYPES([UPSCONN_t, UPSCONN],
+    [],
+    [],
+    [[
+      #include <stdlib.h>
+      #include <stdio.h>
+      #include <upsclient.h>
+    ]]
+  )
+
+  CPPFLAGS="$SAVE_CPPFLAGS"
 fi
-if test "x$with_libupsclient" = "xyes"
-then
-       BUILD_WITH_LIBUPSCLIENT_CFLAGS="$with_libupsclient_cflags"
-       BUILD_WITH_LIBUPSCLIENT_LIBS="$with_libupsclient_libs"
-       AC_SUBST(BUILD_WITH_LIBUPSCLIENT_CFLAGS)
-       AC_SUBST(BUILD_WITH_LIBUPSCLIENT_LIBS)
+
+if test "x$with_libupsclient" = "xyes"; then
+  BUILD_WITH_LIBUPSCLIENT_CFLAGS="$with_libupsclient_cflags"
+  BUILD_WITH_LIBUPSCLIENT_LIBS="$with_libupsclient_libs"
 fi
+
+AC_SUBST([BUILD_WITH_LIBUPSCLIENT_CFLAGS])
+AC_SUBST([BUILD_WITH_LIBUPSCLIENT_LIBS])
 # }}}
 
 # --with-libxenctrl {{{
-with_libxenctrl_cppflags=""
-with_libxenctrl_ldflags=""
-AC_ARG_WITH(libxenctrl, [AS_HELP_STRING([--with-libxenctrl@<:@=PREFIX@:>@], [Path to libxenctrl.])],
-[
-       if test "x$withval" != "xno" && test "x$withval" != "xyes"
-       then
-               with_libxenctrl_cppflags="-I$withval/include"
-               with_libxenctrl_ldflags="-L$withval/lib"
-               with_libxenctrl="yes"
-       else
-               with_libxenctrl="$withval"
-       fi
-],
-[
-       with_libxenctrl="yes"
-])
-if test "x$with_libxenctrl" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_libxenctrl_cppflags"
+AC_ARG_WITH([libxenctrl],
+  [AS_HELP_STRING([--with-libxenctrl@<:@=PREFIX@:>@], [Path to libxenctrl.])],
+  [
+    if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
+      with_libxenctrl_cppflags="-I$withval/include"
+      with_libxenctrl_ldflags="-L$withval/lib"
+      with_libxenctrl="yes"
+    else
+      with_libxenctrl="$withval"
+    fi
+  ],
+  [with_libxenctrl="yes"]
+)
 
-       AC_CHECK_HEADERS(xenctrl.h, [with_libxenctrl="yes"], [with_libxenctrl="no (xenctrl.h not found)"])
+if test "x$with_libxenctrl" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_libxenctrl_cppflags"
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
+  AC_CHECK_HEADERS([xenctrl.h],
+    [with_libxenctrl="yes"],
+    [with_libxenctrl="no (xenctrl.h not found)"]
+  )
+
+  CPPFLAGS="$SAVE_CPPFLAGS"
 fi
-if test "x$with_libxenctrl" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       SAVE_LDFLAGS="$LDFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_libxenctrl_cppflags"
-       LDFLAGS="$LDFLAGS $with_libxenctrl_ldflags"
 
-       #Xen versions older than 3.4 has no xc_getcpuinfo()
-       AC_CHECK_LIB(xenctrl, xc_getcpuinfo, [with_libxenctrl="yes"], [with_libxenctrl="no (symbol 'xc_getcpuinfo' not found)"], [])
+if test "x$with_libxenctrl" = "xyes"; then
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $with_libxenctrl_ldflags"
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
-       LDFLAGS="$SAVE_LDFLAGS"
-       LIBXENCTL_CPPFLAGS="$with_libxenctl_cppflags"
-       LIBXENCTL_LDFLAGS="$with_libxenctl_ldflags"
-       AC_SUBST(LIBXENCTL_CPPFLAGS)
-       AC_SUBST(LIBXENCTL_LDFLAGS)
+  #Xen versions older than 3.4 has no xc_getcpuinfo()
+  AC_CHECK_LIB([xenctrl], [xc_getcpuinfo],
+    [with_libxenctrl="yes"],
+    [with_libxenctrl="no (symbol 'xc_getcpuinfo' not found)"]
+  )
+
+  LDFLAGS="$SAVE_LDFLAGS"
 fi
+
+LIBXENCTL_CPPFLAGS="$with_libxenctl_cppflags"
+LIBXENCTL_LDFLAGS="$with_libxenctl_ldflags"
+AC_SUBST([LIBXENCTL_CPPFLAGS])
+AC_SUBST([LIBXENCTL_LDFLAGS])
 # }}}
 
 # --with-libxmms {{{
 with_xmms_config="xmms-config"
-with_xmms_cflags=""
-with_xmms_libs=""
-AC_ARG_WITH(libxmms, [AS_HELP_STRING([--with-libxmms@<:@=PREFIX@:>@], [Path to libxmms.])],
-[
-       if test "x$withval" != "xno" \
-               && test "x$withval" != "xyes"
-       then
-               if test -f "$withval" && test -x "$withval";
-               then
-                       with_xmms_config="$withval"
-               else if test -x "$withval/bin/xmms-config"
-               then
-                       with_xmms_config="$withval/bin/xmms-config"
-               fi; fi
-               with_libxmms="yes"
-       else if test "x$withval" = "xno"
-       then
-               with_libxmms="no"
-       else
-               with_libxmms="yes"
-       fi; fi
-],
-[
-       with_libxmms="yes"
-])
-if test "x$with_libxmms" = "xyes"
-then
-       with_xmms_cflags=`$with_xmms_config --cflags 2>/dev/null`
-       xmms_config_status=$?
+AC_ARG_WITH([libxmms],
+  [AS_HELP_STRING([--with-libxmms@<:@=PREFIX@:>@], [Path to libxmms.])],
+  [
+    if test "x$withval" = "xno" || test "x$withval" = "xyes"; then
+      with_libxmms="$withval"
+    else
+      if test -f "$withval" && test -x "$withval"; then
+        with_xmms_config="$withval"
+      else if test -x "$withval/bin/xmms-config"; then
+        with_xmms_config="$withval/bin/xmms-config"
+      fi; fi
+      with_libxmms="yes"
+    fi
+  ],
+  [with_libxmms="yes"]
+)
 
-       if test $xmms_config_status -ne 0
-       then
-               with_libxmms="no"
-       fi
+if test "x$with_libxmms" = "xyes"; then
+  with_xmms_cflags=`$with_xmms_config --cflags 2>/dev/null`
+  if test $? -ne 0; then
+    with_libxmms="no"
+  fi
 fi
-if test "x$with_libxmms" = "xyes"
-then
-       with_xmms_libs=`$with_xmms_config --libs 2>/dev/null`
-       xmms_config_status=$?
 
-       if test $xmms_config_status -ne 0
-       then
-               with_libxmms="no"
-       fi
+if test "x$with_libxmms" = "xyes"; then
+  with_xmms_libs=`$with_xmms_config --libs 2>/dev/null`
+  if test $? -ne 0; then
+    with_libxmms="no"
+  fi
 fi
-if test "x$with_libxmms" = "xyes"
-then
-       AC_CHECK_LIB(xmms, xmms_remote_get_info,
-       [
-               BUILD_WITH_LIBXMMS_CFLAGS="$with_xmms_cflags"
-               BUILD_WITH_LIBXMMS_LIBS="$with_xmms_libs"
-               AC_SUBST(BUILD_WITH_LIBXMMS_CFLAGS)
-               AC_SUBST(BUILD_WITH_LIBXMMS_LIBS)
-       ],
-       [
-               with_libxmms="no"
-       ],
-       [$with_xmms_libs])
-fi
-with_libxmms_numeric=0
-if test "x$with_libxmms" = "xyes"
-then
-       with_libxmms_numeric=1
+
+if test "x$with_libxmms" = "xyes"; then
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$with_xmms_cflags"
+
+  AC_CHECK_HEADER([xmmsctrl.h],
+    [with_libxmms="yes"],
+    [with_libxmms="no"],
+  )
+
+  CFLAGS="$SAVE_CFLAGS"
+fi
+
+if test "x$with_libxmms" = "xyes"; then
+  SAVE_LIBS="$LIBS"
+  LIBS="$with_xmms_libs"
+
+  AC_CHECK_LIB([xmms], [xmms_remote_get_info],
+    [with_libxmss="yes"],
+    [with_libxmms="no"],
+    [$with_xmms_libs]
+
+  )
+
+  LIBS="$SAVE_LIBS"
 fi
-AC_DEFINE_UNQUOTED(HAVE_LIBXMMS, [$with_libxmms_numeric], [Define to 1 if you have the 'xmms' library (-lxmms).])
-AM_CONDITIONAL(BUILD_WITH_LIBXMMS, test "x$with_libxmms" = "xyes")
+
+BUILD_WITH_LIBXMMS_CFLAGS="$with_xmms_cflags"
+BUILD_WITH_LIBXMMS_LIBS="$with_xmms_libs"
+
+AC_SUBST([BUILD_WITH_LIBXMMS_CFLAGS])
+AC_SUBST([BUILD_WITH_LIBXMMS_LIBS])
 # }}}
 
 # --with-libyajl {{{
-with_libyajl_cppflags=""
-with_libyajl_ldflags=""
-AC_ARG_WITH(libyajl, [AS_HELP_STRING([--with-libyajl@<:@=PREFIX@:>@], [Path to libyajl.])],
-[
-       if test "x$withval" != "xno" && test "x$withval" != "xyes"
-       then
-               with_libyajl_cppflags="-I$withval/include"
-               with_libyajl_ldflags="-L$withval/lib"
-               with_libyajl="yes"
-       else
-               with_libyajl="$withval"
-       fi
-],
-[
-       with_libyajl="yes"
-])
-if test "x$with_libyajl" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_libyajl_cppflags"
+AC_ARG_WITH([libyajl],
+  [AS_HELP_STRING([--with-libyajl@<:@=PREFIX@:>@], [Path to libyajl.])],
+  [
+    if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
+      with_libyajl_cppflags="-I$withval/include"
+      with_libyajl_ldflags="-L$withval/lib"
+      with_libyajl="yes"
+    else
+      with_libyajl="$withval"
+    fi
+  ],
+  [with_libyajl="yes"]
+)
 
-       AC_CHECK_HEADERS(yajl/yajl_parse.h, [with_libyajl="yes"], [with_libyajl="no (yajl/yajl_parse.h not found)"])
-       AC_CHECK_HEADERS(yajl/yajl_version.h)
+if test "x$with_libyajl" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_libyajl_cppflags"
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
+  AC_CHECK_HEADERS([yajl/yajl_parse.h],
+    [with_libyajl="yes"],
+    [with_libyajl="no (yajl/yajl_parse.h not found)"]
+  )
+
+  AC_CHECK_HEADERS([yajl/yajl_tree.h],
+    [with_libyajl2="yes"],
+    [with_libyajl2="no (yajl/yajl_tree.h not found)"]
+  )
+
+  AC_CHECK_HEADERS([yajl/yajl_version.h])
+
+  CPPFLAGS="$SAVE_CPPFLAGS"
 fi
-if test "x$with_libyajl" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       SAVE_LDFLAGS="$LDFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_libyajl_cppflags"
-       LDFLAGS="$LDFLAGS $with_libyajl_ldflags"
 
-       AC_CHECK_LIB(yajl, yajl_alloc, [with_libyajl="yes"], [with_libyajl="no (Symbol 'yajl_alloc' not found)"])
+if test "x$with_libyajl" = "xyes"; then
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $with_libyajl_ldflags"
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
-       LDFLAGS="$SAVE_LDFLAGS"
+  AC_CHECK_LIB([yajl], [yajl_alloc],
+    [with_libyajl="yes"],
+    [with_libyajl="no (Symbol 'yajl_alloc' not found)"]
+  )
+
+  AC_CHECK_LIB([yajl], [yajl_tree_parse],
+    [with_libyajl2="yes"],
+    [with_libyajl2="no (Symbol 'yajl_tree_parse' not found)"]
+  )
+
+  LDFLAGS="$SAVE_LDFLAGS"
 fi
-if test "x$with_libyajl" = "xyes"
-then
-       BUILD_WITH_LIBYAJL_CPPFLAGS="$with_libyajl_cppflags"
-       BUILD_WITH_LIBYAJL_LDFLAGS="$with_libyajl_ldflags"
-       BUILD_WITH_LIBYAJL_LIBS="-lyajl"
-       AC_SUBST(BUILD_WITH_LIBYAJL_CPPFLAGS)
-       AC_SUBST(BUILD_WITH_LIBYAJL_LDFLAGS)
-       AC_SUBST(BUILD_WITH_LIBYAJL_LIBS)
-       AC_DEFINE(HAVE_LIBYAJL, 1, [Define if libyajl is present and usable.])
-fi
-AM_CONDITIONAL(BUILD_WITH_LIBYAJL, test "x$with_libyajl" = "xyes")
+
+if test "x$with_libyajl" = "xyes"; then
+  BUILD_WITH_LIBYAJL_CPPFLAGS="$with_libyajl_cppflags"
+  BUILD_WITH_LIBYAJL_LDFLAGS="$with_libyajl_ldflags"
+  BUILD_WITH_LIBYAJL_LIBS="-lyajl"
+  AC_DEFINE([HAVE_LIBYAJL], [1], [Define if libyajl is present and usable.])
+fi
+
+AC_SUBST([BUILD_WITH_LIBYAJL_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBYAJL_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBYAJL_LIBS])
+
+AM_CONDITIONAL([BUILD_WITH_LIBYAJL], [test "x$with_libyajl" = "xyes"])
 # }}}
 
 # --with-mic {{{
-with_mic_cflags="-I/opt/intel/mic/sysmgmt/sdk/include"
-with_mic_ldpath="-L/opt/intel/mic/sysmgmt/sdk/lib/Linux"
-with_mic_libs=""
-AC_ARG_WITH(mic,[AS_HELP_STRING([--with-mic@<:@=PREFIX@:>@], [Path to Intel MIC Access API.])],
-[
-       if test "x$withval" = "xno"
-       then
-               with_mic="no"
-       else if test "x$withval" = "xyes"
-       then
-               with_mic="yes"
-       else if test -d "$with_mic/lib"
-       then
-               AC_MSG_NOTICE([Not checking for Intel Mic: Manually configured])
-               with_mic_cflags="-I$withval/include"
-               with_mic_ldpath="-L$withval/lib/Linux"
-               with_mic_libs="$PTHREAD_LIBS -lMicAccessSDK -lscif"
-               with_mic="yes"
-       fi; fi; fi
-],
-[with_mic="yes"])
-if test "x$with_mic" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_mic_cflags"
-       AC_CHECK_HEADERS(MicAccessApi.h,[],[with_mic="no (MicAccessApi not found)"])
-       CPPFLAGS="$SAVE_CPPFLAGS"
+with_mic_cppflags="-I/opt/intel/mic/sysmgmt/sdk/include"
+with_mic_ldflags="-L/opt/intel/mic/sysmgmt/sdk/lib/Linux"
+with_mic_libs="-lMicAccessSDK -scif"
+AC_ARG_WITH([mic],
+  [AS_HELP_STRING([--with-mic@<:@=PREFIX@:>@], [Path to Intel MIC Access API.])],
+  [
+    if test "x$withval" = "xno" || test "x$withval" = "xyes"; then
+      with_mic="$withval"
+    else if test -d "$with_mic/lib"; then
+      with_mic_cppflags="-I$withval/include"
+      with_mic_ldflags="-L$withval/lib/Linux"
+      with_mic="yes"
+    fi; fi
+  ],
+  [with_mic="yes"]
+)
+
+if test "x$with_mic" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_mic_cppflags"
+
+  AC_CHECK_HEADERS([MicAccessApi.h],
+    [with_mic="yes"],
+    [with_mic="no (MicAccessApi not found)"]
+  )
+
+  CPPFLAGS="$SAVE_CPPFLAGS"
 fi
-if test "x$with_mic" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       SAVE_LDFLAGS="$LDFLAGS"
 
-       CPPFLAGS="$CPPFLAGS $with_mic_cflags"
-       LDFLAGS="$LDFLAGS $with_mic_ldpath"
+if test "x$with_mic" = "xyes"; then
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $with_mic_ldflags"
 
-       AC_CHECK_LIB(MicAccessSDK, MicInitAPI,
-                       [with_mic_ldpath="$with_mic_ldpath"
-                       with_mic_libs="$PTHREAD_LIBS -lMicAccessSDK -lscif"],
-                       [with_mic="no (symbol MicInitAPI not found)"],[$PTHREAD_LIBS -lscif])
+  AC_CHECK_LIB([MicAccessSDK], [MicInitAPI],
+    [with_mic="yes"],
+    [with_mic="no (symbol MicInitAPI not found)"],
+    [$PTHREAD_LIBS -lscif]
+  )
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
-       LDFLAGS="$SAVE_LDFLAGS"
+  LDFLAGS="$SAVE_LDFLAGS"
 fi
 
-if test "x$with_mic" = "xyes"
-then
-       BUILD_WITH_MIC_CPPFLAGS="$with_mic_cflags"
-       BUILD_WITH_MIC_LIBPATH="$with_mic_ldpath"
-       BUILD_WITH_MIC_LDADD="$with_mic_libs"
-       AC_SUBST(BUILD_WITH_MIC_CPPFLAGS)
-       AC_SUBST(BUILD_WITH_MIC_LIBPATH)
-       AC_SUBST(BUILD_WITH_MIC_LDADD)
+if test "x$with_mic" = "xyes"; then
+  BUILD_WITH_MIC_CPPFLAGS="$with_mic_cppflags"
+  BUILD_WITH_MIC_LDFLAGS="$with_mic_ldflags"
+  BUILD_WITH_MIC_LIBS="$with_mic_libs"
 fi
+AC_SUBST([BUILD_WITH_MIC_CPPFLAGS])
+AC_SUBST([BUILD_WITH_MIC_LDFLAGS])
+AC_SUBST([BUILD_WITH_MIC_LIBS])
 #}}}
 
 # --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"])
+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
+      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
-       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
+if test "x$with_libvarnish" = "xuse_pkgconfig"; then
+  $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
+
+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"
+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"
+if test "x$with_libvarnish" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_libvarnish_cflags"
 
-       AC_CHECK_HEADERS(vapi/vsc.h,
-               [AC_DEFINE([HAVE_VARNISH_V4], [1], [Varnish 4 API support])],
-               [AC_CHECK_HEADERS(vsc.h,
-                       [AC_DEFINE([HAVE_VARNISH_V3], [1], [Varnish 3 API support])],
-                       [AC_CHECK_HEADERS(varnishapi.h,
-                               [AC_DEFINE([HAVE_VARNISH_V2], [1], [Varnish 2 API support])],
-                               [with_libvarnish="no (found none of the varnish header files)"])])])
+  AC_CHECK_HEADERS([vapi/vsc.h],
+    [AC_DEFINE([HAVE_VARNISH_V4], [1], [Varnish 4 API support])],
+    [
+      AC_CHECK_HEADERS([vsc.h],
+        [AC_DEFINE([HAVE_VARNISH_V3], [1], [Varnish 3 API support]) ],
+        [
+          AC_CHECK_HEADERS([varnishapi.h],
+            [AC_DEFINE([HAVE_VARNISH_V2], [1], [Varnish 2 API support])],
+            [with_libvarnish="no (found none of the varnish header files)"]
+          )
+        ]
+      )
+    ]
+  )
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
+  CPPFLAGS="$SAVE_CPPFLAGS"
 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)
+
+if test "x$with_libvarnish" = "xyes"; then
+  BUILD_WITH_LIBVARNISH_CFLAGS="$with_libvarnish_cflags"
+  BUILD_WITH_LIBVARNISH_LIBS="$with_libvarnish_libs"
 fi
+
+AC_SUBST([BUILD_WITH_LIBVARNISH_CFLAGS])
+AC_SUBST([BUILD_WITH_LIBVARNISH_LIBS])
 # }}}
 
 # pkg-config --exists 'libxml-2.0'; pkg-config --exists libvirt {{{
-with_libxml2="no (pkg-config isn't available)"
-with_libxml2_cflags=""
-with_libxml2_ldflags=""
-with_libvirt="no (pkg-config isn't available)"
-with_libvirt_cflags=""
-with_libvirt_ldflags=""
 $PKG_CONFIG --exists 'libxml-2.0' 2>/dev/null
-if test "$?" = "0"
-then
-       with_libxml2="yes"
+if test $? -eq 0; then
+  with_libxml2="yes"
 else
-       with_libxml2="no (pkg-config doesn't know libxml-2.0)"
+  with_libxml2="no (pkg-config doesn't know libxml-2.0)"
 fi
 
 $PKG_CONFIG --exists libvirt 2>/dev/null
-if test "$?" = "0"
-then
-       with_libvirt="yes"
+if test $? = 0; then
+  with_libvirt="yes"
 else
-       with_libvirt="no (pkg-config doesn't know libvirt)"
+  with_libvirt="no (pkg-config doesn't know libvirt)"
 fi
-if test "x$with_libxml2" = "xyes"
-then
-       with_libxml2_cflags="`$PKG_CONFIG --cflags libxml-2.0`"
-       if test $? -ne 0
-       then
-               with_libxml2="no"
-       fi
-       with_libxml2_ldflags="`$PKG_CONFIG --libs libxml-2.0`"
-       if test $? -ne 0
-       then
-               with_libxml2="no"
-       fi
+
+if test "x$with_libxml2" = "xyes"; then
+  with_libxml2_cflags="`$PKG_CONFIG --cflags libxml-2.0`"
+  if test $? -ne 0; then
+    with_libxml2="no"
+  fi
+
+  with_libxml2_ldflags="`$PKG_CONFIG --libs libxml-2.0`"
+  if test $? -ne 0; then
+    with_libxml2="no"
+  fi
 fi
-if test "x$with_libxml2" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_libxml2_cflags"
 
-       AC_CHECK_HEADERS(libxml/parser.h, [],
-                     [with_libxml2="no (libxml/parser.h not found)"])
+if test "x$with_libxml2" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_libxml2_cflags"
+
+  AC_CHECK_HEADERS([libxml/parser.h],
+    [with_libxml2="yes"],
+    [with_libxml2="no (libxml/parser.h not found)"]
+  )
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
+  CPPFLAGS="$SAVE_CPPFLAGS"
 fi
-if test "x$with_libxml2" = "xyes"
-then
-       SAVE_CFLAGS="$CFLAGS"
-       SAVE_LDFLAGS="$LDFLAGS"
 
-       CFLAGS="$CFLAGS $with_libxml2_cflags"
-       LDFLAGS="$LDFLAGS $with_libxml2_ldflags"
+if test "x$with_libxml2" = "xyes"; then
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $with_libxml2_ldflags"
 
-       AC_CHECK_LIB(xml2, xmlXPathEval,
-                    [with_libxml2="yes"],
-                    [with_libxml2="no (symbol xmlXPathEval not found)"])
+  AC_CHECK_LIB([xml2], [xmlXPathEval],
+    [with_libxml2="yes"],
+    [with_libxml2="no (symbol xmlXPathEval not found)"]
+  )
 
-       CFLAGS="$SAVE_CFLAGS"
-       LDFLAGS="$SAVE_LDFLAGS"
+  LDFLAGS="$SAVE_LDFLAGS"
 fi
-dnl Add the right compiler flags and libraries.
+
 if test "x$with_libxml2" = "xyes"; then
-       BUILD_WITH_LIBXML2_CFLAGS="$with_libxml2_cflags"
-       BUILD_WITH_LIBXML2_LIBS="$with_libxml2_ldflags"
-       AC_SUBST(BUILD_WITH_LIBXML2_CFLAGS)
-       AC_SUBST(BUILD_WITH_LIBXML2_LIBS)
+  BUILD_WITH_LIBXML2_CFLAGS="$with_libxml2_cflags"
+  BUILD_WITH_LIBXML2_LIBS="$with_libxml2_ldflags"
 fi
-if test "x$with_libvirt" = "xyes"
-then
-       with_libvirt_cflags="`$PKG_CONFIG --cflags libvirt`"
-       if test $? -ne 0
-       then
-               with_libvirt="no"
-       fi
-       with_libvirt_ldflags="`$PKG_CONFIG --libs libvirt`"
-       if test $? -ne 0
-       then
-               with_libvirt="no"
-       fi
+
+AC_SUBST([BUILD_WITH_LIBXML2_CFLAGS])
+AC_SUBST([BUILD_WITH_LIBXML2_LIBS])
+
+if test "x$with_libvirt" = "xyes"; then
+  with_libvirt_cflags="`$PKG_CONFIG --cflags libvirt`"
+  if test $? -ne 0; then
+    with_libvirt="no"
+  fi
+
+  with_libvirt_ldflags="`$PKG_CONFIG --libs libvirt`"
+  if test $? -ne 0; then
+    with_libvirt="no"
+  fi
 fi
-if test "x$with_libvirt" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_libvirt_cflags"
 
-       AC_CHECK_HEADERS(libvirt/libvirt.h, [],
-                     [with_libvirt="no (libvirt/libvirt.h not found)"])
+if test "x$with_libvirt" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_libvirt_cflags"
+
+  AC_CHECK_HEADERS([libvirt/libvirt.h],
+    [with_libvirt="yes"],
+    [with_libvirt="no (libvirt/libvirt.h not found)"]
+  )
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
+  CPPFLAGS="$SAVE_CPPFLAGS"
 fi
-if test "x$with_libvirt" = "xyes"
-then
-       SAVE_CFLAGS="$CFLAGS"
-       SAVE_LDFLAGS="$LDFLAGS"
 
-       CFLAGS="$CFLAGS $with_libvirt_cflags"
-       LDFLAGS="$LDFLAGS $with_libvirt_ldflags"
+if test "x$with_libvirt" = "xyes"; then
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $with_libvirt_ldflags"
 
-       AC_CHECK_LIB(virt, virDomainBlockStats,
-                    [with_libvirt="yes"],
-                    [with_libvirt="no (symbol virDomainBlockStats not found)"])
+  AC_CHECK_LIB([virt], [virDomainBlockStats],
+    [with_libvirt="yes"],
+    [with_libvirt="no (symbol virDomainBlockStats not found)"]
+  )
 
-       CFLAGS="$SAVE_CFLAGS"
-       LDFLAGS="$SAVE_LDFLAGS"
+  LDFLAGS="$SAVE_LDFLAGS"
 fi
-dnl Add the right compiler flags and libraries.
+
 if test "x$with_libvirt" = "xyes"; then
-       BUILD_WITH_LIBVIRT_CFLAGS="$with_libvirt_cflags"
-       BUILD_WITH_LIBVIRT_LIBS="$with_libvirt_ldflags"
-       AC_SUBST(BUILD_WITH_LIBVIRT_CFLAGS)
-       AC_SUBST(BUILD_WITH_LIBVIRT_LIBS)
+  BUILD_WITH_LIBVIRT_CFLAGS="$with_libvirt_cflags"
+  BUILD_WITH_LIBVIRT_LIBS="$with_libvirt_ldflags"
 fi
+
+AC_SUBST([BUILD_WITH_LIBVIRT_CFLAGS])
+AC_SUBST([BUILD_WITH_LIBVIRT_LIBS])
 # }}}
 
 # $PKG_CONFIG --exists OpenIPMIpthread {{{
 with_libopenipmipthread="yes"
-with_libopenipmipthread_cflags=""
-with_libopenipmipthread_libs=""
-
-if test "x$with_libopenipmipthread" = "xyes"
-then
-       AC_MSG_CHECKING([for libOpenIPMIpthread])
-       $PKG_CONFIG --exists OpenIPMIpthread 2>/dev/null
-       if test "$?" != "0"
-       then
-               with_libopenipmipthread="no (pkg-config doesn't know OpenIPMIpthread)"
-       fi
-       AC_MSG_RESULT([$with_libopenipmipthread])
-fi
-
-if test "x$with_libopenipmipthread" = "xyes"
-then
-       AC_MSG_CHECKING([for libOpenIPMIpthread CFLAGS])
-       temp_result="`$PKG_CONFIG --cflags OpenIPMIpthread`"
-       if test "$?" = "0"
-       then
-               with_libopenipmipthread_cflags="$temp_result"
-       else
-               with_libopenipmipthread="no ($PKG_CONFIG --cflags OpenIPMIpthread failed)"
-               temp_result="$PKG_CONFIG --cflags OpenIPMIpthread failed"
-       fi
-       AC_MSG_RESULT([$temp_result])
+AC_MSG_CHECKING([for libOpenIPMIpthread])
+$PKG_CONFIG --exists OpenIPMIpthread 2>/dev/null
+if test $? -ne 0; then
+  with_libopenipmipthread="no (pkg-config doesn't know OpenIPMIpthread)"
+fi
+AC_MSG_RESULT([$with_libopenipmipthread])
+
+if test "x$with_libopenipmipthread" = "xyes"; then
+  AC_MSG_CHECKING([for libOpenIPMIpthread CFLAGS])
+  temp_result="`$PKG_CONFIG --cflags OpenIPMIpthread`"
+  if test $? -eq 0; then
+    with_libopenipmipthread_cflags="$temp_result"
+  else
+    with_libopenipmipthread="no ($PKG_CONFIG --cflags OpenIPMIpthread failed)"
+    temp_result="$PKG_CONFIG --cflags OpenIPMIpthread failed"
+  fi
+  AC_MSG_RESULT([$temp_result])
 fi
 
-if test "x$with_libopenipmipthread" = "xyes"
-then
-       AC_MSG_CHECKING([for libOpenIPMIpthread LDFLAGS])
-       temp_result="`$PKG_CONFIG --libs OpenIPMIpthread`"
-       if test "$?" = "0"
-       then
-               with_libopenipmipthread_ldflags="$temp_result"
-       else
-               with_libopenipmipthread="no ($PKG_CONFIG --libs OpenIPMIpthread failed)"
-               temp_result="$PKG_CONFIG --libs OpenIPMIpthread failed"
-       fi
-       AC_MSG_RESULT([$temp_result])
+if test "x$with_libopenipmipthread" = "xyes"; then
+  AC_MSG_CHECKING([for libOpenIPMIpthread LDFLAGS])
+  temp_result="`$PKG_CONFIG --libs OpenIPMIpthread`"
+  if test $? -eq 0; then
+    with_libopenipmipthread_ldflags="$temp_result"
+  else
+    with_libopenipmipthread="no ($PKG_CONFIG --libs OpenIPMIpthread failed)"
+    temp_result="$PKG_CONFIG --libs OpenIPMIpthread failed"
+  fi
+  AC_MSG_RESULT([$temp_result])
 fi
 
-if test "x$with_libopenipmipthread" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_libopenipmipthread_cflags"
-
-       AC_CHECK_HEADERS(OpenIPMI/ipmi_smi.h,
-                        [with_libopenipmipthread="yes"],
-                        [with_libopenipmipthread="no (OpenIPMI/ipmi_smi.h not found)"],
-[#include <OpenIPMI/ipmiif.h>
-#include <OpenIPMI/ipmi_err.h>
-#include <OpenIPMI/ipmi_posix.h>
-#include <OpenIPMI/ipmi_conn.h>
-])
+if test "x$with_libopenipmipthread" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_libopenipmipthread_cflags"
+
+  AC_CHECK_HEADERS([OpenIPMI/ipmi_smi.h],
+    [with_libopenipmipthread="yes"],
+    [with_libopenipmipthread="no (OpenIPMI/ipmi_smi.h not found)"],
+    [[
+      #include <OpenIPMI/ipmiif.h>
+      #include <OpenIPMI/ipmi_err.h>
+      #include <OpenIPMI/ipmi_posix.h>
+      #include <OpenIPMI/ipmi_conn.h>
+    ]]
+  )
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
+  CPPFLAGS="$SAVE_CPPFLAGS"
 fi
 
-if test "x$with_libopenipmipthread" = "xyes"
-then
-       BUILD_WITH_OPENIPMI_CFLAGS="$with_libopenipmipthread_cflags"
-       BUILD_WITH_OPENIPMI_LIBS="$with_libopenipmipthread_ldflags"
-       AC_SUBST(BUILD_WITH_OPENIPMI_CFLAGS)
-       AC_SUBST(BUILD_WITH_OPENIPMI_LIBS)
+if test "x$with_libopenipmipthread" = "xyes"; then
+  BUILD_WITH_OPENIPMI_CFLAGS="$with_libopenipmipthread_cflags"
+  BUILD_WITH_OPENIPMI_LIBS="$with_libopenipmipthread_ldflags"
 fi
+
+AC_SUBST([BUILD_WITH_OPENIPMI_CFLAGS])
+AC_SUBST([BUILD_WITH_OPENIPMI_LIBS])
 # }}}
 
 # --with-libatasmart {{{
-with_libatasmart_cppflags=""
-with_libatasmart_ldflags=""
-AC_ARG_WITH(libatasmart, [AS_HELP_STRING([--with-libatasmart@<:@=PREFIX@:>@], [Path to libatasmart.])],
-[
-       if test "x$withval" != "xno" && test "x$withval" != "xyes"
-       then
-               with_libatasmart_cppflags="-I$withval/include"
-               with_libatasmart_ldflags="-L$withval/lib"
-               with_libatasmart="yes"
-       else
-               with_libatasmart="$withval"
-       fi
-],
-[
-       if test "x$ac_system" = "xLinux"
-       then
-               with_libatasmart="yes"
-       else
-               with_libatasmart="no (Linux only library)"
-       fi
-])
-if test "x$with_libatasmart" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_libatasmart_cppflags"
+AC_ARG_WITH([libatasmart],
+  [AS_HELP_STRING([--with-libatasmart@<:@=PREFIX@:>@], [Path to libatasmart.])],
+  [
+    if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
+      with_libatasmart_cppflags="-I$withval/include"
+      with_libatasmart_ldflags="-L$withval/lib"
+      with_libatasmart="yes"
+    else
+      with_libatasmart="$withval"
+    fi
+  ],
+  [
+    if test "x$ac_system" = "xLinux"; then
+      with_libatasmart="yes"
+    else
+      with_libatasmart="no (Linux only library)"
+    fi
+  ]
+)
+
+if test "x$with_libatasmart" = "xyes"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_libatasmart_cppflags"
 
-       AC_CHECK_HEADERS(atasmart.h, [with_libatasmart="yes"], [with_libatasmart="no (atasmart.h not found)"])
+  AC_CHECK_HEADERS([atasmart.h],
+    [with_libatasmart="yes"],
+    [with_libatasmart="no (atasmart.h not found)"])
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
+  CPPFLAGS="$SAVE_CPPFLAGS"
 fi
-if test "x$with_libatasmart" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       SAVE_LDFLAGS="$LDFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_libatasmart_cppflags"
-       LDFLAGS="$LDFLAGS $with_libatasmart_ldflags"
 
-       AC_CHECK_LIB(atasmart, sk_disk_open, [with_libatasmart="yes"], [with_libatasmart="no (Symbol 'sk_disk_open' not found)"])
+if test "x$with_libatasmart" = "xyes"; then
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $with_libatasmart_ldflags"
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
-       LDFLAGS="$SAVE_LDFLAGS"
+  AC_CHECK_LIB([atasmart], [sk_disk_open],
+    [with_libatasmart="yes"],
+    [with_libatasmart="no (Symbol 'sk_disk_open' not found)"]
+  )
+
+  LDFLAGS="$SAVE_LDFLAGS"
 fi
-if test "x$with_libatasmart" = "xyes"
-then
-       BUILD_WITH_LIBATASMART_CPPFLAGS="$with_libatasmart_cppflags"
-       BUILD_WITH_LIBATASMART_LDFLAGS="$with_libatasmart_ldflags"
-       BUILD_WITH_LIBATASMART_LIBS="-latasmart"
-       AC_SUBST(BUILD_WITH_LIBATASMART_CPPFLAGS)
-       AC_SUBST(BUILD_WITH_LIBATASMART_LDFLAGS)
-       AC_SUBST(BUILD_WITH_LIBATASMART_LIBS)
-       AC_DEFINE(HAVE_LIBATASMART, 1, [Define if libatasmart is present and usable.])
-fi
-AM_CONDITIONAL(BUILD_WITH_LIBATASMART, test "x$with_libatasmart" = "xyes")
+
+if test "x$with_libatasmart" = "xyes"; then
+  BUILD_WITH_LIBATASMART_CPPFLAGS="$with_libatasmart_cppflags"
+  BUILD_WITH_LIBATASMART_LDFLAGS="$with_libatasmart_ldflags"
+  BUILD_WITH_LIBATASMART_LIBS="-latasmart"
+fi
+
+AC_SUBST([BUILD_WITH_LIBATASMART_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBATASMART_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBATASMART_LIBS])
 # }}}
 
 PKG_CHECK_MODULES([LIBNOTIFY], [libnotify],
-               [with_libnotify="yes"],
-               [with_libnotify="no (pkg-config doesn't know libnotify)"]
+  [with_libnotify="yes"],
+  [with_libnotify="no (pkg-config doesn't know libnotify)"]
 )
 
 PKG_CHECK_MODULES([LIBRIEMANN_CLIENT], [riemann-client >= 1.6.0],
  [with_libriemann_client="yes"],
- [with_libriemann_client="no (pkg-config doesn't know libriemann-client)"])
+ [with_libriemann_client="no (pkg-config doesn't know libriemann-client)"]
+)
 
 # Check for enabled/disabled features
 #
@@ -5796,61 +5772,59 @@ PKG_CHECK_MODULES([LIBRIEMANN_CLIENT], [riemann-client >= 1.6.0],
 # AC_COLLECTD(name, enable/disable, info-text, feature/module)
 # ------------------------------------------------------------
 dnl
-m4_define([my_toupper], [m4_translit([$1], m4_defn([m4_cr_letters]), m4_defn([m4_cr_LETTERS]))])
+m4_define([my_toupper],[m4_translit([$1], m4_defn([m4_cr_letters]), m4_defn([m4_cr_LETTERS]))])
 dnl
 AC_DEFUN(
-       [AC_COLLECTD],
-       [
-       m4_if([$1], [], [AC_FATAL([AC_COLLECTD([$1], [$2], [$3], [$4]): 1st argument must not be empty])])dnl
-       m4_if(
-               [$2],
-               [enable],
-               [dnl
-               m4_define([EnDis],[disabled])dnl
-               m4_define([YesNo],[no])dnl
-               ],dnl
-               [m4_if(
-                       [$2],
-                       [disable],
-                       [dnl
-                       m4_define([EnDis],[enabled])dnl
-                       m4_define([YesNo],[yes])dnl
-                       ],
-                       [dnl
-                       AC_FATAL([AC_COLLECTD([$1], [$2], [$3], [$4]): 2nd argument must be either enable or disable])dnl
-                       ]dnl
-               )]dnl
-       )dnl
-       m4_if([$3], [feature], [],
-               [m4_if(
-                       [$3], [module], [],
-                       [dnl
-                       AC_FATAL([AC_COLLECTD([$1], [$2], [$3], [$4]): 3rd argument must be either feature or disable])dnl
-                       ]dnl
-               )]dnl
-       )dnl
-       AC_ARG_ENABLE(
-               [$1],
-               AS_HELP_STRING([--$2-$1], [$2 $4 (EnDis by def)]),
-               [],
-               enable_$1='[YesNo]'dnl
-       )# AC_ARG_ENABLE
-if test "x$enable_$1" = "xno"
-then
-       collectd_$1=0
-else
-       if test "x$enable_$1" = "xyes"
-       then
-               collectd_$1=1
-       else
-               AC_MSG_NOTICE([please specify either --enable-$1 or --disable-$1; enabling $1.])
-               collectd_$1=1
-               enable_$1='yes'
-       fi
-fi
-       AC_DEFINE_UNQUOTED([COLLECT_]my_toupper([$1]), [$collectd_$1], [wether or not to enable $3 $4])
-       AM_CONDITIONAL([BUILD_]my_toupper([$3])[_]my_toupper([$1]), [test "x$enable_$1" = "xyes"])dnl
-       ]dnl
+  [AC_COLLECTD],
+  [
+  m4_if([$1], [], [AC_FATAL([AC_COLLECTD([$1], [$2], [$3], [$4]): 1st argument must not be empty])])dnl
+  m4_if(
+    [$2],
+    [enable],
+    [dnl
+    m4_define([EnDis],[disabled])dnl
+    m4_define([YesNo],[no])dnl
+    ],dnl
+    [m4_if(
+      [$2],
+      [disable],
+      [dnl
+      m4_define([EnDis],[enabled])dnl
+      m4_define([YesNo],[yes])dnl
+      ],
+      [dnl
+      AC_FATAL([AC_COLLECTD([$1], [$2], [$3], [$4]): 2nd argument must be either enable or disable])dnl
+      ]dnl
+    )]dnl
+  )dnl
+  m4_if([$3], [feature], [],
+    [m4_if(
+      [$3], [module], [],
+      [dnl
+      AC_FATAL([AC_COLLECTD([$1], [$2], [$3], [$4]): 3rd argument must be either feature or disable])dnl
+      ]dnl
+    )]dnl
+  )dnl
+  AC_ARG_ENABLE(
+    [$1],
+    AS_HELP_STRING([--$2-$1], [$2 $4 (EnDis by def)]),
+    [],
+    enable_$1='[YesNo]'dnl
+  )# AC_ARG_ENABLE
+  if test "x$enable_$1" = "xno"; then
+    collectd_$1=0
+  else
+    if test "x$enable_$1" = "xyes"; then
+      collectd_$1=1
+    else
+      AC_MSG_NOTICE([please specify either --enable-$1 or --disable-$1; enabling $1.])
+      collectd_$1=1
+      enable_$1='yes'
+    fi
+  fi
+  AC_DEFINE_UNQUOTED([COLLECT_]my_toupper([$1]), [$collectd_$1], [whether or not to enable $3 $4])
+  AM_CONDITIONAL([BUILD_]my_toupper([$3])[_]my_toupper([$1]), [test "x$enable_$1" = "xyes"])dnl
+  ]dnl
 )# AC_COLLECTD(name, enable/disable, info-text, feature/module)
 
 # AC_PLUGIN(name, default, info)
@@ -5861,47 +5835,42 @@ AC_DEFUN(
   [
     enable_plugin="no"
     force="no"
-    AC_ARG_ENABLE([$1], AS_HELP_STRING([--enable-$1],[$3]),
-    [
-     if test "x$enableval" = "xyes"
-     then
-            enable_plugin="yes"
-     else if test "x$enableval" = "xforce"
-     then
-            enable_plugin="yes"
-            force="yes"
-     else
-            enable_plugin="no (disabled on command line)"
-     fi; fi
-    ],
-    [
-        if test "x$enable_all_plugins" = "xauto"
-        then
-            if test "x$2" = "xyes"
-            then
-                    enable_plugin="yes"
-            else
-                    enable_plugin="$2"
-            fi
-        else
-            enable_plugin="$enable_all_plugins"
-        fi
-    ])
-    if test "x$enable_plugin" = "xyes"
-    then
-           if test "x$2" = "xyes" || test "x$force" = "xyes"
-           then
-                   AC_DEFINE([HAVE_PLUGIN_]my_toupper([$1]), 1, [Define to 1 if the $1 plugin is enabled.])
-                   if test "x$2" != "xyes"
-                   then
-                           dependency_warning="yes"
-                   fi
-           else # User passed "yes" but dependency checking yielded "no" => Dependency problem.
-                   dependency_error="yes"
-                   enable_plugin="$2 (dependency error)"
-           fi
+    AC_ARG_ENABLE([$1],
+      [AS_HELP_STRING([--enable-$1],[$3])],
+      [
+        if test "x$enableval" = "xyes"; then
+          enable_plugin="yes"
+        else if test "x$enableval" = "xforce"; then
+          enable_plugin="yes"
+          force="yes"
+        else
+          enable_plugin="no (disabled on command line)"
+        fi; fi
+      ],
+      [
+        if test "x$enable_all_plugins" = "xauto"; then
+          if test "x$2" = "xyes"; then
+            enable_plugin="yes"
+          else
+            enable_plugin="$2"
+          fi
+        else
+          enable_plugin="$enable_all_plugins"
+        fi
+      ]
+    )
+    if test "x$enable_plugin" = "xyes"; then
+      if test "x$2" = "xyes" || test "x$force" = "xyes"; then
+        AC_DEFINE([HAVE_PLUGIN_]my_toupper([$1]), 1, [Define to 1 if the $1 plugin is enabled.])
+        if test "x$2" != "xyes"; then
+          dependency_warning="yes"
+        fi
+      else # User passed "yes" but dependency checking yielded "no" => Dependency problem.
+        dependency_error="yes"
+        enable_plugin="$2 (dependency error)"
+      fi
     fi
-    AM_CONDITIONAL([BUILD_PLUGIN_]my_toupper([$1]), test "x$enable_plugin" = "xyes")
+    AM_CONDITIONAL([BUILD_PLUGIN_]my_toupper([$1]), [test "x$enable_plugin" = "xyes"])
     enable_$1="$enable_plugin"
   ]
 )# AC_PLUGIN(name, default, info)
@@ -5933,6 +5902,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"
@@ -5943,15 +5913,18 @@ plugin_grpc="no"
 plugin_hugepages="no"
 plugin_intel_rdt="no"
 plugin_interface="no"
+plugin_ipc="no"
 plugin_ipmi="no"
 plugin_ipvs="no"
 plugin_irq="no"
 plugin_load="no"
 plugin_log_logstash="no"
+plugin_mcelog="no"
 plugin_memory="no"
 plugin_multimeter="no"
 plugin_nfs="no"
 plugin_numa="no"
+plugin_ovs_events="no"
 plugin_perl="no"
 plugin_pinba="no"
 plugin_processes="no"
@@ -5978,374 +5951,309 @@ plugin_zone="no"
 plugin_zookeeper="no"
 
 # Linux
-if test "x$ac_system" = "xLinux"
-then
-       plugin_battery="yes"
-       plugin_cgroups="yes"
-       plugin_conntrack="yes"
-       plugin_contextswitch="yes"
-       plugin_cpu="yes"
-       plugin_cpufreq="yes"
-       plugin_disk="yes"
-       plugin_drbd="yes"
-       plugin_entropy="yes"
-       plugin_fhcount="yes"
-       plugin_fscache="yes"
-       plugin_hugepages="yes"
-       plugin_interface="yes"
-       plugin_ipc="yes"
-       plugin_irq="yes"
-       plugin_load="yes"
-       plugin_lvm="yes"
-       plugin_memory="yes"
-       plugin_nfs="yes"
-       plugin_numa="yes"
-       plugin_processes="yes"
-       plugin_protocols="yes"
-       plugin_serial="yes"
-       plugin_swap="yes"
-       plugin_tcpconns="yes"
-       plugin_thermal="yes"
-       plugin_uptime="yes"
-       plugin_vmem="yes"
-       plugin_vserver="yes"
-       plugin_wireless="yes"
-       plugin_zfs_arc="yes"
-
-       if test "x$have_linux_ip_vs_h" = "xyes" || test "x$have_net_ip_vs_h" = "xyes" || test "x$have_ip_vs_h" = "xyes"
-       then
-               plugin_ipvs="yes"
-       fi
-       if test "x$c_cv_have_usable_asm_msrindex_h" = "xyes" && test "x$have_cpuid_h" = "xyes"
-       then
-               plugin_turbostat="yes"
-       fi
-       
-       if test "x$c_cv_have_clock_boottime_monotonic" = "xyes"
-       then
-               plugin_cpusleep="yes"
-       fi
+if test "x$ac_system" = "xLinux"; then
+  plugin_battery="yes"
+  plugin_cgroups="yes"
+  plugin_conntrack="yes"
+  plugin_contextswitch="yes"
+  plugin_cpu="yes"
+  plugin_cpufreq="yes"
+  plugin_disk="yes"
+  plugin_drbd="yes"
+  plugin_entropy="yes"
+  plugin_fhcount="yes"
+  plugin_fscache="yes"
+  plugin_hugepages="yes"
+  plugin_interface="yes"
+  plugin_ipc="yes"
+  plugin_irq="yes"
+  plugin_load="yes"
+  plugin_lvm="yes"
+  plugin_mcelog="yes"
+  plugin_memory="yes"
+  plugin_nfs="yes"
+  plugin_numa="yes"
+  plugin_processes="yes"
+  plugin_protocols="yes"
+  plugin_serial="yes"
+  plugin_swap="yes"
+  plugin_tcpconns="yes"
+  plugin_thermal="yes"
+  plugin_uptime="yes"
+  plugin_vmem="yes"
+  plugin_vserver="yes"
+  plugin_wireless="yes"
+  plugin_zfs_arc="yes"
+
+  if test "x$have_linux_ip_vs_h" = "xyes" || test "x$have_net_ip_vs_h" = "xyes" || test "x$have_ip_vs_h" = "xyes"; then
+    plugin_ipvs="yes"
+  fi
+
+  if test "x$c_cv_have_usable_asm_msrindex_h" = "xyes" && test "x$have_cpuid_h" = "xyes"; then
+    plugin_turbostat="yes"
+  fi
+  
+  if test "x$c_cv_have_clock_boottime_monotonic" = "xyes"; then
+    plugin_cpusleep="yes"
+  fi
 fi
 
-if test "x$ac_system" = "xOpenBSD"
-then
-       plugin_tcpconns="yes"
+if test "x$ac_system" = "xOpenBSD"; then
+  plugin_tcpconns="yes"
 fi
 
-if test "x$ac_system" = "xNetBSD"
-then
-       plugin_disk="yes"
-       plugin_entropy="yes"
-       plugin_irq="yes"
-       plugin_processes="yes"
+if test "x$ac_system" = "xNetBSD"; then
+  plugin_disk="yes"
+  plugin_entropy="yes"
+  plugin_irq="yes"
+  plugin_processes="yes"
 fi
 
 # Mac OS X devices
-if test "x$with_libiokit" = "xyes"
-then
-       plugin_battery="yes"
-       plugin_disk="yes"
+if test "x$with_libiokit" = "xyes"; then
+  plugin_battery="yes"
+  plugin_disk="yes"
 fi
 
 # AIX
 
-if test "x$ac_system" = "xAIX"
-then
-       plugin_ipc="yes"
-       plugin_tcpconns="yes"
+if test "x$ac_system" = "xAIX"; then
+  plugin_ipc="yes"
+  plugin_tcpconns="yes"
 fi
 
 # FreeBSD
 
-if test "x$ac_system" = "xFreeBSD"
-then
-       plugin_disk="yes"
-       plugin_zfs_arc="yes"
+if test "x$ac_system" = "xFreeBSD"; then
+  plugin_disk="yes"
+  plugin_zfs_arc="yes"
 fi
 
 
-if test "x$with_perfstat" = "xyes"
-then
-       plugin_contextswitch="yes"
-       plugin_cpu="yes"
-       plugin_disk="yes"
-       plugin_interface="yes"
-       plugin_load="yes"
-       plugin_memory="yes"
-       plugin_swap="yes"
-       plugin_uptime="yes"
+if test "x$with_perfstat" = "xyes"; then
+  plugin_contextswitch="yes"
+  plugin_cpu="yes"
+  plugin_disk="yes"
+  plugin_interface="yes"
+  plugin_load="yes"
+  plugin_memory="yes"
+  plugin_swap="yes"
+  plugin_uptime="yes"
 fi
 
-if test "x$with_procinfo" = "xyes"
-then
-       plugin_processes="yes"
+if test "x$with_procinfo" = "xyes"; then
+  plugin_processes="yes"
 fi
 
 # Solaris
-if test "x$with_kstat" = "xyes"
-then
-       plugin_nfs="yes"
-       plugin_processes="yes"
-       plugin_uptime="yes"
-       plugin_zfs_arc="yes"
-       plugin_zone="yes"
-fi
-
-if test "x$with_devinfo$with_kstat" = "xyesyes"
-then
-       plugin_cpu="yes"
-       plugin_disk="yes"
-       plugin_interface="yes"
-       plugin_memory="yes"
-       plugin_tape="yes"
+if test "x$with_kstat" = "xyes"; then
+  plugin_nfs="yes"
+  plugin_processes="yes"
+  plugin_uptime="yes"
+  plugin_zfs_arc="yes"
+  plugin_zone="yes"
 fi
 
-# libi2c-dev
-if test "x$ac_system" = "xLinux"
-then
-AC_CHECK_DECL(i2c_smbus_read_i2c_block_data,
-       [with_libi2c="yes"],
-       [with_libi2c="no (symbol i2c_smbus_read_i2c_block_data not found - have you installed libi2c-dev ?)"],
-       [[#include <stdlib.h>
-       #include <linux/i2c-dev.h>]])
-else
-       with_libi2c="no (Linux only)"
+if test "x$with_devinfo" = "xyes" && test "x$with_kstat" = "xyes"; then
+  plugin_cpu="yes"
+  plugin_disk="yes"
+  plugin_interface="yes"
+  plugin_memory="yes"
+  plugin_tape="yes"
 fi
 
-if test "x$with_libi2c" = "xyes"
-then
-       plugin_barometer="yes"
+if test "x$with_libi2c" = "xyes"; then
+  plugin_barometer="yes"
 fi
 
 
 # libstatgrab
-if test "x$with_libstatgrab" = "xyes"
-then
-       plugin_cpu="yes"
-       plugin_disk="yes"
-       plugin_interface="yes"
-       plugin_load="yes"
-       plugin_memory="yes"
-       plugin_swap="yes"
-       plugin_users="yes"
+if test "x$with_libstatgrab" = "xyes"; then
+  plugin_cpu="yes"
+  plugin_disk="yes"
+  plugin_interface="yes"
+  plugin_load="yes"
+  plugin_memory="yes"
+  plugin_swap="yes"
+  plugin_users="yes"
+fi
+
+if test "x$with_libcurl" = "xyes" && test "x$with_libxml2" = "xyes"; then
+  plugin_ascent="yes"
+  if test "x$have_strptime" = "xyes"; then
+    plugin_bind="yes"
+  fi
 fi
 
-if test "x$with_libcurl" = "xyes" && test "x$with_libxml2" = "xyes"
-then
-       plugin_ascent="yes"
-       if test "x$have_strptime" = "xyes"
-       then
-               plugin_bind="yes"
-       fi
+if test "x$with_libopenipmipthread" = "xyes"; then
+  plugin_ipmi="yes"
 fi
 
-if test "x$with_libopenipmipthread" = "xyes"
-then
-       plugin_ipmi="yes"
+if test "x$with_libcurl" = "xyes" && test "x$with_libyajl" = "xyes"; then
+  plugin_curl_json="yes"
 fi
 
-if test "x$with_libcurl" = "xyes" && test "x$with_libyajl" = "xyes"
-then
-       plugin_curl_json="yes"
+if test "x$with_libcurl" = "xyes" && test "x$with_libxml2" = "xyes"; then
+  plugin_curl_xml="yes"
 fi
 
-if test "x$with_libcurl" = "xyes" && test "x$with_libxml2" = "xyes"
-then
-       plugin_curl_xml="yes"
+if test "x$with_libyajl" = "xyes"; then
+  plugin_ceph="yes"
 fi
 
-if test "x$with_libyajl" = "xyes"
-then
-       plugin_ceph="yes"
+if test "x$have_processor_info" = "xyes"; then
+  plugin_cpu="yes"
 fi
 
-if test "x$have_processor_info" = "xyes"
-then
-       plugin_cpu="yes"
+if test "x$have_sysctl" = "xyes"; then
+  plugin_cpu="yes"
+  plugin_memory="yes"
+  plugin_uptime="yes"
+  if test "x$ac_system" = "xDarwin"; then
+    plugin_swap="yes"
+  fi
 fi
-if test "x$have_sysctl" = "xyes"
-then
-       plugin_cpu="yes"
-       plugin_memory="yes"
-       plugin_uptime="yes"
-       if test "x$ac_system" = "xDarwin"
-       then
-               plugin_swap="yes"
-       fi
+
+if test "x$have_sysctlbyname" = "xyes"; then
+  plugin_contextswitch="yes"
+  plugin_cpu="yes"
+  plugin_memory="yes"
+  plugin_tcpconns="yes"
 fi
-if test "x$have_sysctlbyname" = "xyes"
-then
-       plugin_contextswitch="yes"
-       plugin_cpu="yes"
-       plugin_memory="yes"
-       plugin_tcpconns="yes"
+
+if test "x$have_getvfsstat" = "xyes" || test "x$have_getfsstat" = "xyes"; then
+  plugin_df="yes"
 fi
 
-# Df plugin: Check if we know how to determine mount points first.
-#if test "x$have_listmntent" = "xyes"; then
-#      plugin_df="yes"
-#fi
-if test "x$have_getvfsstat" = "xyes" || test "x$have_getfsstat" = "xyes"
-then
-       plugin_df="yes"
+if test "x$c_cv_have_two_getmntent" = "xyes" || test "x$have_getmntent" = "xgen" || test "x$have_getmntent" = "xsun"; then
+  plugin_df="yes"
 fi
-if test "x$c_cv_have_two_getmntent" = "xyes" || test "x$have_getmntent" = "xgen" || test "x$have_getmntent" = "xsun"
-then
-       plugin_df="yes"
+
+if test "x$c_cv_have_one_getmntent" = "xyes"; then
+  plugin_df="yes"
 fi
-#if test "x$have_getmntent" = "xseq"
-#then
-#      plugin_df="yes"
-#fi
-if test "x$c_cv_have_one_getmntent" = "xyes"
-then
-       plugin_df="yes"
+
+if test "x$c_cv_have_getmntent_r" = "xyes"; then
+  plugin_df="yes"
 fi
 
-if test "x$c_cv_have_getmntent_r" = "xyes"
-then
-       plugin_df="yes"
+if test "x$plugin_df" = "xyes"; then
+  plugin_df="no"
+  if test "x$have_statfs" = "xyes"; then
+    plugin_df="yes"
+  fi
+
+  if test "x$have_statvfs" = "xyes"; then
+    plugin_df="yes"
+  fi
 fi
 
-# Df plugin: Check if we have either `statfs' or `statvfs' second.
-if test "x$plugin_df" = "xyes"
-then
-       plugin_df="no"
-       if test "x$have_statfs" = "xyes"
-       then
-               plugin_df="yes"
-       fi
-       if test "x$have_statvfs" = "xyes"
-       then
-               plugin_df="yes"
-       fi
+if test "x$have_linux_sockios_h" = "xyes" && test "x$have_linux_ethtool_h" = "xyes"; then
+  plugin_ethstat="yes"
 fi
 
-if test "x$have_linux_sockios_h$have_linux_ethtool_h" = "xyesyes"
-then
-       plugin_ethstat="yes"
+if test "x$with_libgps" = "xyes"; then
+  plugin_gps="yes"
 fi
 
-if test "x$with_libgrpcpp" = "xyes" && test "x$with_libprotobuf" = "xyes" && test "x$have_protoc3" = "xyes" && test "x$GRPC_CPP_PLUGIN" != "x"
-then
-       plugin_grpc="yes"
+if test "x$with_libgrpcpp" = "xyes" && test "x$with_libprotobuf" = "xyes" && test "x$have_protoc3" = "xyes" && test "x$GRPC_CPP_PLUGIN" != "x"; then
+  plugin_grpc="yes"
 fi
 
-if test "x$have_getifaddrs" = "xyes"
-then
-       plugin_interface="yes"
+if test "x$have_getifaddrs" = "xyes"; then
+  plugin_interface="yes"
 fi
 
-if test "x$with_libgps" = "xyes"
-then
-       plugin_gps="yes"
+if test "x$have_getloadavg" = "xyes"; then
+  plugin_load="yes"
 fi
 
-if test "x$have_getloadavg" = "xyes"
-then
-       plugin_load="yes"
+if test "x$with_libyajl" = "xyes"; then
+  plugin_log_logstash="yes"
 fi
 
-if test "x$with_libyajl" = "xyes"
-then
-       plugin_log_logstash="yes"
+if test "x$with_libyajl" = "xyes" && test "x$with_libyajl2" = "xyes"; then
+  plugin_ovs_events="yes"
 fi
 
-if test "x$c_cv_have_libperl$c_cv_have_perl_ithreads" = "xyesyes"
-then
-       plugin_perl="yes"
+if test "x$with_libperl" = "xyes" && test "x$c_cv_have_perl_ithreads" = "xyes"; then
+  plugin_perl="yes"
 fi
 
-if test "x$have_protoc_c" = "xyes" && test "x$with_libprotobuf_c" = "xyes"
-then
-       plugin_pinba="yes"
-       if test "x$with_libmicrohttpd" = "xyes"
-       then
-               plugin_write_prometheus="yes"
-       fi
+if test "x$have_protoc_c" = "xyes" && test "x$with_libprotobuf_c" = "xyes"; then
+  plugin_pinba="yes"
+  if test "x$with_libmicrohttpd" = "xyes"; then
+    plugin_write_prometheus="yes"
+  fi
 fi
 
 # Mac OS X memory interface
-if test "x$have_host_statistics" = "xyes"
-then
-       plugin_memory="yes"
+if test "x$have_host_statistics" = "xyes"; then
+  plugin_memory="yes"
 fi
 
-if test "x$have_termios_h" = "xyes"
-then
-       if test "x$ac_system" != "xAIX"
-       then
-               plugin_multimeter="yes"
-       fi
-       plugin_ted="yes"
+if test "x$have_termios_h" = "xyes"; then
+  if test "x$ac_system" != "xAIX"; then
+    plugin_multimeter="yes"
+  fi
+  plugin_ted="yes"
 fi
 
-if test "x$have_thread_info" = "xyes"
-then
-       plugin_processes="yes"
+if test "x$have_thread_info" = "xyes"; then
+  plugin_processes="yes"
 fi
 
-if test "x$with_kvm_getprocs" = "xyes" && test "x$have_struct_kinfo_proc_freebsd" = "xyes"
-then
-       plugin_processes="yes"
+if test "x$with_kvm_getprocs" = "xyes" && test "x$have_struct_kinfo_proc_freebsd" = "xyes"; then
+  plugin_processes="yes"
 fi
 
-if test "x$with_kvm_getprocs" = "xyes" && test "x$have_struct_kinfo_proc_openbsd" = "xyes"
-then
-       plugin_processes="yes"
+if test "x$with_kvm_getprocs" = "xyes" && test "x$have_struct_kinfo_proc_openbsd" = "xyes"; then
+  plugin_processes="yes"
 fi
 
-if test "x$with_libpython" != "xno"
-then
-       plugin_python="yes"
+if test "x$with_libpython" != "xno"; then
+  plugin_python="yes"
 fi
 
-if test "x$with_libatasmart" = "xyes" && test "x$with_libudev" = "xyes"
-then
-       plugin_smart="yes"
+if test "x$with_libatasmart" = "xyes" && test "x$with_libudev" = "xyes"; then
+  plugin_smart="yes"
 fi
 
-if test "x$with_kvm_getswapinfo" = "xyes"
-then
-       plugin_swap="yes"
+if test "x$with_kvm_getswapinfo" = "xyes"; then
+  plugin_swap="yes"
 fi
 
-if test "x$have_swapctl" = "xyes" && test "x$c_cv_have_swapctl_two_args" = "xyes"
-then
-       plugin_swap="yes"
+if test "x$have_swapctl" = "xyes" && test "x$c_cv_have_swapctl_two_args" = "xyes"; then
+  plugin_swap="yes"
 fi
 
-if test "x$have_swapctl" = "xyes" && test "x$c_cv_have_swapctl_three_args" = "xyes"
-then
-       plugin_swap="yes"
+if test "x$have_swapctl" = "xyes" && test "x$c_cv_have_swapctl_three_args" = "xyes"; then
+  plugin_swap="yes"
 fi
 
-if test "x$with_kvm_openfiles$with_kvm_nlist" = "xyesyes"
-then
-       plugin_tcpconns="yes"
+if test "x$with_kvm_openfiles = "xyes" && $with_kvm_nlist" = "xyes"; then
+  plugin_tcpconns="yes"
 fi
 
-if test "x$have_getutent" = "xyes"
-then
-       plugin_users="yes"
+if test "x$have_getutent" = "xyes"; then
+  plugin_users="yes"
 fi
-if test "x$have_getutxent" = "xyes"
-then
-       plugin_users="yes"
+
+if test "x$have_getutxent" = "xyes"; then
+  plugin_users="yes"
 fi
 
-if test "x$with_libxml2" = "xyes" && test "x$with_libvirt" = "xyes"
-then
-       plugin_virt="yes"
+if test "x$with_libxml2" = "xyes" && test "x$with_libvirt" = "xyes"; then
+  plugin_virt="yes"
 fi
 
-if test "x$with_libxenctrl" = "xyes"
-then
+if test "x$with_libxenctrl" = "xyes"; then
   plugin_xencpu="yes"
 fi
 
 if test "x$with_libdpdk" = "xyes"
 then
+  plugin_dpdkevents="$dpdk_keepalive"
   plugin_dpdkstat="yes"
 fi
 
@@ -6353,19 +6261,18 @@ m4_divert_once([HELP_ENABLE], [
 collectd plugins:])
 
 AC_ARG_ENABLE([all-plugins],
-               AS_HELP_STRING([--enable-all-plugins],[enable all plugins (auto by def)]),
-               [
-                if test "x$enableval" = "xyes"
-                then
-                        enable_all_plugins="yes"
-                else if test "x$enableval" = "xauto"
-                then
-                        enable_all_plugins="auto"
-                else
-                        enable_all_plugins="no"
-                fi; fi
-               ],
-               [enable_all_plugins="auto"])
+  [AS_HELP_STRING([--enable-all-plugins], [enable all plugins @<:@default=yes@:>@])],
+  [
+     if test "x$enableval" = "xyes"; then
+       enable_all_plugins="yes"
+     else if test "x$enableval" = "xauto"; then
+       enable_all_plugins="auto"
+     else
+       enable_all_plugins="no"
+     fi; fi
+  ],
+  [enable_all_plugins="auto"]
+)
 
 m4_divert_once([HELP_ENABLE], [])
 
@@ -6395,7 +6302,8 @@ AC_PLUGIN([dbi],                 [$with_libdbi],            [General database st
 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([dpdkstat],            [$plugin_dpdkstat],        [Stats & Status from DPDK])
+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])
 AC_PLUGIN([entropy],             [$plugin_entropy],         [Entropy statistics])
@@ -6430,6 +6338,7 @@ AC_PLUGIN([match_regex],         [yes],                     [The regex match])
 AC_PLUGIN([match_timediff],      [yes],                     [The timediff match])
 AC_PLUGIN([match_value],         [yes],                     [The value match])
 AC_PLUGIN([mbmon],               [yes],                     [Query mbmond])
+AC_PLUGIN([mcelog],              [$plugin_mcelog],          [Machine Check Exceptions notifications])
 AC_PLUGIN([md],                  [$have_linux_raid_md_u_h], [md (Linux software RAID) devices])
 AC_PLUGIN([memcachec],           [$with_libmemcached],      [memcachec statistics])
 AC_PLUGIN([memcached],           [yes],                     [memcached statistics])
@@ -6455,6 +6364,7 @@ AC_PLUGIN([onewire],             [$with_libowcapi],         [OneWire sensor stat
 AC_PLUGIN([openldap],            [$with_libldap],           [OpenLDAP statistics])
 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([perl],                [$plugin_perl],            [Embed a Perl interpreter])
 AC_PLUGIN([pf],                  [$have_net_pfvar_h],       [BSD packet filter (PF) statistics])
 # FIXME: Check for libevent, too.
@@ -6526,45 +6436,41 @@ LOAD_PLUGIN_LOG_LOGSTASH=""
 
 AC_MSG_CHECKING([which default log plugin to load])
 default_log_plugin="none"
-if test "x$enable_syslog" = "xyes"
-then
-       default_log_plugin="syslog"
+if test "x$enable_syslog" = "xyes"; then
+  default_log_plugin="syslog"
 else
-       LOAD_PLUGIN_SYSLOG="##"
+  LOAD_PLUGIN_SYSLOG="##"
 fi
 
-if test "x$enable_logfile" = "xyes"
-then
-       if test "x$default_log_plugin" = "xnone"
-       then
-               default_log_plugin="logfile"
-       else
-               LOAD_PLUGIN_LOGFILE="#"
-       fi
+if test "x$enable_logfile" = "xyes"; then
+  if test "x$default_log_plugin" = "xnone"; then
+    default_log_plugin="logfile"
+  else
+    LOAD_PLUGIN_LOGFILE="#"
+  fi
 else
-       LOAD_PLUGIN_LOGFILE="##"
+  LOAD_PLUGIN_LOGFILE="##"
 fi
 
-if test "x$enable_log_logstash" = "xyes"
-then
+if test "x$enable_log_logstash" = "xyes"; then
   LOAD_PLUGIN_LOG_LOGSTASH="#"
 else
   LOAD_PLUGIN_LOG_LOGSTASH="##"
 fi
 
-
 AC_MSG_RESULT([$default_log_plugin])
 
-AC_SUBST(LOAD_PLUGIN_SYSLOG)
-AC_SUBST(LOAD_PLUGIN_LOGFILE)
-AC_SUBST(LOAD_PLUGIN_LOG_LOGSTASH)
+AC_SUBST([LOAD_PLUGIN_SYSLOG])
+AC_SUBST([LOAD_PLUGIN_LOGFILE])
+AC_SUBST([LOAD_PLUGIN_LOG_LOGSTASH])
 
-DEFAULT_LOG_LEVEL="info"
 if test "x$enable_debug" = "xyes"
 then
-       DEFAULT_LOG_LEVEL="debug"
+  DEFAULT_LOG_LEVEL="debug"
+else
+  DEFAULT_LOG_LEVEL="info"
 fi
-AC_SUBST(DEFAULT_LOG_LEVEL)
+AC_SUBST([DEFAULT_LOG_LEVEL])
 
 # Load only one of rrdtool, network, csv in the default config.
 LOAD_PLUGIN_RRDTOOL=""
@@ -6573,73 +6479,65 @@ LOAD_PLUGIN_CSV=""
 
 AC_MSG_CHECKING([which default write plugin to load])
 default_write_plugin="none"
-if test "x$enable_rrdtool" = "xyes"
-then
-       default_write_plugin="rrdtool"
+if test "x$enable_rrdtool" = "xyes"; then
+  default_write_plugin="rrdtool"
 else
-       LOAD_PLUGIN_RRDTOOL="##"
+  LOAD_PLUGIN_RRDTOOL="##"
 fi
 
-if test "x$enable_network" = "xyes"
-then
-       if test "x$default_write_plugin" = "xnone"
-       then
-               default_write_plugin="network"
-       else
-               LOAD_PLUGIN_NETWORK="#"
-       fi
+if test "x$enable_network" = "xyes"; then
+  if test "x$default_write_plugin" = "xnone"; then
+    default_write_plugin="network"
+  else
+    LOAD_PLUGIN_NETWORK="#"
+  fi
 else
-       LOAD_PLUGIN_NETWORK="##"
+  LOAD_PLUGIN_NETWORK="##"
 fi
 
-if test "x$enable_csv" = "xyes"
-then
-       if test "x$default_write_plugin" = "xnone"
-       then
-               default_write_plugin="csv"
-       else
-               LOAD_PLUGIN_CSV="#"
-       fi
+if test "x$enable_csv" = "xyes"; then
+  if test "x$default_write_plugin" = "xnone"; then
+    default_write_plugin="csv"
+  else
+    LOAD_PLUGIN_CSV="#"
+  fi
 else
-       LOAD_PLUGIN_CSV="##"
+  LOAD_PLUGIN_CSV="##"
 fi
 AC_MSG_RESULT([$default_write_plugin])
 
-AC_SUBST(LOAD_PLUGIN_RRDTOOL)
-AC_SUBST(LOAD_PLUGIN_NETWORK)
-AC_SUBST(LOAD_PLUGIN_CSV)
+AC_SUBST([LOAD_PLUGIN_RRDTOOL])
+AC_SUBST([LOAD_PLUGIN_NETWORK])
+AC_SUBST([LOAD_PLUGIN_CSV])
 
 dnl ip_vs.h
-if test "x$ac_system" = "xLinux" \
-       && test "x$have_linux_ip_vs_h$have_net_ip_vs_h$have_ip_vs_h" = "xnonono"
-then
-       enable_ipvs="$enable_ipvs (ip_vs.h not found)"
+if test "x$ac_system" = "xLinux" && test "x$have_linux_ip_vs_h" = "xno" && "x$have_net_ip_vs_h" = "xno" && "x$have_ip_vs_h" = "xno"; then
+  enable_ipvs="$enable_ipvs (ip_vs.h not found)"
 fi
 
-if test "x$ip_vs_h_needs_kernel_cflags" = "xyes"
-then
-       enable_ipvs="$enable_ipvs (needs $KERNEL_CFLAGS)"
+if test "x$ip_vs_h_needs_kernel_cflags" = "xyes"; then
+  enable_ipvs="$enable_ipvs (needs $KERNEL_CFLAGS)"
 fi
 
 dnl Perl bindings
 PERL_BINDINGS_OPTIONS="PREFIX=${prefix}"
 AC_ARG_WITH(perl-bindings, [AS_HELP_STRING([--with-perl-bindings@<:@=OPTIONS@:>@], [Options passed to "perl Makefile.PL".])],
 [
-       if test "x$withval" != "xno" && test "x$withval" != "xyes"
-       then
-               PERL_BINDINGS_OPTIONS="$withval"
-               with_perl_bindings="yes"
-       else
-               with_perl_bindings="$withval"
-       fi
+  if test "x$withval" != "xno" && test "x$withval" != "xyes"
+  then
+    PERL_BINDINGS_OPTIONS="$withval"
+    with_perl_bindings="yes"
+  else
+    with_perl_bindings="$withval"
+  fi
 ],
 [
-       if test -n "$perl_interpreter"
-       then
-               with_perl_bindings="yes"
-       else
-               with_perl_bindings="no (no perl interpreter found)"
-       fi
+  if test "x$PERL" != "x"
+  then
+    with_perl_bindings="yes"
+  else
+    with_perl_bindings="no (no perl interpreter found)"
+  fi
 ])
 
 if test "x$with_perl_bindings" = "xyes"
@@ -6655,12 +6553,13 @@ fi
 
 if test "x$with_perl_bindings" = "xyes"
 then
-       PERL_BINDINGS="perl"
+  PERL_BINDINGS="perl"
 else
-       PERL_BINDINGS=""
+  PERL_BINDINGS=""
 fi
-AC_SUBST(PERL_BINDINGS)
-AC_SUBST(PERL_BINDINGS_OPTIONS)
+
+AC_SUBST([PERL_BINDINGS])
+AC_SUBST([PERL_BINDINGS_OPTIONS])
 
 dnl libcollectdclient
 LCC_VERSION_MAJOR=`echo $PACKAGE_VERSION | cut -d'.' -f1`
@@ -6671,49 +6570,48 @@ LCC_VERSION_EXTRA=`echo $PACKAGE_VERSION | cut -d'.' -f4-`
 
 LCC_VERSION_STRING="$LCC_VERSION_MAJOR.$LCC_VERSION_MINOR.$LCC_VERSION_PATCH"
 
-AC_SUBST(LCC_VERSION_MAJOR)
-AC_SUBST(LCC_VERSION_MINOR)
-AC_SUBST(LCC_VERSION_PATCH)
-AC_SUBST(LCC_VERSION_EXTRA)
-AC_SUBST(LCC_VERSION_STRING)
+AC_SUBST([LCC_VERSION_MAJOR])
+AC_SUBST([LCC_VERSION_MINOR])
+AC_SUBST([LCC_VERSION_PATCH])
+AC_SUBST([LCC_VERSION_EXTRA])
+AC_SUBST([LCC_VERSION_STRING])
 
-AC_CONFIG_FILES(src/libcollectdclient/collectd/lcc_features.h)
+AC_CONFIG_FILES([src/libcollectdclient/collectd/lcc_features.h])
 
 AM_CFLAGS="-Wall"
 AM_CXXFLAGS="-Wall"
-if test "x$enable_werror" != "xno"
-then
-        AM_CFLAGS="$AM_CFLAGS -Werror"
-        AM_CXXFLAGS="$AM_CXXFLAGS -Werror"
+if test "x$enable_werror" != "xno"; then
+  AM_CFLAGS="$AM_CFLAGS -Werror"
+  AM_CXXFLAGS="$AM_CXXFLAGS -Werror"
 fi
+
 AC_SUBST([AM_CFLAGS])
 AC_SUBST([AM_CXXFLAGS])
 
-AC_CONFIG_FILES([Makefile proto/Makefile src/Makefile src/daemon/Makefile src/collectd.conf src/libcollectdclient/Makefile src/libcollectdclient/libcollectdclient.pc src/liboconfig/Makefile bindings/Makefile bindings/java/Makefile])
+AC_CONFIG_FILES([ \
+  Makefile \
+  src/collectd.conf \
+  src/libcollectdclient/libcollectdclient.pc \
+])
+
 AC_OUTPUT
 
-if test "x$with_librrd" = "xyes" \
-       && test "x$librrd_threadsafe" != "xyes"
-then
-       with_librrd="yes (warning: librrd is not thread-safe)"
+if test "x$with_librrd" = "xyes" && test "x$librrd_threadsafe" != "xyes"; then
+  with_librrd="yes (warning: librrd is not thread-safe)"
 fi
 
-if test "x$with_libperl" = "xyes"
-then
-       with_libperl="yes (version `$perl_interpreter -MConfig -e 'print $Config{version};'`)"
+if test "x$with_libperl" = "xyes"; then
+  with_libperl="yes (version `$PERL -MConfig -e 'print $Config{version};'`)"
 else
-       enable_perl="no (needs libperl)"
+  enable_perl="no (needs libperl)"
 fi
 
-if test "x$enable_perl" = "xno" && test "x$c_cv_have_perl_ithreads" = "xno"
-then
-       enable_perl="no (libperl doesn't support ithreads)"
+if test "x$enable_perl" = "xno" && test "x$c_cv_have_perl_ithreads" = "xno"; then
+  enable_perl="no (libperl doesn't support ithreads)"
 fi
 
-if test "x$with_perl_bindings" = "xyes" \
-       && test "x$PERL_BINDINGS_OPTIONS" != "x"
-then
-       with_perl_bindings="yes ($PERL_BINDINGS_OPTIONS)"
+if test "x$with_perl_bindings" = "xyes" && test "x$PERL_BINDINGS_OPTIONS" != "x"; then
+  with_perl_bindings="yes ($PERL_BINDINGS_OPTIONS)"
 fi
 
 AC_MSG_RESULT()
@@ -6744,7 +6642,6 @@ AC_MSG_RESULT([    libganglia  . . . . . $with_libganglia])
 AC_MSG_RESULT([    libgcrypt . . . . . . $with_libgcrypt])
 AC_MSG_RESULT([    libgps  . . . . . . . $with_libgps])
 AC_MSG_RESULT([    libgrpc++ . . . . . . $with_libgrpcpp])
-AC_MSG_RESULT([    libhal  . . . . . . . $with_libhal])
 AC_MSG_RESULT([    libhiredis  . . . . . $with_libhiredis])
 AC_MSG_RESULT([    libi2c-dev  . . . . . $with_libi2c])
 AC_MSG_RESULT([    libiokit  . . . . . . $with_libiokit])
@@ -6765,7 +6662,6 @@ AC_MSG_RESULT([    libmysql  . . . . . . $with_libmysql])
 AC_MSG_RESULT([    libnetapp . . . . . . $with_libnetapp])
 AC_MSG_RESULT([    libnetsnmp  . . . . . $with_libnetsnmp])
 AC_MSG_RESULT([    libnotify . . . . . . $with_libnotify])
-AC_MSG_RESULT([    liboconfig  . . . . . $with_liboconfig])
 AC_MSG_RESULT([    libopenipmi . . . . . $with_libopenipmipthread])
 AC_MSG_RESULT([    liboping  . . . . . . $with_liboping])
 AC_MSG_RESULT([    libowcapi . . . . . . $with_libowcapi])
@@ -6832,6 +6728,7 @@ AC_MSG_RESULT([    dbi . . . . . . . . . $enable_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])
@@ -6846,7 +6743,7 @@ AC_MSG_RESULT([    gps . . . . . . . . . $enable_gps])
 AC_MSG_RESULT([    grpc  . . . . . . . . $enable_grpc])
 AC_MSG_RESULT([    hddtemp . . . . . . . $enable_hddtemp])
 AC_MSG_RESULT([    hugepages . . . . . . $enable_hugepages])
-AC_MSG_RESULT([    intel_rdt. . . . .  . $enable_intel_rdt])
+AC_MSG_RESULT([    intel_rdt . . . . . . $enable_intel_rdt])
 AC_MSG_RESULT([    interface . . . . . . $enable_interface])
 AC_MSG_RESULT([    ipc . . . . . . . . . $enable_ipc])
 AC_MSG_RESULT([    ipmi  . . . . . . . . $enable_ipmi])
@@ -6867,6 +6764,7 @@ AC_MSG_RESULT([    match_regex . . . . . $enable_match_regex])
 AC_MSG_RESULT([    match_timediff  . . . $enable_match_timediff])
 AC_MSG_RESULT([    match_value . . . . . $enable_match_value])
 AC_MSG_RESULT([    mbmon . . . . . . . . $enable_mbmon])
+AC_MSG_RESULT([    mcelog  . . . . . . . $enable_mcelog])
 AC_MSG_RESULT([    md  . . . . . . . . . $enable_md])
 AC_MSG_RESULT([    memcachec . . . . . . $enable_memcachec])
 AC_MSG_RESULT([    memcached . . . . . . $enable_memcached])
@@ -6892,6 +6790,7 @@ AC_MSG_RESULT([    onewire . . . . . . . $enable_onewire])
 AC_MSG_RESULT([    openldap  . . . . . . $enable_openldap])
 AC_MSG_RESULT([    openvpn . . . . . . . $enable_openvpn])
 AC_MSG_RESULT([    oracle  . . . . . . . $enable_oracle])
+AC_MSG_RESULT([    ovs_events  . . . . . $enable_ovs_events])
 AC_MSG_RESULT([    perl  . . . . . . . . $enable_perl])
 AC_MSG_RESULT([    pf  . . . . . . . . . $enable_pf])
 AC_MSG_RESULT([    pinba . . . . . . . . $enable_pinba])
@@ -6956,11 +6855,11 @@ AC_MSG_RESULT([    zookeeper . . . . . . $enable_zookeeper])
 AC_MSG_RESULT()
 
 if test "x$dependency_error" = "xyes"; then
-       AC_MSG_ERROR("Some plugins are missing dependencies - see the summary above for details")
+  AC_MSG_ERROR("Some plugins are missing dependencies - see the summary above for details")
 fi
 
 if test "x$dependency_warning" = "xyes"; then
-       AC_MSG_WARN("Some plugins seem to have missing dependencies but have been enabled forcibly - see the summary above for details")
+  AC_MSG_WARN("Some plugins seem to have missing dependencies but have been enabled forcibly - see the summary above for details")
 fi
 
-# vim: set fdm=marker :
+# vim: set fdm=marker sw=2 sts=2 ts=2 et :
index 5f401f0..6e2ea19 100644 (file)
@@ -49,6 +49,21 @@ should look something like this:
   datadir: "/var/lib/collectd/rrd/"
   libdir: "/usr/lib/collectd/"
 
+docker/
+-------
+Sample docker setup using an LD_PRELOAD wrapper to redirect system calls
+accessing /proc and /sys to prefixed bind-mounts inside the container.
+
+Drop your collectd configuration snippets in the
+contrib/docker/collectd.conf.d/ directory, and build an image including them:
+ $ docker build -t my_collectd ./contrib/docker/
+
+Then run it with the required bind-mounts:
+ $ docker run -it --rm \
+    -v /proc:/rootfs/proc:ro -v /sys:/rootfs/sys:ro \
+    --name collectd my_collectd
+ $ docker exec -it collectd collectdctl listval
+
 exec-munin.px
 -------------
   Script to be used with the exec-plugin (see collectd-exec(5) for details)
diff --git a/contrib/docker/50docker-apt-conf b/contrib/docker/50docker-apt-conf
new file mode 100644 (file)
index 0000000..3f898b3
--- /dev/null
@@ -0,0 +1,4 @@
+APT::Install-Recommends "0";
+APT::Install-Suggests "0";
+APT::Get::Assume-Yes "1";
+APT::Get::AutomaticRemove "1";
diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile
new file mode 100644 (file)
index 0000000..a691f2e
--- /dev/null
@@ -0,0 +1,24 @@
+FROM debian:stable
+
+ENV DEBIAN_FRONTEND noninteractive
+COPY 50docker-apt-conf /etc/apt/apt.conf.d/
+
+COPY rootfs_prefix/ /usr/src/rootfs_prefix/
+
+RUN apt-get update \
+ && apt-get upgrade \
+ && apt-get install \
+    collectd-core \
+    collectd-utils \
+    build-essential \
+ && make -C /usr/src/rootfs_prefix/ \
+ && apt-get --purge remove build-essential \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/*
+
+COPY collectd.conf /etc/collectd/collectd.conf
+COPY collectd.conf.d /etc/collectd/collectd.conf.d
+
+ENV LD_PRELOAD /usr/src/rootfs_prefix/rootfs_prefix.so
+
+CMD [ "/usr/sbin/collectd", "-f"]
diff --git a/contrib/docker/collectd.conf b/contrib/docker/collectd.conf
new file mode 100644 (file)
index 0000000..bbcd079
--- /dev/null
@@ -0,0 +1,16 @@
+LoadPlugin logfile
+<Plugin logfile>
+       LogLevel "info"
+       File STDOUT
+       Timestamp true
+       PrintSeverity true
+</Plugin>
+
+LoadPlugin unixsock
+<Plugin unixsock>
+        SocketGroup "nogroup"
+</Plugin>
+
+<Include "/etc/collectd/collectd.conf.d">
+        Filter "*.conf"
+</Include>
diff --git a/contrib/docker/collectd.conf.d/sample.conf b/contrib/docker/collectd.conf.d/sample.conf
new file mode 100644 (file)
index 0000000..cbd7ce1
--- /dev/null
@@ -0,0 +1,4 @@
+LoadPlugin cpu
+LoadPlugin memory
+LoadPlugin disk
+LoadPlugin df
diff --git a/contrib/docker/rootfs_prefix/.gitignore b/contrib/docker/rootfs_prefix/.gitignore
new file mode 100644 (file)
index 0000000..c95ccf8
--- /dev/null
@@ -0,0 +1 @@
+rootprefix.so
diff --git a/contrib/docker/rootfs_prefix/Makefile b/contrib/docker/rootfs_prefix/Makefile
new file mode 100644 (file)
index 0000000..f26bebd
--- /dev/null
@@ -0,0 +1,2 @@
+rootfs_prefix.so: rootfs_prefix.c
+       $(CC) -Wall -Werror -fPIC -shared -o rootfs_prefix.so rootfs_prefix.c -ldl
diff --git a/contrib/docker/rootfs_prefix/rootfs_prefix.c b/contrib/docker/rootfs_prefix/rootfs_prefix.c
new file mode 100644 (file)
index 0000000..2b83151
--- /dev/null
@@ -0,0 +1,58 @@
+#define _GNU_SOURCE
+
+#include <dirent.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <error.h>
+#include <stdio.h>
+#include <string.h>
+
+#define PREFIX "/rootfs"
+#define BUFSIZE 256
+
+const char *add_prefix(const char *orig, char *prefixed) {
+  if ((strncmp(orig, "/proc", strlen("/proc")) != 0) &&
+      (strncmp(orig, "/sys", strlen("/sys")) != 0))
+    return orig;
+
+  int status = snprintf(prefixed, BUFSIZE, "%s%s", PREFIX, orig);
+  if (status < 1) {
+    error(status, errno, "adding '%s' prefix to file path failed: '%s' -> '%s'",
+          PREFIX, orig, prefixed);
+    return orig;
+  } else if ((unsigned int)status >= BUFSIZE) {
+    error(status, ENAMETOOLONG,
+          "'%s' got truncated when adding '%s' prefix: '%s'", orig, PREFIX,
+          prefixed);
+    return orig;
+  } else {
+    return (const char *)prefixed;
+  }
+}
+
+FILE *fopen(const char *path, const char *mode) {
+  char filename[BUFSIZE] = "\0";
+
+  FILE *(*original_fopen)(const char *, const char *);
+  original_fopen = dlsym(RTLD_NEXT, "fopen");
+
+  return (*original_fopen)(add_prefix(path, filename), mode);
+}
+
+DIR *opendir(const char *name) {
+  char filename[BUFSIZE] = "\0";
+
+  DIR *(*original_opendir)(const char *);
+  original_opendir = dlsym(RTLD_NEXT, "opendir");
+
+  return (*original_opendir)(add_prefix(name, filename));
+}
+
+int *open(const char *pathname, int flags) {
+  char filename[BUFSIZE] = "\0";
+
+  int *(*original_open)(const char *, int);
+  original_open = dlsym(RTLD_NEXT, "open");
+
+  return (*original_open)(add_prefix(pathname, filename), flags);
+}
index abad290..451589d 100644 (file)
@@ -88,6 +88,7 @@
 %define with_lvm 0%{!?_without_lvm:1}
 %define with_madwifi 0%{!?_without_madwifi:1}
 %define with_mbmon 0%{!?_without_mbmon:1}
+%define with_mcelog 0%{!?_without_mcelog:1}
 %define with_md 0%{!?_without_md:1}
 %define with_memcachec 0%{!?_without_memcachec:1}
 %define with_memcached 0%{!?_without_memcached:1}
 %define with_olsrd 0%{!?_without_olsrd:1}
 %define with_openldap 0%{!?_without_openldap:1}
 %define with_openvpn 0%{!?_without_openvpn:1}
+%define with_ovs_events 0%{!?_without_ovs_events:1}
 %define with_perl 0%{!?_without_perl:1}
 %define with_pinba 0%{!?_without_pinba:1}
 %define with_ping 0%{!?_without_ping:1}
 %define with_cpusleep 0
 %define with_gps 0
 %define with_mqtt 0
+%define with_ovs_events 0
 %define with_redis 0
 %define with_rrdcached 0
 %define with_write_redis 0
@@ -243,7 +246,7 @@ Source:             https://collectd.org/files/%{name}-%{version}.tar.bz2
 License:       GPLv2
 Group:         System Environment/Daemons
 BuildRoot:     %{_tmppath}/%{name}-%{version}-root
-BuildRequires: libgcrypt-devel, kernel-headers, libtool-ltdl-devel, libcap-devel, which, xfsprogs-devel
+BuildRequires: libgcrypt-devel, kernel-headers, libcap-devel, which, xfsprogs-devel
 Vendor:                collectd development team <collectd@verplant.org>
 
 %if 0%{?fedora} || 0%{?rhel} >= 7
@@ -539,6 +542,16 @@ This plugin collects size of “Logical Volumes” (LV) and “Volume Groups”
 of Linux' “Logical Volume Manager” (LVM).
 %endif
 
+%if %{with_mcelog}
+%package mcelog
+Summary:       Mcelog plugin for collectd
+Group:         System Environment/Daemons
+Requires:      %{name}%{?_isa} = %{version}-%{release}
+%description mcelog
+This plugin monitors machine check exceptions reported by mcelog and generates
+appropriate notifications when machine check exceptions are detected.
+%endif
+
 %if %{with_memcachec}
 %package memcachec
 Summary:       Memcachec plugin for collectd
@@ -654,6 +667,18 @@ BuildRequires: openldap-devel
 This plugin reads monitoring information from OpenLDAP's cn=Monitor subtree.
 %endif
 
+%if %{with_ovs_events}
+%package ovs_events
+Summary:       Open vSwitch events plugin for collectd
+Group:         System Environment/Daemons
+Requires:      %{name}%{?_isa} = %{version}-%{release}
+BuildRequires: yajl-devel
+%description ovs_events
+This plugin monitors the link status of Open vSwitch (OVS) connected
+interfaces, dispatches the values to collectd and sends notifications
+whenever a link state change occurs in the OVS database.
+%endif
+
 %if %{with_perl}
 %package perl
 Summary:       Perl plugin for collectd
@@ -1280,6 +1305,12 @@ Collectd utilities
 %define _with_mbmon --disable-mbmon
 %endif
 
+%if %{with_mcelog}
+%define _with_mcelog --enable-mcelog
+%else
+%define _with_mbmon --disable-mcelog
+%endif
+
 %if %{with_md}
 %define _with_md --enable-md
 %else
@@ -1430,6 +1461,12 @@ Collectd utilities
 %define _with_oracle --disable-oracle
 %endif
 
+%if %{with_ovs_events}
+%define _with_ovs_events --enable-ovs_events
+%else
+%define _with_ovs_events --disable-ovs_events
+%endif
+
 %if %{with_perl}
 %define _with_perl --enable-perl --with-perl-bindings="INSTALLDIRS=vendor"
 %else
@@ -1768,7 +1805,6 @@ Collectd utilities
 %configure CFLAGS="%{optflags} -DLT_LAZY_OR_NOW=\"RTLD_LAZY|RTLD_GLOBAL\"" \
        %{?_python_config} \
        --disable-static \
-       --without-included-ltdl \
        --enable-all-plugins=yes \
        --enable-match_empty_counter \
        --enable-match_hashed \
@@ -1836,6 +1872,7 @@ Collectd utilities
        %{?_with_lvm} \
        %{?_with_madwifi} \
        %{?_with_mbmon} \
+       %{?_with_mcelog} \
        %{?_with_md} \
        %{?_with_memcachec} \
        %{?_with_memcached} \
@@ -1861,6 +1898,7 @@ Collectd utilities
        %{?_with_openldap} \
        %{?_with_openvpn} \
        %{?_with_oracle} \
+       %{?_with_ovs_events} \
        %{?_with_perl} \
        %{?_with_pf} \
        %{?_with_pinba} \
@@ -2135,6 +2173,9 @@ fi
 %if %{with_mbmon}
 %{_libdir}/%{name}/mbmon.so
 %endif
+%if %{with_mcelog}
+%{_libdir}/%{name}/mcelog.so
+%endif
 %if %{with_md}
 %{_libdir}/%{name}/md.so
 %endif
@@ -2168,6 +2209,9 @@ fi
 %if %{with_olsrd}
 %{_libdir}/%{name}/olsrd.so
 %endif
+%if %{with_ovs_events}
+%{_libdir}/%{name}/ovs_events.so
+%endif
 %if %{with_powerdns}
 %{_libdir}/%{name}/powerdns.so
 %endif
@@ -2595,6 +2639,12 @@ fi
 * Sun Jan 01 2017 Marc Fournier <marc.fournier@camptocamp.com> - 5.7.1-1
 - New upstream version
 
+* Sat Dec 31 2016 Ruben Kerkhof <ruben@rubenkerkhof.com> - 5.7.0-4
+- Add new ovs_events plugin
+
+* Sat Dec 31 2016 Ruben Kerkhof <ruben@rubenkerkhof.com> - 5.7.0-3
+- Add new mcelog plugin
+
 * Tue Nov 29 2016 Ruben Kerkhof <ruben@rubenkerkhof.com> - 5.7.0-2
 - Disable redis plugin on RHEL 6, hiredis has been retired from EPEL6
 
index 7bc15d7..4e2f6ae 100644 (file)
@@ -18,6 +18,7 @@ ProtectHome=true
 #   ceph            CAP_DAC_OVERRIDE
 #   dns             CAP_NET_RAW
 #   exec            CAP_SETUID CAP_SETGID
+#   intel_rdt       CAP_SYS_RAWIO
 #   iptables        CAP_NET_ADMIN
 #   ping            CAP_NET_RAW
 #   smart           CAP_SYS_RAWIO
index 8991a61..fe9f0e6 100644 (file)
@@ -148,34 +148,6 @@ instruction set manually:
 
      *  Run `ldconfig` to update the shared library cache.
 
-### Static library
-
-To build static DPDK library for use with collectd:
-
- *  To configure DPDK to build the combined static library `libdpdk.a` ensure
-    that `CONFIG_RTE_BUILD_SHARED_LIB` is set to “n” in `config/common_base` in
-    your DPDK as follows:
-
-        #
-        # Compile to share library
-        #
-        CONFIG_RTE_BUILD_SHARED_LIB=n
-
- *  Prepare the configuration for the appropriate target as specified at:
-    http://dpdk.org/doc/guides/linux_gsg/build_dpdk.html.
-
-    For example:
-
-        make config T=x86_64-native-linuxapp-gcc
-
- *  Build the target using `-fPIC`:
-
-        make EXTRA_CFLAGS=-fPIC -j
-
- *  Install DPDK to `/usr`:
-
-        sudo make install prefix=/usr
-
 ## Build collectd with DPDK
 
 **Note:** DPDK 16.04 is the minimum version and currently supported version of
@@ -199,33 +171,32 @@ implications.
 See also: http://dpdk.org/doc/guides/prog_guide/multi_proc_support.html
 
  *  Generate the build script as specified below. (i.e. run `build.sh`).
- *  Configure collectd with the DPDK shared library:
-
-        ./configure --with-libdpdk=/usr
+ *  Configure collectd with the DPDK shared library. If DPDK is installed in
+    custom installation path you can specify headers include path using
+    LIBDPDK_CPPFLAGS variable and libraries path with LIBDPDK_LDFLAGS.
+    Example:
 
-### Build with the static DPDK library
+        ./configure
 
-To configure collectd with the DPDK static library:
+        or for custom DPKD installation:
 
- *  Run *configure* with the following CFLAGS:
+        ./configure LIBDPDK_CPPFLAGS="-I/home/joe/include/dpdk" LIBDPDK_LDFLAGS="-L/home/joe/usr/lib"
 
-        ./configure --with-libdpdk=/usr CFLAGS=" -lpthread -Wl,--whole-archive -Wl,-ldpdk -Wl,-lm -Wl,-lrt -Wl,-lpcap -Wl,-ldl -Wl,--no-whole-archive"
-
- *  Make sure that dpdk and dpdkstat are enabled in the *configure* output.
+ *  Make sure that libdpdk and dpdkstat are enabled in the *configure* output.
 
     Expected output:
 
         Libraries:
         ...
         libdpdk  . . . . . . . . yes
-        
+
         Modules:
         ...
         dpdkstat . . . . . . .yes
 
  *  Build collectd:
 
-        make -j && make -j install.
+    make -j && make -j install
 
     **Note:** As mentioned above, if you are building on Ubuntu 14.04 with
     GCC <= 4.8.X, you need to use:
diff --git a/docs/README.virt.md b/docs/README.virt.md
new file mode 100644 (file)
index 0000000..a80e9ea
--- /dev/null
@@ -0,0 +1,240 @@
+Inside the virt plugin
+======================
+
+Originally written: 20161111
+
+Last updated: 20161124
+
+This document will explain the new domain tag support introduced
+in the virt plugin, and will provide one important use case for this feature.
+In the reminder of this document, we consider
+
+* libvirt <= 2.0.0
+* QEMU <= 2.6.0
+
+
+Domain tags and domains partitioning across virt reader instances
+-----------------------------------------------------------------
+
+The virt plugin gained the `Instances` option. It allows to start
+more than one reader instance, so the the libvirt domains could be queried
+by more than one reader thread.
+The default value for `Instances` is `1`.
+With default settings, the plugin will behave in a fully transparent,
+backward compatible way.
+It is recommended to set this value to one multiple of the
+daemon `ReadThreads` value.
+
+Each reader instance will query only a subset of the libvirt domain.
+The subset is identified as follows:
+
+1. Each virt reader instance is named `virt-$NUM`, where `NUM` is
+   the progressive order of instances. If you configure `Instances 3`
+   you will have `virt-0`, `virt-1`, `virt-2`. Please note: the `virt-0`
+   instance is special, and will always be available.
+2. Each virt reader instance will iterate over all the libvirt active domains,
+   and will look for one `tag` attribute (see below) in the domain metadata section.
+3. Each virt reader instance will take care *only* of the libvirt domains whose
+   tag matches with its own
+4. The special `virt-0` instance will take care of all the libvirt domains with
+   no tags, or with tags which are not in the set \[virt-0 ... virt-$NUM\]
+
+Collectd will just use the domain tags, but never enforces or requires them.
+It is up to an external entity, like a software management system,
+to attach and manage the tags to the domain.
+
+Please note that unless you have such tag-aware management sofware,
+it most likely make no sense to enable more than one reader instance on your
+setup.
+
+
+Libvirt tag metadata format
+----------------------------
+
+This is the snipped to be added to libvirt domains:
+
+    <ovirtmap:tag xmlns:ovirtmap="http://ovirt.org/ovirtmap/tag/1.0">
+      $TAG
+    </ovirtmap:tag>
+
+it must be included in the <metadata> section.
+
+Check the `src/virt_test.c` file for really minimal example of libvirt domains.
+
+
+Examples
+--------
+
+### Example one: 10 libvirt domains named "domain-A" ... "domain-J", virt plugin with instances=5, using 5 different tags
+
+
+    libvirt domain name -    tag    - read instance - reason
+    domain-A                virt-0         0          tag match
+    domain-B                virt-1         1          tag match
+    domain-C                virt-2         2          tag match
+    domain-D                virt-3         3          tag match
+    domain-E                virt-4         4          tag match
+    domain-F                virt-0         0          tag match
+    domain-G                virt-1         1          tag match
+    domain-H                virt-2         2          tag match
+    domain-I                virt-3         3          tag match
+    domain-J                virt-4         4          tag match
+
+
+  Because the domain where properly tagged, all the read instances have even load. Please note that the the virt plugin
+  knows nothing, and should know nothing, about *how* the libvirt domain are tagged. This is entirely up to the
+  management system.
+
+
+Example two: 10 libvirt domains named "domain-A" ... "domain-J", virt plugin with instances=3, using 5 different tags
+
+
+    libvirt domain name -    tag    - read instance - reason
+    domain-A                virt-0         0          tag match
+    domain-B                virt-1         1          tag match
+    domain-C                virt-2         2          tag match
+    domain-D                virt-3         0          adopted by instance #0
+    domain-E                virt-4         0          adopted by instance #0
+    domain-F                virt-0         0          rag match
+    domain-G                virt-1         1          tag match
+    domain-H                virt-2         2          tag match
+    domain-I                virt-3         0          adopted by instance #0
+    domain-J                virt-4         0          adopted by instance #0
+
+
+  In this case we have uneven load, but no domain is ignored.
+
+
+### Example three: 10 libvirt domains named "domain-A" ... "domain-J", virt plugin with instances=5, using 3 different tags
+
+
+    libvirt domain name -    tag    - read instance - reason
+    domain-A                virt-0         0          tag match
+    domain-B                virt-1         1          tag match
+    domain-C                virt-2         2          tag match
+    domain-D                virt-0         0          tag match
+    domain-E                virt-1         1          tag match
+    domain-F                virt-2         2          tag match
+    domain-G                virt-0         0          tag match
+    domain-H                virt-1         1          tag match
+    domain-I                virt-2         2          tag match
+    domain-J                virt-0         0          tag match
+
+
+  Once again we have uneven load and two idle read instances, but besides that no domain is left unmonitored
+
+
+### Example four: 10 libvirt domains named "domain-A" ... "domain-J", virt plugin with instances=5, partial tagging
+
+
+    libvirt domain name -    tag    - read instance - reason
+    domain-A                virt-0         0          tag match
+    domain-B                virt-1         1          tag match
+    domain-C                virt-2         2          tag match
+    domain-D                virt-0         0          tag match
+    domain-E                               0          adopted by instance #0
+    domain-F                               0          adopted by instance #0
+    domain-G                               0          adopted by instance #0
+    domain-H                               0          adopted by instance #0
+    domain-I                               0          adopted by instance #0
+    domain-J                               0          adopted by instance #0
+
+
+The lack of tags causes uneven load, but no domain are unmonitored.
+
+
+Possible extensions - custom tag format
+---------------------------------------
+
+The aformentioned approach relies on fixed tag format, `virt-$N`. The algorithm works fine with any tag, which
+is just one string, compared for equality. However, using custom strings for tags creates the need for a mapping
+between tags and the read instances.
+This mapping needs to be updated as long as domain are created or destroyed, and the virt plugin needs to be
+notified of the changes.
+
+This adds a significant amount of complexity, with little gain with respect to the fixed schema adopted initially.
+For this reason, the introdution of dynamic, custom mapping was not implemented.
+
+
+Dealing with datacenters: libvirt, qemu, shared storage
+-------------------------------------------------------
+
+When used in a datacenter, QEMU is most often configured to use shared storage. This is
+the default configuration of datacenter management solutions like [oVirt](http://www.ovirt.org).
+The actual shared storage could be implemented on top of NFS for small installations, or most likely
+ISCSI or Fiber Channel. The key takeaway is that the storage is accessed over the network,
+not using e.g. the SATA or PCI bus of any given host, so any network issue could cause
+one or more storage operations to delay, or to be lost entirely.
+
+In that case, the userspace process that requested the operation can end up in the D state,
+and become unresponsive, and unkillable.
+
+
+Dealing with unresponsive domains
+---------------------------------
+
+All the above considered, one robust management or monitoring application must deal with the fact that
+the libvirt API can block for a long time, or forever. This is not an issue or a bug of one specific
+API, but it is rather a byproduct of how libvirt and QEMU interact.
+
+Whenever we query more than one VM, we should take care to avoid that one blocked VM prevent other,
+well behaving VMs to be queried. We don't want one rogue VM to disrupt well-behaving VMs.
+Unfortunately, any way we enumerate VMs, either implicitely, using the libvirt bulk stats API,
+or explicitely, listing all libvirt domains and query each one in turn, we may unpredictably encounter
+one unresponsive VM.
+
+There are many possible approaches to deal with this issue. The virt plugin supports
+a simple but effective approach partitioning the domains, as follows.
+
+1. The virt plugin always register one or more `read` callbacks. The `zero` read callback is guaranteed to
+   be always present, so it performs special duties (more details later)
+   Each callback will be named 'virt-$N', where `N` ranges from 0 (zero) to M-1, where M is the number of instances configured.
+   `M` equals to `5` by default, because this is the same default number of threads in the libvirt worker pool.
+2. Each of the read callbacks queries libvirt for the list of all the active domains, and retrieves the libvirt domain metadata.
+   Both of those operations are safe wrt domain blocked in I/O (they affect only the libvirtd daemon).
+3. Each of the read callbacks extracts the `tag` from the domain metadata using a well-known format (see below).
+   Each of the read callbacks discards any domain which has no tag, or whose tag doesn't match with the read callback tag.
+3.a. The read callback tag equals to the read callback name, thus `virt-$N`. Remember that `virt-0` is guaranteed to be
+     always present.
+3.b. Since the `virt-0` reader is always present, it will take care of domains with no tag, or with unrecognized tag.
+     One unrecognized tag is any tag which has not the scheme `virt-$N`.
+4. Each read callback only samples the subset of domains with matching tag. The `virt-0` reader will possibly do more,
+   but worst case the load will be unbalanced, no domain will be left unsampled.
+
+To make this approach work, some entity must attach the tags to the libvirt domains, in such a way that all
+the domains which run on a given host and insist on the same network-based storage share the same tag.
+This minimizes the disruption, because when using the shared storage, if one domain becomes unresponsive because
+of unavailable storage, the most likely thing to happen is that others domain using the same storage will soon become
+unavailable; should the box run other libvirt domains using other network-based storage, they could be monitored
+safely.
+
+In case of [oVirt](http://www.ovirt.org), the aforementioned tagging is performed by the host agent.
+
+Please note that this approach is ineffective if the host completely lose network access to the storage network.
+In this case, however, no recovery is possible and no damage limitation is possible.
+
+Lastly, please note that if the virt plugin is configured with instances=1, it behaves exactly like before.
+
+
+Addendum: high level overview: libvirt client, libvirt daemon, qemu
+--------------------------------------------------------------------
+
+Let's review how the client application (collectd + virt plugin), the libvirtd daemon and the
+QEMU processes interact with each other.
+
+The libvirt daemon talks to QEMU using the JSON QMP protcol over one unix domain socket.
+The details of the protocol are not important now, but the key part is that the protocol
+is a simple request/response, meaning that libvirtd must serialize all the interactions
+with the QEMU monitor, and must protects its endpoint with a lock.
+No out of order request/responses are possible (e.g. no pipelining or async replies).
+This means that if for any reason one QMP request could not be completed, any other caller
+trying to access the QEMU monitor will block until the blocked caller returns.
+
+To retrieve some key informations, most notably about the block device state or the balloon
+device state, the libvirtd daemon *must* use the QMP protocol.
+
+The QEMU core, including the handling of the QMP protocol, is single-threaded.
+All the above combined make it possible for a client to block forever waiting for one QMP
+request, if QEMU itself is blocked. The most likely cause of block is I/O, and this is especially
+true considering how QEMU is used in a datacenter.
+
diff --git a/m4/.gitignore b/m4/.gitignore
new file mode 100644 (file)
index 0000000..f935021
--- /dev/null
@@ -0,0 +1 @@
+!.gitignore
diff --git a/proto/Makefile.am b/proto/Makefile.am
deleted file mode 100644 (file)
index 62d3bed..0000000
+++ /dev/null
@@ -1 +0,0 @@
-EXTRA_DIST = collectd.proto types.proto prometheus.proto
diff --git a/src/Makefile.am b/src/Makefile.am
deleted file mode 100644 (file)
index 11bc17d..0000000
+++ /dev/null
@@ -1,1521 +0,0 @@
-SUBDIRS = libcollectdclient
-if BUILD_WITH_OWN_LIBOCONFIG
-SUBDIRS += liboconfig
-endif
-SUBDIRS += daemon
-
-PLUGIN_LDFLAGS = -module -avoid-version -export-symbols-regex '\<module_register\>'
-
-AM_CPPFLAGS = -I$(srcdir)/daemon
-AM_CPPFLAGS += -DPREFIX='"${prefix}"'
-AM_CPPFLAGS += -DCONFIGFILE='"${sysconfdir}/${PACKAGE_NAME}.conf"'
-AM_CPPFLAGS += -DLOCALSTATEDIR='"${localstatedir}"'
-AM_CPPFLAGS += -DPKGLOCALSTATEDIR='"${localstatedir}/lib/${PACKAGE_NAME}"'
-if BUILD_FEATURE_DAEMON
-AM_CPPFLAGS += -DPIDFILE='"${localstatedir}/run/${PACKAGE_NAME}.pid"'
-endif
-AM_CPPFLAGS += -DPLUGINDIR='"${pkglibdir}"'
-AM_CPPFLAGS += -DPKGDATADIR='"${pkgdatadir}"'
-
-LOG_COMPILER = env VALGRIND="@VALGRIND@" $(abs_top_srcdir)/testwrapper.sh
-
-V_PROTOC = $(v_protoc_@AM_V@)
-v_protoc_ = $(v_protoc_@AM_DEFAULT_V@)
-v_protoc_0 = @echo "  PROTOC  " $@;
-
-noinst_LTLIBRARIES =
-check_PROGRAMS =
-TESTS =
-
-noinst_LTLIBRARIES += libformat_graphite.la
-libformat_graphite_la_SOURCES  = utils_format_graphite.c utils_format_graphite.h
-libformat_graphite_la_CPPFLAGS = $(AM_CPPFLAGS)
-libformat_graphite_la_LDFLAGS  = $(AM_LDFLAGS)
-check_PROGRAMS += test_format_graphite
-TESTS += test_format_graphite
-test_format_graphite_SOURCES = utils_format_graphite_test.c testing.h
-test_format_graphite_LDADD = libformat_graphite.la daemon/libmetadata.la daemon/libplugin_mock.la -lm
-
-noinst_LTLIBRARIES += libformat_json.la
-libformat_json_la_SOURCES   = utils_format_json.c utils_format_json.h
-libformat_json_la_CPPFLAGS  = $(AM_CPPFLAGS)
-libformat_json_la_LDFLAGS   = $(AM_LDFLAGS)
-libformat_json_la_LIBADD    =
-if BUILD_WITH_LIBYAJL
-libformat_json_la_CPPFLAGS += $(BUILD_WITH_LIBYAJL_CPPFLAGS)
-libformat_json_la_LDFLAGS  += $(BUILD_WITH_LIBYAJL_LDFLAGS)
-libformat_json_la_LIBADD   += $(BUILD_WITH_LIBYAJL_LIBS)
-check_PROGRAMS += test_format_json
-TESTS += test_format_json
-test_format_json_SOURCES = utils_format_json_test.c testing.h
-test_format_json_LDADD = libformat_json.la daemon/libmetadata.la daemon/libplugin_mock.la -lm
-endif
-
-noinst_LTLIBRARIES += liblatency.la
-liblatency_la_SOURCES = utils_latency.c utils_latency.h utils_latency_config.c utils_latency_config.h
-liblatency_la_LIBADD = daemon/libcommon.la -lm
-check_PROGRAMS += test_utils_latency
-TESTS += test_utils_latency
-test_utils_latency_SOURCES = utils_latency_test.c testing.h
-test_utils_latency_LDADD = liblatency.la daemon/libplugin_mock.la -lm
-
-noinst_LTLIBRARIES += libcmds.la
-libcmds_la_SOURCES = utils_cmds.c utils_cmds.h \
-                     utils_cmd_flush.c utils_cmd_flush.h \
-                     utils_cmd_getthreshold.c utils_cmd_getthreshold.h \
-                     utils_cmd_getval.c utils_cmd_getval.h \
-                     utils_cmd_listval.c utils_cmd_listval.h \
-                     utils_cmd_putnotif.c utils_cmd_putnotif.h \
-                     utils_cmd_putval.c utils_cmd_putval.h \
-                     utils_parse_option.c utils_parse_option.h
-libcmds_la_LIBADD = daemon/libcommon.la daemon/libmetadata.la -lm
-check_PROGRAMS += test_utils_cmds
-TESTS += test_utils_cmds
-test_utils_cmds_SOURCES = utils_cmds_test.c testing.h
-test_utils_cmds_LDADD = libcmds.la \
-                        daemon/libplugin_mock.la
-
-noinst_LTLIBRARIES += liblookup.la
-liblookup_la_SOURCES = utils_vl_lookup.c utils_vl_lookup.h
-liblookup_la_LIBADD = daemon/libavltree.la
-check_PROGRAMS += test_utils_vl_lookup
-TESTS += test_utils_vl_lookup
-test_utils_vl_lookup_SOURCES = utils_vl_lookup_test.c testing.h
-test_utils_vl_lookup_LDADD = liblookup.la daemon/libplugin_mock.la
-if BUILD_WITH_LIBKSTAT
-test_utils_vl_lookup_LDADD += -lkstat
-endif
-
-noinst_LTLIBRARIES += libmount.la
-libmount_la_SOURCES = utils_mount.c utils_mount.h
-check_PROGRAMS += test_utils_mount
-TESTS += test_utils_mount
-test_utils_mount_SOURCES = utils_mount_test.c testing.h
-test_utils_mount_LDADD = libmount.la daemon/libplugin_mock.la
-if BUILD_WITH_LIBKSTAT
-test_utils_mount_LDADD += -lkstat
-endif
-
-sbin_PROGRAMS = collectdmon
-bin_PROGRAMS = collectd-nagios collectdctl collectd-tg
-
-collectdmon_SOURCES = collectdmon.c
-
-collectd_nagios_SOURCES = collectd-nagios.c
-collectd_nagios_CPPFLAGS = $(AM_CPPFLAGS) \
-       -I$(top_srcdir)/src/libcollectdclient/collectd \
-       -I$(top_builddir)/src/libcollectdclient/collectd
-collectd_nagios_LDADD = libcollectdclient/libcollectdclient.la
-if BUILD_WITH_LIBSOCKET
-collectd_nagios_LDADD += -lsocket
-endif
-if BUILD_AIX
-collectd_nagios_LDADD += -lm
-endif
-
-
-collectdctl_SOURCES = collectdctl.c
-collectdctl_CPPFLAGS = $(AM_CPPFLAGS) \
-       -I$(top_srcdir)/src/libcollectdclient/collectd \
-       -I$(top_builddir)/src/libcollectdclient/collectd
-collectdctl_LDADD = libcollectdclient/libcollectdclient.la
-if BUILD_WITH_LIBSOCKET
-collectdctl_LDADD += -lsocket
-endif
-if BUILD_AIX
-collectdctl_LDADD += -lm
-endif
-
-
-collectd_tg_SOURCES = collectd-tg.c
-collectd_tg_CPPFLAGS = $(AM_CPPFLAGS) \
-       -I$(top_srcdir)/src/libcollectdclient/collectd \
-       -I$(top_builddir)/src/libcollectdclient/collectd
-collectd_tg_LDADD = \
-       $(PTHREAD_LIBS) \
-       daemon/libheap.la \
-       libcollectdclient/libcollectdclient.la
-if BUILD_WITH_LIBSOCKET
-collectd_tg_LDADD += -lsocket
-endif
-if BUILD_WITH_LIBRT
-collectd_tg_LDADD += -lrt
-endif
-if BUILD_AIX
-collectd_tg_LDADD += -lm
-endif
-
-
-pkglib_LTLIBRARIES =
-
-BUILT_SOURCES =
-CLEANFILES =
-
-if HAVE_PROTOC3
-if HAVE_GRPC_CPP
-BUILT_SOURCES += collectd.grpc.pb.cc collectd.pb.cc types.pb.cc
-CLEANFILES += collectd.grpc.pb.cc collectd.pb.cc types.pb.cc \
-               collectd.grpc.pb.h collectd.pb.h types.pb.h
-
-collectd.grpc.pb.cc: $(top_srcdir)/proto/collectd.proto $(top_srcdir)/proto/types.proto
-       $(V_PROTOC)@PROTOC@ -I$(top_srcdir)/proto \
-               --grpc_out=$(builddir) --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN) $<
-
-collectd.pb.cc: $(top_srcdir)/proto/collectd.proto $(top_srcdir)/proto/types.proto
-       $(V_PROTOC)@PROTOC@ -I$(top_srcdir)/proto --cpp_out=$(builddir) $<
-
-types.pb.cc: $(top_srcdir)/proto/types.proto
-       $(V_PROTOC)@PROTOC@ -I$(top_srcdir)/proto --cpp_out=$(builddir) $<
-endif
-endif
-
-if BUILD_PLUGIN_AGGREGATION
-pkglib_LTLIBRARIES += aggregation.la
-aggregation_la_SOURCES = aggregation.c \
-                         utils_vl_lookup.c utils_vl_lookup.h
-aggregation_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-aggregation_la_LIBADD = -lm
-endif
-
-if BUILD_PLUGIN_AMQP
-pkglib_LTLIBRARIES += amqp.la
-amqp_la_SOURCES = amqp.c
-amqp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRABBITMQ_LDFLAGS)
-amqp_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBRABBITMQ_CPPFLAGS)
-amqp_la_LIBADD = $(BUILD_WITH_LIBRABBITMQ_LIBS) \
-                 libcmds.la libformat_graphite.la libformat_json.la
-endif
-
-if BUILD_PLUGIN_APACHE
-pkglib_LTLIBRARIES += apache.la
-apache_la_SOURCES = apache.c
-apache_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-apache_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS)
-apache_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS)
-endif
-
-
-if BUILD_PLUGIN_APCUPS
-pkglib_LTLIBRARIES += apcups.la
-apcups_la_SOURCES = apcups.c
-apcups_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-apcups_la_LIBADD =
-if BUILD_WITH_LIBSOCKET
-apcups_la_LIBADD += -lsocket
-endif
-endif
-
-if BUILD_PLUGIN_APPLE_SENSORS
-pkglib_LTLIBRARIES += apple_sensors.la
-apple_sensors_la_SOURCES = apple_sensors.c
-apple_sensors_la_LDFLAGS = $(PLUGIN_LDFLAGS) -framework IOKit
-endif
-
-if BUILD_PLUGIN_AQUAERO
-pkglib_LTLIBRARIES += aquaero.la
-aquaero_la_SOURCES = aquaero.c
-aquaero_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBAQUAERO5_CFLAGS)
-aquaero_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBAQUAERO5_LDFLAGS)
-aquaero_la_LIBADD = -laquaero5
-endif
-
-if BUILD_PLUGIN_ASCENT
-pkglib_LTLIBRARIES += ascent.la
-ascent_la_SOURCES = ascent.c
-ascent_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-ascent_la_CFLAGS = $(AM_CFLAGS) \
-               $(BUILD_WITH_LIBCURL_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS)
-ascent_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBXML2_LIBS)
-endif
-
-if BUILD_PLUGIN_BAROMETER
-pkglib_LTLIBRARIES += barometer.la
-barometer_la_SOURCES = barometer.c
-barometer_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-barometer_la_LIBADD = -lm
-endif
-
-if BUILD_PLUGIN_BATTERY
-pkglib_LTLIBRARIES += battery.la
-battery_la_SOURCES = battery.c battery_statefs.c
-battery_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-if BUILD_WITH_LIBIOKIT
-battery_la_LDFLAGS += -framework IOKit
-endif
-endif
-
-if BUILD_PLUGIN_BIND
-pkglib_LTLIBRARIES += bind.la
-bind_la_SOURCES = bind.c
-bind_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-bind_la_CFLAGS = $(AM_CFLAGS) \
-                $(BUILD_WITH_LIBCURL_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS)
-bind_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBXML2_LIBS)
-endif
-
-if BUILD_PLUGIN_CEPH
-pkglib_LTLIBRARIES += ceph.la
-ceph_la_SOURCES = ceph.c
-ceph_la_CFLAGS = $(AM_CFLAGS)
-ceph_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS)
-ceph_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS)
-ceph_la_LIBADD = $(BUILD_WITH_LIBYAJL_LIBS)
-endif
-
-if BUILD_PLUGIN_CGROUPS
-pkglib_LTLIBRARIES += cgroups.la
-cgroups_la_SOURCES = cgroups.c
-cgroups_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-cgroups_la_LIBADD = libmount.la
-endif
-
-if BUILD_PLUGIN_CHRONY
-pkglib_LTLIBRARIES += chrony.la
-chrony_la_SOURCES = chrony.c
-chrony_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-chrony_la_LIBADD = -lm
-endif
-
-if BUILD_PLUGIN_CONNTRACK
-pkglib_LTLIBRARIES += conntrack.la
-conntrack_la_SOURCES = conntrack.c
-conntrack_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_CONTEXTSWITCH
-pkglib_LTLIBRARIES += contextswitch.la
-contextswitch_la_SOURCES = contextswitch.c
-contextswitch_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-contextswitch_la_LIBADD =
-if BUILD_WITH_PERFSTAT
-contextswitch_la_LIBADD += -lperfstat
-endif
-endif
-
-if BUILD_PLUGIN_CPU
-pkglib_LTLIBRARIES += cpu.la
-cpu_la_SOURCES = cpu.c
-cpu_la_CFLAGS = $(AM_CFLAGS)
-cpu_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-cpu_la_LIBADD =
-if BUILD_WITH_LIBKSTAT
-cpu_la_LIBADD += -lkstat
-endif
-if BUILD_WITH_LIBDEVINFO
-cpu_la_LIBADD += -ldevinfo
-endif
-if BUILD_WITH_LIBSTATGRAB
-cpu_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
-cpu_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
-endif
-if BUILD_WITH_PERFSTAT
-cpu_la_LIBADD += -lperfstat
-endif
-endif
-
-if BUILD_PLUGIN_CPUFREQ
-pkglib_LTLIBRARIES += cpufreq.la
-cpufreq_la_SOURCES = cpufreq.c
-cpufreq_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_CPUSLEEP
-pkglib_LTLIBRARIES += cpusleep.la
-cpusleep_la_SOURCES = cpusleep.c
-cpusleep_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_CSV
-pkglib_LTLIBRARIES += csv.la
-csv_la_SOURCES = csv.c
-csv_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_CURL
-pkglib_LTLIBRARIES += curl.la
-curl_la_SOURCES = curl.c \
-                  utils_curl_stats.c utils_curl_stats.h \
-                  utils_match.c utils_match.h
-curl_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-curl_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS)
-curl_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) liblatency.la
-endif
-
-if BUILD_PLUGIN_CURL_JSON
-pkglib_LTLIBRARIES += curl_json.la
-curl_json_la_SOURCES = curl_json.c \
-                 utils_curl_stats.c utils_curl_stats.h
-curl_json_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS)
-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)
-endif
-
-if BUILD_PLUGIN_CURL_XML
-pkglib_LTLIBRARIES += curl_xml.la
-curl_xml_la_SOURCES = curl_xml.c \
-                 utils_curl_stats.c utils_curl_stats.h
-curl_xml_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-curl_xml_la_CFLAGS = $(AM_CFLAGS) \
-               $(BUILD_WITH_LIBCURL_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS)
-curl_xml_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBXML2_LIBS)
-endif
-
-if BUILD_PLUGIN_DBI
-pkglib_LTLIBRARIES += dbi.la
-dbi_la_SOURCES = dbi.c \
-                utils_db_query.c utils_db_query.h
-dbi_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBDBI_CPPFLAGS)
-dbi_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBDBI_LDFLAGS)
-dbi_la_LIBADD = $(BUILD_WITH_LIBDBI_LIBS)
-endif
-
-if BUILD_PLUGIN_DF
-pkglib_LTLIBRARIES += df.la
-df_la_SOURCES = df.c
-df_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-df_la_LIBADD = libmount.la
-endif
-
-if BUILD_PLUGIN_DISK
-pkglib_LTLIBRARIES += disk.la
-disk_la_SOURCES = disk.c
-disk_la_CFLAGS = $(AM_CFLAGS)
-disk_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-disk_la_LIBADD =
-if BUILD_WITH_LIBKSTAT
-disk_la_LIBADD += -lkstat
-endif
-if BUILD_WITH_LIBDEVINFO
-disk_la_LIBADD += -ldevinfo
-endif
-if BUILD_WITH_LIBIOKIT
-disk_la_LDFLAGS += -framework IOKit
-endif
-if BUILD_WITH_LIBSTATGRAB
-disk_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
-disk_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
-endif
-if BUILD_WITH_LIBUDEV
-disk_la_CFLAGS += $(BUILD_WITH_LIBUDEV_CFLAGS)
-disk_la_LDFLAGS += $(BUILD_WITH_LIBUDEV_LDFLAGS)
-disk_la_LIBADD += $(BUILD_WITH_LIBUDEV_LIBS)
-endif
-if BUILD_FREEBSD
-disk_la_LIBADD += -ldevstat -lgeom
-endif
-if BUILD_WITH_PERFSTAT
-disk_la_LIBADD += -lperfstat
-endif
-endif
-
-if BUILD_PLUGIN_DNS
-pkglib_LTLIBRARIES += dns.la
-dns_la_SOURCES = dns.c utils_dns.c utils_dns.h
-dns_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-dns_la_LIBADD = -lpcap
-endif
-
-if BUILD_PLUGIN_DPDKSTAT
-pkglib_LTLIBRARIES += dpdkstat.la
-dpdkstat_la_SOURCES = dpdkstat.c
-dpdkstat_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBDPDK_CPPFLAGS)
-dpdkstat_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBDPDK_LDFLAGS)
-dpdkstat_la_LIBADD = -ldpdk
-endif
-
-if BUILD_PLUGIN_DRBD
-pkglib_LTLIBRARIES += drbd.la
-drbd_la_SOURCES = drbd.c
-drbd_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_EMAIL
-pkglib_LTLIBRARIES += email.la
-email_la_SOURCES = email.c
-email_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_ENTROPY
-pkglib_LTLIBRARIES += entropy.la
-entropy_la_SOURCES = entropy.c
-entropy_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_EXEC
-pkglib_LTLIBRARIES += exec.la
-exec_la_SOURCES = exec.c
-exec_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-exec_la_LIBADD = libcmds.la
-endif
-
-if BUILD_PLUGIN_ETHSTAT
-pkglib_LTLIBRARIES += ethstat.la
-ethstat_la_SOURCES = ethstat.c
-ethstat_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_FHCOUNT
-pkglib_LTLIBRARIES += fhcount.la
-fhcount_la_SOURCES = fhcount.c
-fhcount_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_FILECOUNT
-pkglib_LTLIBRARIES += filecount.la
-filecount_la_SOURCES = filecount.c
-filecount_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_GMOND
-pkglib_LTLIBRARIES += gmond.la
-gmond_la_SOURCES = gmond.c
-gmond_la_CPPFLAGS = $(AM_CPPFLAGS) $(GANGLIA_CPPFLAGS)
-gmond_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(GANGLIA_LDFLAGS)
-gmond_la_LIBADD = $(GANGLIA_LIBS)
-endif
-
-if BUILD_PLUGIN_GPS
-pkglib_LTLIBRARIES += gps.la
-gps_la_SOURCES = gps.c
-gps_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBGPS_CFLAGS)
-gps_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBGPS_LDFLAGS)
-gps_la_LIBADD = -lpthread $(BUILD_WITH_LIBGPS_LIBS)
-endif
-
-if BUILD_PLUGIN_GRPC
-pkglib_LTLIBRARIES += grpc.la
-grpc_la_SOURCES = grpc.cc
-nodist_grpc_la_SOURCES = collectd.grpc.pb.cc collectd.pb.cc types.pb.cc
-grpc_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBGRPCPP_CPPFLAGS) $(BUILD_WITH_LIBPROTOBUF_CPPFLAGS)
-grpc_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBGRPCPP_LDFLAGS) $(BUILD_WITH_LIBPROTOBUF_LDFLAGS)
-grpc_la_LIBADD = $(BUILD_WITH_LIBGRPCPP_LIBS) $(BUILD_WITH_LIBPROTOBUF_LIBS)
-endif
-
-if BUILD_PLUGIN_HDDTEMP
-pkglib_LTLIBRARIES += hddtemp.la
-hddtemp_la_SOURCES = hddtemp.c
-hddtemp_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-hddtemp_la_LIBADD =
-if BUILD_WITH_LIBSOCKET
-hddtemp_la_LIBADD += -lsocket
-endif
-endif
-
-if BUILD_PLUGIN_HUGEPAGES
-pkglib_LTLIBRARIES += hugepages.la
-hugepages_la_SOURCES = hugepages.c
-hugepages_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_INTERFACE
-pkglib_LTLIBRARIES += interface.la
-interface_la_SOURCES = interface.c
-interface_la_CFLAGS = $(AM_CFLAGS)
-interface_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-interface_la_LIBADD =
-if BUILD_WITH_LIBSTATGRAB
-interface_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
-interface_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
-else
-if BUILD_WITH_LIBKSTAT
-interface_la_LIBADD += -lkstat
-endif
-if BUILD_WITH_LIBDEVINFO
-interface_la_LIBADD += -ldevinfo
-endif # BUILD_WITH_LIBDEVINFO
-endif # !BUILD_WITH_LIBSTATGRAB
-if BUILD_WITH_PERFSTAT
-interface_la_LIBADD += -lperfstat
-endif
-endif # BUILD_PLUGIN_INTERFACE
-
-if BUILD_PLUGIN_IPC
-pkglib_LTLIBRARIES += ipc.la
-ipc_la_SOURCES = ipc.c
-ipc_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_IPTABLES
-pkglib_LTLIBRARIES += iptables.la
-iptables_la_SOURCES = iptables.c
-iptables_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBIPTC_CPPFLAGS)
-iptables_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-iptables_la_LIBADD = $(BUILD_WITH_LIBIPTC_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_IPMI
-pkglib_LTLIBRARIES += ipmi.la
-ipmi_la_SOURCES = ipmi.c
-ipmi_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_OPENIPMI_CFLAGS)
-ipmi_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-ipmi_la_LIBADD = $(BUILD_WITH_OPENIPMI_LIBS)
-endif
-
-if BUILD_PLUGIN_IPVS
-pkglib_LTLIBRARIES += ipvs.la
-ipvs_la_SOURCES = ipvs.c
-ipvs_la_CFLAGS = $(AM_CFLAGS)
-if IP_VS_H_NEEDS_KERNEL_CFLAGS
-ipvs_la_CFLAGS += $(KERNEL_CFLAGS)
-endif
-ipvs_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_IRQ
-pkglib_LTLIBRARIES += irq.la
-irq_la_SOURCES = irq.c
-irq_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_JAVA
-pkglib_LTLIBRARIES += java.la
-java_la_SOURCES = java.c
-java_la_CPPFLAGS = $(AM_CPPFLAGS) $(JAVA_CPPFLAGS)
-java_la_CFLAGS = $(AM_CFLAGS) $(JAVA_CFLAGS)
-java_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(JAVA_LDFLAGS)
-java_la_LIBADD = $(JAVA_LIBS)
-endif
-
-if BUILD_PLUGIN_LOAD
-pkglib_LTLIBRARIES += load.la
-load_la_SOURCES = load.c
-load_la_CFLAGS = $(AM_CFLAGS)
-load_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-load_la_LIBADD =
-if BUILD_WITH_LIBSTATGRAB
-load_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
-load_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
-endif # BUILD_WITH_LIBSTATGRAB
-if BUILD_WITH_PERFSTAT
-load_la_LIBADD += -lperfstat
-endif
-endif # BUILD_PLUGIN_LOAD
-
-if BUILD_PLUGIN_LOGFILE
-pkglib_LTLIBRARIES += logfile.la
-logfile_la_SOURCES = logfile.c
-logfile_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_LOG_LOGSTASH
-pkglib_LTLIBRARIES += log_logstash.la
-log_logstash_la_SOURCES = log_logstash.c
-log_logstash_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS)
-log_logstash_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS)
-log_logstash_la_LIBADD = $(BUILD_WITH_LIBYAJL_LIBS)
-endif
-
-if BUILD_PLUGIN_LPAR
-pkglib_LTLIBRARIES += lpar.la
-lpar_la_SOURCES = lpar.c
-lpar_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-lpar_la_LIBADD = -lperfstat
-endif
-
-if BUILD_PLUGIN_LUA
-pkglib_LTLIBRARIES += lua.la
-lua_la_SOURCES = lua.c \
-                utils_lua.c utils_lua.h
-lua_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBLUA_CFLAGS)
-lua_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-lua_la_LIBADD = $(BUILD_WITH_LIBLUA_LIBS)
-endif
-
-if BUILD_PLUGIN_LVM
-pkglib_LTLIBRARIES += lvm.la
-lvm_la_SOURCES = lvm.c
-lvm_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBLVM2APP_CPPFLAGS)
-lvm_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBLVM2APP_LDFLAGS)
-lvm_la_LIBADD = $(BUILD_WITH_LIBLVM2APP_LIBS)
-endif
-
-if BUILD_PLUGIN_MADWIFI
-pkglib_LTLIBRARIES += madwifi.la
-madwifi_la_SOURCES = madwifi.c madwifi.h
-madwifi_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_MATCH_EMPTY_COUNTER
-pkglib_LTLIBRARIES += match_empty_counter.la
-match_empty_counter_la_SOURCES = match_empty_counter.c
-match_empty_counter_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_MATCH_HASHED
-pkglib_LTLIBRARIES += match_hashed.la
-match_hashed_la_SOURCES = match_hashed.c
-match_hashed_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_MATCH_REGEX
-pkglib_LTLIBRARIES += match_regex.la
-match_regex_la_SOURCES = match_regex.c
-match_regex_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_MATCH_TIMEDIFF
-pkglib_LTLIBRARIES += match_timediff.la
-match_timediff_la_SOURCES = match_timediff.c
-match_timediff_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_MATCH_VALUE
-pkglib_LTLIBRARIES += match_value.la
-match_value_la_SOURCES = match_value.c
-match_value_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_MBMON
-pkglib_LTLIBRARIES += mbmon.la
-mbmon_la_SOURCES = mbmon.c
-mbmon_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-mbmon_la_LIBADD =
-if BUILD_WITH_LIBSOCKET
-mbmon_la_LIBADD += -lsocket
-endif
-endif
-
-if BUILD_PLUGIN_MD
-pkglib_LTLIBRARIES += md.la
-md_la_SOURCES = md.c
-md_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_MEMCACHEC
-pkglib_LTLIBRARIES += memcachec.la
-memcachec_la_SOURCES = memcachec.c \
-                       utils_match.c utils_match.h
-memcachec_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBMEMCACHED_LDFLAGS)
-memcachec_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBMEMCACHED_CPPFLAGS)
-memcachec_la_LIBADD = $(BUILD_WITH_LIBMEMCACHED_LIBS) liblatency.la
-endif
-
-if BUILD_PLUGIN_MEMCACHED
-pkglib_LTLIBRARIES += memcached.la
-memcached_la_SOURCES = memcached.c
-memcached_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-memcached_la_LIBADD =
-if BUILD_WITH_LIBSOCKET
-memcached_la_LIBADD += -lsocket
-endif
-endif
-
-if BUILD_PLUGIN_MEMORY
-pkglib_LTLIBRARIES += memory.la
-memory_la_SOURCES = memory.c
-memory_la_CFLAGS = $(AM_CFLAGS)
-memory_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-memory_la_LIBADD =
-if BUILD_WITH_LIBKSTAT
-memory_la_LIBADD += -lkstat
-endif
-if BUILD_WITH_LIBDEVINFO
-memory_la_LIBADD += -ldevinfo
-endif
-if BUILD_WITH_LIBSTATGRAB
-memory_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
-memory_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
-endif
-if BUILD_WITH_PERFSTAT
-memory_la_LIBADD += -lperfstat
-endif
-endif
-
-if BUILD_PLUGIN_MIC
-pkglib_LTLIBRARIES += mic.la
-mic_la_SOURCES = mic.c
-mic_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_MIC_LIBPATH)
-mic_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_MIC_CPPFLAGS)
-mic_la_LIBADD = $(BUILD_WITH_MIC_LDADD)
-endif
-
-if BUILD_PLUGIN_MODBUS
-pkglib_LTLIBRARIES += modbus.la
-modbus_la_SOURCES = modbus.c
-modbus_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-modbus_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBMODBUS_CFLAGS)
-modbus_la_LIBADD = $(BUILD_WITH_LIBMODBUS_LIBS)
-endif
-
-if BUILD_PLUGIN_MQTT
-pkglib_LTLIBRARIES += mqtt.la
-mqtt_la_SOURCES = mqtt.c
-mqtt_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBMOSQUITTO_CPPFLAGS)
-mqtt_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBMOSQUITTO_LDFLAGS)
-mqtt_la_LIBADD = $(BUILD_WITH_LIBMOSQUITTO_LIBS)
-endif
-
-if BUILD_PLUGIN_MULTIMETER
-pkglib_LTLIBRARIES += multimeter.la
-multimeter_la_SOURCES = multimeter.c
-multimeter_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_MYSQL
-pkglib_LTLIBRARIES += mysql.la
-mysql_la_SOURCES = mysql.c
-mysql_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBMYSQL_CFLAGS)
-mysql_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-mysql_la_LIBADD = $(BUILD_WITH_LIBMYSQL_LIBS)
-endif
-
-if BUILD_PLUGIN_NETAPP
-pkglib_LTLIBRARIES += netapp.la
-netapp_la_SOURCES = netapp.c
-netapp_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBNETAPP_CPPFLAGS)
-netapp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBNETAPP_LDFLAGS)
-netapp_la_LIBADD = $(LIBNETAPP_LIBS)
-endif
-
-if BUILD_PLUGIN_NETLINK
-pkglib_LTLIBRARIES += netlink.la
-netlink_la_SOURCES = netlink.c
-netlink_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-netlink_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBMNL_CFLAGS)
-netlink_la_LIBADD = $(BUILD_WITH_LIBMNL_LIBS)
-endif
-
-if BUILD_PLUGIN_NETWORK
-pkglib_LTLIBRARIES += network.la
-network_la_SOURCES = network.c network.h \
-                    utils_fbhash.c utils_fbhash.h
-network_la_CPPFLAGS = $(AM_CPPFLAGS)
-network_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-network_la_LIBADD =
-if BUILD_WITH_LIBSOCKET
-network_la_LIBADD += -lsocket
-endif
-if BUILD_WITH_LIBGCRYPT
-network_la_CPPFLAGS += $(GCRYPT_CPPFLAGS)
-network_la_LDFLAGS += $(GCRYPT_LDFLAGS)
-network_la_LIBADD += $(GCRYPT_LIBS)
-endif
-endif
-
-if BUILD_PLUGIN_NFS
-pkglib_LTLIBRARIES += nfs.la
-nfs_la_SOURCES = nfs.c
-nfs_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_FSCACHE
-pkglib_LTLIBRARIES += fscache.la
-fscache_la_SOURCES = fscache.c
-fscache_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_NGINX
-pkglib_LTLIBRARIES += nginx.la
-nginx_la_SOURCES = nginx.c
-nginx_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS)
-nginx_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-nginx_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS)
-endif
-
-if BUILD_PLUGIN_NOTIFY_DESKTOP
-pkglib_LTLIBRARIES += notify_desktop.la
-notify_desktop_la_SOURCES = notify_desktop.c
-notify_desktop_la_CFLAGS = $(AM_CFLAGS) $(LIBNOTIFY_CFLAGS)
-notify_desktop_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-notify_desktop_la_LIBADD = $(LIBNOTIFY_LIBS)
-endif
-
-if BUILD_PLUGIN_NOTIFY_EMAIL
-pkglib_LTLIBRARIES += notify_email.la
-notify_email_la_SOURCES = notify_email.c
-notify_email_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-notify_email_la_LIBADD = -lesmtp
-endif
-
-if BUILD_PLUGIN_NOTIFY_NAGIOS
-pkglib_LTLIBRARIES += notify_nagios.la
-notify_nagios_la_SOURCES = notify_nagios.c
-notify_nagios_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_NTPD
-pkglib_LTLIBRARIES += ntpd.la
-ntpd_la_SOURCES = ntpd.c
-ntpd_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-ntpd_la_LIBADD =
-if BUILD_WITH_LIBSOCKET
-ntpd_la_LIBADD += -lsocket
-endif
-endif
-
-if BUILD_PLUGIN_NUMA
-pkglib_LTLIBRARIES += numa.la
-numa_la_SOURCES = numa.c
-numa_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_NUT
-pkglib_LTLIBRARIES += nut.la
-nut_la_SOURCES = nut.c
-nut_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBUPSCLIENT_CFLAGS)
-nut_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-nut_la_LIBADD = $(BUILD_WITH_LIBUPSCLIENT_LIBS)
-endif
-
-if BUILD_PLUGIN_OLSRD
-pkglib_LTLIBRARIES += olsrd.la
-olsrd_la_SOURCES = olsrd.c
-olsrd_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-olsrd_la_LIBADD =
-if BUILD_WITH_LIBSOCKET
-olsrd_la_LIBADD += -lsocket
-endif
-endif
-
-if BUILD_PLUGIN_ONEWIRE
-pkglib_LTLIBRARIES += onewire.la
-onewire_la_SOURCES = 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)
-endif
-
-if BUILD_PLUGIN_OPENLDAP
-pkglib_LTLIBRARIES += openldap.la
-openldap_la_SOURCES = openldap.c
-openldap_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBLDAP_CPPFLAGS)
-openldap_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBLDAP_LDFLAGS)
-openldap_la_LIBADD = -lldap
-endif
-
-if BUILD_PLUGIN_OPENVPN
-pkglib_LTLIBRARIES += openvpn.la
-openvpn_la_SOURCES = openvpn.c
-openvpn_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_ORACLE
-pkglib_LTLIBRARIES += oracle.la
-oracle_la_SOURCES = oracle.c \
-       utils_db_query.c utils_db_query.h
-oracle_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_ORACLE_CPPFLAGS)
-oracle_la_LIBADD = $(BUILD_WITH_ORACLE_LIBS)
-oracle_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_PERL
-pkglib_LTLIBRARIES += perl.la
-perl_la_SOURCES = perl.c
-# Despite C99 providing the "bool" type thru stdbool.h, Perl defines its own
-# version of that type if HAS_BOOL is not defined... *sigh*
-perl_la_CPPFLAGS = $(AM_CPPFLAGS) -DHAS_BOOL=1
-# Despite off_t being 64 bit wide on 64 bit platforms, Perl insist on using
-# off64_t which is only exposed when _LARGEFILE64_SOURCE is defined... *sigh*
-# On older platforms we also need _REENTRANT. _GNU_SOURCE sets both of these.
-perl_la_CPPFLAGS += -D_GNU_SOURCE
-perl_la_CFLAGS  = $(AM_CFLAGS) \
-               $(PERL_CFLAGS) \
-               -DXS_VERSION=\"$(VERSION)\" -DVERSION=\"$(VERSION)\"
-# Work-around for issues #41 and #42 - Perl 5.10 incorrectly introduced
-# __attribute__nonnull__(3) for Perl_load_module().
-if HAVE_BROKEN_PERL_LOAD_MODULE
-perl_la_CFLAGS += -Wno-nonnull
-endif
-perl_la_LDFLAGS = $(PLUGIN_LDFLAGS) \
-               $(PERL_LDFLAGS)
-perl_la_LIBADD = $(PERL_LIBS)
-endif
-
-if BUILD_PLUGIN_PF
-pkglib_LTLIBRARIES += pf.la
-pf_la_SOURCES = pf.c
-pf_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_PINBA
-pkglib_LTLIBRARIES += pinba.la
-pinba_la_SOURCES = pinba.c
-nodist_pinba_la_SOURCES = pinba.pb-c.c pinba.pb-c.h
-pinba_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBPROTOBUF_C_CPPFLAGS)
-pinba_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBPROTOBUF_C_LDFLAGS)
-pinba_la_LIBADD = $(BUILD_WITH_LIBPROTOBUF_C_LIBS)
-endif
-
-if BUILD_PLUGIN_PING
-pkglib_LTLIBRARIES += ping.la
-ping_la_SOURCES = ping.c
-ping_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBOPING_CPPFLAGS)
-ping_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBOPING_LDFLAGS)
-ping_la_LIBADD = -loping -lm
-endif
-
-if BUILD_PLUGIN_POSTGRESQL
-pkglib_LTLIBRARIES += postgresql.la
-postgresql_la_SOURCES = postgresql.c \
-                utils_db_query.c utils_db_query.h
-postgresql_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBPQ_CPPFLAGS)
-postgresql_la_LDFLAGS = $(PLUGIN_LDFLAGS) \
-               $(BUILD_WITH_LIBPQ_LDFLAGS)
-postgresql_la_LIBADD = -lpq
-endif
-
-if BUILD_PLUGIN_POWERDNS
-pkglib_LTLIBRARIES += powerdns.la
-powerdns_la_SOURCES = powerdns.c
-powerdns_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_PYTHON
-pkglib_LTLIBRARIES += python.la
-python_la_SOURCES = python.c pyconfig.c pyvalues.c cpython.h
-python_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBPYTHON_CPPFLAGS)
-if COMPILER_IS_GCC
-python_la_CPPFLAGS += -fno-strict-aliasing -Wno-strict-aliasing
-endif
-python_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBPYTHON_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_PROCESSES
-pkglib_LTLIBRARIES += processes.la
-processes_la_SOURCES = processes.c
-processes_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-processes_la_LIBADD =
-if BUILD_WITH_LIBKVM_GETPROCS
-processes_la_LIBADD += -lkvm
-endif
-endif
-
-if BUILD_PLUGIN_PROTOCOLS
-pkglib_LTLIBRARIES += protocols.la
-protocols_la_SOURCES = protocols.c
-protocols_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_INTEL_RDT
-pkglib_LTLIBRARIES += intel_rdt.la
-intel_rdt_la_SOURCES = intel_rdt.c
-intel_rdt_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBPQOS_LDFLAGS)
-intel_rdt_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBPQOS_CPPFLAGS)
-intel_rdt_la_LIBADD = $(BUILD_WITH_LIBPQOS_LIBS)
-endif
-
-if BUILD_PLUGIN_REDIS
-pkglib_LTLIBRARIES += redis.la
-redis_la_SOURCES = redis.c
-redis_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBHIREDIS_LDFLAGS)
-redis_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBHIREDIS_CPPFLAGS)
-redis_la_LIBADD = -lhiredis
-endif
-
-if BUILD_PLUGIN_ROUTEROS
-pkglib_LTLIBRARIES += routeros.la
-routeros_la_SOURCES = routeros.c
-routeros_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBROUTEROS_CPPFLAGS)
-routeros_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBROUTEROS_LDFLAGS)
-routeros_la_LIBADD = -lrouteros
-endif
-
-if BUILD_PLUGIN_RRDCACHED
-pkglib_LTLIBRARIES += rrdcached.la
-rrdcached_la_SOURCES = rrdcached.c utils_rrdcreate.c utils_rrdcreate.h
-rrdcached_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRRD_LDFLAGS)
-rrdcached_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBRRD_CFLAGS)
-rrdcached_la_LIBADD = $(BUILD_WITH_LIBRRD_LIBS)
-endif
-
-if BUILD_PLUGIN_RRDTOOL
-pkglib_LTLIBRARIES += rrdtool.la
-rrdtool_la_SOURCES = rrdtool.c utils_rrdcreate.c utils_rrdcreate.h
-rrdtool_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRRD_LDFLAGS)
-rrdtool_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBRRD_CFLAGS)
-rrdtool_la_LIBADD = $(BUILD_WITH_LIBRRD_LIBS)
-endif
-
-if BUILD_PLUGIN_SENSORS
-pkglib_LTLIBRARIES += sensors.la
-sensors_la_SOURCES = sensors.c
-sensors_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBSENSORS_CFLAGS)
-sensors_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBSENSORS_LDFLAGS)
-sensors_la_LIBADD = -lsensors
-endif
-
-if BUILD_PLUGIN_SERIAL
-pkglib_LTLIBRARIES += serial.la
-serial_la_SOURCES = serial.c
-serial_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_SIGROK
-pkglib_LTLIBRARIES += sigrok.la
-sigrok_la_SOURCES = sigrok.c
-sigrok_la_CFLAGS = $(AM_CFLAGS) $(LIBSIGROK_CFLAGS)
-sigrok_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-sigrok_la_LIBADD = $(LIBSIGROK_LIBS)
-endif
-
-if BUILD_PLUGIN_SMART
-if BUILD_WITH_LIBUDEV
-pkglib_LTLIBRARIES += smart.la
-smart_la_SOURCES = smart.c
-smart_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBATASMART_CPPFLAGS) $(BUILD_WITH_LIBUDEV_CFLAGS)
-smart_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBATASMART_LDFLAGS) $(BUILD_WITH_LIBUDEV_LDFLAGS)
-smart_la_LIBADD = $(BUILD_WITH_LIBATASMART_LIBS) $(BUILD_WITH_LIBUDEV_LIBS)
-endif
-endif
-
-if BUILD_PLUGIN_SNMP
-pkglib_LTLIBRARIES += snmp.la
-snmp_la_SOURCES = snmp.c
-snmp_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBNETSNMP_CPPFLAGS)
-snmp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBNETSNMP_LDFLAGS)
-snmp_la_LIBADD = $(BUILD_WITH_LIBNETSNMP_LIBS)
-endif
-
-if BUILD_PLUGIN_STATSD
-pkglib_LTLIBRARIES += statsd.la
-statsd_la_SOURCES = statsd.c
-statsd_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-statsd_la_LIBADD = liblatency.la
-endif
-
-if BUILD_PLUGIN_SWAP
-pkglib_LTLIBRARIES += swap.la
-swap_la_SOURCES = swap.c
-swap_la_CFLAGS = $(AM_CFLAGS)
-swap_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-swap_la_LIBADD =
-if BUILD_WITH_LIBKSTAT
-swap_la_LIBADD += -lkstat
-endif
-if BUILD_WITH_LIBDEVINFO
-swap_la_LIBADD += -ldevinfo
-endif
-if BUILD_WITH_LIBKVM_GETSWAPINFO
-swap_la_LIBADD += -lkvm
-endif
-if BUILD_WITH_LIBSTATGRAB
-swap_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
-swap_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
-endif
-if BUILD_WITH_PERFSTAT
-swap_la_LIBADD += -lperfstat
-endif
-
-endif
-
-if BUILD_PLUGIN_SYSLOG
-pkglib_LTLIBRARIES += syslog.la
-syslog_la_SOURCES = syslog.c
-syslog_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_TABLE
-pkglib_LTLIBRARIES += table.la
-table_la_SOURCES = table.c
-table_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_TAIL
-pkglib_LTLIBRARIES += tail.la
-tail_la_SOURCES = tail.c \
-                  utils_match.c utils_match.h \
-                  utils_tail.c utils_tail.h \
-                  utils_tail_match.c utils_tail_match.h
-tail_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-tail_la_LIBADD = liblatency.la
-endif
-
-if BUILD_PLUGIN_TAIL_CSV
-pkglib_LTLIBRARIES += tail_csv.la
-tail_csv_la_SOURCES = tail_csv.c \
-                      utils_tail.c utils_tail.h
-tail_csv_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_TAPE
-pkglib_LTLIBRARIES += tape.la
-tape_la_SOURCES = tape.c
-tape_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-tape_la_LIBADD = -lkstat -ldevinfo
-endif
-
-if BUILD_PLUGIN_TARGET_NOTIFICATION
-pkglib_LTLIBRARIES += target_notification.la
-target_notification_la_SOURCES = target_notification.c
-target_notification_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_TARGET_REPLACE
-pkglib_LTLIBRARIES += target_replace.la
-target_replace_la_SOURCES = target_replace.c
-target_replace_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_TARGET_SCALE
-pkglib_LTLIBRARIES += target_scale.la
-target_scale_la_SOURCES = target_scale.c
-target_scale_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_TARGET_SET
-pkglib_LTLIBRARIES += target_set.la
-target_set_la_SOURCES = target_set.c
-target_set_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_TARGET_V5UPGRADE
-pkglib_LTLIBRARIES += target_v5upgrade.la
-target_v5upgrade_la_SOURCES = target_v5upgrade.c
-target_v5upgrade_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_TCPCONNS
-pkglib_LTLIBRARIES += tcpconns.la
-tcpconns_la_SOURCES = tcpconns.c
-tcpconns_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-tcpconns_la_LIBADD =
-if BUILD_WITH_LIBKVM_NLIST
-tcpconns_la_LIBADD += -lkvm
-endif
-endif
-
-if BUILD_PLUGIN_TEAMSPEAK2
-pkglib_LTLIBRARIES += teamspeak2.la
-teamspeak2_la_SOURCES = teamspeak2.c
-teamspeak2_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_TED
-pkglib_LTLIBRARIES += ted.la
-ted_la_SOURCES = ted.c
-ted_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_THERMAL
-pkglib_LTLIBRARIES += thermal.la
-thermal_la_SOURCES = thermal.c
-thermal_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_THRESHOLD
-pkglib_LTLIBRARIES += threshold.la
-threshold_la_SOURCES = threshold.c
-threshold_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_TOKYOTYRANT
-pkglib_LTLIBRARIES += tokyotyrant.la
-tokyotyrant_la_SOURCES = tokyotyrant.c
-tokyotyrant_la_CPPFLAGS  = $(AM_CPPFLAGS) $(BUILD_WITH_LIBTOKYOTYRANT_CPPFLAGS)
-tokyotyrant_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBTOKYOTYRANT_LDFLAGS)
-tokyotyrant_la_LIBADD  = $(BUILD_WITH_LIBTOKYOTYRANT_LIBS)
-if BUILD_WITH_LIBSOCKET
-tokyotyrant_la_LIBADD += -lsocket
-endif
-endif
-
-if BUILD_PLUGIN_TURBOSTAT
-pkglib_LTLIBRARIES += turbostat.la
-turbostat_la_SOURCES = turbostat.c
-turbostat_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_UNIXSOCK
-pkglib_LTLIBRARIES += unixsock.la
-unixsock_la_SOURCES = unixsock.c
-unixsock_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-unixsock_la_LIBADD =  libcmds.la
-endif
-
-if BUILD_PLUGIN_UPTIME
-pkglib_LTLIBRARIES += uptime.la
-uptime_la_SOURCES = uptime.c
-uptime_la_CFLAGS = $(AM_CFLAGS)
-uptime_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-uptime_la_LIBADD =
-if BUILD_WITH_LIBKSTAT
-uptime_la_LIBADD += -lkstat
-endif
-if BUILD_WITH_PERFSTAT
-uptime_la_LIBADD += -lperfstat
-endif
-endif
-
-if BUILD_PLUGIN_USERS
-pkglib_LTLIBRARIES += users.la
-users_la_SOURCES = users.c
-users_la_CFLAGS = $(AM_CFLAGS)
-users_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-users_la_LIBADD =
-if BUILD_WITH_LIBSTATGRAB
-users_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
-users_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
-endif
-endif
-
-if BUILD_PLUGIN_UUID
-pkglib_LTLIBRARIES += uuid.la
-uuid_la_SOURCES = uuid.c
-uuid_la_CFLAGS  = $(AM_CFLAGS) $(BUILD_WITH_LIBHAL_CFLAGS)
-uuid_la_LIBADD  = $(BUILD_WITH_LIBHAL_LIBS)
-uuid_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_VARNISH
-pkglib_LTLIBRARIES += varnish.la
-varnish_la_SOURCES = varnish.c
-varnish_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-varnish_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBVARNISH_CFLAGS)
-varnish_la_LIBADD = $(BUILD_WITH_LIBVARNISH_LIBS)
-endif
-
-if BUILD_PLUGIN_VIRT
-pkglib_LTLIBRARIES += virt.la
-virt_la_SOURCES = 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)
-endif
-
-if BUILD_PLUGIN_VMEM
-pkglib_LTLIBRARIES += vmem.la
-vmem_la_SOURCES = vmem.c
-vmem_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_VSERVER
-pkglib_LTLIBRARIES += vserver.la
-vserver_la_SOURCES = vserver.c
-vserver_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_WIRELESS
-pkglib_LTLIBRARIES += wireless.la
-wireless_la_SOURCES = wireless.c
-wireless_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_WRITE_GRAPHITE
-pkglib_LTLIBRARIES += write_graphite.la
-write_graphite_la_SOURCES = write_graphite.c
-write_graphite_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-write_graphite_la_LIBADD = libformat_graphite.la
-endif
-
-if BUILD_PLUGIN_WRITE_HTTP
-pkglib_LTLIBRARIES += write_http.la
-write_http_la_SOURCES = write_http.c \
-                       utils_format_kairosdb.c utils_format_kairosdb.h
-write_http_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-write_http_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS)
-write_http_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) libformat_json.la
-endif
-
-if BUILD_PLUGIN_WRITE_KAFKA
-pkglib_LTLIBRARIES += write_kafka.la
-write_kafka_la_SOURCES = write_kafka.c \
-                         utils_crc32.c utils_crc32.h
-write_kafka_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBRDKAFKA_CPPFLAGS)
-write_kafka_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRDKAFKA_LDFLAGS)
-write_kafka_la_LIBADD = $(BUILD_WITH_LIBRDKAFKA_LIBS) \
-                        libcmds.la libformat_graphite.la libformat_json.la
-endif
-
-if BUILD_PLUGIN_WRITE_LOG
-pkglib_LTLIBRARIES += write_log.la
-write_log_la_SOURCES = write_log.c
-write_log_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-write_log_la_LIBADD = libformat_graphite.la libformat_json.la
-endif
-
-if BUILD_PLUGIN_WRITE_MONGODB
-pkglib_LTLIBRARIES += write_mongodb.la
-write_mongodb_la_SOURCES = write_mongodb.c
-write_mongodb_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBMONGOC_CPPFLAGS)
-write_mongodb_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBMONGOC_LDFLAGS)
-write_mongodb_la_LIBADD = -lmongoc
-endif
-
-if BUILD_PLUGIN_WRITE_PROMETHEUS
-pkglib_LTLIBRARIES += write_prometheus.la
-write_prometheus_la_SOURCES = write_prometheus.c
-nodist_write_prometheus_la_SOURCES = prometheus.pb-c.c prometheus.pb-c.h
-write_prometheus_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBPROTOBUF_C_CPPFLAGS) $(BUILD_WITH_LIBMICROHTTPD_CPPFLAGS)
-write_prometheus_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBPROTOBUF_C_LDFLAGS) $(BUILD_WITH_LIBMICROHTTPD_LDFLAGS)
-write_prometheus_la_LIBADD = $(BUILD_WITH_LIBPROTOBUF_C_LIBS) $(BUILD_WITH_LIBMICROHTTPD_LIBS)
-endif
-
-if BUILD_PLUGIN_WRITE_REDIS
-pkglib_LTLIBRARIES += write_redis.la
-write_redis_la_SOURCES = write_redis.c
-write_redis_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBHIREDIS_LDFLAGS)
-write_redis_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBHIREDIS_CPPFLAGS)
-write_redis_la_LIBADD = -lhiredis
-endif
-
-if BUILD_PLUGIN_WRITE_RIEMANN
-pkglib_LTLIBRARIES += write_riemann.la
-write_riemann_la_SOURCES = write_riemann.c write_riemann_threshold.c write_riemann_threshold.h
-write_riemann_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBRIEMANN_CLIENT_LIBS)
-write_riemann_la_CFLAGS = $(AM_CFLAGS) $(LIBRIEMANN_CLIENT_CFLAGS)
-endif
-
-if BUILD_PLUGIN_WRITE_SENSU
-pkglib_LTLIBRARIES += write_sensu.la
-write_sensu_la_SOURCES = write_sensu.c
-write_sensu_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_WRITE_TSDB
-pkglib_LTLIBRARIES += write_tsdb.la
-write_tsdb_la_SOURCES = write_tsdb.c
-write_tsdb_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_XENCPU
-pkglib_LTLIBRARIES += xencpu.la
-xencpu_la_SOURCES = xencpu.c
-xencpu_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBXENCTL_CPPFLAGS)
-xencpu_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBXENCTL_LDFLAGS)
-xencpu_la_LIBADD = -lxenctrl
-endif
-
-if BUILD_PLUGIN_XMMS
-pkglib_LTLIBRARIES += xmms.la
-xmms_la_SOURCES = xmms.c
-xmms_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBXMMS_CFLAGS)
-xmms_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-xmms_la_LIBADD = $(BUILD_WITH_LIBXMMS_LIBS)
-endif
-
-if BUILD_PLUGIN_ZFS_ARC
-pkglib_LTLIBRARIES += zfs_arc.la
-zfs_arc_la_SOURCES = zfs_arc.c
-zfs_arc_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-if BUILD_FREEBSD
-zfs_arc_la_LIBADD = -lm
-endif
-if BUILD_SOLARIS
-zfs_arc_la_LIBADD = -lkstat
-endif
-endif
-
-if BUILD_PLUGIN_ZOOKEEPER
-pkglib_LTLIBRARIES += zookeeper.la
-zookeeper_la_SOURCES = zookeeper.c
-zookeeper_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-BUILT_SOURCES += $(dist_man_MANS)
-
-if BUILD_PLUGIN_ZONE
-pkglib_LTLIBRARIES += zone.la
-zone_la_SOURCES = zone.c
-zone_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-dist_man_MANS = collectd.1 \
-               collectd.conf.5 \
-               collectd-email.5 \
-               collectd-exec.5 \
-               collectdctl.1 \
-               collectd-java.5 \
-               collectd-lua.5 \
-               collectdmon.1 \
-               collectd-nagios.1 \
-               collectd-perl.5 \
-               collectd-python.5 \
-               collectd-snmp.5 \
-               collectd-tg.1 \
-               collectd-threshold.5 \
-               collectd-unixsock.5 \
-               types.db.5
-
-EXTRA_DIST =   collectd.conf.pod \
-               collectd-email.pod \
-               collectd-exec.pod \
-               collectdctl.pod \
-               collectd-java.pod \
-               collectd-lua.pod \
-               collectdmon.pod \
-               collectd-nagios.pod \
-               collectd-perl.pod \
-               collectd-python.pod \
-               collectd.pod \
-               collectd-snmp.pod \
-               collectd-tg.pod \
-               collectd-threshold.pod \
-               collectd-unixsock.pod \
-               postgresql_default.conf \
-               types.db \
-               types.db.pod \
-               valgrind.FreeBSD.suppress
-
-AM_V_POD2MAN_C = $(am__v_POD2MAN_C_@AM_V@)
-am__v_POD2MAN_C_ = $(am__v_POD2MAN_C_@AM_DEFAULT_V@)
-am__v_POD2MAN_C_0 = @echo "  POD2MAN " $@;
-am__v_POD2MAN_C_1 =
-
-.pod.1:
-       $(AM_V_POD2MAN_C)pod2man --release=$(VERSION) --center=$(PACKAGE) $< \
-               >.pod2man.tmp.$$$$ 2>/dev/null && mv -f .pod2man.tmp.$$$$ $@ || true
-       @if grep '\<POD ERRORS\>' $@ >/dev/null 2>&1; \
-       then \
-               echo "$@ has some POD errors!"; false; \
-       fi
-
-.pod.5:
-       $(AM_V_POD2MAN_C)pod2man --section=5 --release=$(VERSION) --center=$(PACKAGE) $< \
-               >.pod2man.tmp.$$$$ 2>/dev/null && mv -f .pod2man.tmp.$$$$ $@ || true
-       @if grep '\<POD ERRORS\>' $@ >/dev/null 2>&1; \
-       then \
-               echo "$@ has some POD errors!"; false; \
-       fi
-
-AM_V_PROTOC_C = $(am__v_PROTOC_C_@AM_V@)
-am__v_PROTOC_C_ = $(am__v_PROTOC_C_@AM_DEFAULT_V@)
-am__v_PROTOC_C_0 = @echo "  PROTOC-C" $@;
-am__v_PROTOC_C_1 =
-
-# Protocol buffer for the "pinba" plugin.
-EXTRA_DIST += pinba.proto
-if BUILD_PLUGIN_PINBA
-CLEANFILES += pinba.pb-c.c pinba.pb-c.h
-BUILT_SOURCES += pinba.pb-c.c pinba.pb-c.h
-
-pinba.pb-c.c pinba.pb-c.h: pinba.proto
-       $(AM_V_PROTOC_C)$(PROTOC_C) -I$(srcdir) --c_out . $(srcdir)/pinba.proto
-endif
-
-# Protocol buffer for the "write_prometheus" plugin.
-if BUILD_PLUGIN_WRITE_PROMETHEUS
-CLEANFILES += prometheus.pb-c.c prometheus.pb-c.h
-BUILT_SOURCES += prometheus.pb-c.c prometheus.pb-c.h
-
-prometheus.pb-c.c prometheus.pb-c.h: $(top_srcdir)/proto/prometheus.proto
-       $(AM_V_PROTOC_C)$(PROTOC_C) -I$(top_srcdir)/proto --c_out=$(builddir) $(top_srcdir)/proto/prometheus.proto
-endif
-
-install-exec-hook:
-       $(mkinstalldirs) $(DESTDIR)$(sysconfdir)
-       if test -e $(DESTDIR)$(sysconfdir)/collectd.conf; \
-       then \
-               $(INSTALL) -m 0640 collectd.conf $(DESTDIR)$(sysconfdir)/collectd.conf.pkg-orig; \
-       else \
-               $(INSTALL) -m 0640 collectd.conf $(DESTDIR)$(sysconfdir)/collectd.conf; \
-       fi; \
-       $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
-       $(INSTALL) -m 0644 $(srcdir)/types.db $(DESTDIR)$(pkgdatadir)/types.db;
-       $(INSTALL) -m 0644 $(srcdir)/postgresql_default.conf \
-               $(DESTDIR)$(pkgdatadir)/postgresql_default.conf;
-
-uninstall-hook:
-       rm -f $(DESTDIR)$(pkgdatadir)/types.db;
-       rm -f $(DESTDIR)$(sysconfdir)/collectd.conf
-       rm -f $(DESTDIR)$(pkgdatadir)/postgresql_default.conf;
-
-if BUILD_PLUGIN_CEPH
-test_plugin_ceph_SOURCES = ceph_test.c
-test_plugin_ceph_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS)
-test_plugin_ceph_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS)
-test_plugin_ceph_LDADD = daemon/libplugin_mock.la $(BUILD_WITH_LIBYAJL_LIBS)
-check_PROGRAMS += test_plugin_ceph
-TESTS += test_plugin_ceph
-endif
index 4e20d0c..8d501f6 100644 (file)
@@ -752,5 +752,3 @@ void module_register(void) {
   plugin_register_read("aggregation", agg_read);
   plugin_register_write("aggregation", agg_write, /* user_data = */ NULL);
 }
-
-/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */
index cd07023..4870107 100644 (file)
@@ -1022,5 +1022,3 @@ void module_register(void) {
   plugin_register_complex_config("amqp", camqp_config);
   plugin_register_shutdown("amqp", camqp_shutdown);
 } /* void module_register */
-
-/* vim: set sw=4 sts=4 et fdm=marker : */
index eaef61b..547d745 100644 (file)
@@ -573,5 +573,3 @@ void module_register(void) {
   plugin_register_complex_config("apache", config);
   plugin_register_init("apache", apache_init);
 } /* void module_register */
-
-/* vim: set sw=8 noet fdm=marker : */
index 2f8cccd..902b5f9 100644 (file)
 #include "common.h"
 #include "plugin.h"
 
-#if HAVE_CTYPE_H
-#include <ctype.h>
-#endif
-
 #if HAVE_MACH_MACH_TYPES_H
 #include <mach/mach_types.h>
 #endif
index 4a78f68..22278e0 100644 (file)
@@ -161,5 +161,3 @@ void module_register(void) {
   plugin_register_read("aquaero", aquaero_read);
   plugin_register_shutdown("aquaero", aquaero_shutdown);
 } /* void module_register */
-
-/* vim: set sw=8 sts=8 noet : */
index 840fe8b..5f0d85e 100644 (file)
@@ -571,5 +571,3 @@ void module_register(void) {
   plugin_register_init("ascent", ascent_init);
   plugin_register_read("ascent", ascent_read);
 } /* void module_register */
-
-/* vim: set sw=2 sts=2 ts=8 et fdm=marker : */
index 4b9baf4..4f6a8c1 100644 (file)
@@ -87,9 +87,9 @@ int battery_read_statefs(void) {
   }
 
   struct {
-    char *path;
-    char *type;
-    char *type_instance;
+    const char *path;
+    const char *type;
+    const char *type_instance;
     gauge_t factor;
   } metrics[] = {
       {STATEFS_ROOT "Current", "current", NULL, 1e-6},        // from uA to A
index 9bb662f..3876177 100644 (file)
@@ -1613,5 +1613,3 @@ void module_register(void) {
   plugin_register_read("bind", bind_read);
   plugin_register_shutdown("bind", bind_shutdown);
 } /* void module_register */
-
-/* vim: set sw=2 sts=2 ts=8 et fdm=marker : */
index 4e435b3..2331e33 100644 (file)
@@ -1446,4 +1446,3 @@ void module_register(void) {
   plugin_register_read("ceph", ceph_read);
   plugin_register_shutdown("ceph", ceph_shutdown);
 }
-/* vim: set sw=4 sts=4 et : */
index 3da4098..2f65b50 100644 (file)
@@ -187,5 +187,3 @@ int main(void) {
 
   END_TEST;
 }
-
-/* vim: set sw=2 sts=2 et : */
index 7ded64d..3bde325 100644 (file)
@@ -423,5 +423,3 @@ int main(int argc, char **argv) /* {{{ */
   lcc_network_destroy(net);
   exit(EXIT_SUCCESS);
 } /* }}} int main */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index e5b9643..dc7d6eb 100644 (file)
 #@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_LVM_TRUE@LoadPlugin lvm
 #@BUILD_PLUGIN_MADWIFI_TRUE@LoadPlugin madwifi
 #@BUILD_PLUGIN_MBMON_TRUE@LoadPlugin mbmon
+#@BUILD_PLUGIN_MCELOG_TRUE@LoadPlugin mcelog
 #@BUILD_PLUGIN_MD_TRUE@LoadPlugin md
 #@BUILD_PLUGIN_MEMCACHEC_TRUE@LoadPlugin memcachec
 #@BUILD_PLUGIN_MEMCACHED_TRUE@LoadPlugin memcached
 #@BUILD_PLUGIN_OPENLDAP_TRUE@LoadPlugin openldap
 #@BUILD_PLUGIN_OPENVPN_TRUE@LoadPlugin openvpn
 #@BUILD_PLUGIN_ORACLE_TRUE@LoadPlugin oracle
+#@BUILD_PLUGIN_OVS_EVENTS_TRUE@LoadPlugin ovs_events
 #@BUILD_PLUGIN_PERL_TRUE@LoadPlugin perl
 #@BUILD_PLUGIN_PINBA_TRUE@LoadPlugin pinba
 #@BUILD_PLUGIN_PING_TRUE@LoadPlugin ping
 #      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>
-#       Interval 1
-#       Coremask "0xf"
-#       ProcessType "secondary"
-#       FilePrefix "rte"
-#       EnabledPortMask 0xffff
-#       PortName "interface1"
-#       PortName "interface2"
+#  <EAL>
+#    Coremask "0x2"
+#    MemoryChannels "4"
+#    ProcessType "secondary"
+#    FilePrefix "rte"
+#  </EAL>
+#  SharedMemObj "dpdk_collectd_stats_0"
+#  EnabledPortMask 0xffff
+#  PortName "interface1"
+#  PortName "interface2"
 #</Plugin>
 
 #<Plugin email>
 #      Port "411"
 #</Plugin>
 
+#<Plugin mcelog>
+#      McelogClientSocket "/var/run/mcelog-client"
+#      McelogLogfile "/var/log/mcelog"
+#</Plugin>
+
 #<Plugin md>
 #      Device "/dev/md0"
 #      IgnoreSelected false
 
 #<Plugin nut>
 #      UPS "upsname@hostname:port"
+#      ForceSSL true
+#      VerifyPeer true
+#      CAPath "/path/to/folder"
 #</Plugin>
 
 #<Plugin olsrd>
 #  </Database>
 #</Plugin>
 
+#<Plugin ovs_events>
+#  Port "6640"
+#  Address "127.0.0.1"
+#  Socket "/var/run/openvswitch/db.sock"
+#  Interfaces "br0" "veth0"
+#  SendNotification false
+#  DispatchValues true
+#</Plugin>
+
 #<Plugin perl>
 #      IncludeDir "/my/include/path"
 #      BaseName "Collectd::Plugins"
 #      HostnameFormat name
 #      InterfaceFormat name
 #      PluginInstanceFormat name
+#      Instances 1
+#      ExtraStats "disk pcpu"
 #</Plugin>
 
 #<Plugin vmem>
index 11cfaeb..6d927d2 100644 (file)
@@ -2383,6 +2383,128 @@ Enabled by default, collects unknown (and thus presented as numeric only) query
 
 =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
@@ -2391,18 +2513,24 @@ extended NIC stats API in DPDK.
 B<Synopsis:>
 
  <Plugin "dpdkstat">
-    Coremask "0x4"
-    MemoryChannels "4"
-    ProcessType "secondary"
-    FilePrefix "rte"
-    EnabledPortMask 0xffff
-    PortName "interface1"
-    PortName "interface2"
+   <EAL>
+     Coremask "0x4"
+     MemoryChannels "4"
+     ProcessType "secondary"
+     FilePrefix "rte"
+     SocketMemory "1024"
+   </EAL>
+   SharedMemObj "dpdk_collectd_stats_0"
+   EnabledPortMask 0xffff
+   PortName "interface1"
+   PortName "interface2"
  </Plugin>
 
 B<Options:>
 
-=over 4
+=head3 The EAL block
+
+=over 5
 
 =item B<Coremask> I<Mask>
 
@@ -2425,7 +2553,16 @@ The prefix text used for hugepage filenames. The filename will be set to
 =item B<SocketMemory> I<MB>
 
 A string containing amount of Memory to allocate from hugepages on specific
-sockets in MB
+sockets in MB. This is an optional value.
+
+=back
+
+=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>
 
@@ -2949,6 +3086,10 @@ allows to monitor instructions per clock (IPC).
 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">
@@ -3322,6 +3463,28 @@ TCP-Port to connect to. Defaults to B<411>.
 
 =back
 
+=head2 Plugin C<mcelog>
+
+The C<mcelog plugin> uses mcelog to retrieve machine check exceptions.
+
+By default the plugin connects to B<"/var/run/mcelog-client"> to check if the
+mcelog server is running. When the server is running, the plugin will tail the
+specified logfile to retrieve machine check exception information and send a
+notification with the details from the logfile. The plugin will use the mcelog
+client protocol to retrieve memory related machine check exceptions.
+
+=over 4
+
+=item B<McelogClientSocket> I<Path>
+Connect to the mcelog client socket using the UNIX domain socket at I<Path>.
+Defaults to B<"/var/run/mcelog-client">.
+
+=item B<McelogLogfile> I<Path>
+
+The mcelog file to parse. Defaults to B<"/var/log/mcelog">.
+
+=back
+
 =head2 Plugin C<md>
 
 The C<md plugin> collects information from Linux Software-RAID devices (md).
@@ -5086,6 +5249,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>
@@ -5431,6 +5623,75 @@ refer to them from.
 
 =back
 
+=head2 Plugin C<ovs_events>
+
+The I<ovs_events> plugin monitors the link status of I<Open vSwitch> (OVS)
+connected interfaces, dispatches the values to collectd and sends the
+notification whenever the link state change occurs. This plugin uses OVS
+database to get a link state change notification.
+
+B<Synopsis:>
+
+ <Plugin "ovs_events">
+   Port 6640
+   Address "127.0.0.1"
+   Socket "/var/run/openvswitch/db.sock"
+   Interfaces "br0" "veth0"
+   SendNotification false
+   DispatchValues true
+ </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<Interfaces> [I<ifname> ...]
+
+List of interface names to be monitored by this plugin. If this option is not
+specified or is empty then all OVS connected interfaces on all bridges are
+monitored.
+
+Default: empty (all interfaces on all bridges are monitored)
+
+=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.
+
+=item B<DispatchValues> I<true|false>
+
+Dispatch the OVS DB interface link status value with configured plugin interval.
+Defaults to true. Please note, if B<SendNotification> and B<DispatchValues>
+options are false, no OVS information will be provided by the plugin.
+
+=back
+
+B<Note:> By default, the global interval setting is used within which to
+retrieve the OVS link status. To configure a plugin-specific interval, please
+use B<Interval> option of the OVS B<LoadPlugin> block settings. For milliseconds
+simple divide the time by 1000 for example if the desired interval is 50ms, set
+interval to 0.05.
+
 =head2 Plugin C<perl>
 
 This plugin embeds a Perl-interpreter into collectd and provides an interface
@@ -7973,6 +8234,23 @@ You can also specify combinations of the B<name> and B<uuid> fields.
 For example B<name uuid> means to concatenate the guest name and UUID
 (with a literal colon character between, thus I<"foo:1234-1234-1234-1234">).
 
+=item B<Instances> B<integer>
+
+How many read instances you want to use for this plugin. The default is one,
+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:
+B<disk> report extra statistics like number of flush operations and total
+service time for read, write and flush operations.
+B<pcpu> report the physical user/system cpu time consumed by the hypervisor, per-vm.
+
 =back
 
 =head2 Plugin C<vmem>
@@ -8143,6 +8421,8 @@ packets.
 Synopsis:
 
  <Plugin write_tsdb>
+   ResolveInterval 60
+   ResolveJitter 60
    <Node "example">
      Host "tsd-1.my.domain"
      Port "4242"
@@ -8151,7 +8431,36 @@ Synopsis:
  </Plugin>
 
 The configuration consists of one or more E<lt>B<Node>E<nbsp>I<Name>E<gt>
-blocks. Inside the B<Node> blocks, the following options are recognized:
+blocks and global directives.
+
+Global directives are:
+
+=over 4
+
+=item B<ResolveInterval> I<seconds>
+
+=item B<ResolveJitter> I<seconds>
+
+When I<collectd> connects to a TSDB node, it will request the hostname from
+DNS. This can become a problem if the TSDB node is unavailable or badly
+configured because collectd will request DNS in order to reconnect for every
+metric, which can flood your DNS. So you can cache the last value for
+I<ResolveInterval> seconds.
+Defaults to the I<Interval> of the I<write_tsdb plugin>, e.g. 10E<nbsp>seconds.
+
+You can also define a jitter, a random interval to wait in addition to
+I<ResolveInterval>. This prevents all your collectd servers to resolve the
+hostname at the same time when the connection fails.
+Defaults to the I<Interval> of the I<write_tsdb plugin>, e.g. 10E<nbsp>seconds.
+
+B<Note:> If the DNS resolution has already been successful when the socket
+closes, the plugin will try to reconnect immediately with the cached
+information. DNS is queried only when the socket is closed for a longer than
+I<ResolveInterval> + I<ResolveJitter> seconds.
+
+=back
+
+Inside the B<Node> blocks, the following options are recognized:
 
 =over 4
 
index 30d1cdc..248baad 100644 (file)
@@ -585,5 +585,3 @@ int main(int argc, char **argv) {
     return (status);
   return (0);
 } /* main */
-
-/* vim: set sw=2 ts=2 tw=78 expandtab : */
index 9040f8d..4a7d1a6 100644 (file)
@@ -386,5 +386,3 @@ int main(int argc, char **argv) {
   free(collectd_argv);
   return 0;
 } /* main */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
index 9091fef..c0bdd56 100644 (file)
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -862,5 +862,3 @@ void module_register(void) {
   plugin_register_config("cpu", cpu_config, config_keys, config_keys_num);
   plugin_register_read("cpu", cpu_read);
 } /* void module_register */
-
-/* vim: set sw=8 sts=8 noet fdm=marker : */
index c6f0b60..4906d92 100644 (file)
@@ -679,5 +679,3 @@ void module_register(void) {
   plugin_register_read("curl", cc_read);
   plugin_register_shutdown("curl", cc_shutdown);
 } /* void module_register */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index e6c0b51..4d8677a 100644 (file)
@@ -940,5 +940,3 @@ void module_register(void) {
   plugin_register_complex_config("curl_json", cj_config);
   plugin_register_init("curl_json", cj_init);
 } /* void module_register */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index 4e4c6f9..1c28227 100644 (file)
@@ -1026,5 +1026,3 @@ void module_register(void) {
   plugin_register_complex_config("curl_xml", cx_config);
   plugin_register_init("curl_xml", cx_init);
 } /* void module_register */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am
deleted file mode 100644 (file)
index 5207943..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-AM_CPPFLAGS = -I$(top_srcdir)/src
-AM_CPPFLAGS += -DPREFIX='"${prefix}"'
-AM_CPPFLAGS += -DCONFIGFILE='"${sysconfdir}/${PACKAGE_NAME}.conf"'
-AM_CPPFLAGS += -DLOCALSTATEDIR='"${localstatedir}"'
-AM_CPPFLAGS += -DPKGLOCALSTATEDIR='"${localstatedir}/lib/${PACKAGE_NAME}"'
-if BUILD_FEATURE_DAEMON
-AM_CPPFLAGS += -DPIDFILE='"${localstatedir}/run/${PACKAGE_NAME}.pid"'
-endif
-AM_CPPFLAGS += -DPLUGINDIR='"${pkglibdir}"'
-AM_CPPFLAGS += -DPKGDATADIR='"${pkgdatadir}"'
-
-# Link to these libraries..
-COMMON_LIBS = $(PTHREAD_LIBS)
-if BUILD_WITH_CAPABILITY
-COMMON_LIBS += -lcap
-endif
-if BUILD_WITH_LIBRT
-COMMON_LIBS += -lrt
-endif
-if BUILD_WITH_LIBPOSIX4
-COMMON_LIBS += -lposix4
-endif
-if BUILD_WITH_LIBSOCKET
-COMMON_LIBS += -lsocket
-endif
-if BUILD_WITH_LIBRESOLV
-COMMON_LIBS += -lresolv
-endif
-if BUILD_WITH_LIBKSTAT
-COMMON_LIBS += -lkstat
-endif
-if BUILD_WITH_LIBDEVINFO
-COMMON_LIBS += -ldevinfo
-endif
-
-sbin_PROGRAMS = collectd
-
-noinst_LTLIBRARIES = libavltree.la libcommon.la libheap.la libmetadata.la libplugin_mock.la
-
-libavltree_la_SOURCES = utils_avltree.c utils_avltree.h
-
-libcommon_la_SOURCES = common.c common.h
-libcommon_la_LIBADD = $(COMMON_LIBS)
-
-libheap_la_SOURCES = utils_heap.c utils_heap.h
-
-libmetadata_la_SOURCES = meta_data.c meta_data.h
-
-libplugin_mock_la_SOURCES = plugin_mock.c utils_cache_mock.c \
-                           utils_time.c utils_time.h
-libplugin_mock_la_CPPFLAGS = $(AM_CPPFLAGS) -DMOCK_TIME
-libplugin_mock_la_LIBADD = $(COMMON_LIBS) libcommon.la
-
-collectd_SOURCES = collectd.c collectd.h \
-                  configfile.c configfile.h \
-                  filter_chain.c filter_chain.h \
-                  meta_data.c meta_data.h \
-                  plugin.c plugin.h \
-                  utils_cache.c utils_cache.h \
-                  utils_complain.c utils_complain.h \
-                  utils_ignorelist.c utils_ignorelist.h \
-                  utils_llist.c utils_llist.h \
-                  utils_random.c utils_random.h \
-                  utils_subst.c utils_subst.h \
-                  utils_time.c utils_time.h \
-                  types_list.c types_list.h \
-                  utils_threshold.c utils_threshold.h
-
-
-collectd_CPPFLAGS =  $(AM_CPPFLAGS) $(LTDLINCL)
-collectd_CFLAGS = $(AM_CFLAGS)
-collectd_LDFLAGS = -export-dynamic
-collectd_LDADD = libavltree.la libcommon.la libheap.la -lm $(COMMON_LIBS)
-collectd_DEPENDENCIES = libavltree.la libcommon.la libheap.la libmetadata.la
-
-# The daemon needs to call sg_init, so we need to link it against libstatgrab,
-# too. -octo
-if BUILD_WITH_LIBSTATGRAB
-collectd_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
-collectd_LDADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
-endif
-
-if BUILD_WITH_OWN_LIBOCONFIG
-collectd_LDADD += $(LIBLTDL) $(top_builddir)/src/liboconfig/liboconfig.la
-collectd_DEPENDENCIES += $(top_builddir)/src/liboconfig/liboconfig.la
-else
-collectd_LDADD += -loconfig
-endif
-
-LOG_COMPILER = env VALGRIND="@VALGRIND@" $(abs_top_srcdir)/testwrapper.sh
-
-check_PROGRAMS = test_common test_meta_data test_utils_avltree test_utils_heap test_utils_time test_utils_subst
-TESTS          = test_common test_meta_data test_utils_avltree test_utils_heap test_utils_time test_utils_subst
-
-test_common_SOURCES = common_test.c ../testing.h
-test_common_LDADD = libplugin_mock.la
-
-test_meta_data_SOURCES = meta_data_test.c ../testing.h
-test_meta_data_LDADD = libmetadata.la libplugin_mock.la
-
-test_utils_avltree_SOURCES = utils_avltree_test.c ../testing.h
-test_utils_avltree_LDADD = libavltree.la $(COMMON_LIBS)
-
-test_utils_heap_SOURCES = utils_heap_test.c ../testing.h
-test_utils_heap_LDADD = libheap.la $(COMMON_LIBS)
-
-test_utils_time_SOURCES = utils_time_test.c ../testing.h
-
-test_utils_subst_SOURCES = utils_subst_test.c ../testing.h \
-                          utils_subst.c utils_subst.h
-test_utils_subst_LDADD = libplugin_mock.la
index 4ec002d..38ffd0f 100644 (file)
 #include "config.h"
 #endif
 
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #if HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
 #if HAVE_SYS_STAT_H
 #include <sys/stat.h>
 #endif
-#if STDC_HEADERS
-#include <stddef.h>
-#include <stdlib.h>
-#else
-#if HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#endif
-#if HAVE_STRING_H
-#if !STDC_HEADERS && HAVE_MEMORY_H
-#include <memory.h>
-#endif
-#include <string.h>
-#endif
 #if HAVE_STRINGS_H
 #include <strings.h>
 #endif
-#if HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-#if HAVE_STDINT_H
-#include <stdint.h>
-#endif
 #if HAVE_UNISTD_H
 #include <unistd.h>
 #endif
 #ifndef WIFEXITED
 #define WIFEXITED(stat_val) (((stat_val)&255) == 0)
 #endif
-#if HAVE_SIGNAL_H
-#include <signal.h>
-#endif
 #if HAVE_FCNTL_H
 #include <fcntl.h>
 #endif
-#if HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#if HAVE_LIMITS_H
-#include <limits.h>
-#endif
 #if TIME_WITH_SYS_TIME
 #include <sys/time.h>
 #include <time.h>
 #include <sys/socket.h>
 #endif
 
-#if HAVE_ASSERT_H
-#include <assert.h>
-#else
-#define assert(...) /* nop */
-#endif
-
-#if !defined(HAVE__BOOL) || !HAVE__BOOL
-typedef int _Bool;
-#undef HAVE__BOOL
-#define HAVE__BOOL 1
-#endif
-
 #if NAN_STATIC_DEFAULT
 #include <math.h>
 /* #endif NAN_STATIC_DEFAULT*/
@@ -212,12 +182,6 @@ typedef int _Bool;
 #endif
 #endif
 
-#if HAVE_STDARG_H
-#include <stdarg.h>
-#endif
-#if HAVE_CTYPE_H
-#include <ctype.h>
-#endif
 #if HAVE_SYS_PARAM_H
 #include <sys/param.h>
 #endif
index 1fa99eb..64dbee6 100644 (file)
 #include "plugin.h"
 #include "utils_cache.h"
 
-#ifdef HAVE_MATH_H
-#include <math.h>
-#endif
-
 /* for getaddrinfo */
 #include <netdb.h>
 #include <sys/types.h>
index 0c96945..f18d9fd 100644 (file)
@@ -392,5 +392,3 @@ int main(void) {
 
   END_TEST;
 }
-
-/* vim: set sw=2 sts=2 et : */
index 3934e1f..654cc49 100644 (file)
@@ -245,7 +245,7 @@ static int dispatch_value_plugindir(oconfig_item_t *ci) {
 
 static int dispatch_loadplugin(oconfig_item_t *ci) {
   const char *name;
-  unsigned int flags = 0;
+  _Bool global = 0;
   plugin_ctx_t ctx = {0};
   plugin_ctx_t old_ctx;
   int ret_val;
@@ -270,7 +270,7 @@ static int dispatch_loadplugin(oconfig_item_t *ci) {
     oconfig_item_t *child = ci->children + i;
 
     if (strcasecmp("Globals", child->key) == 0)
-      cf_util_get_flag(child, &flags, PLUGIN_FLAGS_GLOBAL);
+      cf_util_get_boolean(child, &global);
     else if (strcasecmp("Interval", child->key) == 0)
       cf_util_get_cdtime(child, &ctx.interval);
     else if (strcasecmp("FlushInterval", child->key) == 0)
@@ -285,7 +285,7 @@ static int dispatch_loadplugin(oconfig_item_t *ci) {
   }
 
   old_ctx = plugin_set_ctx(ctx);
-  ret_val = plugin_load(name, (uint32_t)flags);
+  ret_val = plugin_load(name, global);
   /* reset to the "global" context */
   plugin_set_ctx(old_ctx);
 
index 9c4a89c..f21ea32 100644 (file)
@@ -942,5 +942,3 @@ int fc_configure(const oconfig_item_t *ci) /* {{{ */
 
   return (-1);
 } /* }}} int fc_configure */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index 36ccbae..5cc06fc 100644 (file)
@@ -101,4 +101,3 @@ int fc_default_action(const data_set_t *ds, value_list_t *vl);
 int fc_configure(const oconfig_item_t *ci);
 
 #endif /* FILTER_CHAIN_H */
-/* vim: set sw=2 sts=2 et : */
index 583d819..3ac5370 100644 (file)
@@ -690,7 +690,7 @@ int meta_data_get_boolean(meta_data_t *md, /* {{{ */
 int meta_data_as_string(meta_data_t *md, /* {{{ */
                         const char *key, char **value) {
   meta_entry_t *e;
-  char *actual;
+  const char *actual;
   char buffer[MD_MAX_NONSTRING_CHARS]; /* For non-string types. */
   char *temp;
   int type;
@@ -746,5 +746,3 @@ int meta_data_as_string(meta_data_t *md, /* {{{ */
 
   return (0);
 } /* }}} int meta_data_as_string */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index 3ef3360..50fdb8d 100644 (file)
@@ -69,4 +69,3 @@ int meta_data_get_boolean(meta_data_t *md, const char *key, _Bool *value);
 int meta_data_as_string(meta_data_t *md, const char *key, char **value);
 
 #endif /* META_DATA_H */
-/* vim: set sw=2 sts=2 et : */
index 803c745..bcd457d 100644 (file)
@@ -114,5 +114,3 @@ int main(void) {
 
   END_TEST;
 }
-
-/* vim: set sw=2 sts=2 et : */
index 0f06737..b37e9b3 100644 (file)
@@ -46,7 +46,7 @@
 #include <pthread_np.h> /* for pthread_set_name_np(3) */
 #endif
 
-#include <ltdl.h>
+#include <dlfcn.h>
 
 /*
  * Private structures
@@ -388,40 +388,25 @@ static int plugin_unregister(llist_t *list, const char *name) /* {{{ */
  * object, but it will bitch about a shared object not having a
  * ``module_register'' symbol..
  */
-static int plugin_load_file(char *file, uint32_t flags) {
-  lt_dlhandle dlh;
+static int plugin_load_file(const char *file, _Bool global) {
   void (*reg_handle)(void);
 
-  lt_dlinit();
-  lt_dlerror(); /* clear errors */
+  int flags = RTLD_NOW;
+  if (global)
+    flags |= RTLD_GLOBAL;
 
-#if LIBTOOL_VERSION == 2
-  if (flags & PLUGIN_FLAGS_GLOBAL) {
-    lt_dladvise advise;
-    lt_dladvise_init(&advise);
-    lt_dladvise_global(&advise);
-    dlh = lt_dlopenadvise(file, advise);
-    lt_dladvise_destroy(&advise);
-  } else {
-    dlh = lt_dlopen(file);
-  }
-#else /* if LIBTOOL_VERSION == 1 */
-  if (flags & PLUGIN_FLAGS_GLOBAL)
-    WARNING("plugin_load_file: The global flag is not supported, "
-            "libtool 2 is required for this.");
-  dlh = lt_dlopen(file);
-#endif
+  void *dlh = dlopen(file, flags);
 
   if (dlh == NULL) {
     char errbuf[1024] = "";
 
     ssnprintf(errbuf, sizeof(errbuf),
-              "lt_dlopen (\"%s\") failed: %s. "
+              "dlopen (\"%s\") failed: %s. "
               "The most common cause for this problem is "
               "missing dependencies. Use ldd(1) to check "
               "the dependencies of the plugin "
               "/ shared object.",
-              file, lt_dlerror());
+              file, dlerror());
 
     ERROR("%s", errbuf);
     /* Make sure this is printed to STDERR in any case, but also
@@ -432,10 +417,11 @@ static int plugin_load_file(char *file, uint32_t flags) {
     return (1);
   }
 
-  if ((reg_handle = (void (*)(void))lt_dlsym(dlh, "module_register")) == NULL) {
+  reg_handle = (void (*)(void))dlsym(dlh, "module_register");
+  if (reg_handle == NULL) {
     WARNING("Couldn't find symbol \"module_register\" in \"%s\": %s\n", file,
-            lt_dlerror());
-    lt_dlclose(dlh);
+            dlerror());
+    dlclose(dlh);
     return (-1);
   }
 
@@ -972,7 +958,7 @@ static void plugin_free_loaded(void) {
 }
 
 #define BUFSIZE 512
-int plugin_load(char const *plugin_name, uint32_t flags) {
+int plugin_load(char const *plugin_name, _Bool global) {
   DIR *dh;
   const char *dir;
   char filename[BUFSIZE] = "";
@@ -1006,7 +992,7 @@ int plugin_load(char const *plugin_name, uint32_t flags) {
    */
   if ((strcasecmp("perl", plugin_name) == 0) ||
       (strcasecmp("python", plugin_name) == 0))
-    flags |= PLUGIN_FLAGS_GLOBAL;
+    global = 1;
 
   /* `cpu' should not match `cpufreq'. To solve this we add `.so' to the
    * type when matching the filename */
@@ -1044,7 +1030,7 @@ int plugin_load(char const *plugin_name, uint32_t flags) {
       continue;
     }
 
-    status = plugin_load_file(filename, flags);
+    status = plugin_load_file(filename, global);
     if (status == 0) {
       /* success */
       plugin_mark_loaded(plugin_name);
@@ -2590,5 +2576,3 @@ int plugin_thread_create(pthread_t *thread, const pthread_attr_t *attr,
 
   return 0;
 } /* int plugin_thread_create */
-
-/* vim: set sw=8 ts=8 noet fdm=marker : */
index f6448a5..4f877e0 100644 (file)
@@ -36,8 +36,6 @@
 
 #include <pthread.h>
 
-#define PLUGIN_FLAGS_GLOBAL 0x0001
-
 #ifndef DATA_MAX_NAME_LEN
 #define DATA_MAX_NAME_LEN 128
 #endif
@@ -226,7 +224,7 @@ void plugin_set_dir(const char *dir);
  *
  * ARGUMENTS
  *  `name'      Name of the plugin to load.
- *  `flags'     Hints on how to handle this plugin.
+ *  `global'    Make this plugins symbols available for other shared libraries.
  *
  * RETURN VALUE
  *  Returns zero upon success, a value greater than zero if no plugin was found
@@ -236,7 +234,7 @@ void plugin_set_dir(const char *dir);
  *  Re-loading an already loaded module is detected and zero is returned in
  *  this case.
  */
-int plugin_load(const char *name, uint32_t flags);
+int plugin_load(const char *name, _Bool global);
 
 int plugin_init_all(void);
 void plugin_read_all(void);
index ddfc789..9e7ba39 100644 (file)
@@ -32,6 +32,12 @@ kstat_ctl_t *kc = NULL;
 
 char hostname_g[] = "example.com";
 
+int plugin_register_config(const char *name,
+                           int (*callback)(const char *key, const char *val),
+                           const char **keys, int keys_num) {
+  return ENOTSUP;
+}
+
 int plugin_register_complex_config(const char *type,
                                    int (*callback)(oconfig_item_t *)) {
   return ENOTSUP;
@@ -45,6 +51,13 @@ int plugin_register_read(const char *name, int (*callback)(void)) {
   return ENOTSUP;
 }
 
+int plugin_register_complex_read(const char *group, const char *name,
+                                 int (*callback)(user_data_t *),
+                                 cdtime_t interval,
+                                 user_data_t const *user_data) {
+  return ENOTSUP;
+}
+
 int plugin_register_shutdown(const char *name, int (*callback)(void)) {
   return ENOTSUP;
 }
@@ -76,5 +89,3 @@ void plugin_log(int level, char const *format, ...) {
 }
 
 cdtime_t plugin_get_interval(void) { return TIME_T_TO_CDTIME_T(10); }
-
-/* vim: set sw=2 sts=2 et : */
index b1a7203..b053157 100644 (file)
@@ -191,7 +191,3 @@ int read_types_list(const char *file) {
 
   return (0);
 } /* int read_types_list */
-
-/*
- * vim: shiftwidth=2:softtabstop=2:tabstop=8
- */
index 0a84f6f..345f97b 100644 (file)
@@ -135,5 +135,3 @@ int main(void) {
 
   END_TEST;
 }
-
-/* vim: set sw=2 sts=2 et : */
index fe0e083..0caf22c 100644 (file)
@@ -938,5 +938,3 @@ int uc_meta_data_exists(const value_list_t *vl,
                                                 const char *key, _Bool *value)
                                                 UC_WRAP(meta_data_get_boolean)
 #undef UC_WRAP
-
-    /* vim: set sw=2 ts=8 sts=2 tw=78 : */
index 2f40873..24c58ff 100644 (file)
@@ -133,5 +133,4 @@ int uc_meta_data_get_double(const value_list_t *vl, const char *key,
 int uc_meta_data_get_boolean(const value_list_t *vl, const char *key,
                              _Bool *value);
 
-/* vim: set shiftwidth=2 softtabstop=2 tabstop=8 : */
 #endif /* !UTILS_CACHE_H */
index fb45243..d2162ba 100644 (file)
@@ -97,5 +97,3 @@ void c_do_release(int level, c_complain_t *c, const char *format, ...) {
 
   plugin_log(level, "%s", message);
 } /* c_release */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
index fbeea90..46d3a19 100644 (file)
@@ -113,5 +113,3 @@ c_do_release(int level, c_complain_t *c, const char *format, ...);
   } while (0)
 
 #endif /* UTILS_COMPLAIN_H */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
index 8dd501d..3bae48e 100644 (file)
@@ -203,5 +203,3 @@ void *c_heap_get_root(c_heap_t *h) {
 
   return (ret);
 } /* void *c_heap_get_root */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index 2f77cc4..d2d70cd 100644 (file)
@@ -97,4 +97,3 @@ int c_heap_insert(c_heap_t *h, void *ptr);
 void *c_heap_get_root(c_heap_t *h);
 
 #endif /* UTILS_HEAP_H */
-/* vim: set sw=2 sts=2 et : */
index 8443b60..dec84f9 100644 (file)
@@ -76,5 +76,3 @@ int main(void) {
 
   END_TEST;
 }
-
-/* vim: set sw=2 sts=2 et : */
index d490986..77b500f 100644 (file)
@@ -50,7 +50,7 @@ static void cdrand_seed(void) {
   have_seed = 1;
 }
 
-double cdrand_d() {
+double cdrand_d(void) {
   double r;
 
   pthread_mutex_lock(&lock);
@@ -61,7 +61,7 @@ double cdrand_d() {
   return (r);
 }
 
-uint32_t cdrand_u() {
+uint32_t cdrand_u(void) {
   long r;
 
   pthread_mutex_lock(&lock);
index e25ae9b..75bdc12 100644 (file)
@@ -29,7 +29,7 @@
  *
  * This function is thread- and reentrant-safe.
  */
-double cdrand_d();
+double cdrand_d(void);
 
 /**
  * cdrand_u returns a random uint32_t value uniformly distributed in the range
@@ -37,7 +37,7 @@ double cdrand_d();
  *
  * This function is thread- and reentrant-safe.
  */
-uint32_t cdrand_u();
+uint32_t cdrand_u(void);
 
 /**
  * Returns a random long between min and max, inclusively.
index 7056c5f..5235343 100644 (file)
@@ -159,5 +159,3 @@ char *subst_string(char *buf, size_t buflen, const char *string,
 
   return (buf);
 } /* char *subst_string */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
index 025f8d4..a10b258 100644 (file)
@@ -100,5 +100,3 @@ char *subst_string(char *buf, size_t buflen, const char *string,
                    const char *needle, const char *replacement);
 
 #endif /* UTILS_SUBST_H */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
index e335b50..00ea0ea 100644 (file)
@@ -132,5 +132,3 @@ int main(void) {
 
   END_TEST;
 }
-
-/* vim: set sw=2 sts=2 et : */
index 585ad12..cefc6e2 100644 (file)
@@ -61,5 +61,3 @@ threshold_t *threshold_search(const value_list_t *vl);
 int ut_search_threshold(const value_list_t *vl, threshold_t *ret_threshold);
 
 #endif /* UTILS_THRESHOLD_H */
-
-/* vim: set sw=2 sts=2 ts=8 : */
index 9ba2b5a..815d969 100644 (file)
@@ -240,5 +240,3 @@ int rfc3339nano_local(char *buffer, size_t buffer_size, cdtime_t t) /* {{{ */
 
   return format_rfc3339_local(buffer, buffer_size, t, 1);
 } /* }}} int rfc3339nano */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index db510af..60a6ea9 100644 (file)
@@ -130,4 +130,3 @@ int rfc3339_local(char *buffer, size_t buffer_size, cdtime_t t);
 int rfc3339nano_local(char *buffer, size_t buffer_size, cdtime_t t);
 
 #endif /* UTILS_TIME_H */
-/* vim: set sw=2 sts=2 et : */
index c1c60a2..c0179cc 100644 (file)
@@ -167,5 +167,3 @@ int main(void) {
 
   END_TEST;
 }
-
-/* vim: set sw=2 sts=2 et : */
index 7cab1d5..2b374e9 100644 (file)
--- a/src/dbi.c
+++ b/src/dbi.c
@@ -780,7 +780,3 @@ void module_register(void) /* {{{ */
   plugin_register_init("dbi", cdbi_init);
   plugin_register_shutdown("dbi", cdbi_shutdown);
 } /* }}} void module_register */
-
-/*
- * vim: shiftwidth=2 softtabstop=2 et fdm=marker
- */
index e01e150..58a1c18 100644 (file)
@@ -139,7 +139,7 @@ static int pnumdisk;
 #error "No applicable input method."
 #endif
 
-#if HAVE_LIBUDEV
+#if HAVE_UDEV_H
 #include <libudev.h>
 
 static char *conf_udev_name_attr = NULL;
@@ -173,7 +173,7 @@ static int disk_config(const char *key, const char *value) {
             "on Mach / Mac OS X and will be ignored.");
 #endif
   } else if (strcasecmp("UdevNameAttr", key) == 0) {
-#if HAVE_LIBUDEV
+#if HAVE_UDEV_H
     if (conf_udev_name_attr != NULL) {
       free(conf_udev_name_attr);
       conf_udev_name_attr = NULL;
@@ -209,7 +209,7 @@ static int disk_init(void) {
 /* #endif HAVE_IOKIT_IOKITLIB_H */
 
 #elif KERNEL_LINUX
-#if HAVE_LIBUDEV
+#if HAVE_UDEV_H
   if (conf_udev_name_attr != NULL) {
     handle_udev = udev_new();
     if (handle_udev == NULL) {
@@ -217,7 +217,7 @@ static int disk_init(void) {
       return (-1);
     }
   }
-#endif /* HAVE_LIBUDEV */
+#endif /* HAVE_UDEV_H */
 /* #endif KERNEL_LINUX */
 
 #elif KERNEL_FREEBSD
@@ -260,10 +260,10 @@ static int disk_init(void) {
 
 static int disk_shutdown(void) {
 #if KERNEL_LINUX
-#if HAVE_LIBUDEV
+#if HAVE_UDEV_H
   if (handle_udev != NULL)
     udev_unref(handle_udev);
-#endif /* HAVE_LIBUDEV */
+#endif /* HAVE_UDEV_H */
 #endif /* KERNEL_LINUX */
   return (0);
 } /* int disk_shutdown */
@@ -325,7 +325,7 @@ static counter_t disk_calc_time_incr(counter_t delta_time,
 }
 #endif
 
-#if HAVE_LIBUDEV
+#if HAVE_UDEV_H
 /**
  * Attempt to provide an rename disk instance from an assigned udev attribute.
  *
@@ -842,7 +842,7 @@ static int disk_read(void) {
 
     output_name = disk_name;
 
-#if HAVE_LIBUDEV
+#if HAVE_UDEV_H
     char *alt_name = NULL;
     if (conf_udev_name_attr != NULL) {
       alt_name =
@@ -853,7 +853,7 @@ static int disk_read(void) {
 #endif
 
     if (ignorelist_match(ignorelist, output_name) != 0) {
-#if HAVE_LIBUDEV
+#if HAVE_UDEV_H
       /* release udev-based alternate name, if allocated */
       sfree(alt_name);
 #endif
@@ -879,7 +879,7 @@ static int disk_read(void) {
         submit_io_time(output_name, io_time, weighted_time);
     } /* if (is_disk) */
 
-#if HAVE_LIBUDEV
+#if HAVE_UDEV_H
     /* release udev-based alternate name, if allocated */
     sfree(alt_name);
 #endif
diff --git a/src/dpdkevents.c b/src/dpdkevents.c
new file mode 100644 (file)
index 0000000..6be6bc0
--- /dev/null
@@ -0,0 +1,584 @@
+/*
+ * collectd - src/dpdkevents.c
+ * MIT License
+ *
+ * Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *   Maryam Tahhan <maryam.tahhan@intel.com>
+ *   Harry van Haaren <harry.van.haaren@intel.com>
+ *   Serhiy Pshyk <serhiyx.pshyk@intel.com>
+ *   Kim-Marie Jones <kim-marie.jones@intel.com>
+ *   Krzysztof Matczak <krzysztofx@intel.com>
+ */
+
+#include "collectd.h"
+
+#include "common.h"
+#include "plugin.h"
+
+#include "semaphore.h"
+#include "sys/mman.h"
+#include "utils_dpdk.h"
+#include "utils_time.h"
+
+#include <rte_config.h>
+#include <rte_eal.h>
+#include <rte_ethdev.h>
+#include <rte_keepalive.h>
+
+#define DPDK_EVENTS_PLUGIN "dpdkevents"
+#define DPDK_EVENTS_NAME "dpdk_collectd_events"
+#define ETH_LINK_NA 0xFF
+
+#define INT64_BIT_SIZE 64
+#define KEEPALIVE_PLUGIN_INSTANCE "keepalive"
+#define RTE_KEEPALIVE_SHM_NAME "/dpdk_keepalive_shm_name"
+
+typedef struct dpdk_keepalive_shm_s {
+  sem_t core_died;
+  enum rte_keepalive_state core_state[RTE_KEEPALIVE_MAXCORES];
+  uint64_t core_last_seen_times[RTE_KEEPALIVE_MAXCORES];
+} dpdk_keepalive_shm_t;
+
+typedef struct dpdk_ka_monitor_s {
+  cdtime_t read_time;
+  int lcore_state;
+} dpdk_ka_monitor_t;
+
+typedef struct dpdk_link_status_config_s {
+  int enabled;
+  int send_updated;
+  uint32_t enabled_port_mask;
+  char port_name[RTE_MAX_ETHPORTS][DATA_MAX_NAME_LEN];
+  int notify;
+} dpdk_link_status_config_t;
+
+typedef struct dpdk_keep_alive_config_s {
+  int enabled;
+  int send_updated;
+  uint128_t lcore_mask;
+  dpdk_keepalive_shm_t *shm;
+  char shm_name[DATA_MAX_NAME_LEN];
+  int notify;
+} dpdk_keep_alive_config_t;
+
+typedef struct dpdk_events_config_s {
+  cdtime_t interval;
+  dpdk_link_status_config_t link_status;
+  dpdk_keep_alive_config_t keep_alive;
+} dpdk_events_config_t;
+
+typedef struct dpdk_link_info_s {
+  cdtime_t read_time;
+  int status_updated;
+  int link_status;
+} dpdk_link_info_t;
+
+typedef struct dpdk_events_ctx_s {
+  dpdk_events_config_t config;
+  uint32_t nb_ports;
+  dpdk_link_info_t link_info[RTE_MAX_ETHPORTS];
+  dpdk_ka_monitor_t core_info[RTE_KEEPALIVE_MAXCORES];
+} dpdk_events_ctx_t;
+
+#define DPDK_EVENTS_CTX_GET(a) ((dpdk_events_ctx_t *)dpdk_helper_priv_get(a))
+
+#define DPDK_EVENTS_TRACE()                                                    \
+  DEBUG("%s:%s:%d pid=%u", DPDK_EVENTS_PLUGIN, __FUNCTION__, __LINE__, getpid())
+
+static dpdk_helper_ctx_t *g_hc;
+
+static int dpdk_event_keep_alive_shm_create(void) {
+  dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(g_hc);
+  char *shm_name;
+
+  if (strlen(ec->config.keep_alive.shm_name)) {
+    shm_name = ec->config.keep_alive.shm_name;
+  } else {
+    shm_name = RTE_KEEPALIVE_SHM_NAME;
+    WARNING(DPDK_EVENTS_PLUGIN ": Keep alive shared memory identifier is not "
+                               "specified, using default one: %s",
+            shm_name);
+  }
+
+  char errbuf[ERR_BUF_SIZE];
+  int fd = shm_open(shm_name, O_RDWR, 0);
+  if (fd < 0) {
+    ERROR(DPDK_EVENTS_PLUGIN ": Failed to open %s as SHM:%s. Is DPDK KA "
+                             "primary application running?",
+          shm_name, sstrerror(errno, errbuf, sizeof(errbuf)));
+    return errno;
+  } else {
+    ec->config.keep_alive.shm =
+        (dpdk_keepalive_shm_t *)mmap(0, sizeof(*(ec->config.keep_alive.shm)),
+                                     PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+    close(fd);
+    if (ec->config.keep_alive.shm == MAP_FAILED) {
+      ERROR(DPDK_EVENTS_PLUGIN ": Failed to mmap KA SHM:%s",
+            sstrerror(errno, errbuf, sizeof(errbuf)));
+      return errno;
+    }
+  }
+
+  return 0;
+}
+
+static void dpdk_events_default_config(void) {
+  dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(g_hc);
+
+  ec->config.interval = plugin_get_interval();
+
+  /* Link Status */
+  ec->config.link_status.enabled = 0;
+  ec->config.link_status.enabled_port_mask = ~0;
+  ec->config.link_status.send_updated = 1;
+  ec->config.link_status.notify = 0;
+
+  for (int i = 0; i < RTE_MAX_ETHPORTS; i++) {
+    ec->config.link_status.port_name[i][0] = 0;
+  }
+
+  /* Keep Alive */
+  ec->config.keep_alive.enabled = 0;
+  ec->config.keep_alive.send_updated = 1;
+  ec->config.keep_alive.notify = 0;
+  memset(&ec->config.keep_alive.lcore_mask, 0,
+         sizeof(ec->config.keep_alive.lcore_mask));
+  memset(&ec->config.keep_alive.shm_name, 0,
+         sizeof(ec->config.keep_alive.shm_name));
+}
+
+static int dpdk_events_preinit(void) {
+  DPDK_EVENTS_TRACE();
+
+  if (g_hc != NULL) {
+    /* already initialized if config callback was called before init callback */
+    DEBUG("dpdk_events_preinit: helper already initialized.");
+    return 0;
+  }
+
+  int ret =
+      dpdk_helper_init(DPDK_EVENTS_NAME, sizeof(dpdk_events_ctx_t), &g_hc);
+  if (ret != 0) {
+    ERROR(DPDK_EVENTS_PLUGIN ": failed to initialize %s helper(error: %s)",
+          DPDK_EVENTS_NAME, strerror(ret));
+    return ret;
+  }
+
+  dpdk_events_default_config();
+
+  dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(g_hc);
+  for (int i = 0; i < RTE_MAX_ETHPORTS; i++) {
+    ec->link_info[i].link_status = ETH_LINK_NA;
+  }
+
+  for (int i = 0; i < RTE_KEEPALIVE_MAXCORES; i++) {
+    ec->core_info[i].lcore_state = ETH_LINK_NA;
+  }
+
+  return ret;
+}
+
+static int dpdk_events_link_status_config(dpdk_events_ctx_t *ec,
+                                          oconfig_item_t *ci) {
+  ec->config.link_status.enabled = 1;
+
+  DEBUG(DPDK_EVENTS_PLUGIN ": Subscribed for Link Status Events.");
+
+  for (int i = 0; i < ci->children_num; i++) {
+    oconfig_item_t *child = ci->children + i;
+
+    if (strcasecmp("EnabledPortMask", child->key) == 0) {
+      ec->config.link_status.enabled_port_mask =
+          (uint32_t)child->values[0].value.number;
+      DEBUG(DPDK_EVENTS_PLUGIN ": LinkStatus:Enabled Port Mask 0x%X",
+            ec->config.link_status.enabled_port_mask);
+    } else if (strcasecmp("SendEventsOnUpdate", child->key) == 0) {
+      ec->config.link_status.send_updated = child->values[0].value.boolean;
+      DEBUG(DPDK_EVENTS_PLUGIN ": LinkStatus:SendEventsOnUpdate %d",
+            (int)child->values[0].value.boolean);
+    } else if (strcasecmp("SendNotification", child->key) == 0) {
+      ec->config.link_status.notify = child->values[0].value.boolean;
+      DEBUG(DPDK_EVENTS_PLUGIN ": LinkStatus:SendNotification %d",
+            (int)child->values[0].value.boolean);
+    }
+  }
+
+  int port_num = 0;
+
+  /* parse port names after EnabledPortMask was parsed */
+  for (int i = 0; i < ci->children_num; i++) {
+    oconfig_item_t *child = ci->children + i;
+    if (strcasecmp("PortName", child->key) == 0) {
+      while (!(ec->config.link_status.enabled_port_mask & (1 << port_num)))
+        port_num++;
+      ssnprintf(ec->config.link_status.port_name[port_num], DATA_MAX_NAME_LEN,
+                "%s", child->values[0].value.string);
+      DEBUG(DPDK_EVENTS_PLUGIN ": LinkStatus:Port %d Name: %s", port_num,
+            ec->config.link_status.port_name[port_num]);
+      port_num++;
+    }
+  }
+
+  return 0;
+}
+
+static int dpdk_events_keep_alive_config(dpdk_events_ctx_t *ec,
+                                         oconfig_item_t *ci) {
+  ec->config.keep_alive.enabled = 1;
+  DEBUG(DPDK_EVENTS_PLUGIN ": Subscribed for Keep Alive Events.");
+
+  for (int i = 0; i < ci->children_num; i++) {
+    oconfig_item_t *child = ci->children + i;
+
+    if (strcasecmp("SendEventsOnUpdate", child->key) == 0) {
+      ec->config.keep_alive.send_updated = child->values[0].value.boolean;
+      DEBUG(DPDK_EVENTS_PLUGIN ": KeepAlive:SendEventsOnUpdate %d",
+            (int)child->values[0].value.boolean);
+    } else if (strcasecmp("LCoreMask", child->key) == 0) {
+      char lcore_mask[DATA_MAX_NAME_LEN];
+      ssnprintf(lcore_mask, sizeof(lcore_mask), "%s",
+                child->values[0].value.string);
+      ec->config.keep_alive.lcore_mask =
+          str_to_uint128(lcore_mask, strlen(lcore_mask));
+      DEBUG(DPDK_EVENTS_PLUGIN ": KeepAlive:LCoreMask 0x%" PRIX64 "%" PRIX64 "",
+            ec->config.keep_alive.lcore_mask.high,
+            ec->config.keep_alive.lcore_mask.low);
+    } else if (strcasecmp("KeepAliveShmName", child->key) == 0) {
+      ssnprintf(ec->config.keep_alive.shm_name,
+                sizeof(ec->config.keep_alive.shm_name), "%s",
+                child->values[0].value.string);
+      DEBUG(DPDK_EVENTS_PLUGIN ": KeepAlive:KeepAliveShmName %s",
+            ec->config.keep_alive.shm_name);
+    } else if (strcasecmp("SendNotification", child->key) == 0) {
+      ec->config.keep_alive.notify = child->values[0].value.boolean;
+      DEBUG(DPDK_EVENTS_PLUGIN ": KeepAlive:SendNotification %d",
+            (int)child->values[0].value.boolean);
+    }
+  }
+
+  return 0;
+}
+
+static int dpdk_events_config(oconfig_item_t *ci) {
+  DPDK_EVENTS_TRACE();
+
+  int ret = dpdk_events_preinit();
+  if (ret)
+    return ret;
+
+  dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(g_hc);
+
+  for (int i = 0; i < ci->children_num; i++) {
+    oconfig_item_t *child = ci->children + i;
+    if (strcasecmp("EAL", child->key) == 0) {
+      dpdk_helper_eal_config_parse(g_hc, child);
+    } else if (strcasecmp("Event", child->key) == 0) {
+      if (strcasecmp(child->values[0].value.string, "link_status") == 0) {
+        dpdk_events_link_status_config(ec, child);
+      } else if (strcasecmp(child->values[0].value.string, "keep_alive") == 0) {
+        dpdk_events_keep_alive_config(ec, child);
+      } else {
+        ERROR(DPDK_EVENTS_PLUGIN ": The selected event \"%s\" is unknown.",
+              child->values[0].value.string);
+      }
+    }
+  }
+
+  if (!ec->config.keep_alive.enabled && !ec->config.link_status.enabled) {
+    ERROR(DPDK_EVENTS_PLUGIN ": At least one type of events should be "
+                             "configured for collecting. Plugin misconfigured");
+    return -1;
+  }
+
+  return ret;
+}
+
+static int dpdk_helper_link_status_get(dpdk_helper_ctx_t *phc) {
+  dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(phc);
+
+  /* get Link Status values from DPDK */
+  uint8_t nb_ports = rte_eth_dev_count();
+  if (nb_ports == 0) {
+    DPDK_CHILD_LOG("dpdkevent-helper: No DPDK ports available. "
+                   "Check bound devices to DPDK driver.\n");
+    return -ENODEV;
+  }
+  ec->nb_ports = nb_ports > RTE_MAX_ETHPORTS ? RTE_MAX_ETHPORTS : nb_ports;
+
+  for (int i = 0; i < ec->nb_ports; i++) {
+    if (ec->config.link_status.enabled_port_mask & (1 << i)) {
+      struct rte_eth_link link;
+      ec->link_info[i].read_time = cdtime();
+      rte_eth_link_get_nowait(i, &link);
+      if ((link.link_status == ETH_LINK_NA) ||
+          (link.link_status != ec->link_info[i].link_status)) {
+        ec->link_info[i].link_status = link.link_status;
+        ec->link_info[i].status_updated = 1;
+        DPDK_CHILD_LOG(" === PORT %d Link Status: %s\n", i,
+                       link.link_status ? "UP" : "DOWN");
+      }
+    }
+  }
+
+  return 0;
+}
+
+/* this function is called from helper context */
+int dpdk_helper_command_handler(dpdk_helper_ctx_t *phc, enum DPDK_CMD cmd) {
+  if (phc == NULL) {
+    DPDK_CHILD_LOG(DPDK_EVENTS_PLUGIN ": Invalid argument(phc)\n");
+    return -EINVAL;
+  }
+
+  if (cmd != DPDK_CMD_GET_EVENTS) {
+    DPDK_CHILD_LOG(DPDK_EVENTS_PLUGIN ": Unknown command (cmd=%d)\n", cmd);
+    return -EINVAL;
+  }
+
+  dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(phc);
+  int ret = 0;
+  if (ec->config.link_status.enabled)
+    ret = dpdk_helper_link_status_get(phc);
+
+  return ret;
+}
+
+static void dpdk_events_notification_dispatch(int severity,
+                                              const char *plugin_instance,
+                                              cdtime_t time, const char *msg) {
+  notification_t n = {
+      .severity = severity, .time = time, .plugin = DPDK_EVENTS_PLUGIN};
+  sstrncpy(n.host, hostname_g, sizeof(n.host));
+  sstrncpy(n.plugin_instance, plugin_instance, sizeof(n.plugin_instance));
+  sstrncpy(n.message, msg, sizeof(n.message));
+  plugin_dispatch_notification(&n);
+}
+
+static void dpdk_events_gauge_submit(const char *plugin_instance,
+                                     const char *type_instance, gauge_t value,
+                                     cdtime_t time) {
+  value_list_t vl = {.values = &(value_t){.gauge = value},
+                     .values_len = 1,
+                     .time = time,
+                     .plugin = DPDK_EVENTS_PLUGIN,
+                     .type = "gauge",
+                     .meta = NULL};
+  sstrncpy(vl.host, hostname_g, sizeof(vl.host));
+  sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance));
+  sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
+  plugin_dispatch_values(&vl);
+}
+
+static int dpdk_events_link_status_dispatch(dpdk_helper_ctx_t *phc) {
+  dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(phc);
+  DEBUG(DPDK_EVENTS_PLUGIN ": %s:%d ports=%u", __FUNCTION__, __LINE__,
+        ec->nb_ports);
+
+  /* dispatch Link Status values to collectd */
+  for (int i = 0; i < ec->nb_ports; i++) {
+    if (ec->config.link_status.enabled_port_mask & (1 << i)) {
+      if (!ec->config.link_status.send_updated ||
+          ec->link_info[i].status_updated) {
+
+        DEBUG(DPDK_EVENTS_PLUGIN ": Dispatch PORT %d Link Status: %s", i,
+              ec->link_info[i].link_status ? "UP" : "DOWN");
+
+        char dev_name[DATA_MAX_NAME_LEN];
+        if (ec->config.link_status.port_name[i][0] != 0) {
+          ssnprintf(dev_name, sizeof(dev_name), "%s",
+                    ec->config.link_status.port_name[i]);
+        } else {
+          ssnprintf(dev_name, sizeof(dev_name), "port.%d", i);
+        }
+
+        if (ec->config.link_status.notify) {
+          int sev = ec->link_info[i].link_status ? NOTIF_OKAY : NOTIF_WARNING;
+          char msg[DATA_MAX_NAME_LEN];
+          ssnprintf(msg, sizeof(msg), "Link Status: %s",
+                    ec->link_info[i].link_status ? "UP" : "DOWN");
+          dpdk_events_notification_dispatch(sev, dev_name,
+                                            ec->link_info[i].read_time, msg);
+        } else {
+          dpdk_events_gauge_submit(dev_name, "link_status",
+                                   (gauge_t)ec->link_info[i].link_status,
+                                   ec->link_info[i].read_time);
+        }
+        ec->link_info[i].status_updated = 0;
+      }
+    }
+  }
+
+  return 0;
+}
+
+static void dpdk_events_keep_alive_dispatch(dpdk_helper_ctx_t *phc) {
+  dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(phc);
+
+  /* dispatch Keep Alive values to collectd */
+  for (int i = 0; i < RTE_KEEPALIVE_MAXCORES; i++) {
+    if (i < INT64_BIT_SIZE) {
+      if (!(ec->config.keep_alive.lcore_mask.low & ((uint64_t)1 << i)))
+        continue;
+    } else if (i >= INT64_BIT_SIZE && i < INT64_BIT_SIZE * 2) {
+      if (!(ec->config.keep_alive.lcore_mask.high &
+            ((uint64_t)1 << (i - INT64_BIT_SIZE))))
+        continue;
+    } else {
+      WARNING(DPDK_EVENTS_PLUGIN
+              ": %s:%d Core id %u is out of 0 to %u range, skipping",
+              __FUNCTION__, __LINE__, i, INT64_BIT_SIZE * 2);
+      continue;
+    }
+
+    char core_name[DATA_MAX_NAME_LEN];
+    ssnprintf(core_name, sizeof(core_name), "lcore%u", i);
+
+    if (!ec->config.keep_alive.send_updated ||
+        (ec->core_info[i].lcore_state !=
+         ec->config.keep_alive.shm->core_state[i])) {
+      ec->core_info[i].lcore_state = ec->config.keep_alive.shm->core_state[i];
+      ec->core_info[i].read_time = cdtime();
+
+      if (ec->config.keep_alive.notify) {
+        char msg[DATA_MAX_NAME_LEN];
+        int sev;
+
+        switch (ec->config.keep_alive.shm->core_state[i]) {
+        case RTE_KA_STATE_ALIVE:
+          sev = NOTIF_OKAY;
+          ssnprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: ALIVE", i);
+          break;
+        case RTE_KA_STATE_MISSING:
+          ssnprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: MISSING", i);
+          sev = NOTIF_WARNING;
+          break;
+        case RTE_KA_STATE_DEAD:
+          ssnprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: DEAD", i);
+          sev = NOTIF_FAILURE;
+          break;
+        case RTE_KA_STATE_UNUSED:
+          ssnprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: UNUSED", i);
+          sev = NOTIF_OKAY;
+          break;
+        case RTE_KA_STATE_GONE:
+          ssnprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: GONE", i);
+          sev = NOTIF_FAILURE;
+          break;
+        case RTE_KA_STATE_DOZING:
+          ssnprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: DOZING", i);
+          sev = NOTIF_OKAY;
+          break;
+        case RTE_KA_STATE_SLEEP:
+          ssnprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: SLEEP", i);
+          sev = NOTIF_OKAY;
+          break;
+        default:
+          ssnprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: UNKNOWN", i);
+          sev = NOTIF_FAILURE;
+        }
+
+        dpdk_events_notification_dispatch(sev, KEEPALIVE_PLUGIN_INSTANCE,
+                                          ec->core_info[i].read_time, msg);
+      } else {
+        dpdk_events_gauge_submit(KEEPALIVE_PLUGIN_INSTANCE, core_name,
+                                 ec->config.keep_alive.shm->core_state[i],
+                                 ec->core_info[i].read_time);
+      }
+    }
+  }
+}
+
+static int dpdk_events_read(user_data_t *ud) {
+  DPDK_EVENTS_TRACE();
+
+  if (g_hc == NULL) {
+    ERROR(DPDK_EVENTS_PLUGIN ": plugin not initialized.");
+    return -1;
+  }
+
+  dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(g_hc);
+
+  if (ec->config.link_status.enabled) {
+    int cmd_res = 0;
+    int ret = dpdk_helper_command(g_hc, DPDK_CMD_GET_EVENTS, &cmd_res,
+                                  ec->config.interval);
+    if (cmd_res == 0 && ret == 0) {
+      dpdk_events_link_status_dispatch(g_hc);
+    }
+  }
+
+  if (ec->config.keep_alive.enabled) {
+    dpdk_events_keep_alive_dispatch(g_hc);
+  }
+
+  return 0;
+}
+
+static int dpdk_events_init(void) {
+  DPDK_EVENTS_TRACE();
+
+  int ret = dpdk_events_preinit();
+  if (ret)
+    return ret;
+
+  dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(g_hc);
+
+  if (ec->config.keep_alive.enabled) {
+    ret = dpdk_event_keep_alive_shm_create();
+    if (ret) {
+      ERROR(DPDK_EVENTS_PLUGIN ": %s : error %d in ka_shm_create()",
+            __FUNCTION__, ret);
+      return ret;
+    }
+  }
+  return 0;
+}
+
+static int dpdk_events_shutdown(void) {
+  DPDK_EVENTS_TRACE();
+  int ret;
+
+  dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(g_hc);
+  if (ec->config.keep_alive.enabled) {
+    ret = munmap(ec->config.keep_alive.shm, sizeof(dpdk_keepalive_shm_t));
+    if (ret) {
+      ERROR(DPDK_EVENTS_PLUGIN ": munmap KA monitor returned %d", ret);
+      return ret;
+    }
+  }
+
+  ret = dpdk_helper_shutdown(g_hc);
+  g_hc = NULL;
+  if (ret)
+    ERROR(DPDK_EVENTS_PLUGIN ": failed to cleanup %s helper", DPDK_EVENTS_NAME);
+
+  return ret;
+}
+
+void module_register(void) {
+  plugin_register_init(DPDK_EVENTS_PLUGIN, dpdk_events_init);
+  plugin_register_complex_config(DPDK_EVENTS_PLUGIN, dpdk_events_config);
+  plugin_register_complex_read(NULL, DPDK_EVENTS_PLUGIN, dpdk_events_read, 0,
+                               NULL);
+  plugin_register_shutdown(DPDK_EVENTS_PLUGIN, dpdk_events_shutdown);
+}
index 6d0aabf..6b057f2 100644 (file)
@@ -1,4 +1,4 @@
-/*-
+/*
  * collectd - src/dpdkstat.c
  * MIT License
  *
  *   Maryam Tahhan <maryam.tahhan@intel.com>
  *   Harry van Haaren <harry.van.haaren@intel.com>
  *   Taras Chornyi <tarasx.chornyi@intel.com>
+ *   Serhiy Pshyk <serhiyx.pshyk@intel.com>
+ *   Krzysztof Matczak <krzysztofx.matczak@intel.com>
  */
 
 #include "collectd.h"
 
-#include "common.h" /* auxiliary functions */
-#include "plugin.h" /* plugin_register_*, plugin_dispatch_values */
-#include "utils_time.h"
-
-#include <getopt.h>
-#include <poll.h>
-#include <semaphore.h>
-#include <sys/mman.h>
-#include <sys/queue.h>
+#include "common.h"
+#include "utils_dpdk.h"
 
-#include <rte_atomic.h>
-#include <rte_branch_prediction.h>
-#include <rte_common.h>
 #include <rte_config.h>
-#include <rte_debug.h>
-#include <rte_debug.h>
-#include <rte_eal.h>
 #include <rte_ethdev.h>
-#include <rte_launch.h>
-#include <rte_lcore.h>
-#include <rte_log.h>
-#include <rte_malloc.h>
-#include <rte_memory.h>
-#include <rte_memzone.h>
-#include <rte_per_lcore.h>
-#include <rte_string_fns.h>
-#include <rte_tailq.h>
-#include <rte_version.h>
-
-#define DPDK_DEFAULT_RTE_CONFIG "/var/run/.rte_config"
-#define DPDK_MAX_ARGC 8
-#define DPDKSTAT_MAX_BUFFER_SIZE (4096 * 4)
-#define DPDK_SHM_NAME "dpdk_collectd_stats_shm"
-#define ERR_BUF_SIZE 1024
-#define REINIT_SHM 1
-#define RESET 1
-#define NO_RESET 0
+
+#define DPDK_STATS_PLUGIN "dpdkstat"
+#define DPDK_STATS_NAME "dpdk_collectd_stats"
+
+#define DPDK_STATS_TRACE()                                                     \
+  DEBUG("%s:%s:%d pid=%u", DPDK_STATS_PLUGIN, __FUNCTION__, __LINE__, getpid())
+
+struct dpdk_stats_config_s {
+  cdtime_t interval;
+  uint32_t enabled_port_mask;
+  char port_name[RTE_MAX_ETHPORTS][DATA_MAX_NAME_LEN];
+};
+typedef struct dpdk_stats_config_s dpdk_stats_config_t;
 
 #define RTE_VERSION_16_07 RTE_VERSION_NUM(16, 7, 0, 16)
 
     ctx->xstats = (struct rte_eth_xstat *)&ctx->raw_data[0];                   \
     ctx->xnames =                                                              \
         (struct rte_eth_xstat_name *)&ctx                                      \
-            ->raw_data[ctx->num_xstats * sizeof(struct rte_eth_xstat)];        \
+            ->raw_data[ctx->stats_count * sizeof(struct rte_eth_xstat)];       \
   } while (0)
 #endif
 
-enum DPDK_HELPER_ACTION {
-  DPDK_HELPER_ACTION_COUNT_STATS,
-  DPDK_HELPER_ACTION_SEND_STATS,
-};
-
-enum DPDK_HELPER_STATUS {
-  DPDK_HELPER_NOT_INITIALIZED = 0,
-  DPDK_HELPER_WAITING_ON_PRIMARY,
-  DPDK_HELPER_INITIALIZING_EAL,
-  DPDK_HELPER_ALIVE_SENDING_STATS,
-  DPDK_HELPER_GRACEFUL_QUIT,
-};
-
-struct dpdk_config_s {
-  /* General DPDK params */
-  char coremask[DATA_MAX_NAME_LEN];
-  char memory_channels[DATA_MAX_NAME_LEN];
-  char socket_memory[DATA_MAX_NAME_LEN];
-  char process_type[DATA_MAX_NAME_LEN];
-  char file_prefix[DATA_MAX_NAME_LEN];
-  cdtime_t interval;
-  uint32_t eal_initialized;
-  uint32_t enabled_port_mask;
-  char port_name[RTE_MAX_ETHPORTS][DATA_MAX_NAME_LEN];
-  uint32_t eal_argc;
-  /* Helper info */
-  int collectd_reinit_shm;
-  pid_t helper_pid;
-  sem_t sema_helper_get_stats;
-  sem_t sema_stats_in_shm;
-  int helper_pipes[2];
-  enum DPDK_HELPER_STATUS helper_status;
-  enum DPDK_HELPER_ACTION helper_action;
-  /* xstats info */
-  uint32_t num_ports;
-  uint32_t num_xstats;
+struct dpdk_stats_ctx_s {
+  dpdk_stats_config_t config;
+  uint32_t stats_count;
+  uint32_t ports_count;
   cdtime_t port_read_time[RTE_MAX_ETHPORTS];
-  uint32_t num_stats_in_port[RTE_MAX_ETHPORTS];
-  struct rte_eth_link link_status[RTE_MAX_ETHPORTS];
+  uint32_t port_stats_count[RTE_MAX_ETHPORTS];
 #if RTE_VERSION < RTE_VERSION_16_07
   struct rte_eth_xstats *xstats;
 #else
   struct rte_eth_xstat *xstats;
   struct rte_eth_xstat_name *xnames;
 #endif
-  char *raw_data;
-  /* rte_eth_xstats from here on until the end of the SHM */
+  char raw_data[];
 };
-typedef struct dpdk_config_s dpdk_config_t;
-
-static int g_configured;
-static dpdk_config_t *g_configuration;
-
-static void dpdk_config_init_default(void);
-static int dpdk_config(oconfig_item_t *ci);
-static int dpdk_helper_init_eal(void);
-static int dpdk_helper_run(void);
-static int dpdk_helper_spawn(enum DPDK_HELPER_ACTION action);
-static int dpdk_init(void);
-static int dpdk_read(user_data_t *ud);
-static int dpdk_shm_cleanup(void);
-static int dpdk_shm_init(size_t size);
-
-/* Write the default configuration to the g_configuration instances */
-static void dpdk_config_init_default(void) {
-  g_configuration->interval = plugin_get_interval();
-  if (g_configuration->interval == cf_get_default_interval())
-    WARNING("dpdkstat: No time interval was configured, default value %" PRIu64
-            " ms is set",
-            CDTIME_T_TO_MS(g_configuration->interval));
-  /* Default is all ports enabled */
-  g_configuration->enabled_port_mask = ~0;
-  g_configuration->eal_argc = DPDK_MAX_ARGC;
-  g_configuration->eal_initialized = 0;
-  ssnprintf(g_configuration->coremask, DATA_MAX_NAME_LEN, "%s", "0xf");
-  ssnprintf(g_configuration->memory_channels, DATA_MAX_NAME_LEN, "%s", "1");
-  ssnprintf(g_configuration->process_type, DATA_MAX_NAME_LEN, "%s",
-            "secondary");
-  ssnprintf(g_configuration->file_prefix, DATA_MAX_NAME_LEN, "%s",
-            DPDK_DEFAULT_RTE_CONFIG);
-
-  for (int i = 0; i < RTE_MAX_ETHPORTS; i++)
-    g_configuration->port_name[i][0] = 0;
+typedef struct dpdk_stats_ctx_s dpdk_stats_ctx_t;
+
+#define DPDK_STATS_CTX_GET(a) ((dpdk_stats_ctx_t *)dpdk_helper_priv_get(a))
+
+dpdk_helper_ctx_t *g_hc = NULL;
+static char g_shm_name[DATA_MAX_NAME_LEN] = DPDK_STATS_NAME;
+static int dpdk_stats_reinit_helper();
+static void dpdk_stats_default_config(void) {
+  dpdk_stats_ctx_t *ec = DPDK_STATS_CTX_GET(g_hc);
+
+  ec->config.interval = plugin_get_interval();
+  for (int i = 0; i < RTE_MAX_ETHPORTS; i++) {
+    ec->config.port_name[i][0] = 0;
+  }
 }
 
-static int dpdk_config(oconfig_item_t *ci) {
-  int port_counter = 0;
-  /* Allocate g_configuration and
-   * initialize a POSIX SHared Memory (SHM) object.
-   */
-  int err = dpdk_shm_init(sizeof(dpdk_config_t));
-  if (err) {
+static int dpdk_stats_preinit(void) {
+  DPDK_STATS_TRACE();
+
+  if (g_hc != NULL) {
+    /* already initialized if config callback was called before init callback */
+    DEBUG("dpdk_stats_preinit: helper already initialized");
+    return 0;
+  }
+
+  int ret = dpdk_helper_init(g_shm_name, sizeof(dpdk_stats_ctx_t), &g_hc);
+  if (ret != 0) {
     char errbuf[ERR_BUF_SIZE];
-    ERROR("dpdkstat: error in shm_init, %s",
-          sstrerror(errno, errbuf, sizeof(errbuf)));
-    return -1;
+    ERROR("%s: failed to initialize %s helper(error: %s)", DPDK_STATS_PLUGIN,
+          g_shm_name, sstrerror(errno, errbuf, sizeof(errbuf)));
+    return ret;
   }
 
-  /* Set defaults for config, overwritten by loop if config item exists */
-  dpdk_config_init_default();
+  dpdk_stats_default_config();
+  return ret;
+}
+
+static int dpdk_stats_config(oconfig_item_t *ci) {
+  DPDK_STATS_TRACE();
+
+  int ret = dpdk_stats_preinit();
+  if (ret)
+    return ret;
+
+  dpdk_stats_ctx_t *ctx = DPDK_STATS_CTX_GET(g_hc);
 
   for (int i = 0; i < ci->children_num; i++) {
     oconfig_item_t *child = ci->children + i;
 
-    if (strcasecmp("Coremask", child->key) == 0) {
-      cf_util_get_string_buffer(child, g_configuration->coremask,
-                                sizeof(g_configuration->coremask));
-      DEBUG("dpdkstat:COREMASK %s ", g_configuration->coremask);
-    } else if (strcasecmp("MemoryChannels", child->key) == 0) {
-      cf_util_get_string_buffer(child, g_configuration->memory_channels,
-                                sizeof(g_configuration->memory_channels));
-      DEBUG("dpdkstat:Memory Channels %s ", g_configuration->memory_channels);
-    } else if (strcasecmp("SocketMemory", child->key) == 0) {
-      cf_util_get_string_buffer(child, g_configuration->socket_memory,
-                                sizeof(g_configuration->memory_channels));
-      DEBUG("dpdkstat: socket mem %s ", g_configuration->socket_memory);
-    } else if (strcasecmp("ProcessType", child->key) == 0) {
-      cf_util_get_string_buffer(child, g_configuration->process_type,
-                                sizeof(g_configuration->process_type));
-      DEBUG("dpdkstat: proc type %s ", g_configuration->process_type);
-    } else if ((strcasecmp("FilePrefix", child->key) == 0) &&
-               (child->values[0].type == OCONFIG_TYPE_STRING)) {
-      ssnprintf(g_configuration->file_prefix, DATA_MAX_NAME_LEN,
-                "/var/run/.%s_config", child->values[0].value.string);
-      DEBUG("dpdkstat: file prefix %s ", g_configuration->file_prefix);
-    } else if ((strcasecmp("EnabledPortMask", child->key) == 0) &&
-               (child->values[0].type == OCONFIG_TYPE_NUMBER)) {
-      g_configuration->enabled_port_mask =
-          (uint32_t)child->values[0].value.number;
-      DEBUG("dpdkstat: Enabled Port Mask %u",
-            g_configuration->enabled_port_mask);
-    } else if (strcasecmp("PortName", child->key) == 0) {
-      cf_util_get_string_buffer(
-          child, g_configuration->port_name[port_counter],
-          sizeof(g_configuration->port_name[port_counter]));
-      DEBUG("dpdkstat: Port %d Name: %s ", port_counter,
-            g_configuration->port_name[port_counter]);
-      port_counter++;
-    } else {
-      WARNING("dpdkstat: The config option \"%s\" is unknown.", child->key);
+    if ((strcasecmp("EnabledPortMask", child->key) == 0) &&
+        (child->values[0].type == OCONFIG_TYPE_NUMBER)) {
+      ctx->config.enabled_port_mask = child->values[0].value.number;
+      DEBUG("%s: Enabled Port Mask 0x%X", DPDK_STATS_PLUGIN,
+            ctx->config.enabled_port_mask);
+    } else if (strcasecmp("SharedMemObj", child->key) == 0) {
+      cf_util_get_string_buffer(child, g_shm_name, sizeof(g_shm_name));
+      DEBUG("%s: Shared memory object %s", DPDK_STATS_PLUGIN, g_shm_name);
+      dpdk_stats_reinit_helper();
+    } else if (strcasecmp("EAL", child->key) == 0) {
+      ret = dpdk_helper_eal_config_parse(g_hc, child);
+      if (ret)
+        return ret;
     }
-  }                 /* End for (int i = 0; i < ci->children_num; i++)*/
-  g_configured = 1; /* Bypass configuration in dpdk_shm_init(). */
+  }
 
-  return 0;
-}
+  int port_num = 0;
 
-/*
- * Allocate g_configuration and initialize SHared Memory (SHM)
- * for config and helper process
- */
-static int dpdk_shm_init(size_t size) {
-  /*
-   * Check if SHM is already configured: when config items are provided, the
-   * config function initializes SHM. If there is no config, then init() will
-   * just return.
-   */
-  if (g_configuration)
-    return 0;
+  /* parse port names after EnabledPortMask was parsed */
+  for (int i = 0; i < ci->children_num; i++) {
+    oconfig_item_t *child = ci->children + i;
 
-  char errbuf[ERR_BUF_SIZE];
+    if (strcasecmp("PortName", child->key) == 0) {
 
-  /* Create and open a new object, or open an existing object. */
-  int fd = shm_open(DPDK_SHM_NAME, O_CREAT | O_TRUNC | O_RDWR, 0666);
-  if (fd < 0) {
-    WARNING("dpdkstat:Failed to open %s as SHM:%s", DPDK_SHM_NAME,
-            sstrerror(errno, errbuf, sizeof(errbuf)));
-    goto fail;
-  }
-  /* Set the size of the shared memory object. */
-  int ret = ftruncate(fd, size);
-  if (ret != 0) {
-    WARNING("dpdkstat:Failed to resize SHM:%s",
-            sstrerror(errno, errbuf, sizeof(errbuf)));
-    goto fail_close;
-  }
-  /* Map the shared memory object into this process' virtual address space. */
-  g_configuration = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
-  if (g_configuration == MAP_FAILED) {
-    WARNING("dpdkstat:Failed to mmap SHM:%s",
-            sstrerror(errno, errbuf, sizeof(errbuf)));
-    goto fail_close;
-  }
-  /*
-   * Close the file descriptor, the shared memory object still exists
-   * and can only be removed by calling shm_unlink().
-   */
-  close(fd);
-
-  /* Initialize g_configuration. */
-  memset(g_configuration, 0, size);
-
-  /* Initialize the semaphores for SHM use */
-  int err = sem_init(&g_configuration->sema_helper_get_stats, 1, 0);
-  if (err) {
-    ERROR("dpdkstat semaphore init failed: %s",
-          sstrerror(errno, errbuf, sizeof(errbuf)));
-    goto fail;
-  }
-  err = sem_init(&g_configuration->sema_stats_in_shm, 1, 0);
-  if (err) {
-    ERROR("dpdkstat semaphore init failed: %s",
-          sstrerror(errno, errbuf, sizeof(errbuf)));
-    goto fail;
-  }
+      while (!(ctx->config.enabled_port_mask & (1 << port_num)))
+        port_num++;
 
-  g_configuration->xstats = NULL;
+      cf_util_get_string_buffer(child, ctx->config.port_name[port_num],
+                                sizeof(ctx->config.port_name[port_num]));
+      DEBUG("%s: Port %d Name: %s", DPDK_STATS_PLUGIN, port_num,
+            ctx->config.port_name[port_num]);
 
-  return 0;
+      port_num++;
+    }
+  }
 
-fail_close:
-  close(fd);
-fail:
-  /* Reset to zero, as it was set to MAP_FAILED aka: (void *)-1. Avoid
-   * an issue if collectd attempts to run this plugin failure.
-   */
-  g_configuration = 0;
-  return -1;
+  return ret;
 }
 
-static int dpdk_re_init_shm() {
-  dpdk_config_t temp_config;
-  memcpy(&temp_config, g_configuration, sizeof(dpdk_config_t));
-  DEBUG("dpdkstat: %s: ports %" PRIu32 ", xstats %" PRIu32, __func__,
-        temp_config.num_ports, temp_config.num_xstats);
-
-  size_t shm_xstats_size =
-      sizeof(dpdk_config_t) +
-      (DPDK_STATS_CTX_GET_XSTAT_SIZE * g_configuration->num_xstats);
-  DEBUG("=== SHM new size for %" PRIu32 " xstats", g_configuration->num_xstats);
-
-  int err = dpdk_shm_cleanup();
-  if (err) {
-    ERROR("dpdkstat: Error in shm_cleanup in %s", __func__);
-    return err;
-  }
-  err = dpdk_shm_init(shm_xstats_size);
-  if (err) {
-    WARNING("dpdkstat: Error in shm_init in %s", __func__);
-    return err;
-  }
-  /* If the XML config() function has been run, don't re-initialize defaults */
-  if (!g_configured)
-    dpdk_config_init_default();
-
-  memcpy(g_configuration, &temp_config, sizeof(dpdk_config_t));
-  g_configuration->collectd_reinit_shm = 0;
-  g_configuration->raw_data = (char *)(g_configuration + 1);
-  DPDK_STATS_CTX_INIT(g_configuration);
-  return 0;
-}
+static int dpdk_helper_stats_get(dpdk_helper_ctx_t *phc) {
+  int len = 0;
+  int ret = 0;
+  int stats = 0;
+  dpdk_stats_ctx_t *ctx = DPDK_STATS_CTX_GET(phc);
 
-static int dpdk_init(void) {
-  int err = dpdk_shm_init(sizeof(dpdk_config_t));
-  if (err) {
-    ERROR("dpdkstat: %s : error %d in shm_init()", __func__, err);
-    return err;
-  }
+  /* get stats from DPDK */
+  for (uint8_t i = 0; i < ctx->ports_count; i++) {
+    if (!(ctx->config.enabled_port_mask & (1 << i)))
+      continue;
 
-  /* If the XML config() function has been run, dont re-initialize defaults */
-  if (!g_configured) {
-    dpdk_config_init_default();
+    ctx->port_read_time[i] = cdtime();
+    /* Store available stats array length for port */
+    len = ctx->port_stats_count[i];
+
+    ret = rte_eth_xstats_get(i, &ctx->xstats[stats], len);
+    if (ret < 0 || ret > len) {
+      DPDK_CHILD_LOG(DPDK_STATS_PLUGIN
+                     ": Error reading stats (port=%d; len=%d, ret=%d)\n",
+                     i, len, ret);
+      ctx->port_stats_count[i] = 0;
+      return -1;
+    }
+#if RTE_VERSION >= RTE_VERSION_16_07
+    ret = rte_eth_xstats_get_names(i, &ctx->xnames[stats], len);
+    if (ret < 0 || ret > len) {
+      DPDK_CHILD_LOG(DPDK_STATS_PLUGIN
+                     ": Error reading stat names (port=%d; len=%d ret=%d)\n",
+                     i, len, ret);
+      ctx->port_stats_count[i] = 0;
+      return -1;
+    }
+#endif
+    ctx->port_stats_count[i] = ret;
+    stats += ctx->port_stats_count[i];
   }
 
+  assert(stats <= ctx->stats_count);
   return 0;
 }
 
-static int dpdk_helper_stop(int reset) {
-  g_configuration->helper_status = DPDK_HELPER_GRACEFUL_QUIT;
-  if (reset) {
-    g_configuration->eal_initialized = 0;
-    g_configuration->num_ports = 0;
-    g_configuration->xstats = NULL;
-    g_configuration->num_xstats = 0;
-    for (int i = 0; i < RTE_MAX_ETHPORTS; i++)
-      g_configuration->num_stats_in_port[i] = 0;
-  }
-  close(g_configuration->helper_pipes[1]);
-  int err = kill(g_configuration->helper_pid, SIGKILL);
-  if (err) {
-    char errbuf[ERR_BUF_SIZE];
-    WARNING("dpdkstat: error sending kill to helper: %s",
-            sstrerror(errno, errbuf, sizeof(errbuf)));
-  }
+static int dpdk_helper_stats_count_get(dpdk_helper_ctx_t *phc) {
+  uint8_t ports = dpdk_helper_eth_dev_count();
+  if (ports == 0)
+    return -ENODEV;
 
-  return 0;
-}
+  dpdk_stats_ctx_t *ctx = DPDK_STATS_CTX_GET(phc);
+  ctx->ports_count = ports;
 
-static int dpdk_helper_spawn(enum DPDK_HELPER_ACTION action) {
-  char errbuf[ERR_BUF_SIZE];
-  g_configuration->eal_initialized = 0;
-  g_configuration->helper_action = action;
-  /*
-   * Create a pipe for helper stdout back to collectd. This is necessary for
-   * logging EAL failures, as rte_eal_init() calls rte_panic().
-   */
-  if (pipe(g_configuration->helper_pipes) != 0) {
-    DEBUG("dpdkstat: Could not create helper pipe: %s",
-          sstrerror(errno, errbuf, sizeof(errbuf)));
-    return -1;
+  int len = 0;
+  int stats_count = 0;
+  for (int i = 0; i < ports; i++) {
+    if (!(ctx->config.enabled_port_mask & (1 << i)))
+      continue;
+#if RTE_VERSION >= RTE_VERSION_16_07
+    len = rte_eth_xstats_get_names(i, NULL, 0);
+#else
+    len = rte_eth_xstats_get(i, NULL, 0);
+#endif
+    if (len < 0) {
+      DPDK_CHILD_LOG("%s: Cannot get stats count\n", DPDK_STATS_PLUGIN);
+      return -1;
+    }
+    ctx->port_stats_count[i] = len;
+    stats_count += len;
   }
 
-  int pipe0_flags = fcntl(g_configuration->helper_pipes[0], F_GETFL, 0);
-  int pipe1_flags = fcntl(g_configuration->helper_pipes[1], F_GETFL, 0);
-  if (pipe0_flags == -1 || pipe1_flags == -1) {
-    WARNING("dpdkstat: Failed setting up pipe flags: %s",
-            sstrerror(errno, errbuf, sizeof(errbuf)));
-  }
-  int pipe0_err = fcntl(g_configuration->helper_pipes[0], F_SETFL,
-                        pipe1_flags | O_NONBLOCK);
-  int pipe1_err = fcntl(g_configuration->helper_pipes[1], F_SETFL,
-                        pipe0_flags | O_NONBLOCK);
-  if (pipe0_err == -1 || pipe1_err == -1) {
-    WARNING("dpdkstat: Failed setting up pipes: %s",
-            sstrerror(errno, errbuf, sizeof(errbuf)));
-  }
+  DPDK_CHILD_LOG("%s:%s:%d stats_count=%d\n", DPDK_STATS_PLUGIN, __FUNCTION__,
+                 __LINE__, stats_count);
 
-  pid_t pid = fork();
-  if (pid > 0) {
-    close(g_configuration->helper_pipes[1]);
-    g_configuration->helper_pid = pid;
-    DEBUG("dpdkstat: helper pid %li", (long)g_configuration->helper_pid);
-    /* Kick helper once its alive to have it start processing */
-    sem_post(&g_configuration->sema_helper_get_stats);
-  } else if (pid == 0) {
-    /* Replace stdout with a pipe to collectd. */
-    close(g_configuration->helper_pipes[0]);
-    close(STDOUT_FILENO);
-    dup2(g_configuration->helper_pipes[1], STDOUT_FILENO);
-    dpdk_helper_run();
-    exit(0);
-  } else {
-    ERROR("dpdkstat: Failed to fork helper process: %s",
-          sstrerror(errno, errbuf, sizeof(errbuf)));
-    return -1;
-  }
-  return 0;
+  return stats_count;
 }
 
-/*
- * Initialize the DPDK EAL, if this returns, EAL is successfully initialized.
- * On failure, the EAL prints an error message, and the helper process exits.
- */
-static int dpdk_helper_init_eal(void) {
-  g_configuration->helper_status = DPDK_HELPER_INITIALIZING_EAL;
-  char *argp[(g_configuration->eal_argc) + 1];
-  int i = 0;
-
-  argp[i++] = "collectd-dpdk";
-  if (strcasecmp(g_configuration->coremask, "") != 0) {
-    argp[i++] = "-c";
-    argp[i++] = g_configuration->coremask;
-  }
-  if (strcasecmp(g_configuration->memory_channels, "") != 0) {
-    argp[i++] = "-n";
-    argp[i++] = g_configuration->memory_channels;
-  }
-  if (strcasecmp(g_configuration->socket_memory, "") != 0) {
-    argp[i++] = "--socket-mem";
-    argp[i++] = g_configuration->socket_memory;
+static int dpdk_stats_get_size(dpdk_helper_ctx_t *phc) {
+  return (dpdk_helper_data_size_get(phc) - sizeof(dpdk_stats_ctx_t));
+}
+
+int dpdk_helper_command_handler(dpdk_helper_ctx_t *phc, enum DPDK_CMD cmd) {
+  /* this function is called from helper context */
+
+  if (phc == NULL) {
+    DPDK_CHILD_LOG("%s: Invalid argument(phc)\n", DPDK_STATS_PLUGIN);
+    return -EINVAL;
   }
-  if (strcasecmp(g_configuration->file_prefix, "") != 0 &&
-      strcasecmp(g_configuration->file_prefix, DPDK_DEFAULT_RTE_CONFIG) != 0) {
-    argp[i++] = "--file-prefix";
-    argp[i++] = g_configuration->file_prefix;
+
+  if (cmd != DPDK_CMD_GET_STATS) {
+    DPDK_CHILD_LOG("%s: Unknown command (cmd=%d)\n", DPDK_STATS_PLUGIN, cmd);
+    return -EINVAL;
   }
-  if (strcasecmp(g_configuration->process_type, "") != 0) {
-    argp[i++] = "--proc-type";
-    argp[i++] = g_configuration->process_type;
+
+  int stats_count = dpdk_helper_stats_count_get(phc);
+  if (stats_count < 0) {
+    return stats_count;
   }
-  g_configuration->eal_argc = i;
 
-  g_configuration->eal_initialized = 1;
-  int ret = rte_eal_init(g_configuration->eal_argc, argp);
-  if (ret < 0) {
-    g_configuration->eal_initialized = 0;
-    return ret;
+  DPDK_STATS_CTX_GET(phc)->stats_count = stats_count;
+  int stats_size = stats_count * DPDK_STATS_CTX_GET_XSTAT_SIZE;
+
+  if (dpdk_stats_get_size(phc) < stats_size) {
+    DPDK_CHILD_LOG(
+        DPDK_STATS_PLUGIN
+        ":%s:%d not enough space for stats (available=%d, needed=%d)\n",
+        __FUNCTION__, __LINE__, (int)dpdk_stats_get_size(phc), stats_size);
+    return -ENOBUFS;
   }
-  return 0;
+
+  return dpdk_helper_stats_get(phc);
 }
 
-static int dpdk_helper_run(void) {
-  char errbuf[ERR_BUF_SIZE];
-  pid_t ppid = getppid();
-  g_configuration->helper_status = DPDK_HELPER_WAITING_ON_PRIMARY;
-
-  while (1) {
-    /* sem_timedwait() to avoid blocking forever */
-    cdtime_t now = cdtime();
-    cdtime_t safety_period = MS_TO_CDTIME_T(1500);
-    int ret =
-        sem_timedwait(&g_configuration->sema_helper_get_stats,
-                      &CDTIME_T_TO_TIMESPEC(now + safety_period +
-                                            g_configuration->interval * 2));
-
-    if (ret == -1 && errno == ETIMEDOUT) {
-      ERROR("dpdkstat-helper: sem timedwait()"
-            " timeout, did collectd terminate?");
-      dpdk_helper_stop(RESET);
-    }
-    /* Parent PID change means collectd died so quit the helper process. */
-    if (ppid != getppid()) {
-      WARNING("dpdkstat-helper: parent PID changed, quitting.");
-      dpdk_helper_stop(RESET);
+static void dpdk_stats_resolve_cnt_type(char *cnt_type, size_t cnt_type_len,
+                                        const char *cnt_name) {
+  char *type_end;
+  type_end = strrchr(cnt_name, '_');
+
+  if ((type_end != NULL) && (strncmp(cnt_name, "rx_", strlen("rx_")) == 0)) {
+    if (strstr(type_end, "bytes") != NULL) {
+      sstrncpy(cnt_type, "if_rx_octets", cnt_type_len);
+    } else if (strstr(type_end, "error") != NULL) {
+      sstrncpy(cnt_type, "if_rx_errors", cnt_type_len);
+    } else if (strstr(type_end, "dropped") != NULL) {
+      sstrncpy(cnt_type, "if_rx_dropped", cnt_type_len);
+    } else if (strstr(type_end, "packets") != NULL) {
+      sstrncpy(cnt_type, "if_rx_packets", cnt_type_len);
+    } else if (strstr(type_end, "_placement") != NULL) {
+      sstrncpy(cnt_type, "if_rx_errors", cnt_type_len);
+    } else if (strstr(type_end, "_buff") != NULL) {
+      sstrncpy(cnt_type, "if_rx_errors", cnt_type_len);
+    } else {
+      /* Does not fit obvious type: use a more generic one */
+      sstrncpy(cnt_type, "derive", cnt_type_len);
     }
 
-    /* Checking for DPDK primary process. */
-    if (!rte_eal_primary_proc_alive(g_configuration->file_prefix)) {
-      if (g_configuration->eal_initialized) {
-        WARNING("dpdkstat-helper: no primary alive but EAL initialized:"
-                " quitting.");
-        dpdk_helper_stop(RESET);
-      }
-      g_configuration->helper_status = DPDK_HELPER_WAITING_ON_PRIMARY;
-      /* Back to start of while() - waiting for primary process */
-      continue;
+  } else if ((type_end != NULL) &&
+             (strncmp(cnt_name, "tx_", strlen("tx_"))) == 0) {
+    if (strstr(type_end, "bytes") != NULL) {
+      sstrncpy(cnt_type, "if_tx_octets", cnt_type_len);
+    } else if (strstr(type_end, "error") != NULL) {
+      sstrncpy(cnt_type, "if_tx_errors", cnt_type_len);
+    } else if (strstr(type_end, "dropped") != NULL) {
+      sstrncpy(cnt_type, "if_tx_dropped", cnt_type_len);
+    } else if (strstr(type_end, "packets") != NULL) {
+      sstrncpy(cnt_type, "if_tx_packets", cnt_type_len);
+    } else {
+      /* Does not fit obvious type: use a more generic one */
+      sstrncpy(cnt_type, "derive", cnt_type_len);
     }
-
-    if (!g_configuration->eal_initialized) {
-      /* Initialize EAL. */
-      int ret = dpdk_helper_init_eal();
-      if (ret != 0) {
-        WARNING("ERROR INITIALIZING EAL");
-        dpdk_helper_stop(RESET);
-      }
+  } else if ((type_end != NULL) &&
+             (strncmp(cnt_name, "flow_", strlen("flow_"))) == 0) {
+
+    if (strstr(type_end, "_filters") != NULL) {
+      sstrncpy(cnt_type, "operations", cnt_type_len);
+    } else if (strstr(type_end, "error") != NULL)
+      sstrncpy(cnt_type, "errors", cnt_type_len);
+
+  } else if ((type_end != NULL) &&
+             (strncmp(cnt_name, "mac_", strlen("mac_"))) == 0) {
+    if (strstr(type_end, "error") != NULL) {
+      sstrncpy(cnt_type, "errors", cnt_type_len);
     }
+  } else {
+    /* Does not fit obvious type, or strrchr error:
+     *   use a more generic type */
+    sstrncpy(cnt_type, "derive", cnt_type_len);
+  }
+}
 
-    g_configuration->helper_status = DPDK_HELPER_ALIVE_SENDING_STATS;
+static void dpdk_stats_counter_submit(const char *plugin_instance,
+                                      const char *cnt_name, derive_t value,
+                                      cdtime_t port_read_time) {
+  value_list_t vl = VALUE_LIST_INIT;
+  vl.values = &(value_t){.derive = value};
+  vl.values_len = 1;
+  vl.time = port_read_time;
+  sstrncpy(vl.host, hostname_g, sizeof(vl.host));
+  sstrncpy(vl.plugin, DPDK_STATS_PLUGIN, sizeof(vl.plugin));
+  sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance));
+  dpdk_stats_resolve_cnt_type(vl.type, sizeof(vl.type), cnt_name);
+  sstrncpy(vl.type_instance, cnt_name, sizeof(vl.type_instance));
+  plugin_dispatch_values(&vl);
+}
 
-    uint8_t nb_ports = rte_eth_dev_count();
-    if (nb_ports == 0) {
-      DEBUG("dpdkstat-helper: No DPDK ports available. "
-            "Check bound devices to DPDK driver.");
-      dpdk_helper_stop(RESET);
-    }
+static int dpdk_stats_counters_dispatch(dpdk_helper_ctx_t *phc) {
+  dpdk_stats_ctx_t *ctx = DPDK_STATS_CTX_GET(phc);
 
-    if (nb_ports > RTE_MAX_ETHPORTS)
-      nb_ports = RTE_MAX_ETHPORTS;
+  /* dispatch stats values to collectd */
 
-    int len = 0, enabled_port_count = 0, num_xstats = 0;
-    for (uint8_t i = 0; i < nb_ports; i++) {
-      if (!(g_configuration->enabled_port_mask & (1 << i)))
-        continue;
+  DEBUG("%s:%s:%d ports=%u", DPDK_STATS_PLUGIN, __FUNCTION__, __LINE__,
+        ctx->ports_count);
 
-      if (g_configuration->helper_action == DPDK_HELPER_ACTION_COUNT_STATS) {
-#if RTE_VERSION >= RTE_VERSION_16_07
-        len = rte_eth_xstats_get_names(i, NULL, 0);
-#else
-        len = rte_eth_xstats_get(i, NULL, 0);
-#endif
-        if (len < 0) {
-          ERROR("dpdkstat-helper: Cannot get xstats count on port %" PRIu8, i);
-          break;
-        }
-        num_xstats += len;
-        g_configuration->num_stats_in_port[enabled_port_count] = len;
-        enabled_port_count++;
-        continue;
-      } else {
-        len = g_configuration->num_stats_in_port[enabled_port_count];
-        g_configuration->port_read_time[enabled_port_count] = cdtime();
-        ret = rte_eth_xstats_get(
-            i, g_configuration->xstats + num_xstats,
-            g_configuration->num_stats_in_port[enabled_port_count]);
-        if (ret < 0 || ret != len) {
-          DEBUG("dpdkstat-helper: Error reading xstats on port %" PRIu8
-                " len = %d",
-                i, len);
-          break;
-        }
-#if RTE_VERSION >= RTE_VERSION_16_07
-        ret = rte_eth_xstats_get_names(i, g_configuration->xnames + num_xstats,
-                                       len);
-        if (ret < 0 || ret != len) {
-          ERROR("dpdkstat-helper: Error reading xstat names (port=%d; len=%d)",
-                i, len);
-          break;
-        }
-#endif
-        num_xstats += g_configuration->num_stats_in_port[enabled_port_count];
-        enabled_port_count++;
-      }
-    } /* for (nb_ports) */
-
-    if (g_configuration->helper_action == DPDK_HELPER_ACTION_COUNT_STATS) {
-      g_configuration->num_ports = enabled_port_count;
-      g_configuration->num_xstats = num_xstats;
-      DEBUG("dpdkstat-helper ports: %" PRIu32 ", num stats: %" PRIu32,
-            g_configuration->num_ports, g_configuration->num_xstats);
-      /* Exit, allowing collectd to re-init SHM to the right size */
-      g_configuration->collectd_reinit_shm = REINIT_SHM;
-      dpdk_helper_stop(NO_RESET);
+  int stats_count = 0;
+
+  for (int i = 0; i < ctx->ports_count; i++) {
+    if (!(ctx->config.enabled_port_mask & (1 << i)))
+      continue;
+
+    char dev_name[64];
+    if (ctx->config.port_name[i][0] != 0) {
+      ssnprintf(dev_name, sizeof(dev_name), "%s", ctx->config.port_name[i]);
+    } else {
+      ssnprintf(dev_name, sizeof(dev_name), "port.%d", i);
     }
-    /* Now kick collectd send thread to send the stats */
-    int err = sem_post(&g_configuration->sema_stats_in_shm);
-    if (err) {
-      WARNING("dpdkstat: error posting semaphore to helper %s",
-              sstrerror(errno, errbuf, sizeof(errbuf)));
-      dpdk_helper_stop(RESET);
+
+    DEBUG(" === Dispatch stats for port %d (name=%s; stats_count=%d)", i,
+          dev_name, ctx->port_stats_count[i]);
+
+    for (int j = 0; j < ctx->port_stats_count[i]; j++) {
+      const char *cnt_name = DPDK_STATS_XSTAT_GET_NAME(ctx, stats_count);
+      if (cnt_name == NULL)
+        WARNING("dpdkstat: Invalid counter name");
+      else
+        dpdk_stats_counter_submit(
+            dev_name, cnt_name,
+            (derive_t)DPDK_STATS_XSTAT_GET_VALUE(ctx, stats_count),
+            ctx->port_read_time[i]);
+      stats_count++;
+
+      assert(stats_count <= ctx->stats_count);
     }
-  } /* while(1) */
+  }
 
   return 0;
 }
 
-static void dpdk_submit_xstats(const char *dev_name, int count,
-                               uint32_t counters, cdtime_t port_read_time) {
-  for (uint32_t j = 0; j < counters; j++) {
-    value_list_t vl = VALUE_LIST_INIT;
-    char *counter_name;
-    char *type_end;
-
-    vl.values = &(value_t){.derive = (derive_t)DPDK_STATS_XSTAT_GET_VALUE(
-                               g_configuration, count + j)};
-    vl.values_len = 1; /* Submit stats one at a time */
-    vl.time = port_read_time;
-    sstrncpy(vl.plugin, "dpdkstat", sizeof(vl.plugin));
-    sstrncpy(vl.plugin_instance, dev_name, sizeof(vl.plugin_instance));
-    counter_name = DPDK_STATS_XSTAT_GET_NAME(g_configuration, count + j);
-    if (counter_name == NULL) {
-      WARNING("dpdkstat: Failed to get counter name.");
-      return;
-    }
+static int dpdk_stats_reinit_helper() {
+  DPDK_STATS_TRACE();
 
-    type_end = strrchr(counter_name, '_');
-
-    if ((type_end != NULL) &&
-        (strncmp(counter_name, "rx_", strlen("rx_")) == 0)) {
-      if (strstr(type_end, "bytes") != NULL) {
-        sstrncpy(vl.type, "if_rx_octets", sizeof(vl.type));
-      } else if (strstr(type_end, "error") != NULL) {
-        sstrncpy(vl.type, "if_rx_errors", sizeof(vl.type));
-      } else if (strstr(type_end, "dropped") != NULL) {
-        sstrncpy(vl.type, "if_rx_dropped", sizeof(vl.type));
-      } else if (strstr(type_end, "packets") != NULL) {
-        sstrncpy(vl.type, "if_rx_packets", sizeof(vl.type));
-      } else if (strstr(type_end, "_placement") != NULL) {
-        sstrncpy(vl.type, "if_rx_errors", sizeof(vl.type));
-      } else if (strstr(type_end, "_buff") != NULL) {
-        sstrncpy(vl.type, "if_rx_errors", sizeof(vl.type));
-      } else {
-        /* Does not fit obvious type: use a more generic one */
-        sstrncpy(vl.type, "derive", sizeof(vl.type));
-      }
-
-    } else if ((type_end != NULL) &&
-               (strncmp(counter_name, "tx_", strlen("tx_"))) == 0) {
-      if (strstr(type_end, "bytes") != NULL) {
-        sstrncpy(vl.type, "if_tx_octets", sizeof(vl.type));
-      } else if (strstr(type_end, "error") != NULL) {
-        sstrncpy(vl.type, "if_tx_errors", sizeof(vl.type));
-      } else if (strstr(type_end, "dropped") != NULL) {
-        sstrncpy(vl.type, "if_tx_dropped", sizeof(vl.type));
-      } else if (strstr(type_end, "packets") != NULL) {
-        sstrncpy(vl.type, "if_tx_packets", sizeof(vl.type));
-      } else {
-        /* Does not fit obvious type: use a more generic one */
-        sstrncpy(vl.type, "derive", sizeof(vl.type));
-      }
-    } else if ((type_end != NULL) &&
-               (strncmp(counter_name, "flow_", strlen("flow_"))) == 0) {
-
-      if (strstr(type_end, "_filters") != NULL) {
-        sstrncpy(vl.type, "operations", sizeof(vl.type));
-      } else if (strstr(type_end, "error") != NULL)
-        sstrncpy(vl.type, "errors", sizeof(vl.type));
-
-    } else if ((type_end != NULL) &&
-               (strncmp(counter_name, "mac_", strlen("mac_"))) == 0) {
-      if (strstr(type_end, "error") != NULL) {
-        sstrncpy(vl.type, "errors", sizeof(vl.type));
-      }
-    } else {
-      /* Does not fit obvious type, or strrchr error:
-       *   use a more generic type */
-      sstrncpy(vl.type, "derive", sizeof(vl.type));
-    }
+  dpdk_stats_ctx_t *ctx = DPDK_STATS_CTX_GET(g_hc);
 
-    sstrncpy(vl.type_instance, counter_name, sizeof(vl.type_instance));
-    plugin_dispatch_values(&vl);
-  }
-}
+  size_t data_size = sizeof(dpdk_stats_ctx_t) +
+                     (ctx->stats_count * DPDK_STATS_CTX_GET_XSTAT_SIZE);
 
-static int dpdk_read(user_data_t *ud) {
-  int ret = 0;
+  DEBUG("%s:%d helper reinit (new_size=%zu)", __FUNCTION__, __LINE__,
+        data_size);
 
-  /*
-   * Check if SHM flag is set to be re-initialized. AKA DPDK ports have been
-   * counted, so re-init SHM to be large enough to fit all the statistics.
-   */
-  if (g_configuration->collectd_reinit_shm) {
-    DEBUG("dpdkstat: read() now reinit SHM then launching send-thread");
-    dpdk_re_init_shm();
-  }
+  dpdk_stats_ctx_t tmp_ctx;
+  dpdk_eal_config_t tmp_eal;
 
-  /*
-   * Check if DPDK proc is alive, and has already counted port / stats. This
-   * must be done in dpdk_read(), because the DPDK primary process may not be
-   * alive at dpdk_init() time.
-   */
-  if (g_configuration->helper_status == DPDK_HELPER_NOT_INITIALIZED ||
-      g_configuration->helper_status == DPDK_HELPER_GRACEFUL_QUIT) {
-    int action = DPDK_HELPER_ACTION_SEND_STATS;
-    if (g_configuration->num_xstats == 0)
-      action = DPDK_HELPER_ACTION_COUNT_STATS;
-    /* Spawn the helper thread to count stats or to read stats. */
-    int err = dpdk_helper_spawn(action);
-    if (err) {
-      char errbuf[ERR_BUF_SIZE];
-      ERROR("dpdkstat: error spawning helper %s",
-            sstrerror(errno, errbuf, sizeof(errbuf)));
-      return -1;
-    }
-  }
+  memcpy(&tmp_ctx, ctx, sizeof(dpdk_stats_ctx_t));
+  dpdk_helper_eal_config_get(g_hc, &tmp_eal);
 
-  pid_t ws = waitpid(g_configuration->helper_pid, NULL, WNOHANG);
-  /*
-   * Conditions under which to respawn helper:
-   *  waitpid() fails, helper process died (or quit), so respawn
-   */
-  _Bool respawn_helper = 0;
-  if (ws != 0) {
-    respawn_helper = 1;
-  }
+  dpdk_helper_shutdown(g_hc);
 
-  char buf[DPDKSTAT_MAX_BUFFER_SIZE];
-  char out[DPDKSTAT_MAX_BUFFER_SIZE];
+  g_hc = NULL;
 
-  /* non blocking check on helper logging pipe */
-  struct pollfd fds = {
-      .fd = g_configuration->helper_pipes[0], .events = POLLIN,
-  };
-  int data_avail = poll(&fds, 1, 0);
-  if (data_avail < 0) {
+  int ret;
+  ret = dpdk_helper_init(g_shm_name, data_size, &g_hc);
+  if (ret != 0) {
     char errbuf[ERR_BUF_SIZE];
-    if (errno != EINTR || errno != EAGAIN)
-      ERROR("dpdkstats: poll(2) failed: %s",
-            sstrerror(errno, errbuf, sizeof(errbuf)));
-  }
-  while (data_avail) {
-    int nbytes = read(g_configuration->helper_pipes[0], buf, sizeof(buf));
-    if (nbytes <= 0)
-      break;
-    ssnprintf(out, nbytes, "%s", buf);
-    DEBUG("dpdkstat: helper-proc: %s", out);
+    ERROR("%s: failed to initialize %s helper(error: %s)", DPDK_STATS_PLUGIN,
+          g_shm_name, sstrerror(errno, errbuf, sizeof(errbuf)));
+    return ret;
   }
 
-  if (respawn_helper) {
-    if (g_configuration->helper_pid)
-      dpdk_helper_stop(RESET);
-    dpdk_helper_spawn(DPDK_HELPER_ACTION_COUNT_STATS);
+  ctx = DPDK_STATS_CTX_GET(g_hc);
+  memcpy(ctx, &tmp_ctx, sizeof(dpdk_stats_ctx_t));
+  DPDK_STATS_CTX_INIT(ctx);
+  dpdk_helper_eal_config_set(g_hc, &tmp_eal);
+
+  return ret;
+}
+
+static int dpdk_stats_read(user_data_t *ud) {
+  DPDK_STATS_TRACE();
+
+  int ret = 0;
+
+  if (g_hc == NULL) {
+    ERROR("dpdk stats plugin not initialized");
+    return -EINVAL;
   }
 
-  /* Kick helper process through SHM */
-  sem_post(&g_configuration->sema_helper_get_stats);
+  dpdk_stats_ctx_t *ctx = DPDK_STATS_CTX_GET(g_hc);
 
-  cdtime_t now = cdtime();
-  ret = sem_timedwait(&g_configuration->sema_stats_in_shm,
-                      &CDTIME_T_TO_TIMESPEC(now + g_configuration->interval));
-  if (ret == -1) {
-    if (errno == ETIMEDOUT)
-      DEBUG(
-          "dpdkstat: timeout in collectd thread: is a DPDK Primary running? ");
+  int result = 0;
+  ret = dpdk_helper_command(g_hc, DPDK_CMD_GET_STATS, &result,
+                            ctx->config.interval);
+  if (ret != 0) {
     return 0;
   }
 
-  /* Dispatch the stats.*/
-  uint32_t count = 0, port_num = 0;
-
-  for (uint32_t i = 0; i < g_configuration->num_ports; i++) {
-    char dev_name[64];
-    cdtime_t port_read_time = g_configuration->port_read_time[i];
-    uint32_t counters_num = g_configuration->num_stats_in_port[i];
-    size_t ports_max = CHAR_BIT * sizeof(g_configuration->enabled_port_mask);
-    for (size_t j = port_num; j < ports_max; j++) {
-      if ((g_configuration->enabled_port_mask & (1 << j)) != 0)
-        break;
-      port_num++;
-    }
+  if (result == -ENOBUFS) {
+    dpdk_stats_reinit_helper();
+  } else if (result == -ENODEV) {
+    dpdk_helper_shutdown(g_hc);
+  } else if (result == 0) {
+    dpdk_stats_counters_dispatch(g_hc);
+  }
 
-    if (g_configuration->port_name[i][0] != 0)
-      ssnprintf(dev_name, sizeof(dev_name), "%s",
-                g_configuration->port_name[i]);
-    else
-      ssnprintf(dev_name, sizeof(dev_name), "port.%" PRIu32, port_num);
-    dpdk_submit_xstats(dev_name, count, counters_num, port_read_time);
-    count += counters_num;
-    port_num++;
-  } /* for each port */
   return 0;
 }
 
-static int dpdk_shm_cleanup(void) {
-  int ret = munmap(g_configuration, sizeof(dpdk_config_t));
-  g_configuration = 0;
-  if (ret) {
-    ERROR("dpdkstat: munmap returned %d", ret);
-    return ret;
-  }
-  ret = shm_unlink(DPDK_SHM_NAME);
-  if (ret) {
-    ERROR("dpdkstat: shm_unlink returned %d", ret);
+static int dpdk_stats_init(void) {
+  DPDK_STATS_TRACE();
+  int ret = 0;
+
+  ret = dpdk_stats_preinit();
+  if (ret != 0) {
     return ret;
   }
+
   return 0;
 }
 
-static int dpdk_shutdown(void) {
+static int dpdk_stats_shutdown(void) {
+  DPDK_STATS_TRACE();
+
   int ret = 0;
-  char errbuf[ERR_BUF_SIZE];
-  close(g_configuration->helper_pipes[1]);
-  int err = kill(g_configuration->helper_pid, SIGKILL);
-  if (err) {
-    ERROR("dpdkstat: error sending sigkill to helper %s",
-          sstrerror(errno, errbuf, sizeof(errbuf)));
-    ret = -1;
-  }
-  err = dpdk_shm_cleanup();
-  if (err) {
-    ERROR("dpdkstat: error cleaning up SHM: %s",
-          sstrerror(errno, errbuf, sizeof(errbuf)));
-    ret = -1;
+
+  ret = dpdk_helper_shutdown(g_hc);
+  g_hc = NULL;
+  if (ret != 0) {
+    ERROR("%s: failed to cleanup %s helper", DPDK_STATS_PLUGIN, g_shm_name);
+    return ret;
   }
 
   return ret;
 }
 
 void module_register(void) {
-  plugin_register_complex_config("dpdkstat", dpdk_config);
-  plugin_register_init("dpdkstat", dpdk_init);
-  plugin_register_complex_read(NULL, "dpdkstat", dpdk_read, 0, NULL);
-  plugin_register_shutdown("dpdkstat", dpdk_shutdown);
+  plugin_register_init(DPDK_STATS_PLUGIN, dpdk_stats_init);
+  plugin_register_complex_config(DPDK_STATS_PLUGIN, dpdk_stats_config);
+  plugin_register_complex_read(NULL, DPDK_STATS_PLUGIN, dpdk_stats_read, 0,
+                               NULL);
+  plugin_register_shutdown(DPDK_STATS_PLUGIN, dpdk_stats_shutdown);
 }
index 34e9998..72a8d6e 100644 (file)
@@ -719,5 +719,3 @@ void module_register(void) {
   plugin_register_read("email", email_read);
   plugin_register_shutdown("email", email_shutdown);
 } /* void module_register */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
index bd55252..4b05300 100644 (file)
@@ -325,5 +325,3 @@ void module_register(void) {
   plugin_register_read("ethstat", ethstat_read);
   plugin_register_shutdown("ethstat", ethstat_shutdown);
 }
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index d34f9d9..df05718 100644 (file)
@@ -866,7 +866,3 @@ void module_register(void) {
                                /* user_data = */ NULL);
   plugin_register_shutdown("exec", exec_shutdown);
 } /* void module_register */
-
-/*
- * vim:shiftwidth=2:softtabstop=2:tabstop=8:fdm=marker
- */
index a78b880..608218d 100644 (file)
@@ -511,7 +511,3 @@ void module_register(void) {
   plugin_register_init("filecount", fc_init);
   plugin_register_read("filecount", fc_read);
 } /* void module_register */
-
-/*
- * vim: set sw=2 sts=2 et :
- */
index c410ea3..618bb22 100644 (file)
@@ -217,5 +217,3 @@ static int fscache_read(void) {
 void module_register(void) {
   plugin_register_read("fscache", fscache_read);
 } /* void module_register */
-
-/* vim: set sw=4 sts=4 et : */
index fc9a232..7bfb18d 100644 (file)
@@ -1030,5 +1030,3 @@ void module_register(void) {
   plugin_register_init("gmond", gmond_init);
   plugin_register_shutdown("gmond", gmond_shutdown);
 }
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index 0ae80bb..2f16dbc 100644 (file)
@@ -26,8 +26,8 @@
  *   Florian octo Forster <octo at collectd.org>
  **/
 
-#include <grpc++/grpc++.h>
 #include <google/protobuf/util/time_util.h>
+#include <grpc++/grpc++.h>
 
 #include <fstream>
 #include <iostream>
@@ -61,10 +61,10 @@ using google::protobuf::util::TimeUtil;
  */
 
 struct Listener {
-       grpc::string addr;
-       grpc::string port;
+  grpc::string addr;
+  grpc::string port;
 
-       grpc::SslServerCredentialsOptions *ssl;
+  grpc::SslServerCredentialsOptions *ssl;
 };
 static std::vector<Listener> listeners;
 static grpc::string default_addr("0.0.0.0:50051");
@@ -73,189 +73,187 @@ static grpc::string default_addr("0.0.0.0:50051");
  * helper functions
  */
 
-static bool ident_matches(const value_list_t *vl, const value_list_t *matcher)
-{
-       if (fnmatch(matcher->host, vl->host, 0))
-               return false;
+static bool ident_matches(const value_list_t *vl, const value_list_t *matcher) {
+  if (fnmatch(matcher->host, vl->host, 0))
+    return false;
 
-       if (fnmatch(matcher->plugin, vl->plugin, 0))
-               return false;
-       if (fnmatch(matcher->plugin_instance, vl->plugin_instance, 0))
-               return false;
+  if (fnmatch(matcher->plugin, vl->plugin, 0))
+    return false;
+  if (fnmatch(matcher->plugin_instance, vl->plugin_instance, 0))
+    return false;
 
-       if (fnmatch(matcher->type, vl->type, 0))
-               return false;
-       if (fnmatch(matcher->type_instance, vl->type_instance, 0))
-               return false;
+  if (fnmatch(matcher->type, vl->type, 0))
+    return false;
+  if (fnmatch(matcher->type_instance, vl->type_instance, 0))
+    return false;
 
-       return true;
+  return true;
 } /* ident_matches */
 
-static grpc::string read_file(const char *filename)
-{
-       std::ifstream f;
-       grpc::string s, content;
-
-       f.open(filename);
-       if (!f.is_open()) {
-               ERROR("grpc: Failed to open '%s'", filename);
-               return "";
-       }
-
-       while (std::getline(f, s)) {
-               content += s;
-               content.push_back('\n');
-       }
-       f.close();
-       return content;
+static grpc::string read_file(const char *filename) {
+  std::ifstream f;
+  grpc::string s, content;
+
+  f.open(filename);
+  if (!f.is_open()) {
+    ERROR("grpc: Failed to open '%s'", filename);
+    return "";
+  }
+
+  while (std::getline(f, s)) {
+    content += s;
+    content.push_back('\n');
+  }
+  f.close();
+  return content;
 } /* read_file */
 
 /*
  * proto conversion
  */
 
-static void marshal_ident(const value_list_t *vl, collectd::types::Identifier *msg)
-{
-       msg->set_host(vl->host);
-       msg->set_plugin(vl->plugin);
-       if (vl->plugin_instance[0] != '\0')
-               msg->set_plugin_instance(vl->plugin_instance);
-       msg->set_type(vl->type);
-       if (vl->type_instance[0] != '\0')
-               msg->set_type_instance(vl->type_instance);
+static void marshal_ident(const value_list_t *vl,
+                          collectd::types::Identifier *msg) {
+  msg->set_host(vl->host);
+  msg->set_plugin(vl->plugin);
+  if (vl->plugin_instance[0] != '\0')
+    msg->set_plugin_instance(vl->plugin_instance);
+  msg->set_type(vl->type);
+  if (vl->type_instance[0] != '\0')
+    msg->set_type_instance(vl->type_instance);
 } /* marshal_ident */
 
-static grpc::Status unmarshal_ident(const collectd::types::Identifier &msg, value_list_t *vl,
-               bool require_fields)
-{
-       std::string s;
+static grpc::Status unmarshal_ident(const collectd::types::Identifier &msg,
+                                    value_list_t *vl, bool require_fields) {
+  std::string s;
 
-       s = msg.host();
-       if (!s.length() && require_fields)
-               return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
-                               grpc::string("missing host name"));
-       sstrncpy(vl->host, s.c_str(), sizeof(vl->host));
+  s = msg.host();
+  if (!s.length() && require_fields)
+    return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
+                        grpc::string("missing host name"));
+  sstrncpy(vl->host, s.c_str(), sizeof(vl->host));
 
-       s = msg.plugin();
-       if (!s.length() && require_fields)
-               return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
-                               grpc::string("missing plugin name"));
-       sstrncpy(vl->plugin, s.c_str(), sizeof(vl->plugin));
+  s = msg.plugin();
+  if (!s.length() && require_fields)
+    return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
+                        grpc::string("missing plugin name"));
+  sstrncpy(vl->plugin, s.c_str(), sizeof(vl->plugin));
 
-       s = msg.type();
-       if (!s.length() && require_fields)
-               return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
-                               grpc::string("missing type name"));
-       sstrncpy(vl->type, s.c_str(), sizeof(vl->type));
+  s = msg.type();
+  if (!s.length() && require_fields)
+    return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
+                        grpc::string("missing type name"));
+  sstrncpy(vl->type, s.c_str(), sizeof(vl->type));
 
-       s = msg.plugin_instance();
-       sstrncpy(vl->plugin_instance, s.c_str(), sizeof(vl->plugin_instance));
+  s = msg.plugin_instance();
+  sstrncpy(vl->plugin_instance, s.c_str(), sizeof(vl->plugin_instance));
 
-       s = msg.type_instance();
-       sstrncpy(vl->type_instance, s.c_str(), sizeof(vl->type_instance));
+  s = msg.type_instance();
+  sstrncpy(vl->type_instance, s.c_str(), sizeof(vl->type_instance));
 
-       return grpc::Status::OK;
+  return grpc::Status::OK;
 } /* unmarshal_ident() */
 
-static grpc::Status marshal_value_list(const value_list_t *vl, collectd::types::ValueList *msg)
-{
-       auto id = msg->mutable_identifier();
-       marshal_ident(vl, id);
-
-       auto ds = plugin_get_ds(vl->type);
-       if ((ds == NULL) || (ds->ds_num != vl->values_len)) {
-               return grpc::Status(grpc::StatusCode::INTERNAL,
-                               grpc::string("failed to retrieve data-set for values"));
-       }
-
-       auto t = TimeUtil::NanosecondsToTimestamp(CDTIME_T_TO_NS(vl->time));
-       auto d = TimeUtil::NanosecondsToDuration(CDTIME_T_TO_NS(vl->interval));
-       msg->set_allocated_time(new google::protobuf::Timestamp(t));
-       msg->set_allocated_interval(new google::protobuf::Duration(d));
-
-       for (size_t i = 0; i < vl->values_len; ++i) {
-               auto v = msg->add_values();
-               switch (ds->ds[i].type) {
-                       case DS_TYPE_COUNTER:
-                               v->set_counter(vl->values[i].counter);
-                               break;
-                       case DS_TYPE_GAUGE:
-                               v->set_gauge(vl->values[i].gauge);
-                               break;
-                       case DS_TYPE_DERIVE:
-                               v->set_derive(vl->values[i].derive);
-                               break;
-                       case DS_TYPE_ABSOLUTE:
-                               v->set_absolute(vl->values[i].absolute);
-                               break;
-                       default:
-                               return grpc::Status(grpc::StatusCode::INTERNAL,
-                                               grpc::string("unknown value type"));
-               }
-
-               auto name = msg->add_ds_names();
-               name->assign(ds->ds[i].name);
-       }
-
-       return grpc::Status::OK;
+static grpc::Status marshal_value_list(const value_list_t *vl,
+                                       collectd::types::ValueList *msg) {
+  auto id = msg->mutable_identifier();
+  marshal_ident(vl, id);
+
+  auto ds = plugin_get_ds(vl->type);
+  if ((ds == NULL) || (ds->ds_num != vl->values_len)) {
+    return grpc::Status(grpc::StatusCode::INTERNAL,
+                        grpc::string("failed to retrieve data-set for values"));
+  }
+
+  auto t = TimeUtil::NanosecondsToTimestamp(CDTIME_T_TO_NS(vl->time));
+  auto d = TimeUtil::NanosecondsToDuration(CDTIME_T_TO_NS(vl->interval));
+  msg->set_allocated_time(new google::protobuf::Timestamp(t));
+  msg->set_allocated_interval(new google::protobuf::Duration(d));
+
+  for (size_t i = 0; i < vl->values_len; ++i) {
+    auto v = msg->add_values();
+    switch (ds->ds[i].type) {
+    case DS_TYPE_COUNTER:
+      v->set_counter(vl->values[i].counter);
+      break;
+    case DS_TYPE_GAUGE:
+      v->set_gauge(vl->values[i].gauge);
+      break;
+    case DS_TYPE_DERIVE:
+      v->set_derive(vl->values[i].derive);
+      break;
+    case DS_TYPE_ABSOLUTE:
+      v->set_absolute(vl->values[i].absolute);
+      break;
+    default:
+      return grpc::Status(grpc::StatusCode::INTERNAL,
+                          grpc::string("unknown value type"));
+    }
+
+    auto name = msg->add_ds_names();
+    name->assign(ds->ds[i].name);
+  }
+
+  return grpc::Status::OK;
 } /* marshal_value_list */
 
-static grpc::Status unmarshal_value_list(const collectd::types::ValueList &msg, value_list_t *vl)
-{
-       vl->time = NS_TO_CDTIME_T(TimeUtil::TimestampToNanoseconds(msg.time()));
-       vl->interval = NS_TO_CDTIME_T(TimeUtil::DurationToNanoseconds(msg.interval()));
-
-       auto status = unmarshal_ident(msg.identifier(), vl, true);
-       if (!status.ok())
-               return status;
-
-       value_t *values = NULL;
-       size_t values_len = 0;
-
-       status = grpc::Status::OK;
-       for (auto v : msg.values()) {
-               value_t *val = (value_t *)realloc(values, (values_len + 1) * sizeof(*values));
-               if (!val) {
-                       status = grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED,
-                                       grpc::string("failed to allocate values array"));
-                       break;
-               }
-
-               values = val;
-               val = values + values_len;
-               values_len++;
-
-               switch (v.value_case()) {
-               case collectd::types::Value::ValueCase::kCounter:
-                       val->counter = counter_t(v.counter());
-                       break;
-               case collectd::types::Value::ValueCase::kGauge:
-                       val->gauge = gauge_t(v.gauge());
-                       break;
-               case collectd::types::Value::ValueCase::kDerive:
-                       val->derive = derive_t(v.derive());
-                       break;
-               case collectd::types::Value::ValueCase::kAbsolute:
-                       val->absolute = absolute_t(v.absolute());
-                       break;
-               default:
-                       status = grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
-                                       grpc::string("unknown value type"));
-                       break;
-               }
-
-               if (!status.ok())
-                       break;
-       }
-       if (status.ok()) {
-               vl->values = values;
-               vl->values_len = values_len;
-       }
-       else if (values) {
-               free(values);
-       }
-
-       return status;
+static grpc::Status unmarshal_value_list(const collectd::types::ValueList &msg,
+                                         value_list_t *vl) {
+  vl->time = NS_TO_CDTIME_T(TimeUtil::TimestampToNanoseconds(msg.time()));
+  vl->interval =
+      NS_TO_CDTIME_T(TimeUtil::DurationToNanoseconds(msg.interval()));
+
+  auto status = unmarshal_ident(msg.identifier(), vl, true);
+  if (!status.ok())
+    return status;
+
+  value_t *values = NULL;
+  size_t values_len = 0;
+
+  status = grpc::Status::OK;
+  for (auto v : msg.values()) {
+    value_t *val =
+        (value_t *)realloc(values, (values_len + 1) * sizeof(*values));
+    if (!val) {
+      status = grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED,
+                            grpc::string("failed to allocate values array"));
+      break;
+    }
+
+    values = val;
+    val = values + values_len;
+    values_len++;
+
+    switch (v.value_case()) {
+    case collectd::types::Value::ValueCase::kCounter:
+      val->counter = counter_t(v.counter());
+      break;
+    case collectd::types::Value::ValueCase::kGauge:
+      val->gauge = gauge_t(v.gauge());
+      break;
+    case collectd::types::Value::ValueCase::kDerive:
+      val->derive = derive_t(v.derive());
+      break;
+    case collectd::types::Value::ValueCase::kAbsolute:
+      val->absolute = absolute_t(v.absolute());
+      break;
+    default:
+      status = grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
+                            grpc::string("unknown value type"));
+      break;
+    }
+
+    if (!status.ok())
+      break;
+  }
+  if (status.ok()) {
+    vl->values = values;
+    vl->values_len = values_len;
+  } else if (values) {
+    free(values);
+  }
+
+  return status;
 } /* unmarshal_value_list() */
 
 /*
@@ -263,200 +261,200 @@ static grpc::Status unmarshal_value_list(const collectd::types::ValueList &msg,
  */
 class CollectdImpl : public collectd::Collectd::Service {
 public:
-       grpc::Status QueryValues(grpc::ServerContext *ctx, QueryValuesRequest const *req, grpc::ServerWriter<QueryValuesResponse> *writer) override {
-               value_list_t match;
-               auto status = unmarshal_ident(req->identifier(), &match, false);
-               if (!status.ok()) {
-                       return status;
-               }
-
-               std::queue<value_list_t> value_lists;
-               status = this->queryValuesRead(&match, &value_lists);
-               if (status.ok()) {
-                       status = this->queryValuesWrite(ctx, writer, &value_lists);
-               }
-
-               while (!value_lists.empty()) {
-                       auto vl = value_lists.front();
-                       value_lists.pop();
-                       sfree(vl.values);
-               }
-
-               return status;
-       }
-
-       grpc::Status PutValues(grpc::ServerContext *ctx,
-                                                  grpc::ServerReader<PutValuesRequest> *reader,
-                                                  PutValuesResponse *res) override {
-               PutValuesRequest req;
-
-               while (reader->Read(&req)) {
-                       value_list_t vl = {0};
-                       auto status = unmarshal_value_list(req.value_list(), &vl);
-                       if (!status.ok())
-                               return status;
-
-                       if (plugin_dispatch_values(&vl))
-                               return grpc::Status(grpc::StatusCode::INTERNAL,
-                                                                       grpc::string("failed to enqueue values for writing"));
-               }
-
-               res->Clear();
-               return grpc::Status::OK;
-       }
+  grpc::Status
+  QueryValues(grpc::ServerContext *ctx, QueryValuesRequest const *req,
+              grpc::ServerWriter<QueryValuesResponse> *writer) override {
+    value_list_t match;
+    auto status = unmarshal_ident(req->identifier(), &match, false);
+    if (!status.ok()) {
+      return status;
+    }
+
+    std::queue<value_list_t> value_lists;
+    status = this->queryValuesRead(&match, &value_lists);
+    if (status.ok()) {
+      status = this->queryValuesWrite(ctx, writer, &value_lists);
+    }
+
+    while (!value_lists.empty()) {
+      auto vl = value_lists.front();
+      value_lists.pop();
+      sfree(vl.values);
+    }
+
+    return status;
+  }
+
+  grpc::Status PutValues(grpc::ServerContext *ctx,
+                         grpc::ServerReader<PutValuesRequest> *reader,
+                         PutValuesResponse *res) override {
+    PutValuesRequest req;
+
+    while (reader->Read(&req)) {
+      value_list_t vl = {0};
+      auto status = unmarshal_value_list(req.value_list(), &vl);
+      if (!status.ok())
+        return status;
+
+      if (plugin_dispatch_values(&vl))
+        return grpc::Status(
+            grpc::StatusCode::INTERNAL,
+            grpc::string("failed to enqueue values for writing"));
+    }
+
+    res->Clear();
+    return grpc::Status::OK;
+  }
 
 private:
-       grpc::Status queryValuesRead(value_list_t const *match, std::queue<value_list_t> *value_lists) {
-               uc_iter_t *iter;
-               if ((iter = uc_get_iterator()) == NULL) {
-                       return grpc::Status(grpc::StatusCode::INTERNAL,
-                                                               grpc::string("failed to query values: cannot create iterator"));
-               }
-
-               grpc::Status status = grpc::Status::OK;
-               char *name = NULL;
-               while (uc_iterator_next(iter, &name) == 0) {
-                       value_list_t vl;
-                       if (parse_identifier_vl(name, &vl) != 0) {
-                               status = grpc::Status(grpc::StatusCode::INTERNAL,
-                                                                         grpc::string("failed to parse identifier"));
-                               break;
-                       }
-
-                       if (!ident_matches(&vl, match))
-                               continue;
-
-                       if (uc_iterator_get_time(iter, &vl.time) < 0) {
-                               status = grpc::Status(grpc::StatusCode::INTERNAL,
-                                                                         grpc::string("failed to retrieve value timestamp"));
-                               break;
-                       }
-                       if (uc_iterator_get_interval(iter, &vl.interval) < 0) {
-                               status = grpc::Status(grpc::StatusCode::INTERNAL,
-                                                                         grpc::string("failed to retrieve value interval"));
-                               break;
-                       }
-                       if (uc_iterator_get_values(iter, &vl.values, &vl.values_len) < 0) {
-                               status = grpc::Status(grpc::StatusCode::INTERNAL,
-                                                                         grpc::string("failed to retrieve values"));
-                               break;
-                       }
-
-                       value_lists->push(vl);
-               } // while (uc_iterator_next(iter, &name) == 0)
-
-               uc_iterator_destroy(iter);
-               return status;
-       }
-
-       grpc::Status queryValuesWrite(grpc::ServerContext *ctx,
-                                          grpc::ServerWriter<QueryValuesResponse> *writer,
-                                          std::queue<value_list_t> *value_lists) {
-               while (!value_lists->empty()) {
-                       auto vl = value_lists->front();
-                       QueryValuesResponse res;
-                       res.Clear();
-
-                       auto status = marshal_value_list(&vl, res.mutable_value_list());
-                       if (!status.ok()) {
-                               return status;
-                       }
-
-                       if (!writer->Write(res)) {
-                               return grpc::Status::CANCELLED;
-                       }
-
-                       value_lists->pop();
-                       sfree(vl.values);
-               }
-
-               return grpc::Status::OK;
-       }
+  grpc::Status queryValuesRead(value_list_t const *match,
+                               std::queue<value_list_t> *value_lists) {
+    uc_iter_t *iter;
+    if ((iter = uc_get_iterator()) == NULL) {
+      return grpc::Status(
+          grpc::StatusCode::INTERNAL,
+          grpc::string("failed to query values: cannot create iterator"));
+    }
+
+    grpc::Status status = grpc::Status::OK;
+    char *name = NULL;
+    while (uc_iterator_next(iter, &name) == 0) {
+      value_list_t vl;
+      if (parse_identifier_vl(name, &vl) != 0) {
+        status = grpc::Status(grpc::StatusCode::INTERNAL,
+                              grpc::string("failed to parse identifier"));
+        break;
+      }
+
+      if (!ident_matches(&vl, match))
+        continue;
+
+      if (uc_iterator_get_time(iter, &vl.time) < 0) {
+        status =
+            grpc::Status(grpc::StatusCode::INTERNAL,
+                         grpc::string("failed to retrieve value timestamp"));
+        break;
+      }
+      if (uc_iterator_get_interval(iter, &vl.interval) < 0) {
+        status =
+            grpc::Status(grpc::StatusCode::INTERNAL,
+                         grpc::string("failed to retrieve value interval"));
+        break;
+      }
+      if (uc_iterator_get_values(iter, &vl.values, &vl.values_len) < 0) {
+        status = grpc::Status(grpc::StatusCode::INTERNAL,
+                              grpc::string("failed to retrieve values"));
+        break;
+      }
+
+      value_lists->push(vl);
+    } // while (uc_iterator_next(iter, &name) == 0)
+
+    uc_iterator_destroy(iter);
+    return status;
+  }
+
+  grpc::Status queryValuesWrite(grpc::ServerContext *ctx,
+                                grpc::ServerWriter<QueryValuesResponse> *writer,
+                                std::queue<value_list_t> *value_lists) {
+    while (!value_lists->empty()) {
+      auto vl = value_lists->front();
+      QueryValuesResponse res;
+      res.Clear();
+
+      auto status = marshal_value_list(&vl, res.mutable_value_list());
+      if (!status.ok()) {
+        return status;
+      }
+
+      if (!writer->Write(res)) {
+        return grpc::Status::CANCELLED;
+      }
+
+      value_lists->pop();
+      sfree(vl.values);
+    }
+
+    return grpc::Status::OK;
+  }
 };
 
 /*
  * gRPC server implementation
  */
-class CollectdServer final
-{
+class CollectdServer final {
 public:
-       void Start()
-       {
-               auto auth = grpc::InsecureServerCredentials();
-
-               grpc::ServerBuilder builder;
-
-               if (listeners.empty()) {
-                       builder.AddListeningPort(default_addr, auth);
-                       INFO("grpc: Listening on %s", default_addr.c_str());
-               }
-               else {
-                       for (auto l : listeners) {
-                               grpc::string addr = l.addr + ":" + l.port;
-
-                               auto use_ssl = grpc::string("");
-                               auto a = auth;
-                               if (l.ssl != nullptr) {
-                                       use_ssl = grpc::string(" (SSL enabled)");
-                                       a = grpc::SslServerCredentials(*l.ssl);
-                               }
-
-                               builder.AddListeningPort(addr, a);
-                               INFO("grpc: Listening on %s%s", addr.c_str(), use_ssl.c_str());
-                       }
-               }
-
-               builder.RegisterService(&collectd_service_);
-
-               server_ = builder.BuildAndStart();
-       } /* Start() */
-
-       void Shutdown()
-       {
-               server_->Shutdown();
-       } /* Shutdown() */
+  void Start() {
+    auto auth = grpc::InsecureServerCredentials();
+
+    grpc::ServerBuilder builder;
+
+    if (listeners.empty()) {
+      builder.AddListeningPort(default_addr, auth);
+      INFO("grpc: Listening on %s", default_addr.c_str());
+    } else {
+      for (auto l : listeners) {
+        grpc::string addr = l.addr + ":" + l.port;
+
+        auto use_ssl = grpc::string("");
+        auto a = auth;
+        if (l.ssl != nullptr) {
+          use_ssl = grpc::string(" (SSL enabled)");
+          a = grpc::SslServerCredentials(*l.ssl);
+        }
+
+        builder.AddListeningPort(addr, a);
+        INFO("grpc: Listening on %s%s", addr.c_str(), use_ssl.c_str());
+      }
+    }
+
+    builder.RegisterService(&collectd_service_);
+
+    server_ = builder.BuildAndStart();
+  } /* Start() */
+
+  void Shutdown() { server_->Shutdown(); } /* Shutdown() */
 
 private:
-       CollectdImpl collectd_service_;
+  CollectdImpl collectd_service_;
 
-       std::unique_ptr<grpc::Server> server_;
+  std::unique_ptr<grpc::Server> server_;
 }; /* class CollectdServer */
 
-class CollectdClient final
-{
+class CollectdClient final {
 public:
-       CollectdClient(std::shared_ptr<grpc::ChannelInterface> channel) : stub_(Collectd::NewStub(channel)) {
-       }
-
-       int PutValues(value_list_t const *vl) {
-               grpc::ClientContext ctx;
-
-               PutValuesRequest req;
-               auto status = marshal_value_list(vl, req.mutable_value_list());
-               if (!status.ok()) {
-                       ERROR("grpc: Marshalling value_list_t failed.");
-                       return -1;
-               }
-
-               PutValuesResponse res;
-               auto stream = stub_->PutValues(&ctx, &res);
-               if (!stream->Write(req)) {
-                       NOTICE("grpc: Broken stream.");
-                       /* intentionally not returning. */
-               }
-
-               stream->WritesDone();
-               status = stream->Finish();
-               if (!status.ok()) {
-                       ERROR ("grpc: Error while closing stream.");
-                       return -1;
-               }
-
-               return 0;
-       } /* int PutValues */
+  CollectdClient(std::shared_ptr<grpc::ChannelInterface> channel)
+      : stub_(Collectd::NewStub(channel)) {}
+
+  int PutValues(value_list_t const *vl) {
+    grpc::ClientContext ctx;
+
+    PutValuesRequest req;
+    auto status = marshal_value_list(vl, req.mutable_value_list());
+    if (!status.ok()) {
+      ERROR("grpc: Marshalling value_list_t failed.");
+      return -1;
+    }
+
+    PutValuesResponse res;
+    auto stream = stub_->PutValues(&ctx, &res);
+    if (!stream->Write(req)) {
+      NOTICE("grpc: Broken stream.");
+      /* intentionally not returning. */
+    }
+
+    stream->WritesDone();
+    status = stream->Finish();
+    if (!status.ok()) {
+      ERROR("grpc: Error while closing stream.");
+      return -1;
+    }
+
+    return 0;
+  } /* int PutValues */
 
 private:
-       std::unique_ptr<Collectd::Stub> stub_;
+  std::unique_ptr<Collectd::Stub> stub_;
 };
 
 static CollectdServer *server = nullptr;
@@ -465,216 +463,194 @@ static CollectdServer *server = nullptr;
  * collectd plugin interface
  */
 extern "C" {
-       static void c_grpc_destroy_write_callback (void *ptr) {
-               delete (CollectdClient *) ptr;
-       }
-
-       static int c_grpc_write(__attribute__((unused)) data_set_t const *ds,
-                       value_list_t const *vl,
-                       user_data_t *ud) {
-               CollectdClient *c = (CollectdClient *) ud->data;
-               return c->PutValues(vl);
-       }
-
-       static int c_grpc_config_listen(oconfig_item_t *ci)
-       {
-               if ((ci->values_num != 2)
-                               || (ci->values[0].type != OCONFIG_TYPE_STRING)
-                               || (ci->values[1].type != OCONFIG_TYPE_STRING)) {
-                       ERROR("grpc: The `%s` config option needs exactly "
-                                       "two string argument (address and port).", ci->key);
-                       return -1;
-               }
-
-               auto listener = Listener();
-               listener.addr = grpc::string(ci->values[0].value.string);
-               listener.port = grpc::string(ci->values[1].value.string);
-               listener.ssl = nullptr;
-
-               auto ssl_opts = new(grpc::SslServerCredentialsOptions);
-               grpc::SslServerCredentialsOptions::PemKeyCertPair pkcp = {};
-               bool use_ssl = false;
-
-               for (int i = 0; i < ci->children_num; i++) {
-                       oconfig_item_t *child = ci->children + i;
-
-                       if (!strcasecmp("EnableSSL", child->key)) {
-                               if (cf_util_get_boolean(child, &use_ssl)) {
-                                       ERROR("grpc: Option `%s` expects a boolean value",
-                                                       child->key);
-                                       return -1;
-                               }
-                       }
-                       else if (!strcasecmp("SSLCACertificateFile", child->key)) {
-                               char *certs = NULL;
-                               if (cf_util_get_string(child, &certs)) {
-                                       ERROR("grpc: Option `%s` expects a string value",
-                                                       child->key);
-                                       return -1;
-                               }
-                               ssl_opts->pem_root_certs = read_file(certs);
-                       }
-                       else if (!strcasecmp("SSLCertificateKeyFile", child->key)) {
-                               char *key = NULL;
-                               if (cf_util_get_string(child, &key)) {
-                                       ERROR("grpc: Option `%s` expects a string value",
-                                                       child->key);
-                                       return -1;
-                               }
-                               pkcp.private_key = read_file(key);
-                       }
-                       else if (!strcasecmp("SSLCertificateFile", child->key)) {
-                               char *cert = NULL;
-                               if (cf_util_get_string(child, &cert)) {
-                                       ERROR("grpc: Option `%s` expects a string value",
-                                                       child->key);
-                                       return -1;
-                               }
-                               pkcp.cert_chain = read_file(cert);
-                       }
-                       else {
-                               WARNING("grpc: Option `%s` not allowed in <%s> block.",
-                                               child->key, ci->key);
-                       }
-               }
-
-               ssl_opts->pem_key_cert_pairs.push_back(pkcp);
-               if (use_ssl)
-                       listener.ssl = ssl_opts;
-               else
-                       delete(ssl_opts);
-
-               listeners.push_back(listener);
-               return 0;
-       } /* c_grpc_config_listen() */
-
-       static int c_grpc_config_server(oconfig_item_t *ci)
-       {
-               if ((ci->values_num != 2)
-                               || (ci->values[0].type != OCONFIG_TYPE_STRING)
-                               || (ci->values[1].type != OCONFIG_TYPE_STRING)) {
-                       ERROR("grpc: The `%s` config option needs exactly "
-                                       "two string argument (address and port).", ci->key);
-                       return -1;
-               }
-
-               grpc::SslCredentialsOptions ssl_opts;
-               bool use_ssl = false;
-
-               for (int i = 0; i < ci->children_num; i++) {
-                       oconfig_item_t *child = ci->children + i;
-
-                       if (!strcasecmp("EnableSSL", child->key)) {
-                               if (cf_util_get_boolean(child, &use_ssl)) {
-                                       return -1;
-                               }
-                       }
-                       else if (!strcasecmp("SSLCACertificateFile", child->key)) {
-                               char *certs = NULL;
-                               if (cf_util_get_string(child, &certs)) {
-                                       return -1;
-                               }
-                               ssl_opts.pem_root_certs = read_file(certs);
-                       }
-                       else if (!strcasecmp("SSLCertificateKeyFile", child->key)) {
-                               char *key = NULL;
-                               if (cf_util_get_string(child, &key)) {
-                                       return -1;
-                               }
-                               ssl_opts.pem_private_key = read_file(key);
-                       }
-                       else if (!strcasecmp("SSLCertificateFile", child->key)) {
-                               char *cert = NULL;
-                               if (cf_util_get_string(child, &cert)) {
-                                       return -1;
-                               }
-                               ssl_opts.pem_cert_chain = read_file(cert);
-                       }
-                       else {
-                               WARNING("grpc: Option `%s` not allowed in <%s> block.",
-                                               child->key, ci->key);
-                       }
-               }
-
-               auto node    = grpc::string(ci->values[0].value.string);
-               auto service = grpc::string(ci->values[1].value.string);
-               auto addr    = node + ":" + service;
-
-               CollectdClient *client;
-               if (use_ssl) {
-                       auto channel_creds = grpc::SslCredentials(ssl_opts);
-                       auto channel = grpc::CreateChannel(addr, channel_creds);
-                       client = new CollectdClient(channel);
-               } else {
-                       auto channel = grpc::CreateChannel(addr, grpc::InsecureChannelCredentials());
-                       client = new CollectdClient(channel);
-               }
-
-               auto callback_name = grpc::string("grpc/") + addr;
-               user_data_t ud = {
-                       .data = client,
-                       .free_func = c_grpc_destroy_write_callback,
-               };
-
-               plugin_register_write (callback_name.c_str(), c_grpc_write, &ud);
-               return 0;
-       } /* c_grpc_config_server() */
-
-       static int c_grpc_config(oconfig_item_t *ci)
-       {
-               int i;
-
-               for (i = 0; i < ci->children_num; i++) {
-                       oconfig_item_t *child = ci->children + i;
-
-                       if (!strcasecmp("Listen", child->key)) {
-                               if (c_grpc_config_listen(child))
-                                       return -1;
-                       }
-                       else if (!strcasecmp("Server", child->key)) {
-                               if (c_grpc_config_server(child))
-                                       return -1;
-                       }
-
-                       else {
-                               WARNING("grpc: Option `%s` not allowed here.", child->key);
-                       }
-               }
-
-               return 0;
-       } /* c_grpc_config() */
-
-       static int c_grpc_init(void)
-       {
-               server = new CollectdServer();
-               if (!server) {
-                       ERROR("grpc: Failed to create server");
-                       return -1;
-               }
-
-               server->Start();
-               return 0;
-       } /* c_grpc_init() */
-
-       static int c_grpc_shutdown(void)
-       {
-               if (!server)
-                       return 0;
-
-               server->Shutdown();
-
-               delete server;
-               server = nullptr;
-
-               return 0;
-       } /* c_grpc_shutdown() */
-
-       void module_register(void)
-       {
-               plugin_register_complex_config("grpc", c_grpc_config);
-               plugin_register_init("grpc", c_grpc_init);
-               plugin_register_shutdown("grpc", c_grpc_shutdown);
-       } /* module_register() */
-} /* extern "C" */
+static void c_grpc_destroy_write_callback(void *ptr) {
+  delete (CollectdClient *)ptr;
+}
 
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
+static int c_grpc_write(__attribute__((unused)) data_set_t const *ds,
+                        value_list_t const *vl, user_data_t *ud) {
+  CollectdClient *c = (CollectdClient *)ud->data;
+  return c->PutValues(vl);
+}
+
+static int c_grpc_config_listen(oconfig_item_t *ci) {
+  if ((ci->values_num != 2) || (ci->values[0].type != OCONFIG_TYPE_STRING) ||
+      (ci->values[1].type != OCONFIG_TYPE_STRING)) {
+    ERROR("grpc: The `%s` config option needs exactly "
+          "two string argument (address and port).",
+          ci->key);
+    return -1;
+  }
+
+  auto listener = Listener();
+  listener.addr = grpc::string(ci->values[0].value.string);
+  listener.port = grpc::string(ci->values[1].value.string);
+  listener.ssl = nullptr;
+
+  auto ssl_opts = new (grpc::SslServerCredentialsOptions);
+  grpc::SslServerCredentialsOptions::PemKeyCertPair pkcp = {};
+  bool use_ssl = false;
+
+  for (int i = 0; i < ci->children_num; i++) {
+    oconfig_item_t *child = ci->children + i;
+
+    if (!strcasecmp("EnableSSL", child->key)) {
+      if (cf_util_get_boolean(child, &use_ssl)) {
+        ERROR("grpc: Option `%s` expects a boolean value", child->key);
+        return -1;
+      }
+    } else if (!strcasecmp("SSLCACertificateFile", child->key)) {
+      char *certs = NULL;
+      if (cf_util_get_string(child, &certs)) {
+        ERROR("grpc: Option `%s` expects a string value", child->key);
+        return -1;
+      }
+      ssl_opts->pem_root_certs = read_file(certs);
+    } else if (!strcasecmp("SSLCertificateKeyFile", child->key)) {
+      char *key = NULL;
+      if (cf_util_get_string(child, &key)) {
+        ERROR("grpc: Option `%s` expects a string value", child->key);
+        return -1;
+      }
+      pkcp.private_key = read_file(key);
+    } else if (!strcasecmp("SSLCertificateFile", child->key)) {
+      char *cert = NULL;
+      if (cf_util_get_string(child, &cert)) {
+        ERROR("grpc: Option `%s` expects a string value", child->key);
+        return -1;
+      }
+      pkcp.cert_chain = read_file(cert);
+    } else {
+      WARNING("grpc: Option `%s` not allowed in <%s> block.", child->key,
+              ci->key);
+    }
+  }
+
+  ssl_opts->pem_key_cert_pairs.push_back(pkcp);
+  if (use_ssl)
+    listener.ssl = ssl_opts;
+  else
+    delete (ssl_opts);
+
+  listeners.push_back(listener);
+  return 0;
+} /* c_grpc_config_listen() */
+
+static int c_grpc_config_server(oconfig_item_t *ci) {
+  if ((ci->values_num != 2) || (ci->values[0].type != OCONFIG_TYPE_STRING) ||
+      (ci->values[1].type != OCONFIG_TYPE_STRING)) {
+    ERROR("grpc: The `%s` config option needs exactly "
+          "two string argument (address and port).",
+          ci->key);
+    return -1;
+  }
+
+  grpc::SslCredentialsOptions ssl_opts;
+  bool use_ssl = false;
+
+  for (int i = 0; i < ci->children_num; i++) {
+    oconfig_item_t *child = ci->children + i;
+
+    if (!strcasecmp("EnableSSL", child->key)) {
+      if (cf_util_get_boolean(child, &use_ssl)) {
+        return -1;
+      }
+    } else if (!strcasecmp("SSLCACertificateFile", child->key)) {
+      char *certs = NULL;
+      if (cf_util_get_string(child, &certs)) {
+        return -1;
+      }
+      ssl_opts.pem_root_certs = read_file(certs);
+    } else if (!strcasecmp("SSLCertificateKeyFile", child->key)) {
+      char *key = NULL;
+      if (cf_util_get_string(child, &key)) {
+        return -1;
+      }
+      ssl_opts.pem_private_key = read_file(key);
+    } else if (!strcasecmp("SSLCertificateFile", child->key)) {
+      char *cert = NULL;
+      if (cf_util_get_string(child, &cert)) {
+        return -1;
+      }
+      ssl_opts.pem_cert_chain = read_file(cert);
+    } else {
+      WARNING("grpc: Option `%s` not allowed in <%s> block.", child->key,
+              ci->key);
+    }
+  }
+
+  auto node = grpc::string(ci->values[0].value.string);
+  auto service = grpc::string(ci->values[1].value.string);
+  auto addr = node + ":" + service;
+
+  CollectdClient *client;
+  if (use_ssl) {
+    auto channel_creds = grpc::SslCredentials(ssl_opts);
+    auto channel = grpc::CreateChannel(addr, channel_creds);
+    client = new CollectdClient(channel);
+  } else {
+    auto channel =
+        grpc::CreateChannel(addr, grpc::InsecureChannelCredentials());
+    client = new CollectdClient(channel);
+  }
+
+  auto callback_name = grpc::string("grpc/") + addr;
+  user_data_t ud = {
+      .data = client, .free_func = c_grpc_destroy_write_callback,
+  };
+
+  plugin_register_write(callback_name.c_str(), c_grpc_write, &ud);
+  return 0;
+} /* c_grpc_config_server() */
+
+static int c_grpc_config(oconfig_item_t *ci) {
+  int i;
+
+  for (i = 0; i < ci->children_num; i++) {
+    oconfig_item_t *child = ci->children + i;
+
+    if (!strcasecmp("Listen", child->key)) {
+      if (c_grpc_config_listen(child))
+        return -1;
+    } else if (!strcasecmp("Server", child->key)) {
+      if (c_grpc_config_server(child))
+        return -1;
+    }
+
+    else {
+      WARNING("grpc: Option `%s` not allowed here.", child->key);
+    }
+  }
+
+  return 0;
+} /* c_grpc_config() */
+
+static int c_grpc_init(void) {
+  server = new CollectdServer();
+  if (!server) {
+    ERROR("grpc: Failed to create server");
+    return -1;
+  }
+
+  server->Start();
+  return 0;
+} /* c_grpc_init() */
+
+static int c_grpc_shutdown(void) {
+  if (!server)
+    return 0;
+
+  server->Shutdown();
+
+  delete server;
+  server = nullptr;
+
+  return 0;
+} /* c_grpc_shutdown() */
+
+void module_register(void) {
+  plugin_register_complex_config("grpc", c_grpc_config);
+  plugin_register_init("grpc", c_grpc_init);
+  plugin_register_shutdown("grpc", c_grpc_shutdown);
+} /* module_register() */
+} /* extern "C" */
index 7328836..e2e2e39 100644 (file)
@@ -467,6 +467,10 @@ static int rdt_config_cgroups(oconfig_item_t *item) {
   return (0);
 }
 
+static void rdt_pqos_log(void *context, const size_t size, const char *msg) {
+  DEBUG(RDT_PLUGIN ": %s", msg);
+}
+
 static int rdt_preinit(void) {
   int ret;
 
@@ -481,15 +485,12 @@ static int rdt_preinit(void) {
     return (-ENOMEM);
   }
 
-  /* In case previous instance of the application was not closed properly
-   * call fini and ignore return code. */
-  pqos_fini();
+  struct pqos_config pqos = {.fd_log = -1,
+                             .callback_log = rdt_pqos_log,
+                             .context_log = NULL,
+                             .verbose = 0};
 
-  /* TODO:
-   * stdout should not be used here. Will be reworked when support of log
-   * callback is added to PQoS library.
-  */
-  ret = pqos_init(&(struct pqos_config){.fd_log = STDOUT_FILENO});
+  ret = pqos_init(&pqos);
   if (ret != PQOS_RETVAL_OK) {
     ERROR(RDT_PLUGIN ": Error initializing PQoS library!");
     goto rdt_preinit_error1;
@@ -514,6 +515,9 @@ static int rdt_preinit(void) {
     goto rdt_preinit_error2;
   }
 
+  /* Reset pqos monitoring groups registers */
+  pqos_mon_reset();
+
   return (0);
 
 rdt_preinit_error2:
index c9fb003..8222efb 100644 (file)
--- a/src/ipc.c
+++ b/src/ipc.c
@@ -319,5 +319,3 @@ void module_register(void) /* {{{ */
   plugin_register_read("ipc", ipc_read);
 }
 /* }}} */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index 1bbaf41..f3636fc 100644 (file)
@@ -621,5 +621,3 @@ void module_register(void) {
   plugin_register_read("ipmi", c_ipmi_read);
   plugin_register_shutdown("ipmi", c_ipmi_shutdown);
 } /* void module_register */
-
-/* vim: set sw=2 sts=2 ts=8 fdm=marker et : */
index 2446bd1..a8c4a1d 100644 (file)
@@ -321,5 +321,3 @@ void module_register(void) {
   plugin_register_shutdown("ipvs", cipvs_shutdown);
   return;
 } /* module_register */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
index 63b5e31..2e4d88a 100644 (file)
@@ -2841,5 +2841,3 @@ void module_register(void) {
   plugin_register_init("java", cjni_init);
   plugin_register_shutdown("java", cjni_shutdown);
 } /* void module_register (void) */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
diff --git a/src/libcollectdclient/Makefile.am b/src/libcollectdclient/Makefile.am
deleted file mode 100644 (file)
index e81a594..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-AUTOMAKE_OPTIONS = foreign no-dependencies
-
-pkginclude_HEADERS = collectd/client.h collectd/network.h collectd/network_buffer.h collectd/lcc_features.h
-lib_LTLIBRARIES = libcollectdclient.la
-nodist_pkgconfig_DATA = libcollectdclient.pc
-
-BUILT_SOURCES = collectd/lcc_features.h
-
-libcollectdclient_la_SOURCES = client.c network.c network_buffer.c
-libcollectdclient_la_CPPFLAGS = $(AM_CPPFLAGS) \
-                               -I$(top_srcdir)/src/libcollectdclient/collectd \
-                               -I$(top_builddir)/src/libcollectdclient/collectd \
-                               -I$(top_srcdir)/src/daemon
-libcollectdclient_la_LDFLAGS = -version-info 1:0:0
-libcollectdclient_la_LIBADD = 
-if BUILD_WITH_LIBGCRYPT
-libcollectdclient_la_CPPFLAGS += $(GCRYPT_CPPFLAGS)
-libcollectdclient_la_LDFLAGS += $(GCRYPT_LDFLAGS)
-libcollectdclient_la_LIBADD += $(GCRYPT_LIBS)
-endif
index f61e967..a8f5d0d 100644 (file)
@@ -1021,5 +1021,3 @@ int lcc_sort_identifiers(lcc_connection_t *c, /* {{{ */
   qsort(idents, idents_num, sizeof(*idents), lcc_identifier_compare);
   return (0);
 } /* }}} int lcc_sort_identifiers */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index 36aaf92..8604ff6 100644 (file)
@@ -39,9 +39,7 @@
 /*
  * Includes (for data types)
  */
-#if HAVE_STDINT_H
 #include <stdint.h>
-#endif
 #include <inttypes.h>
 #include <time.h>
 
@@ -141,5 +139,4 @@ int lcc_sort_identifiers(lcc_connection_t *c, lcc_identifier_t *idents,
 
 LCC_END_DECLS
 
-/* vim: set sw=2 sts=2 et : */
 #endif /* LIBCOLLECTD_COLLECTDCLIENT_H */
index 0e6fcd4..304845e 100644 (file)
@@ -62,6 +62,3 @@ const char *lcc_version_extra (void);
 LCC_END_DECLS
 
 #endif /* ! LIBCOLLECTD_LCC_FEATURES_H */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
-
index fdb9b33..35fd7d6 100644 (file)
@@ -73,5 +73,4 @@ int lcc_network_notification_send (lcc_network_t *net,
     const lcc_notification_t *notif);
 #endif
 
-/* vim: set sw=2 sts=2 et : */
 #endif /* LIBCOLLECTDCLIENT_NETWORK_H */
index 5612458..9f39310 100644 (file)
@@ -55,4 +55,3 @@ int lcc_network_buffer_get(lcc_network_buffer_t *nb, void *buffer,
                            size_t *buffer_size);
 
 #endif /* LIBCOLLECTDCLIENT_NETWORK_BUFFER_H */
-/* vim: set sw=2 sts=2 et : */
index a21799c..d096f18 100644 (file)
@@ -446,5 +446,3 @@ int lcc_network_values_send(lcc_network_t *net, /* {{{ */
 
   return (0);
 } /* }}} int lcc_network_values_send */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index aa4941d..866c4cc 100644 (file)
@@ -35,7 +35,7 @@
 
 #include <pthread.h>
 
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
 #if defined __APPLE__
 /* default xcode compiler throws warnings even when deprecated functionality
  * is not used. -Werror breaks the build because of erroneous warnings.
@@ -106,7 +106,7 @@ struct lcc_network_buffer_s {
   char *username;
   char *password;
 
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
   gcry_cipher_hd_t encr_cypher;
   size_t encr_header_len;
   char encr_iv[16];
@@ -131,7 +131,7 @@ static _Bool have_gcrypt(void) /* {{{ */
     return (result);
   need_init = 0;
 
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
 #if GCRYPT_VERSION_NUMBER < 0x010600
   if (gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread))
     return (0);
@@ -475,7 +475,7 @@ static int nb_add_value_list(lcc_network_buffer_t *nb, /* {{{ */
   return (0);
 } /* }}} int nb_add_value_list */
 
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
 static int nb_add_signature(lcc_network_buffer_t *nb) /* {{{ */
 {
   char *buffer;
@@ -688,7 +688,7 @@ int lcc_network_buffer_initialize(lcc_network_buffer_t *nb) /* {{{ */
   nb->ptr = nb->buffer;
   nb->free = nb->size;
 
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
   if (nb->seclevel == SIGN) {
     size_t username_len;
     uint16_t pkg_type = htons(TYPE_SIGN_SHA256);
@@ -739,7 +739,7 @@ int lcc_network_buffer_finalize(lcc_network_buffer_t *nb) /* {{{ */
   if (nb == NULL)
     return (EINVAL);
 
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
   if (nb->seclevel == SIGN)
     return nb_add_signature(nb);
   else if (nb->seclevel == ENCRYPT)
@@ -779,5 +779,3 @@ int lcc_network_buffer_get(lcc_network_buffer_t *nb, /* {{{ */
 
   return (0);
 } /* }}} int lcc_network_buffer_get */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
diff --git a/src/liboconfig/Makefile.am b/src/liboconfig/Makefile.am
deleted file mode 100644 (file)
index 5ac0ef3..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-BUILT_SOURCES = parser.h
-#CLEANFILES = parser.[ch] scanner.c
-AM_YFLAGS = -d
-
-noinst_LTLIBRARIES = liboconfig.la
-
-liboconfig_la_LDFLAGS = -avoid-version $(LEXLIB)
-liboconfig_la_SOURCES = oconfig.c oconfig.h aux_types.h scanner.l parser.y
index 76134db..079adcf 100644 (file)
@@ -196,7 +196,3 @@ void oconfig_free(oconfig_item_t *ci) {
   oconfig_free_all(ci);
   free(ci);
 }
-
-/*
- * vim:shiftwidth=2:tabstop=8:softtabstop=2:fdm=marker
- */
index d27f6f5..3b81062 100644 (file)
@@ -67,7 +67,4 @@ oconfig_item_t *oconfig_clone(const oconfig_item_t *ci);
 
 void oconfig_free(oconfig_item_t *ci);
 
-/*
- * vim: shiftwidth=2:tabstop=8:softtabstop=2
- */
 #endif /* OCONFIG_H */
index 8df4313..0605930 100644 (file)
@@ -339,5 +339,3 @@ void module_register(void) {
   plugin_register_notification("log_logstash", log_logstash_notification,
                                /* user_data = */ NULL);
 } /* void module_register (void) */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
index 6629c0b..eca8c34 100644 (file)
@@ -204,5 +204,3 @@ void module_register(void) {
   plugin_register_notification("logfile", logfile_notification,
                                /* user_data = */ NULL);
 } /* void module_register (void) */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
index df4424c..c019227 100644 (file)
@@ -243,5 +243,3 @@ void module_register(void) {
   plugin_register_init("lpar", lpar_init);
   plugin_register_read("lpar", lpar_read);
 } /* void module_register */
-
-/* vim: set sw=8 noet : */
index 2bd56a1..9eda7d5 100644 (file)
--- a/src/lua.c
+++ b/src/lua.c
@@ -583,5 +583,3 @@ void module_register(void) {
   plugin_register_complex_config("lua", lua_config);
   plugin_register_shutdown("lua", lua_shutdown);
 }
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index 67c5578..0b2ab12 100644 (file)
@@ -79,5 +79,3 @@ void module_register(void) {
           .create = mec_create, .destroy = mec_destroy, .match = mec_match,
       });
 } /* module_register */
-
-/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */
index fad5271..9c8d34f 100644 (file)
@@ -166,5 +166,3 @@ void module_register(void) {
   mproc.match = mh_match;
   fc_register_match("hashed", mproc);
 } /* module_register */
-
-/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */
index 209f773..ea7fcf0 100644 (file)
@@ -364,5 +364,3 @@ void module_register(void) {
   mproc.match = mr_match;
   fc_register_match("regex", mproc);
 } /* module_register */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab fdm=marker : */
index 6d00ed2..f0a456b 100644 (file)
@@ -141,5 +141,3 @@ void module_register(void) {
   mproc.match = mt_match;
   fc_register_match("timediff", mproc);
 } /* module_register */
-
-/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */
index 3c94375..45745ba 100644 (file)
@@ -316,5 +316,3 @@ void module_register(void) {
   mproc.match = mv_match;
   fc_register_match("value", mproc);
 } /* module_register */
-
-/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */
diff --git a/src/mcelog.c b/src/mcelog.c
new file mode 100644 (file)
index 0000000..4e6a6fd
--- /dev/null
@@ -0,0 +1,551 @@
+/*-
+ * collectd - src/mcelog.c
+ * MIT License
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+
+ * Authors:
+ *   Maryam Tahhan <maryam.tahhan@intel.com>
+ *   Volodymyr Mytnyk <volodymyrx.mytnyk@intel.com>
+ *   Taras Chornyi <tarasx.chornyi@intel.com>
+ *   Krzysztof Matczak <krzysztofx.matczak@intel.com>
+ */
+
+#include "common.h"
+#include "collectd.h"
+
+#include <poll.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#define MCELOG_PLUGIN "mcelog"
+#define MCELOG_BUFF_SIZE 1024
+#define MCELOG_POLL_TIMEOUT 1000 /* ms */
+#define MCELOG_SOCKET_STR "SOCKET"
+#define MCELOG_DIMM_NAME "DMI_NAME"
+#define MCELOG_CORRECTED_ERR "corrected memory errors"
+#define MCELOG_UNCORRECTED_ERR "uncorrected memory errors"
+
+typedef struct mcelog_config_s {
+  char logfile[PATH_MAX]; /* mcelog logfile */
+  pthread_t tid;          /* poll thread id */
+} mcelog_config_t;
+
+typedef struct socket_adapter_s socket_adapter_t;
+
+struct socket_adapter_s {
+  int sock_fd;                  /* mcelog server socket fd */
+  struct sockaddr_un unix_sock; /* mcelog client socket */
+  pthread_rwlock_t lock;
+  /* function pointers for socket operations */
+  int (*write)(socket_adapter_t *self, const char *msg, const size_t len);
+  int (*reinit)(socket_adapter_t *self);
+  int (*receive)(socket_adapter_t *self, FILE **p_file);
+  int (*close)(socket_adapter_t *self);
+};
+
+typedef struct mcelog_memory_rec_s {
+  int corrected_err_total; /* x total*/
+  int corrected_err_timed; /* x in 24h*/
+  char corrected_err_timed_period[DATA_MAX_NAME_LEN];
+  int uncorrected_err_total; /* x total*/
+  int uncorrected_err_timed; /* x in 24h*/
+  char uncorrected_err_timed_period[DATA_MAX_NAME_LEN];
+  char location[DATA_MAX_NAME_LEN];  /* SOCKET x CHANNEL x DIMM x*/
+  char dimm_name[DATA_MAX_NAME_LEN]; /* DMI_NAME "DIMM_F1" */
+} mcelog_memory_rec_t;
+
+static int socket_close(socket_adapter_t *self);
+static int socket_write(socket_adapter_t *self, const char *msg,
+                        const size_t len);
+static int socket_reinit(socket_adapter_t *self);
+static int socket_receive(socket_adapter_t *self, FILE **p_file);
+
+static mcelog_config_t g_mcelog_config = {.logfile = "/var/log/mcelog"};
+
+static socket_adapter_t socket_adapter = {
+    .sock_fd = -1,
+    .unix_sock =
+        {
+            .sun_family = AF_UNIX, .sun_path = "/var/run/mcelog-client",
+        },
+    .lock = PTHREAD_RWLOCK_INITIALIZER,
+    .close = socket_close,
+    .write = socket_write,
+    .reinit = socket_reinit,
+    .receive = socket_receive,
+};
+
+static _Bool mcelog_thread_running;
+
+static int mcelog_config(oconfig_item_t *ci) {
+  for (int i = 0; i < ci->children_num; i++) {
+    oconfig_item_t *child = ci->children + i;
+    if (strcasecmp("McelogClientSocket", child->key) == 0) {
+      if (cf_util_get_string_buffer(child, socket_adapter.unix_sock.sun_path,
+                                    sizeof(socket_adapter.unix_sock.sun_path)) <
+          0) {
+        ERROR(MCELOG_PLUGIN ": Invalid configuration option: \"%s\".",
+              child->key);
+        return (-1);
+      }
+    } else if (strcasecmp("McelogLogfile", child->key) == 0) {
+      if (cf_util_get_string_buffer(child, g_mcelog_config.logfile,
+                                    sizeof(g_mcelog_config.logfile)) < 0) {
+        ERROR(MCELOG_PLUGIN ": Invalid configuration option: \"%s\".",
+              child->key);
+        return (-1);
+      }
+    } else {
+      ERROR(MCELOG_PLUGIN ": Invalid configuration option: \"%s\".",
+            child->key);
+      return (-1);
+    }
+  }
+  return (0);
+}
+
+static int socket_close(socket_adapter_t *self) {
+  int ret = 0;
+  pthread_rwlock_rdlock(&self->lock);
+  if (fcntl(self->sock_fd, F_GETFL) != -1) {
+    char errbuf[MCELOG_BUFF_SIZE];
+    if (shutdown(self->sock_fd, SHUT_RDWR) != 0) {
+      ERROR(MCELOG_PLUGIN ": Socket shutdown failed: %s",
+            sstrerror(errno, errbuf, sizeof(errbuf)));
+      ret = -1;
+    }
+    if (close(self->sock_fd) != 0) {
+      ERROR(MCELOG_PLUGIN ": Socket close failed: %s",
+            sstrerror(errno, errbuf, sizeof(errbuf)));
+      ret = -1;
+    }
+  }
+  pthread_rwlock_unlock(&self->lock);
+  return (ret);
+}
+
+static int socket_write(socket_adapter_t *self, const char *msg,
+                        const size_t len) {
+  int ret = 0;
+  pthread_rwlock_rdlock(&self->lock);
+  if (swrite(self->sock_fd, msg, len) < 0)
+    ret = -1;
+  pthread_rwlock_unlock(&self->lock);
+  return (ret);
+}
+
+static void mcelog_dispatch_notification(notification_t *n) {
+  if (!n) {
+    ERROR(MCELOG_PLUGIN ": %s: NULL pointer", __FUNCTION__);
+    return;
+  }
+
+  sstrncpy(n->host, hostname_g, sizeof(n->host));
+  sstrncpy(n->type, "gauge", sizeof(n->type));
+  plugin_dispatch_notification(n);
+  if (n->meta)
+    plugin_notification_meta_free(n->meta);
+}
+
+static int socket_reinit(socket_adapter_t *self) {
+  char errbuff[MCELOG_BUFF_SIZE];
+  int ret = -1;
+  cdtime_t interval = plugin_get_interval();
+  struct timeval socket_timeout = CDTIME_T_TO_TIMEVAL(interval);
+
+  /* synchronization via write lock since sock_fd may be changed here */
+  pthread_rwlock_wrlock(&self->lock);
+  self->sock_fd =
+      socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
+  if (self->sock_fd < 0) {
+    ERROR(MCELOG_PLUGIN ": Could not create a socket. %s",
+          sstrerror(errno, errbuff, sizeof(errbuff)));
+    pthread_rwlock_unlock(&self->lock);
+    return (ret);
+  }
+
+  /* Set socket timeout option */
+  if (setsockopt(self->sock_fd, SOL_SOCKET, SO_SNDTIMEO, &socket_timeout,
+                 sizeof(socket_timeout)) < 0)
+    ERROR(MCELOG_PLUGIN ": Failed to set the socket timeout option.");
+
+  /* downgrading to read lock due to possible recursive read locks
+   * in self->close(self) call */
+  pthread_rwlock_unlock(&self->lock);
+  pthread_rwlock_rdlock(&self->lock);
+  if (connect(self->sock_fd, (struct sockaddr *)&(self->unix_sock),
+              sizeof(self->unix_sock)) < 0) {
+    ERROR(MCELOG_PLUGIN ": Failed to connect to mcelog server. %s",
+          sstrerror(errno, errbuff, sizeof(errbuff)));
+    self->close(self);
+    ret = -1;
+  } else {
+    ret = 0;
+    mcelog_dispatch_notification(
+        &(notification_t){.severity = NOTIF_OKAY,
+                          .time = cdtime(),
+                          .message = "Connected to mcelog server",
+                          .plugin = MCELOG_PLUGIN,
+                          .type_instance = "mcelog_status"});
+  }
+  pthread_rwlock_unlock(&self->lock);
+  return (ret);
+}
+
+static int mcelog_prepare_notification(notification_t *n,
+                                       const mcelog_memory_rec_t *mr) {
+  if (n == NULL || mr == NULL)
+    return (-1);
+
+  if ((mr->location[0] != '\0') &&
+      (plugin_notification_meta_add_string(n, MCELOG_SOCKET_STR, mr->location) <
+       0)) {
+    ERROR(MCELOG_PLUGIN ": add memory location meta data failed");
+    return (-1);
+  }
+  if ((mr->dimm_name[0] != '\0') &&
+      (plugin_notification_meta_add_string(n, MCELOG_DIMM_NAME, mr->dimm_name) <
+       0)) {
+    ERROR(MCELOG_PLUGIN ": add DIMM name meta data failed");
+    plugin_notification_meta_free(n->meta);
+    return (-1);
+  }
+  if (plugin_notification_meta_add_signed_int(n, MCELOG_CORRECTED_ERR,
+                                              mr->corrected_err_total) < 0) {
+    ERROR(MCELOG_PLUGIN ": add corrected errors meta data failed");
+    plugin_notification_meta_free(n->meta);
+    return (-1);
+  }
+  if (plugin_notification_meta_add_signed_int(
+          n, "corrected memory timed errors", mr->corrected_err_timed) < 0) {
+    ERROR(MCELOG_PLUGIN ": add corrected timed errors meta data failed");
+    plugin_notification_meta_free(n->meta);
+    return (-1);
+  }
+  if ((mr->corrected_err_timed_period[0] != '\0') &&
+      (plugin_notification_meta_add_string(n, "corrected errors time period",
+                                           mr->corrected_err_timed_period) <
+       0)) {
+    ERROR(MCELOG_PLUGIN ": add corrected errors period meta data failed");
+    plugin_notification_meta_free(n->meta);
+    return (-1);
+  }
+  if (plugin_notification_meta_add_signed_int(n, MCELOG_UNCORRECTED_ERR,
+                                              mr->uncorrected_err_total) < 0) {
+    ERROR(MCELOG_PLUGIN ": add corrected errors meta data failed");
+    plugin_notification_meta_free(n->meta);
+    return (-1);
+  }
+  if (plugin_notification_meta_add_signed_int(n,
+                                              "uncorrected memory timed errors",
+                                              mr->uncorrected_err_timed) < 0) {
+    ERROR(MCELOG_PLUGIN ": add corrected timed errors meta data failed");
+    plugin_notification_meta_free(n->meta);
+    return (-1);
+  }
+  if ((mr->uncorrected_err_timed_period[0] != '\0') &&
+      (plugin_notification_meta_add_string(n, "uncorrected errors time period",
+                                           mr->uncorrected_err_timed_period) <
+       0)) {
+    ERROR(MCELOG_PLUGIN ": add corrected errors period meta data failed");
+    plugin_notification_meta_free(n->meta);
+    return (-1);
+  }
+
+  return (0);
+}
+
+static int mcelog_submit(const mcelog_memory_rec_t *mr) {
+
+  if (!mr) {
+    ERROR(MCELOG_PLUGIN ": %s: NULL pointer", __FUNCTION__);
+    return (-1);
+  }
+
+  value_list_t vl = {
+      .values_len = 1,
+      .values = &(value_t){.derive = (derive_t)mr->corrected_err_total},
+      .time = cdtime(),
+      .plugin = MCELOG_PLUGIN,
+      .type = "errors",
+      .type_instance = "corrected_memory_errors"};
+
+  if (mr->dimm_name[0] != '\0')
+    ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s_%s",
+              mr->location, mr->dimm_name);
+  else
+    sstrncpy(vl.plugin_instance, mr->location, sizeof(vl.plugin_instance));
+
+  plugin_dispatch_values(&vl);
+
+  ssnprintf(vl.type_instance, sizeof(vl.type_instance),
+            "corrected_memory_errors_in_%s", mr->corrected_err_timed_period);
+  vl.values = &(value_t){.derive = (derive_t)mr->corrected_err_timed};
+  plugin_dispatch_values(&vl);
+
+  sstrncpy(vl.type_instance, "uncorrected_memory_errors",
+           sizeof(vl.type_instance));
+  vl.values = &(value_t){.derive = (derive_t)mr->uncorrected_err_total};
+  plugin_dispatch_values(&vl);
+
+  ssnprintf(vl.type_instance, sizeof(vl.type_instance),
+            "uncorrected_memory_errors_in_%s",
+            mr->uncorrected_err_timed_period);
+  vl.values = &(value_t){.derive = (derive_t)mr->uncorrected_err_timed};
+  plugin_dispatch_values(&vl);
+
+  return (0);
+}
+
+static int parse_memory_info(FILE *p_file, mcelog_memory_rec_t *memory_record) {
+  char buf[DATA_MAX_NAME_LEN] = {0};
+  while (fgets(buf, sizeof(buf), p_file)) {
+    /* Got empty line or "done" */
+    if ((!strncmp("\n", buf, strlen(buf))) ||
+        (!strncmp(buf, "done\n", strlen(buf))))
+      return (1);
+    if (strlen(buf) < 5)
+      continue;
+    if (!strncmp(buf, MCELOG_SOCKET_STR, strlen(MCELOG_SOCKET_STR))) {
+      sstrncpy(memory_record->location, buf, strlen(buf));
+      /* replace spaces with '_' */
+      for (size_t i = 0; i < strlen(memory_record->location); i++)
+        if (memory_record->location[i] == ' ')
+          memory_record->location[i] = '_';
+      DEBUG(MCELOG_PLUGIN ": Got SOCKET INFO %s", memory_record->location);
+    }
+    if (!strncmp(buf, MCELOG_DIMM_NAME, strlen(MCELOG_DIMM_NAME))) {
+      char *name = NULL;
+      char *saveptr = NULL;
+      name = strtok_r(buf, "\"", &saveptr);
+      if (name != NULL && saveptr != NULL) {
+        name = strtok_r(NULL, "\"", &saveptr);
+        if (name != NULL) {
+          sstrncpy(memory_record->dimm_name, name,
+                   sizeof(memory_record->dimm_name));
+          DEBUG(MCELOG_PLUGIN ": Got DIMM NAME %s", memory_record->dimm_name);
+        }
+      }
+    }
+    if (!strncmp(buf, MCELOG_CORRECTED_ERR, strlen(MCELOG_CORRECTED_ERR))) {
+      /* Get next line*/
+      if (fgets(buf, sizeof(buf), p_file) != NULL) {
+        sscanf(buf, "\t%d total", &(memory_record->corrected_err_total));
+        DEBUG(MCELOG_PLUGIN ": Got corrected error total %d",
+              memory_record->corrected_err_total);
+      }
+      if (fgets(buf, sizeof(buf), p_file) != NULL) {
+        sscanf(buf, "\t%d in %s", &(memory_record->corrected_err_timed),
+               memory_record->corrected_err_timed_period);
+        DEBUG(MCELOG_PLUGIN ": Got timed corrected errors %d in %s",
+              memory_record->corrected_err_total,
+              memory_record->corrected_err_timed_period);
+      }
+    }
+    if (!strncmp(buf, MCELOG_UNCORRECTED_ERR, strlen(MCELOG_UNCORRECTED_ERR))) {
+      if (fgets(buf, sizeof(buf), p_file) != NULL) {
+        sscanf(buf, "\t%d total", &(memory_record->uncorrected_err_total));
+        DEBUG(MCELOG_PLUGIN ": Got uncorrected error total %d",
+              memory_record->uncorrected_err_total);
+      }
+      if (fgets(buf, sizeof(buf), p_file) != NULL) {
+        sscanf(buf, "\t%d in %s", &(memory_record->uncorrected_err_timed),
+               memory_record->uncorrected_err_timed_period);
+        DEBUG(MCELOG_PLUGIN ": Got timed uncorrected errors %d in %s",
+              memory_record->uncorrected_err_total,
+              memory_record->uncorrected_err_timed_period);
+      }
+    }
+    memset(buf, 0, sizeof(buf));
+  }
+  /* parsing definitely finished */
+  return (0);
+}
+
+static void poll_worker_cleanup(void *arg) {
+  mcelog_thread_running = 0;
+  FILE *p_file = *((FILE **)arg);
+  if (p_file != NULL)
+    fclose(p_file);
+  free(arg);
+}
+
+static int socket_receive(socket_adapter_t *self, FILE **pp_file) {
+  int res = -1;
+  pthread_rwlock_rdlock(&self->lock);
+  struct pollfd poll_fd = {
+      .fd = self->sock_fd, .events = POLLIN | POLLPRI,
+  };
+
+  if ((res = poll(&poll_fd, 1, MCELOG_POLL_TIMEOUT)) <= 0) {
+    if (res != 0 && errno != EINTR) {
+      char errbuf[MCELOG_BUFF_SIZE];
+      ERROR("mcelog: poll failed: %s",
+            sstrerror(errno, errbuf, sizeof(errbuf)));
+    }
+    pthread_rwlock_unlock(&self->lock);
+    return (res);
+  }
+
+  if (poll_fd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
+    /* connection is broken */
+    ERROR(MCELOG_PLUGIN ": Connection to socket is broken");
+    if (poll_fd.revents & (POLLERR | POLLHUP)) {
+      mcelog_dispatch_notification(
+          &(notification_t){.severity = NOTIF_FAILURE,
+                            .time = cdtime(),
+                            .message = "Connection to mcelog socket is broken.",
+                            .plugin = MCELOG_PLUGIN,
+                            .type_instance = "mcelog_status"});
+    }
+    pthread_rwlock_unlock(&self->lock);
+    return (-1);
+  }
+
+  if (!(poll_fd.revents & (POLLIN | POLLPRI))) {
+    INFO(MCELOG_PLUGIN ": No data to read");
+    pthread_rwlock_unlock(&self->lock);
+    return (0);
+  }
+
+  if ((*pp_file = fdopen(dup(self->sock_fd), "r")) == NULL)
+    res = -1;
+
+  pthread_rwlock_unlock(&self->lock);
+  return (res);
+}
+
+static void *poll_worker(__attribute__((unused)) void *arg) {
+  char errbuf[MCELOG_BUFF_SIZE];
+  mcelog_thread_running = 1;
+  FILE **pp_file = calloc(1, sizeof(*pp_file));
+  if (pp_file == NULL) {
+    ERROR("mcelog: memory allocation failed: %s",
+          sstrerror(errno, errbuf, sizeof(errbuf)));
+    pthread_exit((void *)1);
+  }
+
+  pthread_cleanup_push(poll_worker_cleanup, pp_file);
+
+  while (1) {
+    /* blocking call */
+    int res = socket_adapter.receive(&socket_adapter, pp_file);
+    if (res < 0) {
+      socket_adapter.close(&socket_adapter);
+      while (socket_adapter.reinit(&socket_adapter) != 0) {
+        nanosleep(&CDTIME_T_TO_TIMESPEC(MS_TO_CDTIME_T(MCELOG_POLL_TIMEOUT)),
+                  NULL);
+      }
+      continue;
+    }
+    /* timeout or no data to read */
+    else if (res == 0)
+      continue;
+
+    if (*pp_file == NULL)
+      continue;
+
+    mcelog_memory_rec_t memory_record = {0};
+    while (parse_memory_info(*pp_file, &memory_record)) {
+      /* Check if location was successfully parsed */
+      if (memory_record.location[0] == '\0') {
+        memset(&memory_record, 0, sizeof(memory_record));
+        continue;
+      }
+
+      notification_t n = {.severity = NOTIF_OKAY,
+                          .time = cdtime(),
+                          .message = "Got memory errors info.",
+                          .plugin = MCELOG_PLUGIN,
+                          .type_instance = "memory_erros"};
+
+      if (mcelog_prepare_notification(&n, &memory_record) == 0)
+        mcelog_dispatch_notification(&n);
+      if (mcelog_submit(&memory_record) != 0)
+        ERROR(MCELOG_PLUGIN ": Failed to submit memory errors");
+      memset(&memory_record, 0, sizeof(memory_record));
+    }
+
+    fclose(*pp_file);
+    *pp_file = NULL;
+  }
+
+  mcelog_thread_running = 0;
+  pthread_cleanup_pop(1);
+  return (NULL);
+}
+
+static int mcelog_init(void) {
+  if (socket_adapter.reinit(&socket_adapter) != 0) {
+    ERROR(MCELOG_PLUGIN ": Cannot connect to client socket");
+    return (-1);
+  }
+
+  if (plugin_thread_create(&g_mcelog_config.tid, NULL, poll_worker, NULL,
+                           NULL) != 0) {
+    ERROR(MCELOG_PLUGIN ": Error creating poll thread.");
+    return (-1);
+  }
+  return (0);
+}
+
+static int get_memory_machine_checks(void) {
+  static const char dump[] = "dump all bios\n";
+  int ret = socket_adapter.write(&socket_adapter, dump, sizeof(dump));
+  if (ret != 0)
+    ERROR(MCELOG_PLUGIN ": SENT DUMP REQUEST FAILED");
+  else
+    DEBUG(MCELOG_PLUGIN ": SENT DUMP REQUEST OK");
+  return (ret);
+}
+
+static int mcelog_read(__attribute__((unused)) user_data_t *ud) {
+  DEBUG(MCELOG_PLUGIN ": %s", __FUNCTION__);
+
+  if (get_memory_machine_checks() != 0)
+    ERROR(MCELOG_PLUGIN ": MACHINE CHECK INFO NOT AVAILABLE");
+
+  return (0);
+}
+
+static int mcelog_shutdown(void) {
+  int ret = 0;
+  if (mcelog_thread_running) {
+    pthread_cancel(g_mcelog_config.tid);
+    if (pthread_join(g_mcelog_config.tid, NULL) != 0) {
+      ERROR(MCELOG_PLUGIN ": Stopping thread failed.");
+      ret = -1;
+    }
+  }
+
+  ret = socket_adapter.close(&socket_adapter) || ret;
+  pthread_rwlock_destroy(&(socket_adapter.lock));
+  return (-ret);
+}
+
+void module_register(void) {
+  plugin_register_complex_config(MCELOG_PLUGIN, mcelog_config);
+  plugin_register_init(MCELOG_PLUGIN, mcelog_init);
+  plugin_register_complex_read(NULL, MCELOG_PLUGIN, mcelog_read, 0, NULL);
+  plugin_register_shutdown(MCELOG_PLUGIN, mcelog_shutdown);
+}
index bebbe40..19228ef 100644 (file)
@@ -479,5 +479,3 @@ void module_register(void) {
   plugin_register_read("memcachec", cmc_read);
   plugin_register_shutdown("memcachec", cmc_shutdown);
 } /* void module_register */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index ab5ffd1..bc99e67 100644 (file)
--- a/src/mic.c
+++ b/src/mic.c
@@ -366,7 +366,3 @@ void module_register(void) {
   plugin_register_read("mic", mic_read);
   plugin_register_config("mic", mic_config, config_keys, config_keys_num);
 } /* void module_register */
-
-/*
- * vim: set shiftwidth=8 softtabstop=8 noet textwidth=78 :
- */
index 5d29791..80a2aca 100644 (file)
@@ -982,5 +982,3 @@ void module_register(void) {
   plugin_register_complex_config("modbus", mb_config);
   plugin_register_shutdown("modbus", mb_shutdown);
 } /* void module_register */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index 315974b..a962514 100644 (file)
@@ -757,5 +757,3 @@ void module_register(void) {
   plugin_register_complex_config("mqtt", mqtt_config);
   plugin_register_init("mqtt", mqtt_init);
 } /* void module_register */
-
-/* vim: set sw=4 sts=4 et fdm=marker : */
index 913e277..93ab3d2 100644 (file)
@@ -27,8 +27,7 @@
 #include "common.h"
 #include "plugin.h"
 
-#if HAVE_TERMIOS_H && HAVE_SYS_IOCTL_H && HAVE_MATH_H
-#include <math.h>
+#if HAVE_TERMIOS_H && HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
 #include <termios.h>
 #else
index 45144bf..13e1db9 100644 (file)
@@ -3109,5 +3109,3 @@ void module_register(void) {
   plugin_register_init("netapp", cna_init);
   plugin_register_shutdown("netapp", cna_shutdown);
 }
-
-/* vim: set sw=2 ts=2 noet fdm=marker : */
index 8076c1f..ddae5f2 100644 (file)
@@ -85,6 +85,11 @@ typedef struct ir_ignorelist_s {
   struct ir_ignorelist_s *next;
 } ir_ignorelist_t;
 
+struct qos_stats {
+  struct gnet_stats_basic *bs;
+  struct gnet_stats_queue *qs;
+};
+
 static int ir_ignorelist_invert = 1;
 static ir_ignorelist_t *ir_ignorelist_head = NULL;
 
@@ -387,20 +392,30 @@ static int link_filter_cb(const struct nlmsghdr *nlh,
 
 #if HAVE_TCA_STATS2
 static int qos_attr_cb(const struct nlattr *attr, void *data) {
-  struct gnet_stats_basic **bs = (struct gnet_stats_basic **)data;
+  struct qos_stats *q_stats = (struct qos_stats *)data;
 
   /* skip unsupported attribute in user-space */
   if (mnl_attr_type_valid(attr, TCA_STATS_MAX) < 0)
     return MNL_CB_OK;
 
   if (mnl_attr_get_type(attr) == TCA_STATS_BASIC) {
-    if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, sizeof(**bs)) < 0) {
+    if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, sizeof(*q_stats->bs)) < 0) {
       ERROR("netlink plugin: qos_attr_cb: TCA_STATS_BASIC mnl_attr_validate2 "
             "failed.");
       return MNL_CB_ERROR;
     }
-    *bs = mnl_attr_get_payload(attr);
-    return MNL_CB_STOP;
+    q_stats->bs = mnl_attr_get_payload(attr);
+    return MNL_CB_OK;
+  }
+
+  if (mnl_attr_get_type(attr) == TCA_STATS_QUEUE) {
+    if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, sizeof(*q_stats->qs)) < 0) {
+      ERROR("netlink plugin: qos_attr_cb: TCA_STATS_QUEUE mnl_attr_validate2 "
+            "failed.");
+      return MNL_CB_ERROR;
+    }
+    q_stats->qs = mnl_attr_get_payload(attr);
+    return MNL_CB_OK;
   }
 
   return MNL_CB_OK;
@@ -492,7 +507,9 @@ static int qos_filter_cb(const struct nlmsghdr *nlh, void *args) {
 
 #if HAVE_TCA_STATS2
   mnl_attr_for_each(attr, nlh, sizeof(*tm)) {
-    struct gnet_stats_basic *bs = NULL;
+    struct qos_stats q_stats;
+
+    memset(&q_stats, 0x0, sizeof(q_stats));
 
     if (mnl_attr_get_type(attr) != TCA_STATS2)
       continue;
@@ -503,9 +520,9 @@ static int qos_filter_cb(const struct nlmsghdr *nlh, void *args) {
       return MNL_CB_ERROR;
     }
 
-    mnl_attr_parse_nested(attr, qos_attr_cb, &bs);
+    mnl_attr_parse_nested(attr, qos_attr_cb, &q_stats);
 
-    if (bs != NULL) {
+    if (q_stats.bs != NULL || q_stats.qs != NULL) {
       char type_instance[DATA_MAX_NAME_LEN];
 
       stats_submitted = 1;
@@ -513,8 +530,13 @@ static int qos_filter_cb(const struct nlmsghdr *nlh, void *args) {
       ssnprintf(type_instance, sizeof(type_instance), "%s-%s", tc_type,
                 tc_inst);
 
-      submit_one(dev, "ipt_bytes", type_instance, bs->bytes);
-      submit_one(dev, "ipt_packets", type_instance, bs->packets);
+      if (q_stats.bs != NULL) {
+        submit_one(dev, "ipt_bytes", type_instance, q_stats.bs->bytes);
+        submit_one(dev, "ipt_packets", type_instance, q_stats.bs->packets);
+      }
+      if (q_stats.qs != NULL) {
+        submit_one(dev, "if_tx_dropped", type_instance, q_stats.qs->drops);
+      }
     }
 
     break;
@@ -736,7 +758,3 @@ void module_register(void) {
   plugin_register_read("netlink", ir_read);
   plugin_register_shutdown("netlink", ir_shutdown);
 } /* void module_register */
-
-/*
- * vim: set shiftwidth=2 softtabstop=2 tabstop=8 :
- */
index 8eab08b..e1214cf 100644 (file)
@@ -51,7 +51,7 @@
 #include <net/if.h>
 #endif
 
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
 #if defined __APPLE__
 /* default xcode compiler throws warnings even when deprecated functionality
  * is not used. -Werror breaks the build because of erroneous warnings.
@@ -96,7 +96,7 @@ GCRY_THREAD_OPTION_PTHREAD_IMPL;
  * Private data types
  */
 #define SECURITY_LEVEL_NONE 0
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
 #define SECURITY_LEVEL_SIGN 1
 #define SECURITY_LEVEL_ENCRYPT 2
 #endif
@@ -104,7 +104,7 @@ struct sockent_client {
   int fd;
   struct sockaddr_storage *addr;
   socklen_t addrlen;
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
   int security_level;
   char *username;
   char *password;
@@ -118,7 +118,7 @@ struct sockent_client {
 struct sockent_server {
   int *fd;
   size_t fd_num;
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
   int security_level;
   char *auth_file;
   fbhash_t *userdb;
@@ -468,7 +468,7 @@ static int network_dispatch_notification(notification_t *n) /* {{{ */
   return (status);
 } /* }}} int network_dispatch_notification */
 
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
 static int network_init_gcrypt(void) /* {{{ */
 {
   gcry_error_t err;
@@ -570,7 +570,7 @@ static gcry_cipher_hd_t network_get_aes256_cypher(sockent_t *se, /* {{{ */
 
   return (*cyper_ptr);
 } /* }}} int network_get_aes256_cypher */
-#endif /* HAVE_LIBGCRYPT */
+#endif /* HAVE_GCRYPT_H */
 
 static int write_part_values(char **ret_buffer, size_t *ret_buffer_len,
                              const data_set_t *ds, const value_list_t *vl) {
@@ -978,7 +978,7 @@ static int parse_packet(sockent_t *se, void *buffer, size_t buffer_size,
     buffer_offset += (s);                                                      \
   } while (0)
 
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
 static int parse_part_sign_sha256(sockent_t *se, /* {{{ */
                                   void **ret_buffer, size_t *ret_buffer_len,
                                   int flags) {
@@ -1103,9 +1103,9 @@ static int parse_part_sign_sha256(sockent_t *se, /* {{{ */
 
   return (0);
 } /* }}} int parse_part_sign_sha256 */
-/* #endif HAVE_LIBGCRYPT */
+/* #endif HAVE_GCRYPT_H */
 
-#else  /* if !HAVE_LIBGCRYPT */
+#else  /* if !HAVE_GCRYPT_H */
 static int parse_part_sign_sha256(sockent_t *se, /* {{{ */
                                   void **ret_buffer, size_t *ret_buffer_size,
                                   int flags) {
@@ -1147,9 +1147,9 @@ static int parse_part_sign_sha256(sockent_t *se, /* {{{ */
 
   return (0);
 } /* }}} int parse_part_sign_sha256 */
-#endif /* !HAVE_LIBGCRYPT */
+#endif /* !HAVE_GCRYPT_H */
 
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
 static int parse_part_encr_aes256(sockent_t *se, /* {{{ */
                                   void **ret_buffer, size_t *ret_buffer_len,
                                   int flags) {
@@ -1260,9 +1260,9 @@ static int parse_part_encr_aes256(sockent_t *se, /* {{{ */
 
   return (0);
 } /* }}} int parse_part_encr_aes256 */
-/* #endif HAVE_LIBGCRYPT */
+/* #endif HAVE_GCRYPT_H */
 
-#else  /* if !HAVE_LIBGCRYPT */
+#else  /* if !HAVE_GCRYPT_H */
 static int parse_part_encr_aes256(sockent_t *se, /* {{{ */
                                   void **ret_buffer, size_t *ret_buffer_size,
                                   int flags) {
@@ -1304,7 +1304,7 @@ static int parse_part_encr_aes256(sockent_t *se, /* {{{ */
 
   return (0);
 } /* }}} int parse_part_encr_aes256 */
-#endif /* !HAVE_LIBGCRYPT */
+#endif /* !HAVE_GCRYPT_H */
 
 #undef BUFFER_READ
 
@@ -1316,11 +1316,11 @@ static int parse_packet(sockent_t *se, /* {{{ */
   value_list_t vl = VALUE_LIST_INIT;
   notification_t n = {0};
 
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
   int packet_was_signed = (flags & PP_SIGNED);
   int packet_was_encrypted = (flags & PP_ENCRYPTED);
   int printed_ignore_warning = 0;
-#endif /* HAVE_LIBGCRYPT */
+#endif /* HAVE_GCRYPT_H */
 
   memset(&vl, '\0', sizeof(vl));
   status = 0;
@@ -1353,7 +1353,7 @@ static int parse_packet(sockent_t *se, /* {{{ */
         break;
       }
     }
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
     else if ((se->data.server.security_level == SECURITY_LEVEL_ENCRYPT) &&
              (packet_was_encrypted == 0)) {
       if (printed_ignore_warning == 0) {
@@ -1365,7 +1365,7 @@ static int parse_packet(sockent_t *se, /* {{{ */
       buffer_size -= (size_t)pkg_length;
       continue;
     }
-#endif /* HAVE_LIBGCRYPT */
+#endif /* HAVE_GCRYPT_H */
     else if (pkg_type == TYPE_SIGN_SHA256) {
       status = parse_part_sign_sha256(se, &buffer, &buffer_size, flags);
       if (status != 0) {
@@ -1376,7 +1376,7 @@ static int parse_packet(sockent_t *se, /* {{{ */
         break;
       }
     }
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
     else if ((se->data.server.security_level == SECURITY_LEVEL_SIGN) &&
              (packet_was_encrypted == 0) && (packet_was_signed == 0)) {
       if (printed_ignore_warning == 0) {
@@ -1388,7 +1388,7 @@ static int parse_packet(sockent_t *se, /* {{{ */
       buffer_size -= (size_t)pkg_length;
       continue;
     }
-#endif /* HAVE_LIBGCRYPT */
+#endif /* HAVE_GCRYPT_H */
     else if (pkg_type == TYPE_VALUES) {
       status =
           parse_part_values(&buffer, &buffer_size, &vl.values, &vl.values_len);
@@ -1499,7 +1499,7 @@ static void free_sockent_client(struct sockent_client *sec) /* {{{ */
     sec->fd = -1;
   }
   sfree(sec->addr);
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
   sfree(sec->username);
   sfree(sec->password);
   if (sec->cypher != NULL)
@@ -1517,7 +1517,7 @@ static void free_sockent_server(struct sockent_server *ses) /* {{{ */
   }
 
   sfree(ses->fd);
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
   sfree(ses->auth_file);
   fbh_destroy(ses->userdb);
   if (ses->cypher != NULL)
@@ -1846,7 +1846,7 @@ static sockent_t *sockent_create(int type) /* {{{ */
   if (type == SOCKENT_TYPE_SERVER) {
     se->data.server.fd = NULL;
     se->data.server.fd_num = 0;
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
     se->data.server.security_level = SECURITY_LEVEL_NONE;
     se->data.server.auth_file = NULL;
     se->data.server.userdb = NULL;
@@ -1857,7 +1857,7 @@ static sockent_t *sockent_create(int type) /* {{{ */
     se->data.client.addr = NULL;
     se->data.client.resolve_interval = 0;
     se->data.client.next_resolve_reconnect = 0;
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
     se->data.client.security_level = SECURITY_LEVEL_NONE;
     se->data.client.username = NULL;
     se->data.client.password = NULL;
@@ -1870,7 +1870,7 @@ static sockent_t *sockent_create(int type) /* {{{ */
 
 static int sockent_init_crypto(sockent_t *se) /* {{{ */
 {
-#if HAVE_LIBGCRYPT /* {{{ */
+#if HAVE_GCRYPT_H /* {{{ */
   if (se->type == SOCKENT_TYPE_CLIENT) {
     if (se->data.client.security_level > SECURITY_LEVEL_NONE) {
       if (network_init_gcrypt() < 0) {
@@ -1913,7 +1913,7 @@ static int sockent_init_crypto(sockent_t *se) /* {{{ */
       }
     }
   }
-#endif /* }}} HAVE_LIBGCRYPT */
+#endif /* }}} HAVE_GCRYPT_H */
 
   return (0);
 } /* }}} int sockent_init_crypto */
@@ -2375,7 +2375,7 @@ static void network_send_buffer_plain(sockent_t *se, /* {{{ */
   } /* while (42) */
 } /* }}} void network_send_buffer_plain */
 
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
 #define BUFFER_ADD(p, s)                                                       \
   do {                                                                         \
     memcpy(buffer + buffer_offset, (p), (s));                                  \
@@ -2525,20 +2525,20 @@ static void network_send_buffer_encrypted(sockent_t *se, /* {{{ */
   network_send_buffer_plain(se, buffer, buffer_size);
 } /* }}} void network_send_buffer_encrypted */
 #undef BUFFER_ADD
-#endif /* HAVE_LIBGCRYPT */
+#endif /* HAVE_GCRYPT_H */
 
 static void network_send_buffer(char *buffer, size_t buffer_len) /* {{{ */
 {
   DEBUG("network plugin: network_send_buffer: buffer_len = %zu", buffer_len);
 
   for (sockent_t *se = sending_sockets; se != NULL; se = se->next) {
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
     if (se->data.client.security_level == SECURITY_LEVEL_ENCRYPT)
       network_send_buffer_encrypted(se, buffer, buffer_len);
     else if (se->data.client.security_level == SECURITY_LEVEL_SIGN)
       network_send_buffer_signed(se, buffer, buffer_len);
     else /* if (se->data.client.security_level == SECURITY_LEVEL_NONE) */
-#endif   /* HAVE_LIBGCRYPT */
+#endif   /* HAVE_GCRYPT_H */
       network_send_buffer_plain(se, buffer, buffer_len);
   } /* for (sending_sockets) */
 } /* }}} void network_send_buffer */
@@ -2731,7 +2731,7 @@ static int network_config_set_buffer_size(const oconfig_item_t *ci) /* {{{ */
   return (0);
 } /* }}} int network_config_set_buffer_size */
 
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
 static int network_config_set_security_level(oconfig_item_t *ci, /* {{{ */
                                              int *retval) {
   char *str;
@@ -2755,7 +2755,7 @@ static int network_config_set_security_level(oconfig_item_t *ci, /* {{{ */
 
   return (0);
 } /* }}} int network_config_set_security_level */
-#endif /* HAVE_LIBGCRYPT */
+#endif /* HAVE_GCRYPT_H */
 
 static int network_config_add_listen(const oconfig_item_t *ci) /* {{{ */
 {
@@ -2784,13 +2784,13 @@ static int network_config_add_listen(const oconfig_item_t *ci) /* {{{ */
   for (int i = 0; i < ci->children_num; i++) {
     oconfig_item_t *child = ci->children + i;
 
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
     if (strcasecmp("AuthFile", child->key) == 0)
       cf_util_get_string(child, &se->data.server.auth_file);
     else if (strcasecmp("SecurityLevel", child->key) == 0)
       network_config_set_security_level(child, &se->data.server.security_level);
     else
-#endif /* HAVE_LIBGCRYPT */
+#endif /* HAVE_GCRYPT_H */
         if (strcasecmp("Interface", child->key) == 0)
       network_config_set_interface(child, &se->interface);
     else {
@@ -2798,7 +2798,7 @@ static int network_config_add_listen(const oconfig_item_t *ci) /* {{{ */
     }
   }
 
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
   if ((se->data.server.security_level > SECURITY_LEVEL_NONE) &&
       (se->data.server.auth_file == NULL)) {
     ERROR("network plugin: A security level higher than `none' was "
@@ -2807,7 +2807,7 @@ static int network_config_add_listen(const oconfig_item_t *ci) /* {{{ */
     sockent_destroy(se);
     return (-1);
   }
-#endif /* HAVE_LIBGCRYPT */
+#endif /* HAVE_GCRYPT_H */
 
   status = sockent_init_crypto(se);
   if (status != 0) {
@@ -2862,7 +2862,7 @@ static int network_config_add_server(const oconfig_item_t *ci) /* {{{ */
   for (int i = 0; i < ci->children_num; i++) {
     oconfig_item_t *child = ci->children + i;
 
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
     if (strcasecmp("Username", child->key) == 0)
       cf_util_get_string(child, &se->data.client.username);
     else if (strcasecmp("Password", child->key) == 0)
@@ -2870,7 +2870,7 @@ static int network_config_add_server(const oconfig_item_t *ci) /* {{{ */
     else if (strcasecmp("SecurityLevel", child->key) == 0)
       network_config_set_security_level(child, &se->data.client.security_level);
     else
-#endif /* HAVE_LIBGCRYPT */
+#endif /* HAVE_GCRYPT_H */
         if (strcasecmp("Interface", child->key) == 0)
       network_config_set_interface(child, &se->interface);
     else if (strcasecmp("ResolveInterval", child->key) == 0)
@@ -2880,7 +2880,7 @@ static int network_config_add_server(const oconfig_item_t *ci) /* {{{ */
     }
   }
 
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
   if ((se->data.client.security_level > SECURITY_LEVEL_NONE) &&
       ((se->data.client.username == NULL) ||
        (se->data.client.password == NULL))) {
@@ -2890,7 +2890,7 @@ static int network_config_add_server(const oconfig_item_t *ci) /* {{{ */
     sockent_destroy(se);
     return (-1);
   }
-#endif /* HAVE_LIBGCRYPT */
+#endif /* HAVE_GCRYPT_H */
 
   status = sockent_init_crypto(se);
   if (status != 0) {
@@ -3223,5 +3223,3 @@ void module_register(void) {
   plugin_register_flush("network", network_flush,
                         /* user_data = */ NULL);
 } /* void module_register */
-
-/* vim: set fdm=marker : */
index ffc545c..72c0363 100644 (file)
@@ -267,7 +267,3 @@ void module_register(void) {
   plugin_register_init("nginx", init);
   plugin_register_read("nginx", nginx_read);
 } /* void module_register */
-
-/*
- * vim: set shiftwidth=2 softtabstop=2 tabstop=8 :
- */
index 4840441..d167fbf 100644 (file)
@@ -166,5 +166,3 @@ void module_register(void) {
   plugin_register_init("notify_desktop", c_notify_init);
   return;
 } /* module_register */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
index f42e66c..aaa165a 100644 (file)
@@ -290,5 +290,3 @@ void module_register(void) {
   plugin_register_notification("notify_email", notify_email_notification,
                                /* user_data = */ NULL);
 } /* void module_register (void) */
-
-/* vim: set sw=2 sts=2 ts=8 et : */
index 1351691..c95f7cb 100644 (file)
@@ -153,5 +153,3 @@ void module_register(void) {
   plugin_register_complex_config("notify_nagios", nagios_config);
   plugin_register_notification("notify_nagios", nagios_notify, NULL);
 } /* void module_register (void) */
-
-/* vim: set sw=2 sts=2 ts=8 et : */
index 1dc1857..21b65f5 100644 (file)
@@ -32,9 +32,6 @@
 #include "common.h"
 #include "plugin.h"
 
-#if HAVE_STDINT_H
-#include <stdint.h>
-#endif
 #if HAVE_NETDB_H
 #include <netdb.h>
 #endif
index 049daee..01d74e1 100644 (file)
@@ -152,5 +152,3 @@ void module_register(void) {
   plugin_register_init("numa", numa_init);
   plugin_register_read("numa", numa_read);
 } /* void module_register */
-
-/* vim: set sw=2 sts=2 et : */
index d40e095..5acbdde 100644 (file)
--- a/src/nut.c
+++ b/src/nut.c
@@ -54,8 +54,11 @@ static nut_ups_t *upslist_head = NULL;
 static pthread_mutex_t read_lock = PTHREAD_MUTEX_INITIALIZER;
 static int read_busy = 0;
 
-static const char *config_keys[] = {"UPS"};
+static const char *config_keys[] = {"UPS", "FORCESSL", "VERIFYPEER", "CAPATH"};
 static int config_keys_num = STATIC_ARRAY_SIZE(config_keys);
+static int force_ssl = 0;   // Initialized to default of 0 (false)
+static int verify_peer = 0; // Initialized to default of 0 (false)
+static char *ca_path = NULL;
 
 static void free_nut_ups_t(nut_ups_t *ups) {
   if (ups->conn != NULL) {
@@ -98,9 +101,51 @@ static int nut_add_ups(const char *name) {
   return (0);
 } /* int nut_add_ups */
 
+static int nut_force_ssl(const char *value) {
+  if (strcasecmp(value, "true") == 0)
+    force_ssl = 1;
+  else if (strcasecmp(value, "false") == 0)
+    force_ssl = 0; // Should already be set to 0 from initialization
+  else {
+    force_ssl = 0;
+    WARNING("nut plugin: nut_force_ssl: invalid FORCESSL value "
+            "found. Defaulting to false.");
+  }
+  return (0);
+} /* int nut_parse_force_ssl */
+
+static int nut_verify_peer(const char *value) {
+  if (strcasecmp(value, "true") == 0)
+    verify_peer = 1;
+  else if (strcasecmp(value, "false") == 0)
+    verify_peer = 0; // Should already be set to 0 from initialization
+  else {
+    verify_peer = 0;
+    WARNING("nut plugin: nut_verify_peer: invalid VERIFYPEER value "
+            "found. Defaulting to false.");
+  }
+  return (0);
+} /* int nut_verify_peer */
+
+static int nut_ca_path(const char *value) {
+  if (value != NULL && strcmp(value, "") != 0) {
+    ca_path = malloc(strlen(value) + 1);
+    strncpy(ca_path, value, (strlen(value) + 1));
+  } else {
+    ca_path = NULL; // Should alread be set to NULL from initialization
+  }
+  return (0);
+} /* int nut_ca_path */
+
 static int nut_config(const char *key, const char *value) {
   if (strcasecmp(key, "UPS") == 0)
     return (nut_add_ups(value));
+  else if (strcasecmp(key, "FORCESSL") == 0)
+    return (nut_force_ssl(value));
+  else if (strcasecmp(key, "VERIFYPEER") == 0)
+    return (nut_verify_peer(value));
+  else if (strcasecmp(key, "CAPATH") == 0)
+    return (nut_ca_path(value));
   else
     return (-1);
 } /* int nut_config */
@@ -123,6 +168,119 @@ static void nut_submit(nut_ups_t *ups, const char *type,
   plugin_dispatch_values(&vl);
 } /* void nut_submit */
 
+static int nut_connect(nut_ups_t *ups) {
+#ifdef WITH_UPSCLIENT_27
+  int status;
+  int ssl_status;
+  int ssl_flags;
+
+  if (verify_peer == 1 && force_ssl == 0) {
+    WARNING("nut plugin: nut_connect: VerifyPeer true but ForceSSL "
+            "false. Setting ForceSSL to true.");
+    force_ssl = 1;
+  }
+
+  if (verify_peer == 1 && ca_path == NULL) {
+    ERROR("nut plugin: nut_connect: VerifyPeer true but missing "
+          "CAPath value.");
+    return (-1);
+  }
+
+  if (verify_peer == 1) {
+    status = upscli_init(verify_peer, ca_path, NULL, NULL);
+
+    if (status != 1) {
+      ERROR("nut plugin: nut_connect: upscli_init (%i, %s) failed: %s",
+            verify_peer, ca_path, upscli_strerror(ups->conn));
+      upscli_cleanup();
+      return (-1);
+    }
+  } /* if (verify_peer == 1) */
+
+  if (verify_peer == 1)
+    ssl_flags = (UPSCLI_CONN_REQSSL | UPSCLI_CONN_CERTVERIF);
+  else if (force_ssl == 1)
+    ssl_flags = UPSCLI_CONN_REQSSL;
+  else
+    ssl_flags = UPSCLI_CONN_TRYSSL;
+
+  status = upscli_connect(ups->conn, ups->hostname, ups->port, ssl_flags);
+
+  if (status != 0) {
+    ERROR("nut plugin: nut_connect: upscli_connect (%s, %i) failed: %s",
+          ups->hostname, ups->port, upscli_strerror(ups->conn));
+    sfree(ups->conn);
+    upscli_cleanup();
+    return (-1);
+  } /* if (status != 0) */
+
+  INFO("nut plugin: Connection to (%s, %i) established.", ups->hostname,
+       ups->port);
+
+  // Output INFO or WARNING based on SSL and VERIFICATION
+  ssl_status = upscli_ssl(ups->conn); // 1 for SSL, 0 for not, -1 for error
+  if (ssl_status == 1 && verify_peer == 1) {
+    INFO("nut plugin: Connection is secured with SSL and certificate "
+         "has been verified.");
+  } else if (ssl_status == 1) {
+    INFO("nut plugin: Connection is secured with SSL with no verification "
+         "of server SSL certificate.");
+  } else if (ssl_status == 0) {
+    WARNING("nut plugin: Connection is unsecured (no SSL).");
+  } else {
+    ERROR("nut plugin: nut_connect: upscli_ssl failed: %s",
+          upscli_strerror(ups->conn));
+    sfree(ups->conn);
+    upscli_cleanup();
+    return (-1);
+  } /* if (ssl_status == 1 && verify_peer == 1) */
+  return (0);
+
+#else /* #ifdef WITH_UPSCLIENT_27 */
+  int status;
+  int ssl_status;
+  int ssl_flags;
+
+  if (verify_peer == 1 || ca_path != NULL) {
+    WARNING("nut plugin: nut_connect: Dependency libupsclient version "
+            "insufficient (<2.7) for VerifyPeer support. Ignoring VerifyPeer "
+            "and CAPath.");
+  }
+
+  if (force_ssl == 1)
+    ssl_flags = UPSCLI_CONN_REQSSL;
+  else
+    ssl_flags = UPSCLI_CONN_TRYSSL;
+
+  status = upscli_connect(ups->conn, ups->hostname, ups->port, ssl_flags);
+
+  if (status != 0) {
+    ERROR("nut plugin: nut_connect: upscli_connect (%s, %i) failed: %s",
+          ups->hostname, ups->port, upscli_strerror(ups->conn));
+    sfree(ups->conn);
+    return (-1);
+  } /* if (status != 0) */
+
+  INFO("nut plugin: Connection to (%s, %i) established.", ups->hostname,
+       ups->port);
+
+  // Output INFO or WARNING based on SSL
+  ssl_status = upscli_ssl(ups->conn); // 1 for SSL, 0 for not, -1 for error
+  if (ssl_status == 1) {
+    INFO("nut plugin: Connection is secured with SSL with no verification "
+         "of server SSL certificate.");
+  } else if (ssl_status == 0) {
+    WARNING("nut plugin: Connection is unsecured (no SSL).");
+  } else {
+    ERROR("nut plugin: nut_connect: upscli_ssl failed: %s",
+          upscli_strerror(ups->conn));
+    sfree(ups->conn);
+    return (-1);
+  } /* if (ssl_status == 1 && verify_peer == 1) */
+  return (0);
+#endif
+}
+
 static int nut_read_one(nut_ups_t *ups) {
   const char *query[3] = {"VAR", ups->upsname, NULL};
   unsigned int query_num = 2;
@@ -138,17 +296,10 @@ static int nut_read_one(nut_ups_t *ups) {
       return (-1);
     }
 
-    status =
-        upscli_connect(ups->conn, ups->hostname, ups->port, UPSCLI_CONN_TRYSSL);
-    if (status != 0) {
-      ERROR("nut plugin: nut_read_one: upscli_connect (%s, %i) failed: %s",
-            ups->hostname, ups->port, upscli_strerror(ups->conn));
-      sfree(ups->conn);
-      return (-1);
-    }
+    status = nut_connect(ups);
+    if (status == -1)
+      return -1;
 
-    INFO("nut plugin: Connection to (%s, %i) established.", ups->hostname,
-         ups->port);
   } /* if (ups->conn == NULL) */
 
   /* nut plugin: nut_read_one: upscli_list_start (adpos) failed: Protocol
@@ -159,6 +310,9 @@ static int nut_read_one(nut_ups_t *ups) {
           ups->upsname, upscli_strerror(ups->conn));
     upscli_disconnect(ups->conn);
     sfree(ups->conn);
+#ifdef WITH_UPSCLIENT_27
+    upscli_cleanup();
+#endif
     return (-1);
   }
 
@@ -246,6 +400,9 @@ static int nut_shutdown(void) {
     free_nut_ups_t(this);
     this = next;
   }
+#ifdef WITH_UPSCLIENT_27
+  upscli_cleanup();
+#endif
 
   return (0);
 } /* int nut_shutdown */
@@ -255,5 +412,3 @@ void module_register(void) {
   plugin_register_read("nut", nut_read);
   plugin_register_shutdown("nut", nut_shutdown);
 } /* void module_register */
-
-/* vim: set sw=2 ts=8 sts=2 tw=78 : */
index d1caf46..816a70b 100644 (file)
@@ -631,5 +631,3 @@ void module_register(void) {
   plugin_register_read("olsrd", olsrd_read);
   plugin_register_shutdown("olsrd", olsrd_shutdown);
 } /* void module_register */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index 10fa5ca..407e857 100644 (file)
@@ -534,5 +534,3 @@ void module_register(void) {
   plugin_register_config("onewire", cow_load_config, config_keys,
                          config_keys_num);
 }
-
-/* vim: set sw=2 sts=2 ts=8 et fdm=marker cindent : */
index 90694b7..1045d50 100644 (file)
@@ -715,5 +715,3 @@ void module_register(void) {
                          config_keys_num);
   plugin_register_init("openvpn", openvpn_init);
 } /* void module_register */
-
-/* vim: set sw=2 ts=2 : */
index 4eacc54..b52ea4e 100644 (file)
@@ -706,7 +706,3 @@ void module_register(void) /* {{{ */
   plugin_register_read("oracle", o_read);
   plugin_register_shutdown("oracle", o_shutdown);
 } /* }}} void module_register */
-
-/*
- * vim: shiftwidth=2 softtabstop=2 et fdm=marker
- */
diff --git a/src/ovs_events.c b/src/ovs_events.c
new file mode 100644 (file)
index 0000000..8c2cd12
--- /dev/null
@@ -0,0 +1,657 @@
+/**
+ * collectd - src/ovs_events.c
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *   Volodymyr Mytnyk <volodymyrx.mytnyk@intel.com>
+ **/
+
+#include "collectd.h"
+
+#include "common.h" /* auxiliary functions */
+
+#include "utils_ovs.h" /* OVS helpers */
+
+#define OVS_EVENTS_IFACE_NAME_SIZE 128
+#define OVS_EVENTS_IFACE_UUID_SIZE 64
+#define OVS_EVENTS_EXT_IFACE_ID_SIZE 64
+#define OVS_EVENTS_EXT_VM_UUID_SIZE 64
+#define OVS_EVENTS_PLUGIN "ovs_events"
+#define OVS_EVENTS_CTX_LOCK                                                    \
+  for (int __i = ovs_events_ctx_lock(); __i != 0; __i = ovs_events_ctx_unlock())
+
+/* Link status type */
+enum ovs_events_link_status_e { DOWN, UP };
+typedef enum ovs_events_link_status_e ovs_events_link_status_t;
+
+/* Interface info */
+struct ovs_events_iface_info_s {
+  char name[OVS_EVENTS_IFACE_NAME_SIZE];           /* interface name */
+  char uuid[OVS_EVENTS_IFACE_UUID_SIZE];           /* interface UUID */
+  char ext_iface_id[OVS_EVENTS_EXT_IFACE_ID_SIZE]; /* external interface id */
+  char ext_vm_uuid[OVS_EVENTS_EXT_VM_UUID_SIZE];   /* external VM UUID */
+  ovs_events_link_status_t link_status;            /* interface link status */
+  struct ovs_events_iface_info_s *next;            /* next interface info */
+};
+typedef struct ovs_events_iface_info_s ovs_events_iface_info_t;
+
+/* Interface list */
+struct ovs_events_iface_list_s {
+  char name[OVS_EVENTS_IFACE_NAME_SIZE]; /* interface name */
+  struct ovs_events_iface_list_s *next;  /* next interface info */
+};
+typedef struct ovs_events_iface_list_s ovs_events_iface_list_t;
+
+/* OVS events configuration data */
+struct ovs_events_config_s {
+  _Bool send_notification;                 /* sent notification to collectd? */
+  char ovs_db_node[OVS_DB_ADDR_NODE_SIZE]; /* OVS DB node */
+  char ovs_db_serv[OVS_DB_ADDR_SERVICE_SIZE]; /* OVS DB service */
+  char ovs_db_unix[OVS_DB_ADDR_UNIX_SIZE];    /* OVS DB unix socket path */
+  ovs_events_iface_list_t *ifaces;            /* interface info */
+};
+typedef struct ovs_events_config_s ovs_events_config_t;
+
+/* OVS events context type */
+struct ovs_events_ctx_s {
+  pthread_mutex_t mutex;      /* mutex to lock the context */
+  ovs_db_t *ovs_db;           /* pointer to OVS DB instance */
+  ovs_events_config_t config; /* plugin config */
+  char *ovs_db_select_params; /* OVS DB select parameter request */
+  _Bool is_db_available;      /* specify whether OVS DB is available */
+};
+typedef struct ovs_events_ctx_s ovs_events_ctx_t;
+
+/*
+ * Private variables
+ */
+static ovs_events_ctx_t ovs_events_ctx = {
+    .mutex = PTHREAD_MUTEX_INITIALIZER,
+    .config = {.ovs_db_node = "localhost", /* use default OVS DB node */
+               .ovs_db_serv = "6640"}      /* use default OVS DB service */
+};
+
+/* Forward declaration */
+static int ovs_events_plugin_read(user_data_t *u);
+
+/* This function is used only by "OVS_EVENTS_CTX_LOCK" define (see above).
+ * It always returns 1 when context is locked.
+ */
+static int ovs_events_ctx_lock() {
+  pthread_mutex_lock(&ovs_events_ctx.mutex);
+  return (1);
+}
+
+/* This function is used only by "OVS_EVENTS_CTX_LOCK" define (see above).
+ * It always returns 0 when context is unlocked.
+ */
+static int ovs_events_ctx_unlock() {
+  pthread_mutex_unlock(&ovs_events_ctx.mutex);
+  return (0);
+}
+
+/* Check if given interface name exists in configuration file. It
+ * returns 1 if exists otherwise 0. If no interfaces are configured,
+ * -1 is returned
+ */
+static int ovs_events_config_iface_exists(const char *ifname) {
+  if (ovs_events_ctx.config.ifaces == NULL)
+    return (-1);
+
+  /* check if given interface exists */
+  for (ovs_events_iface_list_t *iface = ovs_events_ctx.config.ifaces; iface;
+       iface = iface->next)
+    if (strcmp(ifname, iface->name) == 0)
+      return (1);
+
+  return (0);
+}
+
+/* Get OVS DB select parameter request based on rfc7047,
+ * "Transact" & "Select" section
+ */
+static char *ovs_events_get_select_params() {
+  size_t buff_size = 0;
+  size_t buff_off = 0;
+  char *opt_buff = NULL;
+  static const char params_fmt[] = "[\"Open_vSwitch\"%s]";
+  static const char option_fmt[] =
+      ",{\"op\":\"select\",\"table\":\"Interface\","
+      "\"where\":[[\"name\",\"==\",\"%s\"]],"
+      "\"columns\":[\"link_state\",\"external_ids\","
+      "\"name\",\"_uuid\"]}";
+  static const char default_opt[] =
+      ",{\"op\":\"select\",\"table\":\"Interface\","
+      "\"where\":[],\"columns\":[\"link_state\","
+      "\"external_ids\",\"name\",\"_uuid\"]}";
+  /* setup OVS DB interface condition */
+  for (ovs_events_iface_list_t *iface = ovs_events_ctx.config.ifaces; iface;
+       iface = iface->next) {
+    /* allocate new buffer (format size + ifname len is good enough) */
+    buff_size += sizeof(option_fmt) + strlen(iface->name);
+    char *new_buff = realloc(opt_buff, buff_size);
+    if (new_buff == NULL) {
+      sfree(opt_buff);
+      return NULL;
+    }
+    opt_buff = new_buff;
+    int ret = ssnprintf(opt_buff + buff_off, buff_size - buff_off, option_fmt,
+                        iface->name);
+    if (ret < 0) {
+      sfree(opt_buff);
+      return NULL;
+    }
+    buff_off += ret;
+  }
+  /* if no interfaces are configured, use default params */
+  if (opt_buff == NULL)
+    if ((opt_buff = strdup(default_opt)) == NULL)
+      return NULL;
+
+  /* allocate memory for OVS DB select params */
+  size_t params_size = sizeof(params_fmt) + strlen(opt_buff);
+  char *params_buff = calloc(1, params_size);
+  if (params_buff == NULL) {
+    sfree(opt_buff);
+    return NULL;
+  }
+
+  /* create OVS DB select params */
+  if (ssnprintf(params_buff, params_size, params_fmt, opt_buff) < 0)
+    sfree(params_buff);
+
+  sfree(opt_buff);
+  return params_buff;
+}
+
+/* Release memory allocated for configuration data */
+static void ovs_events_config_free() {
+  ovs_events_iface_list_t *del_iface = NULL;
+  sfree(ovs_events_ctx.ovs_db_select_params);
+  while (ovs_events_ctx.config.ifaces) {
+    del_iface = ovs_events_ctx.config.ifaces;
+    ovs_events_ctx.config.ifaces = ovs_events_ctx.config.ifaces->next;
+    sfree(del_iface);
+  }
+}
+
+/* Parse/process "Interfaces" configuration option. Returns 0 if success
+ * otherwise -1 (error)
+ */
+static int ovs_events_config_get_interfaces(const oconfig_item_t *ci) {
+  for (int j = 0; j < ci->values_num; j++) {
+    /* check interface name type */
+    if (ci->values[j].type != OCONFIG_TYPE_STRING) {
+      ERROR(OVS_EVENTS_PLUGIN
+            ": given interface name is not a string [idx=%d]", j);
+      return (-1);
+    }
+    /* allocate memory for configured interface */
+    ovs_events_iface_list_t *new_iface = calloc(1, sizeof(*new_iface));
+    if (new_iface == NULL) {
+      ERROR(OVS_EVENTS_PLUGIN ": calloc () copy interface name fail");
+      return (-1);
+    } else {
+      /* store interface name */
+      sstrncpy(new_iface->name, ci->values[j].value.string,
+               sizeof(new_iface->name));
+      new_iface->next = ovs_events_ctx.config.ifaces;
+      ovs_events_ctx.config.ifaces = new_iface;
+      DEBUG(OVS_EVENTS_PLUGIN ": found monitored interface \"%s\"",
+            new_iface->name);
+    }
+  }
+  return (0);
+}
+
+/* Parse plugin configuration file and store the config
+ * in allocated memory. Returns negative value in case of error.
+ */
+static int ovs_events_plugin_config(oconfig_item_t *ci) {
+  _Bool dispatch_values = 1;
+  for (int i = 0; i < ci->children_num; i++) {
+    oconfig_item_t *child = ci->children + i;
+    if (strcasecmp("SendNotification", child->key) == 0) {
+      if (cf_util_get_boolean(child,
+                              &ovs_events_ctx.config.send_notification) != 0) {
+        ovs_events_config_free();
+        return (-1);
+      }
+    } else if (strcasecmp("Address", child->key) == 0) {
+      if (cf_util_get_string_buffer(
+              child, ovs_events_ctx.config.ovs_db_node,
+              sizeof(ovs_events_ctx.config.ovs_db_node)) != 0) {
+        ovs_events_config_free();
+        return (-1);
+      }
+    } else if (strcasecmp("Port", child->key) == 0) {
+      char *service = NULL;
+      if (cf_util_get_service(child, &service) != 0) {
+        ovs_events_config_free();
+        return (-1);
+      }
+      strncpy(ovs_events_ctx.config.ovs_db_serv, service,
+              sizeof(ovs_events_ctx.config.ovs_db_serv));
+      sfree(service);
+    } else if (strcasecmp("Socket", child->key) == 0) {
+      if (cf_util_get_string_buffer(
+              child, ovs_events_ctx.config.ovs_db_unix,
+              sizeof(ovs_events_ctx.config.ovs_db_unix)) != 0) {
+        ovs_events_config_free();
+        return (-1);
+      }
+    } else if (strcasecmp("Interfaces", child->key) == 0) {
+      if (ovs_events_config_get_interfaces(child) != 0) {
+        ovs_events_config_free();
+        return (-1);
+      }
+    } else if (strcasecmp("DispatchValues", child->key) == 0) {
+      if (cf_util_get_boolean(child, &dispatch_values) != 0) {
+        ovs_events_config_free();
+        return (-1);
+      }
+    } else {
+      ERROR(OVS_EVENTS_PLUGIN ": option '%s' is not allowed here", child->key);
+      ovs_events_config_free();
+      return (-1);
+    }
+  }
+  /* Check and warn about invalid configuration */
+  if (!ovs_events_ctx.config.send_notification && !dispatch_values) {
+      WARNING(OVS_EVENTS_PLUGIN ": send notification and dispatch values "
+              "options are disabled. No information will be dispatched by the "
+              "plugin. Please check your configuration");
+  }
+  /* Dispatch link status values if configured */
+  if (dispatch_values)
+    return plugin_register_complex_read(NULL, OVS_EVENTS_PLUGIN,
+                                        ovs_events_plugin_read, 0, NULL);
+
+  return (0);
+}
+
+/* Dispatch OVS interface link status event to collectd */
+static void ovs_events_dispatch_notification(const ovs_events_iface_info_t *ifinfo) {
+  const char *msg_link_status = NULL;
+  notification_t n = {
+      NOTIF_FAILURE, cdtime(), "", "", OVS_EVENTS_PLUGIN, "", "", "", NULL};
+
+  /* convert link status to message string */
+  switch (ifinfo->link_status) {
+  case UP:
+    msg_link_status = "UP";
+    n.severity = NOTIF_OKAY;
+    break;
+  case DOWN:
+    msg_link_status = "DOWN";
+    n.severity = NOTIF_WARNING;
+    break;
+  default:
+    ERROR(OVS_EVENTS_PLUGIN ": unknown interface link status");
+    return;
+  }
+
+  /* add interface metadata to the notification */
+  if (plugin_notification_meta_add_string(&n, "uuid", ifinfo->uuid) < 0) {
+    ERROR(OVS_EVENTS_PLUGIN ": add interface uuid meta data failed");
+    return;
+  }
+
+  if (strlen(ifinfo->ext_vm_uuid) > 0) {
+    if (plugin_notification_meta_add_string(&n, "vm-uuid",
+                                            ifinfo->ext_vm_uuid) < 0) {
+      ERROR(OVS_EVENTS_PLUGIN ": add interface vm-uuid meta data failed");
+      return;
+    }
+  }
+
+  if (strlen(ifinfo->ext_iface_id) > 0) {
+    if (plugin_notification_meta_add_string(&n, "iface-id",
+                                            ifinfo->ext_iface_id) < 0) {
+      ERROR(OVS_EVENTS_PLUGIN ": add interface iface-id meta data failed");
+      return;
+    }
+  }
+
+  /* fill the notification data */
+  ssnprintf(n.message, sizeof(n.message),
+            "link state of \"%s\" interface has been changed to \"%s\"",
+            ifinfo->name, msg_link_status);
+  sstrncpy(n.host, hostname_g, sizeof(n.host));
+  sstrncpy(n.plugin_instance, ifinfo->name, sizeof(n.plugin_instance));
+  sstrncpy(n.type, "gauge", sizeof(n.type));
+  sstrncpy(n.type_instance, "link_status", sizeof(n.type_instance));
+  plugin_dispatch_notification(&n);
+}
+
+/* Dispatch OVS interface link status value to collectd */
+static void ovs_events_link_status_submit(const ovs_events_iface_info_t *ifinfo) {
+  value_list_t vl = VALUE_LIST_INIT;
+  meta_data_t *meta = NULL;
+
+  /* add interface metadata to the submit value */
+  if ((meta = meta_data_create()) != NULL) {
+    if (meta_data_add_string(meta, "uuid", ifinfo->uuid) < 0)
+      ERROR(OVS_EVENTS_PLUGIN ": add interface uuid meta data failed");
+
+    if (strlen(ifinfo->ext_vm_uuid) > 0)
+      if (meta_data_add_string(meta, "vm-uuid", ifinfo->ext_vm_uuid) < 0)
+        ERROR(OVS_EVENTS_PLUGIN ": add interface vm-uuid meta data failed");
+
+    if (strlen(ifinfo->ext_iface_id) > 0)
+      if (meta_data_add_string(meta, "iface-id", ifinfo->ext_iface_id) < 0)
+        ERROR(OVS_EVENTS_PLUGIN ": add interface iface-id meta data failed");
+    vl.meta = meta;
+  } else
+    ERROR(OVS_EVENTS_PLUGIN ": create metadata failed");
+
+  vl.time = cdtime();
+  vl.values = &(value_t){.gauge = (gauge_t)ifinfo->link_status};
+  vl.values_len = 1;
+  sstrncpy(vl.plugin, OVS_EVENTS_PLUGIN, sizeof(vl.plugin));
+  sstrncpy(vl.plugin_instance, ifinfo->name, sizeof(vl.plugin_instance));
+  sstrncpy(vl.type, "gauge", sizeof(vl.type));
+  sstrncpy(vl.type_instance, "link_status", sizeof(vl.type_instance));
+  plugin_dispatch_values(&vl);
+  meta_data_destroy(meta);
+}
+
+/* Dispatch OVS DB terminate connection event to collectd */
+static void ovs_events_dispatch_terminate_notification(const char *msg) {
+  notification_t n = {
+      NOTIF_FAILURE, cdtime(), "", "", OVS_EVENTS_PLUGIN, "", "", "", NULL};
+  sstrncpy(n.message, msg, sizeof(n.message));
+  sstrncpy(n.host, hostname_g, sizeof(n.host));
+  plugin_dispatch_notification(&n);
+}
+
+/* Get OVS DB interface information and stores it into
+ * ovs_events_iface_info_t structure */
+static int ovs_events_get_iface_info(yajl_val jobject,
+                                     ovs_events_iface_info_t *ifinfo) {
+  yajl_val jexternal_ids = NULL;
+  yajl_val jvalue = NULL;
+  yajl_val juuid = NULL;
+  const char *state = NULL;
+
+  /* check YAJL type */
+  if (!YAJL_IS_OBJECT(jobject))
+    return (-1);
+
+  /* zero the interface info structure */
+  memset(ifinfo, 0, sizeof(*ifinfo));
+
+  /* try to find external_ids, name and link_state fields */
+  jexternal_ids = ovs_utils_get_value_by_key(jobject, "external_ids");
+  if (jexternal_ids == NULL || ifinfo == NULL)
+    return (-1);
+
+  /* get iface-id from external_ids field */
+  jvalue = ovs_utils_get_map_value(jexternal_ids, "iface-id");
+  if (jvalue != NULL && YAJL_IS_STRING(jvalue))
+    sstrncpy(ifinfo->ext_iface_id, YAJL_GET_STRING(jvalue),
+             sizeof(ifinfo->ext_iface_id));
+
+  /* get vm-uuid from external_ids field */
+  jvalue = ovs_utils_get_map_value(jexternal_ids, "vm-uuid");
+  if (jvalue != NULL && YAJL_IS_STRING(jvalue))
+    sstrncpy(ifinfo->ext_vm_uuid, YAJL_GET_STRING(jvalue),
+             sizeof(ifinfo->ext_vm_uuid));
+
+  /* get interface uuid */
+  jvalue = ovs_utils_get_value_by_key(jobject, "_uuid");
+  if (jvalue == NULL || !YAJL_IS_ARRAY(jvalue) ||
+      YAJL_GET_ARRAY(jvalue)->len != 2)
+    return (-1);
+  juuid = YAJL_GET_ARRAY(jvalue)->values[1];
+  if (juuid == NULL || !YAJL_IS_STRING(juuid))
+    return (-1);
+  sstrncpy(ifinfo->uuid, YAJL_GET_STRING(juuid), sizeof(ifinfo->uuid));
+
+  /* get interface name */
+  jvalue = ovs_utils_get_value_by_key(jobject, "name");
+  if (jvalue == NULL || !YAJL_IS_STRING(jvalue))
+    return (-1);
+  sstrncpy(ifinfo->name, YAJL_GET_STRING(jvalue), sizeof(ifinfo->name));
+
+  /* get OVS DB interface link status */
+  jvalue = ovs_utils_get_value_by_key(jobject, "link_state");
+  if (jvalue != NULL && ((state = YAJL_GET_STRING(jvalue)) != NULL)) {
+    /* convert OVS table link state to link status */
+    if (strcmp(state, "up") == 0)
+      ifinfo->link_status = UP;
+    else if (strcmp(state, "down") == 0)
+      ifinfo->link_status = DOWN;
+  }
+  return (0);
+}
+
+/* Process OVS DB update table event. It handles link status update event(s)
+ * and dispatches the value(s) to collectd if interface name matches one of
+ * interfaces specified in configuration file.
+ */
+static void ovs_events_table_update_cb(yajl_val jupdates) {
+  yajl_val jnew_val = NULL;
+  yajl_val jupdate = NULL;
+  yajl_val jrow_update = NULL;
+  ovs_events_iface_info_t ifinfo;
+
+  /* JSON "Interface" table update example:
+   * ---------------------------------
+   * {"Interface":
+   *  {
+   *   "9adf1db2-29ca-4140-ab22-ae347a4484de":
+   *    {
+   *     "new":
+   *      {
+   *       "name":"br0",
+   *       "link_state":"up"
+   *      },
+   *     "old":
+   *      {
+   *       "link_state":"down"
+   *      }
+   *    }
+   *  }
+   * }
+   */
+  if (!YAJL_IS_OBJECT(jupdates) || !(YAJL_GET_OBJECT(jupdates)->len > 0)) {
+    ERROR(OVS_EVENTS_PLUGIN ": unexpected OVS DB update event received");
+    return;
+  }
+  /* verify if this is a table event */
+  jupdate = YAJL_GET_OBJECT(jupdates)->values[0];
+  if (!YAJL_IS_OBJECT(jupdate)) {
+    ERROR(OVS_EVENTS_PLUGIN ": unexpected table update event received");
+    return;
+  }
+  /* go through all row updates  */
+  for (size_t row_index = 0; row_index < YAJL_GET_OBJECT(jupdate)->len;
+       ++row_index) {
+    jrow_update = YAJL_GET_OBJECT(jupdate)->values[row_index];
+
+    /* check row update */
+    jnew_val = ovs_utils_get_value_by_key(jrow_update, "new");
+    if (jnew_val == NULL) {
+      ERROR(OVS_EVENTS_PLUGIN ": unexpected row update received");
+      return;
+    }
+    /* get OVS DB interface information */
+    if (ovs_events_get_iface_info(jnew_val, &ifinfo) < 0) {
+      ERROR(OVS_EVENTS_PLUGIN
+            " :unexpected interface information data received");
+      return;
+    }
+    if (ovs_events_config_iface_exists(ifinfo.name) != 0) {
+      DEBUG("name=%s, uuid=%s, ext_iface_id=%s, ext_vm_uuid=%s", ifinfo.name,
+            ifinfo.uuid, ifinfo.ext_iface_id, ifinfo.ext_vm_uuid);
+      /* dispatch notification */
+      ovs_events_dispatch_notification(&ifinfo);
+    }
+  }
+}
+
+/* OVS DB reply callback. It parses reply, receives
+ * interface information and dispatches the info to
+ * collectd
+ */
+static void ovs_events_poll_result_cb(yajl_val jresult, yajl_val jerror) {
+  yajl_val *jvalues = NULL;
+  yajl_val jvalue = NULL;
+  ovs_events_iface_info_t ifinfo;
+
+  if (!YAJL_IS_NULL(jerror)) {
+    ERROR(OVS_EVENTS_PLUGIN "error received by OVS DB server");
+    return;
+  }
+
+  /* result should be an array */
+  if (!YAJL_IS_ARRAY(jresult)) {
+    ERROR(OVS_EVENTS_PLUGIN "invalid data (array is expected)");
+    return;
+  }
+
+  /* go through all rows and get interface info */
+  jvalues = YAJL_GET_ARRAY(jresult)->values;
+  for (size_t i = 0; i < YAJL_GET_ARRAY(jresult)->len; i++) {
+    jvalue = ovs_utils_get_value_by_key(jvalues[i], "rows");
+    if (jvalue == NULL || !YAJL_IS_ARRAY(jvalue)) {
+      ERROR(OVS_EVENTS_PLUGIN "invalid data (array of rows is expected)");
+      return;
+    }
+    /* get interfaces info */
+    for (size_t j = 0; j < YAJL_GET_ARRAY(jvalue)->len; j++) {
+      if (ovs_events_get_iface_info(YAJL_GET_ARRAY(jvalue)->values[j],
+                                    &ifinfo) < 0) {
+        ERROR(OVS_EVENTS_PLUGIN
+              "unexpected interface information data received");
+        return;
+      }
+      DEBUG("name=%s, uuid=%s, ext_iface_id=%s, ext_vm_uuid=%s", ifinfo.name,
+            ifinfo.uuid, ifinfo.ext_iface_id, ifinfo.ext_vm_uuid);
+      ovs_events_link_status_submit(&ifinfo);
+    }
+  }
+}
+
+/* Setup OVS DB table callback. It subscribes to OVS DB 'Interface' table
+ * to receive link status event(s).
+ */
+static void ovs_events_conn_initialize(ovs_db_t *pdb) {
+  const char tb_name[] = "Interface";
+  const char *columns[] = {"_uuid", "external_ids", "name", "link_state", NULL};
+
+  /* register update link status event if needed */
+  if (ovs_events_ctx.config.send_notification) {
+    int ret = ovs_db_table_cb_register(pdb, tb_name, columns,
+                                       ovs_events_table_update_cb, NULL,
+                                       OVS_DB_TABLE_CB_FLAG_MODIFY);
+    if (ret < 0) {
+      ERROR(OVS_EVENTS_PLUGIN ": register OVS DB update callback failed");
+      return;
+    }
+  }
+  OVS_EVENTS_CTX_LOCK { ovs_events_ctx.is_db_available = 1; }
+  DEBUG(OVS_EVENTS_PLUGIN ": OVS DB connection has been initialized");
+}
+
+/* OVS DB terminate connection notification callback */
+static void ovs_events_conn_terminate() {
+  const char msg[] = "OVS DB connection has been lost";
+  if (ovs_events_ctx.config.send_notification)
+    ovs_events_dispatch_terminate_notification(msg);
+  WARNING(OVS_EVENTS_PLUGIN ": %s", msg);
+  OVS_EVENTS_CTX_LOCK { ovs_events_ctx.is_db_available = 0; }
+}
+
+/* Read OVS DB interface link status callback */
+static int ovs_events_plugin_read(__attribute__((unused)) user_data_t *u) {
+  _Bool is_connected = 0;
+  OVS_EVENTS_CTX_LOCK { is_connected = ovs_events_ctx.is_db_available; }
+  if (is_connected)
+    if (ovs_db_send_request(ovs_events_ctx.ovs_db, "transact",
+                            ovs_events_ctx.ovs_db_select_params,
+                            ovs_events_poll_result_cb) < 0) {
+      ERROR(OVS_EVENTS_PLUGIN ": get interface info failed");
+      return (-1);
+    }
+  return (0);
+}
+
+/* Initialize OVS plugin */
+static int ovs_events_plugin_init(void) {
+  ovs_db_t *ovs_db = NULL;
+  ovs_db_callback_t cb = {.post_conn_init = ovs_events_conn_initialize,
+                          .post_conn_terminate = ovs_events_conn_terminate};
+
+  DEBUG(OVS_EVENTS_PLUGIN ": OVS DB address=%s, service=%s, unix=%s",
+        ovs_events_ctx.config.ovs_db_node, ovs_events_ctx.config.ovs_db_serv,
+        ovs_events_ctx.config.ovs_db_unix);
+
+  /* generate OVS DB select condition based on list on configured interfaces */
+  ovs_events_ctx.ovs_db_select_params = ovs_events_get_select_params();
+  if (ovs_events_ctx.ovs_db_select_params == NULL) {
+    ERROR(OVS_EVENTS_PLUGIN ": fail to get OVS DB select condition");
+    goto ovs_events_failure;
+  }
+
+  /* initialize OVS DB */
+  ovs_db = ovs_db_init(ovs_events_ctx.config.ovs_db_node,
+                       ovs_events_ctx.config.ovs_db_serv,
+                       ovs_events_ctx.config.ovs_db_unix, &cb);
+  if (ovs_db == NULL) {
+    ERROR(OVS_EVENTS_PLUGIN ": fail to connect to OVS DB server");
+    goto ovs_events_failure;
+  }
+
+  /* store OVS DB handler */
+  OVS_EVENTS_CTX_LOCK { ovs_events_ctx.ovs_db = ovs_db; }
+
+  DEBUG(OVS_EVENTS_PLUGIN ": plugin has been initialized");
+  return (0);
+
+ovs_events_failure:
+  ERROR(OVS_EVENTS_PLUGIN ": plugin initialize failed");
+  /* release allocated memory */
+  ovs_events_config_free();
+  return (-1);
+}
+
+/* Shutdown OVS plugin */
+static int ovs_events_plugin_shutdown(void) {
+  /* destroy OVS DB */
+  if (ovs_db_destroy(ovs_events_ctx.ovs_db))
+    ERROR(OVS_EVENTS_PLUGIN ": OVSDB object destroy failed");
+
+  /* release memory allocated for config */
+  ovs_events_config_free();
+
+  DEBUG(OVS_EVENTS_PLUGIN ": plugin has been destroyed");
+  return (0);
+}
+
+/* Register OVS plugin callbacks */
+void module_register(void) {
+  plugin_register_complex_config(OVS_EVENTS_PLUGIN, ovs_events_plugin_config);
+  plugin_register_init(OVS_EVENTS_PLUGIN, ovs_events_plugin_init);
+  plugin_register_shutdown(OVS_EVENTS_PLUGIN, ovs_events_plugin_shutdown);
+}
index 5910913..c79cfd2 100644 (file)
@@ -38,9 +38,7 @@
 
 #undef DONT_POISON_SPRINTF_YET
 
-#if HAVE_STDBOOL_H
 #include <stdbool.h>
-#endif
 
 #include <EXTERN.h>
 #include <perl.h>
@@ -2711,5 +2709,3 @@ void module_register(void) {
   plugin_register_complex_config("perl", perl_config);
   return;
 } /* void module_register (void) */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
index 7fd23a0..97eeb0d 100644 (file)
@@ -685,5 +685,3 @@ void module_register(void) /* {{{ */
   plugin_register_read("pinba", plugin_read);
   plugin_register_shutdown("pinba", plugin_shutdown);
 } /* }}} void module_register */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index 82de59f..6d9545f 100644 (file)
@@ -679,5 +679,3 @@ void module_register(void) {
   plugin_register_read("ping", ping_read);
   plugin_register_shutdown("ping", ping_shutdown);
 } /* void module_register */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index 2af8988..3a388a5 100644 (file)
@@ -1265,5 +1265,3 @@ void module_register(void) {
   plugin_register_complex_config("postgresql", c_psql_config);
   plugin_register_shutdown("postgresql", c_psql_shutdown);
 } /* module_register */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
index f2149ef..8562108 100644 (file)
@@ -960,5 +960,3 @@ void module_register(void) {
   plugin_register_read("powerdns", powerdns_read);
   plugin_register_shutdown("powerdns", powerdns_shutdown);
 } /* void module_register */
-
-/* vim: set sw=2 sts=2 ts=8 fdm=marker : */
index 86f690f..4f61351 100644 (file)
@@ -1916,7 +1916,7 @@ static int ps_read(void) {
   ps_list_reset();
 
   /* Open the kvm interface, get a descriptor */
-  kd = kvm_open(NULL, NULL, NULL, 0, errbuf);
+  kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf);
   if (kd == NULL) {
     ERROR("processes plugin: Cannot open kvm interface: %s", errbuf);
     return (0);
index 64735e6..12fbf45 100644 (file)
@@ -213,5 +213,3 @@ void module_register(void) {
                          config_keys_num);
   plugin_register_read("protocols", protocols_read);
 } /* void module_register */
-
-/* vim: set sw=2 sts=2 et : */
index 7875c7e..ea888ca 100644 (file)
@@ -451,5 +451,3 @@ void module_register(void) /* {{{ */
    * X elements */
 }
 /* }}} */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index 07493c7..5c978dc 100644 (file)
@@ -409,5 +409,3 @@ static int cr_config(oconfig_item_t *ci) {
 void module_register(void) {
   plugin_register_complex_config("routeros", cr_config);
 } /* void module_register */
-
-/* vim: set sw=2 noet fdm=marker : */
index 6eb67d4..5cf17c1 100644 (file)
@@ -529,7 +529,3 @@ void module_register(void) {
   plugin_register_init("rrdcached", rc_init);
   plugin_register_shutdown("rrdcached", rc_shutdown);
 } /* void module_register */
-
-/*
- * vim: set sw=2 sts=2 et :
- */
index 3bfec47..ff75edb 100644 (file)
@@ -1695,7 +1695,3 @@ void module_register(void) {
   plugin_register_init("snmp", csnmp_init);
   plugin_register_shutdown("snmp", csnmp_shutdown);
 } /* void module_register */
-
-/*
- * vim: shiftwidth=2 softtabstop=2 tabstop=8 fdm=marker
- */
index 47e01d8..aa4e35c 100644 (file)
@@ -914,5 +914,3 @@ void module_register(void) {
   plugin_register_read("statsd", statsd_read);
   plugin_register_shutdown("statsd", statsd_shutdown);
 }
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index cbe1ab1..19eed46 100644 (file)
@@ -738,5 +738,3 @@ void module_register(void) {
   plugin_register_init("swap", swap_init);
   plugin_register_read("swap", swap_read);
 } /* void module_register */
-
-/* vim: set fdm=marker : */
index 3e8fead..578e019 100644 (file)
@@ -520,5 +520,3 @@ void module_register(void) {
   plugin_register_complex_config("table", tbl_config);
   plugin_register_init("table", tbl_init);
 } /* module_register */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
index bb4eb30..466dbff 100644 (file)
@@ -337,5 +337,3 @@ void module_register(void) {
   plugin_register_init("tail", ctail_init);
   plugin_register_shutdown("tail", ctail_shutdown);
 } /* void module_register */
-
-/* vim: set sw=2 sts=2 ts=8 : */
index b1a3292..425c101 100644 (file)
@@ -551,5 +551,3 @@ void module_register(void) {
   plugin_register_init("tail_csv", tcsv_init);
   plugin_register_shutdown("tail_csv", tcsv_shutdown);
 }
-
-/* vim: set sw=4 sts=4 et : */
index dc93b98..7c82c79 100644 (file)
@@ -260,5 +260,3 @@ void module_register(void) {
   tproc.invoke = tn_invoke;
   fc_register_target("notification", tproc);
 } /* module_register */
-
-/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */
index b43a025..2bdb3b8 100644 (file)
@@ -561,5 +561,3 @@ void module_register(void) {
   tproc.invoke = tr_invoke;
   fc_register_target("replace", tproc);
 } /* module_register */
-
-/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */
index 347d627..4cce8dd 100644 (file)
@@ -457,5 +457,3 @@ void module_register(void) {
   tproc.invoke = ts_invoke;
   fc_register_target("scale", tproc);
 } /* module_register */
-
-/* vim: set sw=2 ts=2 tw=78 fdm=marker : */
index a40273c..e9dbc1d 100644 (file)
@@ -420,5 +420,3 @@ void module_register(void) {
   tproc.invoke = ts_invoke;
   fc_register_target("set", tproc);
 } /* module_register */
-
-/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */
index 54e37e1..27bca39 100644 (file)
@@ -451,5 +451,3 @@ void module_register(void) {
   tproc.invoke = v5_invoke;
   fc_register_target("v5upgrade", tproc);
 } /* module_register */
-
-/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */
index f949d34..08838fb 100644 (file)
 #include "common.h"
 #include "plugin.h"
 
-#if defined(__OpenBSD__) || defined(__NetBSD__)
+#if defined(__OpenBSD__)
+#define HAVE_KVM_GETFILES 1
+#endif
+
+#if defined(__NetBSD__)
 #undef HAVE_SYSCTLBYNAME /* force HAVE_LIBKVM_NLIST path */
 #endif
 
-#if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME && !HAVE_LIBKVM_NLIST && !KERNEL_AIX
+#if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME && !HAVE_KVM_GETFILES && !HAVE_LIBKVM_NLIST && !KERNEL_AIX
 #error "No applicable input method."
 #endif
 
 #include <netinet/tcpip.h>
 /* #endif HAVE_SYSCTLBYNAME */
 
-/* This is for OpenBSD and NetBSD. */
+#elif HAVE_KVM_GETFILES
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#define _KERNEL /* for DTYPE_SOCKET */
+#include <sys/file.h>
+#undef _KERNEL
+
+#include <netinet/in.h>
+
+#include <kvm.h>
+/* #endif HAVE_KVM_GETFILES */
+
+/* This is for NetBSD. */
 #elif HAVE_LIBKVM_NLIST
 #include <arpa/inet.h>
 #include <net/route.h>
 #include <netdb.h>
 #include <netinet/in.h>
+#include <netinet/ip.h>
 #include <netinet/in_pcb.h>
 #include <netinet/in_systm.h>
-#include <netinet/ip.h>
 #include <netinet/ip_var.h>
 #include <netinet/tcp.h>
 #include <netinet/tcp_timer.h>
@@ -169,6 +185,19 @@ static const char *tcp_state[] = {"CLOSED",    "LISTEN",      "SYN_SENT",
 #define TCP_STATE_MAX 10
 /* #endif HAVE_SYSCTLBYNAME */
 
+#elif HAVE_KVM_GETFILES
+static const char *tcp_state[] = {"CLOSED",    "LISTEN",      "SYN_SENT",
+                                  "SYN_RECV",  "ESTABLISHED", "CLOSE_WAIT",
+                                  "FIN_WAIT1", "CLOSING",     "LAST_ACK",
+                                  "FIN_WAIT2", "TIME_WAIT"};
+
+#define TCP_STATE_LISTEN 1
+#define TCP_STATE_MIN 0
+#define TCP_STATE_MAX 10
+
+static kvm_t *kvmd;
+/* #endif HAVE_KVM_GETFILES */
+
 #elif HAVE_LIBKVM_NLIST
 static const char *tcp_state[] = {"CLOSED",    "LISTEN",      "SYN_SENT",
                                   "SYN_RECV",  "ESTABLISHED", "CLOSE_WAIT",
@@ -775,6 +804,49 @@ static int conn_read(void) {
 } /* int conn_read */
   /* #endif HAVE_SYSCTLBYNAME */
 
+#elif HAVE_KVM_GETFILES
+
+static int conn_init(void) {
+  char buf[_POSIX2_LINE_MAX];
+
+  kvmd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, buf);
+  if (kvmd == NULL) {
+    ERROR("tcpconns plugin: kvm_openfiles failed: %s", buf);
+    return (-1);
+  }
+
+  return (0);
+} /* int conn_init */
+
+static int conn_read(void) {
+  struct kinfo_file *kf;
+  int i, fcnt;
+
+  conn_reset_port_entry();
+
+  kf = kvm_getfiles(kvmd, KERN_FILE_BYFILE, DTYPE_SOCKET,
+                   sizeof(*kf), &fcnt);
+  if (kf == NULL) {
+    ERROR("tcpconns plugin: kvm_getfiles failed.");
+    return (-1);
+  }
+
+  for (i = 0; i < fcnt; i++) {
+    if (kf[i].so_protocol != IPPROTO_TCP)
+      continue;
+    if (kf[i].inp_fport == 0)
+      continue;
+    conn_handle_ports(ntohs(kf[i].inp_lport), ntohs(kf[i].inp_fport),
+                      kf[i].t_state);
+  }
+
+  conn_submit_all();
+
+  return (0);
+}
+/* int conn_read */
+/* #endif HAVE_KVM_GETFILES */
+
 #elif HAVE_LIBKVM_NLIST
 static int kread(u_long addr, void *buf, int size) {
   int status;
@@ -958,7 +1030,3 @@ void module_register(void) {
 #endif
   plugin_register_read("tcpconns", conn_read);
 } /* void module_register */
-
-/*
- * vim: set shiftwidth=2 softtabstop=2 tabstop=8 fdm=marker :
- */
index 960d646..a959cdd 100644 (file)
@@ -728,5 +728,3 @@ void module_register(void) {
   plugin_register_read("teamspeak2", tss2_read);
   plugin_register_shutdown("teamspeak2", tss2_shutdown);
 } /* void module_register */
-
-/* vim: set sw=4 ts=4 : */
index cccb3db..fbfd95d 100644 (file)
--- a/src/ted.c
+++ b/src/ted.c
@@ -39,8 +39,7 @@
 #include "common.h"
 #include "plugin.h"
 
-#if HAVE_TERMIOS_H && HAVE_SYS_IOCTL_H && HAVE_MATH_H
-#include <math.h>
+#if HAVE_TERMIOS_H && HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
 #include <termios.h>
 #else
@@ -300,5 +299,3 @@ void module_register(void) {
   plugin_register_read("ted", ted_read);
   plugin_register_shutdown("ted", ted_shutdown);
 } /* void module_register */
-
-/* vim: set sw=4 et : */
index 743db28..a4a999f 100644 (file)
@@ -834,5 +834,3 @@ static int ut_config(oconfig_item_t *ci) { /* {{{ */
 void module_register(void) {
   plugin_register_complex_config("threshold", ut_config);
 }
-
-/* vim: set sw=2 ts=8 sts=2 tw=78 et fdm=marker : */
index cb366d3..09ee25d 100644 (file)
@@ -150,5 +150,3 @@ void module_register(void) {
   plugin_register_read("tokyotyrant", tt_read);
   plugin_register_shutdown("tokyotyrant", tt_shutdown);
 }
-
-/* vim: set sw=8 ts=8 tw=78 : */
index f61360e..b08c89f 100644 (file)
@@ -429,5 +429,3 @@ void module_register(void) {
   plugin_register_init("unixsock", us_init);
   plugin_register_shutdown("unixsock", us_shutdown);
 } /* void module_register (void) */
-
-/* vim: set sw=4 ts=4 sts=4 tw=78 : */
index a8de21a..9e8950b 100644 (file)
@@ -177,5 +177,3 @@ void cmd_destroy_flush(cmd_flush_t *flush) {
   sfree(flush->identifiers);
   flush->identifiers_num = 0;
 } /* void cmd_destroy_flush */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
index d9b4e1b..129aa85 100644 (file)
@@ -40,5 +40,3 @@ cmd_status_t cmd_handle_flush(FILE *fh, char *buffer);
 void cmd_destroy_flush(cmd_flush_t *flush);
 
 #endif /* UTILS_CMD_FLUSH_H */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
index 926375d..063548b 100644 (file)
@@ -181,5 +181,3 @@ int handle_getthreshold(FILE *fh, char *buffer) {
 
   return (0);
 } /* int handle_getthreshold */
-
-/* vim: set sw=2 sts=2 ts=8 et : */
index dd4e5cf..78700ee 100644 (file)
@@ -32,5 +32,3 @@
 int handle_getthreshold(FILE *fh, char *buffer);
 
 #endif /* UTILS_CMD_GETTHRESHOLD_H */
-
-/* vim: set sw=2 sts=2 ts=8 : */
index c23650b..e5f17b6 100644 (file)
@@ -164,5 +164,3 @@ void cmd_destroy_getval(cmd_getval_t *getval) {
 
   sfree(getval->raw_identifier);
 } /* void cmd_destroy_getval */
-
-/* vim: set sw=2 sts=2 ts=8 : */
index 8d488b3..5c03fa4 100644 (file)
@@ -41,5 +41,3 @@ cmd_status_t cmd_handle_getval(FILE *fh, char *buffer);
 void cmd_destroy_getval(cmd_getval_t *getval);
 
 #endif /* UTILS_CMD_GETVAL_H */
-
-/* vim: set sw=2 sts=2 ts=8 : */
index f863889..4e603a2 100644 (file)
@@ -108,5 +108,3 @@ cmd_status_t cmd_handle_listval(FILE *fh, char *buffer) {
 void cmd_destroy_listval(cmd_listval_t *listval __attribute__((unused))) {
   /* nothing to do */
 } /* void cmd_destroy_listval */
-
-/* vim: set sw=2 sts=2 ts=8 : */
index 8a4e8c8..6abdeee 100644 (file)
@@ -41,5 +41,3 @@ cmd_status_t cmd_handle_listval(FILE *fh, char *buffer);
 void cmd_destroy_listval(cmd_listval_t *listval);
 
 #endif /* UTILS_CMD_LISTVAL_H */
-
-/* vim: set sw=2 sts=2 ts=8 : */
index 0edfbb8..8f687fd 100644 (file)
@@ -180,5 +180,3 @@ int handle_putnotif(FILE *fh, char *buffer) {
 
   return (0);
 } /* int handle_putnotif */
-
-/* vim: set shiftwidth=2 softtabstop=2 tabstop=8 : */
index af0b93e..7ad0f1a 100644 (file)
@@ -31,6 +31,4 @@
 
 int handle_putnotif(FILE *fh, char *buffer);
 
-/* vim: set shiftwidth=2 softtabstop=2 tabstop=8 : */
-
 #endif /* UTILS_CMD_PUTNOTIF_H */
index 3ea7c9d..31a9a6f 100644 (file)
@@ -309,5 +309,3 @@ void cmd_error_fh(void *ud, cmd_status_t status, const char *format,
 
   fflush(fh);
 } /* void cmd_error_fh */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
index 9a58227..c803029 100644 (file)
@@ -1059,5 +1059,3 @@ void udb_query_delete_preparation_area(
 
   free(q_area);
 } /* }}} void udb_query_delete_preparation_area */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index 8f06918..4d6129a 100644 (file)
@@ -83,4 +83,3 @@ udb_query_allocate_preparation_area(udb_query_t *q);
 void udb_query_delete_preparation_area(udb_query_preparation_area_t *q_area);
 
 #endif /* UTILS_DB_QUERY_H */
-/* vim: set sw=2 sts=2 et : */
index a4a5784..2bda965 100644 (file)
@@ -1169,6 +1169,3 @@ main(int argc, char *argv[])
     return 0;
 } /* static int main(int argc, char *argv[]) */
 #endif
-/*
- * vim:shiftwidth=4:tabstop=8:softtabstop=4
- */
diff --git a/src/utils_dpdk.c b/src/utils_dpdk.c
new file mode 100644 (file)
index 0000000..e3c7379
--- /dev/null
@@ -0,0 +1,872 @@
+/*
+ * collectd - src/utils_dpdk.c
+ * MIT License
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *   Maryam Tahhan <maryam.tahhan@intel.com>
+ *   Harry van Haaren <harry.van.haaren@intel.com>
+ *   Taras Chornyi <tarasx.chornyi@intel.com>
+ *   Serhiy Pshyk <serhiyx.pshyk@intel.com>
+ *   Krzysztof Matczak <krzysztofx.matczak@intel.com>
+ */
+
+#include "collectd.h"
+
+#include <poll.h>
+#include <semaphore.h>
+#include <sys/mman.h>
+
+#include <rte_config.h>
+#include <rte_eal.h>
+#include <rte_ethdev.h>
+
+#include "common.h"
+#include "utils_dpdk.h"
+
+#define DPDK_DEFAULT_RTE_CONFIG "/var/run/.rte_config"
+#define DPDK_EAL_ARGC 5
+#define DPDK_MAX_BUFFER_SIZE (4096 * 4)
+#define DPDK_CDM_DEFAULT_TIMEOUT 10000
+
+enum DPDK_HELPER_STATUS {
+  DPDK_HELPER_NOT_INITIALIZED = 0,
+  DPDK_HELPER_INITIALIZING,
+  DPDK_HELPER_WAITING_ON_PRIMARY,
+  DPDK_HELPER_INITIALIZING_EAL,
+  DPDK_HELPER_ALIVE_SENDING_EVENTS,
+  DPDK_HELPER_GRACEFUL_QUIT,
+};
+
+#define DPDK_HELPER_TRACE(_name)                                               \
+  DEBUG("%s:%s:%d pid=%ld", _name, __FUNCTION__, __LINE__, (long)getpid())
+
+struct dpdk_helper_ctx_s {
+
+  dpdk_eal_config_t eal_config;
+  int eal_initialized;
+
+  size_t shm_size;
+  const char *shm_name;
+
+  sem_t sema_cmd_start;
+  sem_t sema_cmd_complete;
+  cdtime_t cmd_wait_time;
+
+  pid_t pid;
+  int pipes[2];
+  int status;
+
+  int cmd;
+  int cmd_result;
+
+  char priv_data[];
+};
+
+static int dpdk_shm_init(const char *name, size_t size, void **map);
+static void dpdk_shm_cleanup(const char *name, size_t size, void *map);
+
+static int dpdk_helper_spawn(dpdk_helper_ctx_t *phc);
+static int dpdk_helper_worker(dpdk_helper_ctx_t *phc);
+static int dpdk_helper_eal_init(dpdk_helper_ctx_t *phc);
+static int dpdk_helper_cmd_wait(dpdk_helper_ctx_t *phc, pid_t ppid);
+static int dpdk_helper_exit_command(dpdk_helper_ctx_t *phc,
+                                    enum DPDK_HELPER_STATUS status);
+static int dpdk_helper_exit(dpdk_helper_ctx_t *phc,
+                            enum DPDK_HELPER_STATUS status);
+static int dpdk_helper_status_check(dpdk_helper_ctx_t *phc);
+static void dpdk_helper_config_default(dpdk_helper_ctx_t *phc);
+static const char *dpdk_helper_status_str(enum DPDK_HELPER_STATUS status);
+
+static void dpdk_helper_config_default(dpdk_helper_ctx_t *phc) {
+  if (phc == NULL)
+    return;
+
+  DPDK_HELPER_TRACE(phc->shm_name);
+
+  ssnprintf(phc->eal_config.coremask, DATA_MAX_NAME_LEN, "%s", "0xf");
+  ssnprintf(phc->eal_config.memory_channels, DATA_MAX_NAME_LEN, "%s", "1");
+  ssnprintf(phc->eal_config.process_type, DATA_MAX_NAME_LEN, "%s", "secondary");
+  ssnprintf(phc->eal_config.file_prefix, DATA_MAX_NAME_LEN, "%s",
+            DPDK_DEFAULT_RTE_CONFIG);
+}
+
+int dpdk_helper_eal_config_set(dpdk_helper_ctx_t *phc, dpdk_eal_config_t *ec) {
+  if (phc == NULL) {
+    ERROR("Invalid argument (phc)");
+    return -EINVAL;
+  }
+
+  DPDK_HELPER_TRACE(phc->shm_name);
+
+  if (ec == NULL) {
+    ERROR("Invalid argument (ec)");
+    return -EINVAL;
+  }
+
+  memcpy(&phc->eal_config, ec, sizeof(phc->eal_config));
+
+  return 0;
+}
+
+int dpdk_helper_eal_config_get(dpdk_helper_ctx_t *phc, dpdk_eal_config_t *ec) {
+  if (phc == NULL) {
+    ERROR("Invalid argument (phc)");
+    return -EINVAL;
+  }
+
+  DPDK_HELPER_TRACE(phc->shm_name);
+
+  if (ec == NULL) {
+    ERROR("Invalid argument (ec)");
+    return -EINVAL;
+  }
+
+  memcpy(ec, &phc->eal_config, sizeof(*ec));
+
+  return 0;
+}
+
+int dpdk_helper_eal_config_parse(dpdk_helper_ctx_t *phc, oconfig_item_t *ci) {
+  DPDK_HELPER_TRACE(phc->shm_name);
+
+  if (phc == NULL) {
+    ERROR("Invalid argument (phc)");
+    return -EINVAL;
+  }
+
+  if (ci == NULL) {
+    ERROR("Invalid argument (ci)");
+    return -EINVAL;
+  }
+
+  int status = 0;
+  for (int i = 0; i < ci->children_num; i++) {
+    oconfig_item_t *child = ci->children + i;
+    if (strcasecmp("Coremask", child->key) == 0) {
+      status = cf_util_get_string_buffer(child, phc->eal_config.coremask,
+                                         sizeof(phc->eal_config.coremask));
+      DEBUG("dpdk_common: EAL:Coremask %s", phc->eal_config.coremask);
+    } else if (strcasecmp("MemoryChannels", child->key) == 0) {
+      status =
+          cf_util_get_string_buffer(child, phc->eal_config.memory_channels,
+                                    sizeof(phc->eal_config.memory_channels));
+      DEBUG("dpdk_common: EAL:Memory Channels %s",
+            phc->eal_config.memory_channels);
+    } else if (strcasecmp("SocketMemory", child->key) == 0) {
+      status = cf_util_get_string_buffer(child, phc->eal_config.socket_memory,
+                                         sizeof(phc->eal_config.socket_memory));
+      DEBUG("dpdk_common: EAL:Socket memory %s", phc->eal_config.socket_memory);
+    } else if (strcasecmp("ProcessType", child->key) == 0) {
+      status = cf_util_get_string_buffer(child, phc->eal_config.process_type,
+                                         sizeof(phc->eal_config.process_type));
+      DEBUG("dpdk_common: EAL:Process type %s", phc->eal_config.process_type);
+    } else if ((strcasecmp("FilePrefix", child->key) == 0) &&
+               (child->values[0].type == OCONFIG_TYPE_STRING)) {
+      ssnprintf(phc->eal_config.file_prefix, DATA_MAX_NAME_LEN,
+                "/var/run/.%s_config", child->values[0].value.string);
+      DEBUG("dpdk_common: EAL:File prefix %s", phc->eal_config.file_prefix);
+    } else {
+      ERROR("dpdk_common: Invalid '%s' configuration option", child->key);
+      status = -EINVAL;
+    }
+
+    if (status != 0) {
+      ERROR("dpdk_common: Parsing EAL configuration failed");
+      break;
+    }
+  }
+
+  return status;
+}
+
+static int dpdk_shm_init(const char *name, size_t size, void **map) {
+  DPDK_HELPER_TRACE(name);
+
+  char errbuf[ERR_BUF_SIZE];
+
+  int fd = shm_open(name, O_CREAT | O_TRUNC | O_RDWR, 0666);
+  if (fd < 0) {
+    WARNING("dpdk_shm_init: Failed to open %s as SHM:%s", name,
+            sstrerror(errno, errbuf, sizeof(errbuf)));
+    *map = NULL;
+    return -1;
+  }
+
+  int ret = ftruncate(fd, size);
+  if (ret != 0) {
+    WARNING("dpdk_shm_init: Failed to resize SHM:%s",
+            sstrerror(errno, errbuf, sizeof(errbuf)));
+    close(fd);
+    *map = NULL;
+    dpdk_shm_cleanup(name, size, NULL);
+    return -1;
+  }
+
+  *map = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+  if (*map == MAP_FAILED) {
+    WARNING("dpdk_shm_init:Failed to mmap SHM:%s",
+            sstrerror(errno, errbuf, sizeof(errbuf)));
+    close(fd);
+    *map = NULL;
+    dpdk_shm_cleanup(name, size, NULL);
+    return -1;
+  }
+  /* File descriptor no longer needed for shared memory operations */
+  close(fd);
+  memset(*map, 0, size);
+
+  return 0;
+}
+
+static void dpdk_shm_cleanup(const char *name, size_t size, void *map) {
+  DPDK_HELPER_TRACE(name);
+  char errbuf[ERR_BUF_SIZE];
+
+  if (map != NULL) {
+    if (munmap(map, size))
+      ERROR("munmap failure %s", sstrerror(errno, errbuf, sizeof(errbuf)));
+  }
+
+  if (shm_unlink(name))
+    ERROR("shm_unlink failure %s", sstrerror(errno, errbuf, sizeof(errbuf)));
+}
+
+void *dpdk_helper_priv_get(dpdk_helper_ctx_t *phc) {
+  if (phc)
+    return phc->priv_data;
+
+  return NULL;
+}
+
+int dpdk_helper_data_size_get(dpdk_helper_ctx_t *phc) {
+  if (phc == NULL) {
+    DPDK_CHILD_LOG("Invalid argument(phc)\n");
+    return -EINVAL;
+  }
+
+  return (phc->shm_size - sizeof(dpdk_helper_ctx_t));
+}
+
+int dpdk_helper_init(const char *name, size_t data_size,
+                     dpdk_helper_ctx_t **pphc) {
+  dpdk_helper_ctx_t *phc = NULL;
+  size_t shm_size = sizeof(dpdk_helper_ctx_t) + data_size;
+  char errbuf[ERR_BUF_SIZE];
+
+  if (pphc == NULL) {
+    ERROR("%s:Invalid argument(pphc)", __FUNCTION__);
+    return -EINVAL;
+  }
+
+  if (name == NULL) {
+    ERROR("%s:Invalid argument(name)", __FUNCTION__);
+    return -EINVAL;
+  }
+
+  DPDK_HELPER_TRACE(name);
+
+  /* Allocate dpdk_helper_ctx_t and
+  * initialize a POSIX SHared Memory (SHM) object.
+  */
+  int err = dpdk_shm_init(name, shm_size, (void **)&phc);
+  if (err != 0) {
+    return -errno;
+  }
+
+  err = sem_init(&phc->sema_cmd_start, 1, 0);
+  if (err != 0) {
+    ERROR("sema_cmd_start semaphore init failed: %s",
+          sstrerror(errno, errbuf, sizeof(errbuf)));
+    int errno_m = errno;
+    dpdk_shm_cleanup(name, shm_size, (void *)phc);
+    return -errno_m;
+  }
+
+  err = sem_init(&phc->sema_cmd_complete, 1, 0);
+  if (err != 0) {
+    ERROR("sema_cmd_complete semaphore init failed: %s",
+          sstrerror(errno, errbuf, sizeof(errbuf)));
+    sem_destroy(&phc->sema_cmd_start);
+    int errno_m = errno;
+    dpdk_shm_cleanup(name, shm_size, (void *)phc);
+    return -errno_m;
+  }
+
+  phc->shm_size = shm_size;
+  phc->shm_name = name;
+
+  dpdk_helper_config_default(phc);
+
+  *pphc = phc;
+
+  return 0;
+}
+
+int dpdk_helper_shutdown(dpdk_helper_ctx_t *phc) {
+  if (phc == NULL) {
+    ERROR("%s:Invalid argument(phc)", __FUNCTION__);
+    return -EINVAL;
+  }
+
+  DPDK_HELPER_TRACE(phc->shm_name);
+
+  close(phc->pipes[1]);
+
+  if (phc->status != DPDK_HELPER_NOT_INITIALIZED) {
+    dpdk_helper_exit_command(phc, DPDK_HELPER_GRACEFUL_QUIT);
+  }
+
+  sem_destroy(&phc->sema_cmd_start);
+  sem_destroy(&phc->sema_cmd_complete);
+  dpdk_shm_cleanup(phc->shm_name, phc->shm_size, (void *)phc);
+
+  return 0;
+}
+
+static int dpdk_helper_spawn(dpdk_helper_ctx_t *phc) {
+  char errbuf[ERR_BUF_SIZE];
+  if (phc == NULL) {
+    ERROR("Invalid argument(phc)");
+    return -EINVAL;
+  }
+
+  DPDK_HELPER_TRACE(phc->shm_name);
+
+  phc->eal_initialized = 0;
+  phc->cmd_wait_time = MS_TO_CDTIME_T(DPDK_CDM_DEFAULT_TIMEOUT);
+
+  /*
+   * Create a pipe for helper stdout back to collectd. This is necessary for
+   * logging EAL failures, as rte_eal_init() calls rte_panic().
+   */
+  if (phc->pipes[1]) {
+    DEBUG("dpdk_helper_spawn: collectd closing helper pipe %d", phc->pipes[1]);
+  } else {
+    DEBUG("dpdk_helper_spawn: collectd helper pipe %d, not closing",
+          phc->pipes[1]);
+  }
+
+  if (pipe(phc->pipes) != 0) {
+    DEBUG("dpdk_helper_spawn: Could not create helper pipe: %s",
+          sstrerror(errno, errbuf, sizeof(errbuf)));
+    return -1;
+  }
+
+  int pipe0_flags = fcntl(phc->pipes[0], F_GETFL, 0);
+  int pipe1_flags = fcntl(phc->pipes[1], F_GETFL, 0);
+  if (pipe0_flags == -1 || pipe1_flags == -1) {
+    WARNING("dpdk_helper_spawn: error setting up pipe flags: %s",
+            sstrerror(errno, errbuf, sizeof(errbuf)));
+  }
+  int pipe0_err = fcntl(phc->pipes[0], F_SETFL, pipe1_flags | O_NONBLOCK);
+  int pipe1_err = fcntl(phc->pipes[1], F_SETFL, pipe0_flags | O_NONBLOCK);
+  if (pipe0_err == -1 || pipe1_err == -1) {
+    WARNING("dpdk_helper_spawn: error setting up pipes: %s",
+            sstrerror(errno, errbuf, sizeof(errbuf)));
+  }
+
+  pid_t pid = fork();
+  if (pid > 0) {
+    phc->pid = pid;
+    close(phc->pipes[1]);
+    DEBUG("%s:dpdk_helper_spawn: helper pid %lu", phc->shm_name,
+          (long)phc->pid);
+  } else if (pid == 0) {
+    /* Replace stdout with a pipe to collectd. */
+    close(phc->pipes[0]);
+    close(STDOUT_FILENO);
+    dup2(phc->pipes[1], STDOUT_FILENO);
+    DPDK_CHILD_TRACE(phc->shm_name);
+    dpdk_helper_worker(phc);
+    exit(0);
+  } else {
+    ERROR("dpdk_helper_start: Failed to fork helper process: %s",
+          sstrerror(errno, errbuf, sizeof(errbuf)));
+    return -1;
+  }
+
+  return 0;
+}
+
+static int dpdk_helper_exit(dpdk_helper_ctx_t *phc,
+                            enum DPDK_HELPER_STATUS status) {
+  DPDK_CHILD_LOG("%s:%s:%d %s\n", phc->shm_name, __FUNCTION__, __LINE__,
+                 dpdk_helper_status_str(status));
+
+  close(phc->pipes[1]);
+
+  phc->status = status;
+
+  exit(0);
+
+  return 0;
+}
+
+static int dpdk_helper_exit_command(dpdk_helper_ctx_t *phc,
+                                    enum DPDK_HELPER_STATUS status) {
+  char errbuf[ERR_BUF_SIZE];
+  DPDK_HELPER_TRACE(phc->shm_name);
+
+  close(phc->pipes[1]);
+
+  if (phc->status == DPDK_HELPER_ALIVE_SENDING_EVENTS) {
+    phc->status = status;
+    DEBUG("%s:%s:%d %s", phc->shm_name, __FUNCTION__, __LINE__,
+          dpdk_helper_status_str(status));
+
+    int ret = dpdk_helper_command(phc, DPDK_CMD_QUIT, NULL, 0);
+    if (ret != 0) {
+      DEBUG("%s:%s:%d kill helper (pid=%lu)", phc->shm_name, __FUNCTION__,
+            __LINE__, (long)phc->pid);
+
+      int err = kill(phc->pid, SIGKILL);
+      if (err) {
+        ERROR("%s error sending kill to helper: %s", __FUNCTION__,
+              sstrerror(errno, errbuf, sizeof(errbuf)));
+      }
+    }
+  } else {
+
+    DEBUG("%s:%s:%d kill helper (pid=%lu)", phc->shm_name, __FUNCTION__,
+          __LINE__, (long)phc->pid);
+
+    int err = kill(phc->pid, SIGKILL);
+    if (err) {
+      ERROR("%s error sending kill to helper: %s", __FUNCTION__,
+            sstrerror(errno, errbuf, sizeof(errbuf)));
+    }
+  }
+
+  return 0;
+}
+
+static int dpdk_helper_eal_init(dpdk_helper_ctx_t *phc) {
+  phc->status = DPDK_HELPER_INITIALIZING_EAL;
+  DPDK_CHILD_LOG("%s:%s:%d DPDK_HELPER_INITIALIZING_EAL (start)\n",
+                 phc->shm_name, __FUNCTION__, __LINE__);
+
+  char *argp[DPDK_EAL_ARGC * 2 + 1];
+  int argc = 0;
+
+  /* EAL config must be initialized */
+  assert(phc->eal_config.coremask[0] != 0);
+  assert(phc->eal_config.memory_channels[0] != 0);
+  assert(phc->eal_config.process_type[0] != 0);
+  assert(phc->eal_config.file_prefix[0] != 0);
+
+  argp[argc++] = "collectd-dpdk";
+
+  argp[argc++] = "-c";
+  argp[argc++] = phc->eal_config.coremask;
+
+  argp[argc++] = "-n";
+  argp[argc++] = phc->eal_config.memory_channels;
+
+  if (strcasecmp(phc->eal_config.socket_memory, "") != 0) {
+    argp[argc++] = "--socket-mem";
+    argp[argc++] = phc->eal_config.socket_memory;
+  }
+
+  if (strcasecmp(phc->eal_config.file_prefix, DPDK_DEFAULT_RTE_CONFIG) != 0) {
+    argp[argc++] = "--file-prefix";
+    argp[argc++] = phc->eal_config.file_prefix;
+  }
+
+  argp[argc++] = "--proc-type";
+  argp[argc++] = phc->eal_config.process_type;
+
+  assert(argc <= (DPDK_EAL_ARGC * 2 + 1));
+
+  int ret = rte_eal_init(argc, argp);
+
+  if (ret < 0) {
+
+    phc->eal_initialized = 0;
+
+    DPDK_CHILD_LOG("dpdk_helper_eal_init: ERROR initializing EAL ret=%d\n",
+                   ret);
+
+    printf("dpdk_helper_eal_init: EAL arguments: ");
+    for (int i = 0; i < argc; i++) {
+      printf("%s ", argp[i]);
+    }
+    printf("\n");
+
+    return ret;
+  }
+
+  phc->eal_initialized = 1;
+
+  DPDK_CHILD_LOG("%s:%s:%d DPDK_HELPER_INITIALIZING_EAL (done)\n",
+                 phc->shm_name, __FUNCTION__, __LINE__);
+
+  return 0;
+}
+
+static int dpdk_helper_cmd_wait(dpdk_helper_ctx_t *phc, pid_t ppid) {
+  DPDK_CHILD_TRACE(phc->shm_name);
+
+  struct timespec ts;
+  cdtime_t now = cdtime();
+  cdtime_t cmd_wait_time = MS_TO_CDTIME_T(1500) + phc->cmd_wait_time * 2;
+  ts = CDTIME_T_TO_TIMESPEC(now + cmd_wait_time);
+
+  int ret = sem_timedwait(&phc->sema_cmd_start, &ts);
+  DPDK_CHILD_LOG("%s:%s:%d pid=%lu got sema_cmd_start (ret=%d, errno=%d)\n",
+                 phc->shm_name, __FUNCTION__, __LINE__, (long)getpid(), ret,
+                 errno);
+
+  if (phc->cmd == DPDK_CMD_QUIT) {
+    DPDK_CHILD_LOG("%s:%s:%d pid=%lu exiting\n", phc->shm_name, __FUNCTION__,
+                   __LINE__, (long)getpid());
+    exit(0);
+  } else if (ret == -1 && errno == ETIMEDOUT) {
+    if (phc->status == DPDK_HELPER_ALIVE_SENDING_EVENTS) {
+      DPDK_CHILD_LOG("%s:dpdk_helper_cmd_wait: sem timedwait()"
+                     " timeout, did collectd terminate?\n",
+                     phc->shm_name);
+      dpdk_helper_exit(phc, DPDK_HELPER_GRACEFUL_QUIT);
+    }
+  }
+#if COLLECT_DEBUG
+  int val = 0;
+  if (sem_getvalue(&phc->sema_cmd_start, &val) == 0)
+    DPDK_CHILD_LOG("%s:%s:%d pid=%lu wait sema_cmd_start (value=%d)\n",
+                   phc->shm_name, __FUNCTION__, __LINE__, (long)getpid(), val);
+#endif
+
+  /* Parent PID change means collectd died so quit the helper process. */
+  if (ppid != getppid()) {
+    DPDK_CHILD_LOG("dpdk_helper_cmd_wait: parent PID changed, quitting.\n");
+    dpdk_helper_exit(phc, DPDK_HELPER_GRACEFUL_QUIT);
+  }
+
+  /* Checking for DPDK primary process. */
+  if (!rte_eal_primary_proc_alive(phc->eal_config.file_prefix)) {
+    if (phc->eal_initialized) {
+      DPDK_CHILD_LOG(
+          "%s:dpdk_helper_cmd_wait: no primary alive but EAL initialized:"
+          " quitting.\n",
+          phc->shm_name);
+      dpdk_helper_exit(phc, DPDK_HELPER_NOT_INITIALIZED);
+    }
+
+    phc->status = DPDK_HELPER_WAITING_ON_PRIMARY;
+    DPDK_CHILD_LOG("%s:%s:%d DPDK_HELPER_WAITING_ON_PRIMARY\n", phc->shm_name,
+                   __FUNCTION__, __LINE__);
+
+    return -1;
+  }
+
+  if (!phc->eal_initialized) {
+    int ret = dpdk_helper_eal_init(phc);
+    if (ret != 0) {
+      DPDK_CHILD_LOG("Error initializing EAL\n");
+      dpdk_helper_exit(phc, DPDK_HELPER_NOT_INITIALIZED);
+    }
+    phc->status = DPDK_HELPER_ALIVE_SENDING_EVENTS;
+    DPDK_CHILD_LOG("%s:%s:%d DPDK_HELPER_ALIVE_SENDING_EVENTS\n", phc->shm_name,
+                   __FUNCTION__, __LINE__);
+    return -1;
+  }
+
+  return 0;
+}
+
+static int dpdk_helper_worker(dpdk_helper_ctx_t *phc) {
+  DPDK_CHILD_TRACE(phc->shm_name);
+
+  pid_t ppid = getppid();
+
+  while (1) {
+    if (dpdk_helper_cmd_wait(phc, ppid) == 0) {
+      DPDK_CHILD_LOG("%s:%s:%d DPDK command handle (cmd=%d, pid=%lu)\n",
+                     phc->shm_name, __FUNCTION__, __LINE__, phc->cmd,
+                     (long)getpid());
+      phc->cmd_result = dpdk_helper_command_handler(phc, phc->cmd);
+    } else {
+      phc->cmd_result = -1;
+    }
+
+    /* now kick collectd to get results */
+    int err = sem_post(&phc->sema_cmd_complete);
+    DPDK_CHILD_LOG("%s:%s:%d post sema_cmd_complete (pid=%lu)\n", phc->shm_name,
+                   __FUNCTION__, __LINE__, (long)getpid());
+    if (err) {
+      char errbuf[ERR_BUF_SIZE];
+      DPDK_CHILD_LOG("dpdk_helper_worker: error posting sema_cmd_complete "
+                     "semaphore (%s)\n",
+                     sstrerror(errno, errbuf, sizeof(errbuf)));
+    }
+
+#if COLLECT_DEBUG
+    int val = 0;
+    if (sem_getvalue(&phc->sema_cmd_complete, &val) == 0)
+      DPDK_CHILD_LOG("%s:%s:%d pid=%lu sema_cmd_complete (value=%d)\n",
+                     phc->shm_name, __FUNCTION__, __LINE__, (long)getpid(),
+                     val);
+#endif
+
+  } /* while(1) */
+
+  return 0;
+}
+
+static const char *dpdk_helper_status_str(enum DPDK_HELPER_STATUS status) {
+  switch (status) {
+  case DPDK_HELPER_ALIVE_SENDING_EVENTS:
+    return "DPDK_HELPER_ALIVE_SENDING_EVENTS";
+  case DPDK_HELPER_WAITING_ON_PRIMARY:
+    return "DPDK_HELPER_WAITING_ON_PRIMARY";
+  case DPDK_HELPER_INITIALIZING:
+    return "DPDK_HELPER_INITIALIZING";
+  case DPDK_HELPER_INITIALIZING_EAL:
+    return "DPDK_HELPER_INITIALIZING_EAL";
+  case DPDK_HELPER_GRACEFUL_QUIT:
+    return "DPDK_HELPER_GRACEFUL_QUIT";
+  case DPDK_HELPER_NOT_INITIALIZED:
+    return "DPDK_HELPER_NOT_INITIALIZED";
+  default:
+    return "UNKNOWN";
+  }
+}
+
+static int dpdk_helper_status_check(dpdk_helper_ctx_t *phc) {
+  DEBUG("%s:%s:%d pid=%u %s", phc->shm_name, __FUNCTION__, __LINE__, getpid(),
+        dpdk_helper_status_str(phc->status));
+  char errbuf[ERR_BUF_SIZE];
+
+  if (phc->status == DPDK_HELPER_GRACEFUL_QUIT) {
+    return 0;
+  } else if (phc->status == DPDK_HELPER_NOT_INITIALIZED) {
+    phc->status = DPDK_HELPER_INITIALIZING;
+    DEBUG("%s:%s:%d DPDK_HELPER_INITIALIZING", phc->shm_name, __FUNCTION__,
+          __LINE__);
+    int err = dpdk_helper_spawn(phc);
+    if (err) {
+      ERROR("dpdkstat: error spawning helper %s",
+            sstrerror(errno, errbuf, sizeof(errbuf)));
+    }
+    return -1;
+  }
+
+  pid_t ws = waitpid(phc->pid, NULL, WNOHANG);
+  if (ws != 0) {
+    phc->status = DPDK_HELPER_INITIALIZING;
+    DEBUG("%s:%s:%d DPDK_HELPER_INITIALIZING", phc->shm_name, __FUNCTION__,
+          __LINE__);
+    int err = dpdk_helper_spawn(phc);
+    if (err) {
+      ERROR("dpdkstat: error spawning helper %s",
+            sstrerror(errno, errbuf, sizeof(errbuf)));
+    }
+    return -1;
+  }
+
+  if (phc->status == DPDK_HELPER_INITIALIZING_EAL) {
+    return -1;
+  }
+
+  return 0;
+}
+
+static void dpdk_helper_check_pipe(dpdk_helper_ctx_t *phc) {
+  char buf[DPDK_MAX_BUFFER_SIZE];
+  char out[DPDK_MAX_BUFFER_SIZE];
+
+  /* non blocking check on helper logging pipe */
+  struct pollfd fds = {
+      .fd = phc->pipes[0], .events = POLLIN,
+  };
+  int data_avail = poll(&fds, 1, 0);
+  if (data_avail < 0) {
+    if (errno != EINTR || errno != EAGAIN) {
+      char errbuf[ERR_BUF_SIZE];
+      ERROR("%s: poll(2) failed: %s", phc->shm_name,
+            sstrerror(errno, errbuf, sizeof(errbuf)));
+    }
+  }
+  while (data_avail) {
+    int nbytes = read(phc->pipes[0], buf, sizeof(buf));
+    if (nbytes <= 0)
+      break;
+    sstrncpy(out, buf, nbytes);
+    DEBUG("%s: helper process:\n%s", phc->shm_name, out);
+  }
+}
+
+int dpdk_helper_command(dpdk_helper_ctx_t *phc, enum DPDK_CMD cmd, int *result,
+                        cdtime_t cmd_wait_time) {
+  if (phc == NULL) {
+    ERROR("Invalid argument(phc)");
+    return -EINVAL;
+  }
+
+  DEBUG("%s:%s:%d pid=%lu, cmd=%d", phc->shm_name, __FUNCTION__, __LINE__,
+        (long)getpid(), cmd);
+
+  phc->cmd_wait_time = cmd_wait_time;
+
+  int ret = dpdk_helper_status_check(phc);
+
+  dpdk_helper_check_pipe(phc);
+
+  if (ret != 0) {
+    return ret;
+  }
+
+  DEBUG("%s: DPDK command execute (cmd=%d)", phc->shm_name, cmd);
+
+  phc->cmd_result = 0;
+  phc->cmd = cmd;
+
+  /* kick helper to process command */
+  int err = sem_post(&phc->sema_cmd_start);
+  if (err) {
+    char errbuf[ERR_BUF_SIZE];
+    ERROR("dpdk_helper_worker: error posting sema_cmd_start semaphore (%s)",
+          sstrerror(errno, errbuf, sizeof(errbuf)));
+  }
+
+#if COLLECT_DEBUG
+  int val = 0;
+  if (sem_getvalue(&phc->sema_cmd_start, &val) == 0)
+    DEBUG("%s:dpdk_helper_command: post sema_cmd_start (value=%d)",
+          phc->shm_name, val);
+#endif
+
+  if (phc->cmd != DPDK_CMD_QUIT) {
+
+    /* wait for helper to complete processing */
+    struct timespec ts;
+    cdtime_t now = cdtime();
+
+    if (phc->status != DPDK_HELPER_ALIVE_SENDING_EVENTS) {
+      cmd_wait_time = MS_TO_CDTIME_T(DPDK_CDM_DEFAULT_TIMEOUT);
+    }
+
+    ts = CDTIME_T_TO_TIMESPEC(now + cmd_wait_time);
+    ret = sem_timedwait(&phc->sema_cmd_complete, &ts);
+    if (ret == -1 && errno == ETIMEDOUT) {
+      DPDK_HELPER_TRACE(phc->shm_name);
+      DEBUG("%s:sema_cmd_start: timeout in collectd thread: is a DPDK Primary "
+            "running?",
+            phc->shm_name);
+      return -ETIMEDOUT;
+    }
+
+#if COLLECT_DEBUG
+    val = 0;
+    if (sem_getvalue(&phc->sema_cmd_complete, &val) == 0)
+      DEBUG("%s:dpdk_helper_command: wait sema_cmd_complete (value=%d)",
+            phc->shm_name, val);
+#endif
+
+    if (result) {
+      *result = phc->cmd_result;
+    }
+  }
+
+  dpdk_helper_check_pipe(phc);
+
+  DEBUG("%s: DPDK command complete (cmd=%d, result=%d)", phc->shm_name,
+        phc->cmd, phc->cmd_result);
+
+  return 0;
+}
+
+uint64_t strtoull_safe(const char *str, int *err) {
+  uint64_t val = 0;
+  char *endptr;
+  int res = 0;
+
+  val = strtoull(str, &endptr, 16);
+  if (*endptr) {
+    ERROR("%s Failed to parse the value %s, endptr=%c", __FUNCTION__, str,
+          *endptr);
+    res = -EINVAL;
+  }
+  if (err != NULL)
+    *err = res;
+  return val;
+}
+
+uint128_t str_to_uint128(const char *str, int len) {
+  uint128_t lcore_mask;
+  int err = 0;
+
+  memset(&lcore_mask, 0, sizeof(lcore_mask));
+
+  if (len <= 2 || strncmp(str, "0x", 2) != 0) {
+    ERROR("%s Value %s should be represened in hexadecimal format",
+          __FUNCTION__, str);
+    return lcore_mask;
+  }
+  /* If str is <= 64 bit long ('0x' + 16 chars = 18 chars) then
+   * conversion is straightforward. Otherwise str is splitted into 64b long
+   * blocks */
+  if (len <= 18) {
+    lcore_mask.low = strtoull_safe(str, &err);
+    if (err)
+      return lcore_mask;
+  } else {
+    char low_str[DATA_MAX_NAME_LEN];
+    char high_str[DATA_MAX_NAME_LEN];
+
+    memset(high_str, 0, sizeof(high_str));
+    memset(low_str, 0, sizeof(low_str));
+
+    strncpy(high_str, str, len - 16);
+    strncpy(low_str, str + len - 16, 16);
+
+    lcore_mask.low = strtoull_safe(low_str, &err);
+    if (err)
+      return lcore_mask;
+
+    lcore_mask.high = strtoull_safe(high_str, &err);
+    if (err) {
+      lcore_mask.low = 0;
+      return lcore_mask;
+    }
+  }
+  return lcore_mask;
+}
+
+uint8_t dpdk_helper_eth_dev_count() {
+  uint8_t ports = rte_eth_dev_count();
+  if (ports == 0) {
+    ERROR(
+        "%s:%d: No DPDK ports available. Check bound devices to DPDK driver.\n",
+        __FUNCTION__, __LINE__);
+    return ports;
+  }
+
+  if (ports > RTE_MAX_ETHPORTS) {
+    ERROR("%s:%d: Number of DPDK ports (%u) is greater than "
+          "RTE_MAX_ETHPORTS=%d. Ignoring extra ports\n",
+          __FUNCTION__, __LINE__, ports, RTE_MAX_ETHPORTS);
+    ports = RTE_MAX_ETHPORTS;
+  }
+
+  return ports;
+}
diff --git a/src/utils_dpdk.h b/src/utils_dpdk.h
new file mode 100644 (file)
index 0000000..f97a6b5
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * collectd - src/utils_dpdk.h
+ * MIT License
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *   Maryam Tahhan <maryam.tahhan@intel.com>
+ *   Harry van Haaren <harry.van.haaren@intel.com>
+ *   Taras Chornyi <tarasx.chornyi@intel.com>
+ *   Serhiy Pshyk <serhiyx.pshyk@intel.com>
+ *   Krzysztof Matczak <krzysztofx.matczak@intel.com>
+ */
+
+#ifndef UTILS_DPDK_H
+#define UTILS_DPDK_H
+
+#include <rte_version.h>
+
+#define ERR_BUF_SIZE 1024
+
+enum DPDK_CMD {
+  DPDK_CMD_NONE = 0,
+  DPDK_CMD_QUIT,
+  DPDK_CMD_INIT,
+  DPDK_CMD_GET_STATS,
+  DPDK_CMD_GET_EVENTS,
+  __DPDK_CMD_LAST,
+};
+
+struct dpdk_eal_config_s {
+  char coremask[DATA_MAX_NAME_LEN];
+  char memory_channels[DATA_MAX_NAME_LEN];
+  char socket_memory[DATA_MAX_NAME_LEN];
+  char process_type[DATA_MAX_NAME_LEN];
+  char file_prefix[DATA_MAX_NAME_LEN];
+};
+typedef struct dpdk_eal_config_s dpdk_eal_config_t;
+
+struct uint128_s {
+  u_int64_t high;
+  u_int64_t low;
+};
+typedef struct uint128_s uint128_t;
+
+typedef struct dpdk_helper_ctx_s dpdk_helper_ctx_t;
+
+int dpdk_helper_init(const char *name, size_t data_size,
+                     dpdk_helper_ctx_t **pphc);
+int dpdk_helper_shutdown(dpdk_helper_ctx_t *phc);
+int dpdk_helper_eal_config_parse(dpdk_helper_ctx_t *phc, oconfig_item_t *ci);
+int dpdk_helper_eal_config_set(dpdk_helper_ctx_t *phc, dpdk_eal_config_t *ec);
+int dpdk_helper_eal_config_get(dpdk_helper_ctx_t *phc, dpdk_eal_config_t *ec);
+int dpdk_helper_command(dpdk_helper_ctx_t *phc, enum DPDK_CMD cmd, int *result,
+                        cdtime_t cmd_wait_time);
+void *dpdk_helper_priv_get(dpdk_helper_ctx_t *phc);
+int dpdk_helper_data_size_get(dpdk_helper_ctx_t *phc);
+uint8_t dpdk_helper_eth_dev_count();
+
+/* forward declaration of handler function that is called by helper from
+ * child process. not implemented in helper. must be provided by client. */
+int dpdk_helper_command_handler(dpdk_helper_ctx_t *phc, enum DPDK_CMD cmd);
+
+uint128_t str_to_uint128(const char *str, int len);
+
+/* logging functions that should be used in child process */
+#define DPDK_CHILD_LOG(...) fprintf(stdout, __VA_ARGS__)
+#define DPDK_CHILD_TRACE(_name)                                                \
+  fprintf(stdout, "%s:%s:%d pid=%u\n", _name, __FUNCTION__, __LINE__, getpid())
+
+#endif /* UTILS_DPDK_H */
index ecc5674..f94e2e5 100644 (file)
@@ -255,5 +255,3 @@ char *fbh_get(fbhash_t *h, const char *key) /* {{{ */
 
   return (value_copy);
 } /* }}} char *fbh_get */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index 79e9c00..fcd6e92 100644 (file)
@@ -48,5 +48,3 @@ void fbh_destroy(fbhash_t *h);
 char *fbh_get(fbhash_t *h, const char *key);
 
 #endif /* UTILS_FBHASH_H */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index 4f509f4..0436340 100644 (file)
@@ -237,5 +237,3 @@ int format_graphite(char *buffer, size_t buffer_size, data_set_t const *ds,
   sfree(rates);
   return (status);
 } /* int format_graphite */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index 415a283..a82142f 100644 (file)
@@ -49,12 +49,12 @@ static data_set_t ds_double = {
 
 DEF_TEST(metric_name) {
   struct {
-    char *plugin_instance;
-    char *type_instance;
-    char *prefix;
-    char *suffix;
+    const char *plugin_instance;
+    const char *type_instance;
+    const char *prefix;
+    const char *suffix;
     unsigned int flags;
-    char *want_name;
+    const char *want_name;
   } cases[] = {
       {
           .want_name = "example@com.test.single",
@@ -157,8 +157,35 @@ DEF_TEST(metric_name) {
   return 0;
 }
 
+DEF_TEST(null_termination) {
+  value_list_t vl = {
+      .values = &(value_t){.gauge = 1337},
+      .values_len = 1,
+      .time = TIME_T_TO_CDTIME_T_STATIC(1480063672),
+      .interval = TIME_T_TO_CDTIME_T_STATIC(10),
+      .host = "example.com",
+      .plugin = "test",
+      .type = "single",
+  };
+  char const *want = "example_com.test.single 1337 1480063672\r\n";
+
+  char buffer[128];
+  for (size_t i = 0; i < sizeof(buffer); i++)
+    buffer[i] = (char)i;
+
+  EXPECT_EQ_INT(0, format_graphite(buffer, sizeof(buffer), &ds_single, &vl,
+                                   NULL, NULL, '_', 0));
+  EXPECT_EQ_STR(want, buffer);
+  EXPECT_EQ_INT(0, buffer[strlen(want)]);
+  for (size_t i = strlen(want) + 1; i < sizeof(buffer); i++)
+    EXPECT_EQ_INT((int)i, (int)buffer[i]);
+
+  return 0;
+}
+
 int main(void) {
   RUN_TEST(metric_name);
+  RUN_TEST(null_termination);
 
   END_TEST;
 }
index 0a95a86..1a0e151 100644 (file)
@@ -685,5 +685,3 @@ int format_json_notification(char *buffer, size_t buffer_size, /* {{{ */
   return ENOTSUP;
 } /* }}} int format_json_notification */
 #endif
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index 4c25d18..1e54b97 100644 (file)
@@ -336,5 +336,3 @@ int format_kairosdb_value_list(char *buffer, /* {{{ */
       buffer, ret_buffer_fill, ret_buffer_free, ds, vl, store_rates,
       (*ret_buffer_free) - 2));
 } /* }}} int format_kairosdb_value_list */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index f0311e8..f30b265 100644 (file)
@@ -342,5 +342,3 @@ double latency_counter_get_rate(const latency_counter_t *lc, /* {{{ */
 
   return sum / (CDTIME_T_TO_DOUBLE(now - lc->start_time));
 } /* }}} double latency_counter_get_rate */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index 85493e1..9d878da 100644 (file)
@@ -61,5 +61,3 @@ cdtime_t latency_counter_get_percentile(latency_counter_t *lc, double percent);
  */
 double latency_counter_get_rate(const latency_counter_t *lc, cdtime_t lower,
                                 cdtime_t upper, const cdtime_t now);
-
-/* vim: set sw=2 sts=2 et : */
index ef29d8b..427a159 100644 (file)
@@ -232,5 +232,3 @@ int main(void) {
 
   END_TEST;
 }
-
-/* vim: set sw=2 sts=2 et : */
index dcb84af..7710121 100644 (file)
@@ -317,5 +317,3 @@ int luaC_pushvaluelist(lua_State *L, const data_set_t *ds,
 
   return (0);
 } /* }}} int luaC_pushvaluelist */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index 8ff507c..61d9070 100644 (file)
@@ -53,4 +53,3 @@ int luaC_pushvaluelist(lua_State *L, const data_set_t *ds,
                        const value_list_t *vl);
 
 #endif /* UTILS_LUA_H */
-/* vim: set sw=2 sts=2 et fdm=marker : */
index 11b3f74..e8add2d 100644 (file)
@@ -374,5 +374,3 @@ void *match_get_user_data(cu_match_t *obj) {
     return (NULL);
   return (obj->user_data);
 } /* void *match_get_user_data */
-
-/* vim: set sw=2 sts=2 ts=8 : */
index 1383530..1cff1eb 100644 (file)
@@ -177,5 +177,3 @@ int match_apply(cu_match_t *obj, const char *str);
 void *match_get_user_data(cu_match_t *obj);
 
 #endif /* UTILS_MATCH_H */
-
-/* vim: set sw=2 sts=2 ts=8 : */
index 695038d..76fc8d4 100644 (file)
@@ -109,5 +109,3 @@ int main(void) {
 
   END_TEST;
 }
-
-/* vim: set sw=2 sts=2 et : */
diff --git a/src/utils_ovs.c b/src/utils_ovs.c
new file mode 100644 (file)
index 0000000..57da628
--- /dev/null
@@ -0,0 +1,1371 @@
+/**
+ * collectd - src/utils_ovs.c
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *   Volodymyr Mytnyk <volodymyrx.mytnyk@intel.com>
+ **/
+
+/* clang-format off */
+/*
+ *                         OVS DB API internal architecture diagram
+ * +------------------------------------------------------------------------------+
+ * |OVS plugin      |OVS utils                                                    |
+ * |                |     +------------------------+                              |
+ * |                |     |      echo handler      |                JSON request/ |
+ * |                |  +--+ (ovs_db_table_echo_cb) +<---+---------+ update event/ |
+ * |                |  |  |                        |    |         | result        |
+ * |                |  |  +------------------------+    |         |               |
+ * |                |  |                                |    +----+---+--------+  |
+ * |  +----------+  |  |  +------------------------+    |    |        |        |  |
+ * |  |  update  |  |  |  |     update handler     |    |    |  YAJL  |  JSON  |  |
+ * |  | callback +<-------+(ovs_db_table_update_cp)+<---+    | parser | reader |  |
+ * |  +----------+  |  |  |                        |    |    |        |        |  |
+ * |                |  |  +------------------------+    |    +--------+---+----+  |
+ * |                |  |                                |                 ^       |
+ * |  +----------+  |  |  +------------------------+    |                 |       |
+ * |  |  result  |  |  |  |     result handler     |    |                 |       |
+ * |  | callback +<-------+   (ovs_db_result_cb)   +<---+        JSON raw |       |
+ * |  +----------+  |  |  |                        |               data   |       |
+ * |                |  |  +------------------------+                      |       |
+ * |                |  |                                                  |       |
+ * |                |  |    +------------------+             +------------+----+  |
+ * |  +----------+  |  |    |thread|           |             |thread|          |  |
+ * |  |   init   |  |  |    |                  |  reconnect  |                 |  |
+ * |  | callback +<---------+   EVENT WORKER   +<------------+   POLL WORKER   |  |
+ * |  +----------+  |  |    +------------------+             +--------+--------+  |
+ * |                |  |                                              ^           |
+ * +----------------+-------------------------------------------------------------+
+ *                     |                                              |
+ *                 JSON|echo reply                                 raw|data
+ *                     v                                              v
+ * +-------------------+----------------------------------------------+-----------+
+ * |                                 TCP/UNIX socket                              |
+ * +-------------------------------------------------------------------------------
+ */
+/* clang-format on */
+
+/* collectd headers */
+#include "collectd.h"
+
+#include "common.h"
+
+/* private headers */
+#include "utils_ovs.h"
+
+/* system libraries */
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_POLL_H
+#include <poll.h>
+#endif
+#if HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+
+#include <semaphore.h>
+
+#define OVS_ERROR(fmt, ...)                                                    \
+  do {                                                                         \
+    ERROR("ovs_utils: " fmt, ##__VA_ARGS__);                                   \
+  } while (0)
+#define OVS_DEBUG(fmt, ...)                                                    \
+  do {                                                                         \
+    DEBUG("%s:%d:%s(): " fmt, __FILE__, __LINE__, __FUNCTION__,                \
+          ##__VA_ARGS__);                                                      \
+  } while (0)
+
+#define OVS_DB_POLL_TIMEOUT 1           /* poll receive timeout (sec) */
+#define OVS_DB_POLL_READ_BLOCK_SIZE 512 /* read block size (bytes) */
+#define OVS_DB_DEFAULT_DB_NAME "Open_vSwitch"
+
+#define OVS_DB_EVENT_TIMEOUT 5 /* event thread timeout (sec) */
+#define OVS_DB_EVENT_TERMINATE 1
+#define OVS_DB_EVENT_CONN_ESTABLISHED 2
+#define OVS_DB_EVENT_CONN_TERMINATED 3
+
+#define OVS_DB_POLL_STATE_RUNNING 1
+#define OVS_DB_POLL_STATE_EXITING 2
+
+#define OVS_DB_SEND_REQ_TIMEOUT 5 /* send request timeout (sec) */
+
+#define OVS_YAJL_CALL(func, ...)                                               \
+  do {                                                                         \
+    yajl_gen_ret = yajl_gen_status_ok;                                         \
+    if ((yajl_gen_ret = func(__VA_ARGS__)) != yajl_gen_status_ok)              \
+      goto yajl_gen_failure;                                                   \
+  } while (0)
+#define OVS_YAJL_ERROR_BUFFER_SIZE 1024
+#define OVS_ERROR_BUFF_SIZE 512
+#define OVS_UID_STR_SIZE 17 /* 64-bit HEX string len + '\0' */
+
+/* JSON reader internal data */
+struct ovs_json_reader_s {
+  char *buff_ptr;
+  size_t buff_size;
+  size_t buff_offset;
+  size_t json_offset;
+};
+typedef struct ovs_json_reader_s ovs_json_reader_t;
+
+/* Result callback declaration */
+struct ovs_result_cb_s {
+  sem_t sync;
+  ovs_db_result_cb_t call;
+};
+typedef struct ovs_result_cb_s ovs_result_cb_t;
+
+/* Table callback declaration */
+struct ovs_table_cb_s {
+  ovs_db_table_cb_t call;
+};
+typedef struct ovs_table_cb_s ovs_table_cb_t;
+
+/* Callback declaration */
+struct ovs_callback_s {
+  uint64_t uid;
+  union {
+    ovs_result_cb_t result;
+    ovs_table_cb_t table;
+  };
+  struct ovs_callback_s *next;
+  struct ovs_callback_s *prev;
+};
+typedef struct ovs_callback_s ovs_callback_t;
+
+/* Event thread data declaration */
+struct ovs_event_thread_s {
+  pthread_t tid;
+  pthread_mutex_t mutex;
+  pthread_cond_t cond;
+  int value;
+};
+typedef struct ovs_event_thread_s ovs_event_thread_t;
+
+/* Poll thread data declaration */
+struct ovs_poll_thread_s {
+  pthread_t tid;
+  pthread_mutex_t mutex;
+  int state;
+};
+typedef struct ovs_poll_thread_s ovs_poll_thread_t;
+
+/* OVS DB internal data declaration */
+struct ovs_db_s {
+  ovs_poll_thread_t poll_thread;
+  ovs_event_thread_t event_thread;
+  pthread_mutex_t mutex;
+  ovs_callback_t *remote_cb;
+  ovs_db_callback_t cb;
+  char service[OVS_DB_ADDR_SERVICE_SIZE];
+  char node[OVS_DB_ADDR_NODE_SIZE];
+  char unix_path[OVS_DB_ADDR_NODE_SIZE];
+  int sock;
+};
+
+/* Global variables */
+static uint64_t ovs_uid = 0;
+static pthread_mutex_t ovs_uid_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/* Post an event to event thread.
+ * Possible events are:
+ *  OVS_DB_EVENT_TERMINATE
+ *  OVS_DB_EVENT_CONN_ESTABLISHED
+ *  OVS_DB_EVENT_CONN_TERMINATED
+ */
+static void ovs_db_event_post(ovs_db_t *pdb, int event) {
+  pthread_mutex_lock(&pdb->event_thread.mutex);
+  pdb->event_thread.value = event;
+  pthread_mutex_unlock(&pdb->event_thread.mutex);
+  pthread_cond_signal(&pdb->event_thread.cond);
+}
+
+/* Check if POLL thread is still running. Returns
+ * 1 if running otherwise 0 is returned */
+static _Bool ovs_db_poll_is_running(ovs_db_t *pdb) {
+  int state = 0;
+  pthread_mutex_lock(&pdb->poll_thread.mutex);
+  state = pdb->poll_thread.state;
+  pthread_mutex_unlock(&pdb->poll_thread.mutex);
+  return (state == OVS_DB_POLL_STATE_RUNNING);
+}
+
+/* Generate unique identifier (UID). It is used by OVS DB API
+ * to set "id" field for any OVS DB JSON request. */
+static uint64_t ovs_uid_generate() {
+  uint64_t new_uid;
+  pthread_mutex_lock(&ovs_uid_mutex);
+  new_uid = ++ovs_uid;
+  pthread_mutex_unlock(&ovs_uid_mutex);
+  return new_uid;
+}
+
+/*
+ * Callback API. These function are used to store
+ * registered callbacks in OVS DB API.
+ */
+
+/* Add new callback into OVS DB object */
+static void ovs_db_callback_add(ovs_db_t *pdb, ovs_callback_t *new_cb) {
+  pthread_mutex_lock(&pdb->mutex);
+  if (pdb->remote_cb)
+    pdb->remote_cb->prev = new_cb;
+  new_cb->next = pdb->remote_cb;
+  new_cb->prev = NULL;
+  pdb->remote_cb = new_cb;
+  pthread_mutex_unlock(&pdb->mutex);
+}
+
+/* Remove callback from OVS DB object */
+static void ovs_db_callback_remove(ovs_db_t *pdb, ovs_callback_t *del_cb) {
+  pthread_mutex_lock(&pdb->mutex);
+  ovs_callback_t *pre_cb = del_cb->prev;
+  ovs_callback_t *next_cb = del_cb->next;
+
+  if (next_cb)
+    next_cb->prev = del_cb->prev;
+
+  if (pre_cb)
+    pre_cb->next = del_cb->next;
+  else
+    pdb->remote_cb = del_cb->next;
+
+  free(del_cb);
+  pthread_mutex_unlock(&pdb->mutex);
+}
+
+/* Remove all callbacks form OVS DB object */
+static void ovs_db_callback_remove_all(ovs_db_t *pdb) {
+  pthread_mutex_lock(&pdb->mutex);
+  for (ovs_callback_t *del_cb = pdb->remote_cb; pdb->remote_cb;
+       del_cb = pdb->remote_cb) {
+    pdb->remote_cb = del_cb->next;
+    free(del_cb);
+  }
+  pdb->remote_cb = NULL;
+  pthread_mutex_unlock(&pdb->mutex);
+}
+
+/* Get/find callback in OVS DB object by UID. Returns pointer
+ * to requested callback otherwise NULL is returned.
+ *
+ * IMPORTANT NOTE:
+ *   The OVS DB mutex MUST be locked by the caller
+ *   to make sure that returned callback is still valid.
+ */
+static ovs_callback_t *ovs_db_callback_get(ovs_db_t *pdb, uint64_t uid) {
+  for (ovs_callback_t *cb = pdb->remote_cb; cb != NULL; cb = cb->next)
+    if (cb->uid == uid)
+      return cb;
+  return NULL;
+}
+
+/* Send all requested data to the socket. Returns 0 if
+ * ALL request data has been sent otherwise negative value
+ * is returned */
+static int ovs_db_data_send(const ovs_db_t *pdb, const char *data, size_t len) {
+  ssize_t nbytes = 0;
+  size_t rem = len;
+  size_t off = 0;
+
+  while (rem > 0) {
+    if ((nbytes = send(pdb->sock, data + off, rem, 0)) <= 0)
+      return (-1);
+    rem -= (size_t)nbytes;
+    off += (size_t)nbytes;
+  }
+  return (0);
+}
+
+/*
+ * YAJL (Yet Another JSON Library) helper functions
+ * Documentation (https://lloyd.github.io/yajl/)
+ */
+
+/* Add null-terminated string into YAJL generator handle (JSON object).
+ * Similar function to yajl_gen_string() but takes null-terminated string
+ * instead of string and its length.
+ *
+ * jgen   - YAJL generator handle allocated by yajl_gen_alloc()
+ * string - Null-terminated string
+ */
+static yajl_gen_status ovs_yajl_gen_tstring(yajl_gen hander,
+                                            const char *string) {
+  return yajl_gen_string(hander, (const unsigned char *)string, strlen(string));
+}
+
+/* Add YAJL value into YAJL generator handle (JSON object)
+ *
+ * jgen - YAJL generator handle allocated by yajl_gen_alloc()
+ * jval - YAJL value usually returned by yajl_tree_get()
+ */
+static yajl_gen_status ovs_yajl_gen_val(yajl_gen jgen, yajl_val jval) {
+  size_t array_len = 0;
+  yajl_val *jvalues = NULL;
+  yajl_val jobj_value = NULL;
+  const char *obj_key = NULL;
+  size_t obj_len = 0;
+  yajl_gen_status yajl_gen_ret = yajl_gen_status_ok;
+
+  if (YAJL_IS_STRING(jval))
+    OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, YAJL_GET_STRING(jval));
+  else if (YAJL_IS_DOUBLE(jval))
+    OVS_YAJL_CALL(yajl_gen_double, jgen, YAJL_GET_DOUBLE(jval));
+  else if (YAJL_IS_INTEGER(jval))
+    OVS_YAJL_CALL(yajl_gen_double, jgen, YAJL_GET_INTEGER(jval));
+  else if (YAJL_IS_TRUE(jval))
+    OVS_YAJL_CALL(yajl_gen_bool, jgen, 1);
+  else if (YAJL_IS_FALSE(jval))
+    OVS_YAJL_CALL(yajl_gen_bool, jgen, 0);
+  else if (YAJL_IS_NULL(jval))
+    OVS_YAJL_CALL(yajl_gen_null, jgen);
+  else if (YAJL_IS_ARRAY(jval)) {
+    /* create new array and add all elements into the array */
+    array_len = YAJL_GET_ARRAY(jval)->len;
+    jvalues = YAJL_GET_ARRAY(jval)->values;
+    OVS_YAJL_CALL(yajl_gen_array_open, jgen);
+    for (size_t i = 0; i < array_len; i++)
+      OVS_YAJL_CALL(ovs_yajl_gen_val, jgen, jvalues[i]);
+    OVS_YAJL_CALL(yajl_gen_array_close, jgen);
+  } else if (YAJL_IS_OBJECT(jval)) {
+    /* create new object and add all elements into the object */
+    OVS_YAJL_CALL(yajl_gen_map_open, jgen);
+    obj_len = YAJL_GET_OBJECT(jval)->len;
+    for (size_t i = 0; i < obj_len; i++) {
+      obj_key = YAJL_GET_OBJECT(jval)->keys[i];
+      jobj_value = YAJL_GET_OBJECT(jval)->values[i];
+      OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, obj_key);
+      OVS_YAJL_CALL(ovs_yajl_gen_val, jgen, jobj_value);
+    }
+    OVS_YAJL_CALL(yajl_gen_map_close, jgen);
+  } else {
+    OVS_ERROR("%s() unsupported value type %d (skip)", __FUNCTION__,
+              (int)(jval)->type);
+    goto yajl_gen_failure;
+  }
+  return yajl_gen_status_ok;
+
+yajl_gen_failure:
+  OVS_ERROR("%s() error to generate value", __FUNCTION__);
+  return yajl_gen_ret;
+}
+
+/* OVS DB echo request handler. When OVS DB sends
+ * "echo" request to the client, client should generate
+ * "echo" replay with the same content received in the
+ * request */
+static int ovs_db_table_echo_cb(const ovs_db_t *pdb, yajl_val jnode) {
+  yajl_val jparams;
+  yajl_val jid;
+  yajl_gen jgen;
+  size_t resp_len = 0;
+  const char *resp = NULL;
+  const char *params_path[] = {"params", NULL};
+  const char *id_path[] = {"id", NULL};
+  yajl_gen_status yajl_gen_ret;
+
+  if ((jgen = yajl_gen_alloc(NULL)) == NULL)
+    return (-1);
+
+  /* check & get request attributes */
+  if ((jparams = yajl_tree_get(jnode, params_path, yajl_t_array)) == NULL ||
+      ((jid = yajl_tree_get(jnode, id_path, yajl_t_any)) == NULL)) {
+    OVS_ERROR("parse echo request failed");
+    goto yajl_gen_failure;
+  }
+
+  /* generate JSON echo response */
+  OVS_YAJL_CALL(yajl_gen_map_open, jgen);
+
+  OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "result");
+  OVS_YAJL_CALL(ovs_yajl_gen_val, jgen, jparams);
+
+  OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "error");
+  OVS_YAJL_CALL(yajl_gen_null, jgen);
+
+  OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "id");
+  OVS_YAJL_CALL(ovs_yajl_gen_val, jgen, jid);
+
+  OVS_YAJL_CALL(yajl_gen_map_close, jgen);
+  OVS_YAJL_CALL(yajl_gen_get_buf, jgen, (const unsigned char **)&resp,
+                &resp_len);
+
+  /* send the response */
+  OVS_DEBUG("response: %s", resp);
+  if (ovs_db_data_send(pdb, resp, resp_len) < 0) {
+    OVS_ERROR("send echo reply failed");
+    goto yajl_gen_failure;
+  }
+  /* clean up and return success */
+  yajl_gen_clear(jgen);
+  return (0);
+
+yajl_gen_failure:
+  /* release memory */
+  yajl_gen_clear(jgen);
+  return (-1);
+}
+
+/* Get OVS DB registered callback by YAJL val. The YAJL
+ * value should be YAJL string (UID). Returns NULL if
+ * callback hasn't been found. See also ovs_db_callback_get()
+ * description for addition info.
+ */
+static ovs_callback_t *ovs_db_table_callback_get(ovs_db_t *pdb, yajl_val jid) {
+  char *endptr = NULL;
+  const char *suid = NULL;
+  uint64_t uid;
+
+  if (jid && YAJL_IS_STRING(jid)) {
+    suid = YAJL_GET_STRING(jid);
+    uid = (uint64_t)strtoul(suid, &endptr, 16);
+    if (*endptr == '\0' && uid)
+      return ovs_db_callback_get(pdb, uid);
+  }
+
+  return NULL;
+}
+
+/* OVS DB table update event handler.
+ * This callback is called by POLL thread if OVS DB
+ * table update callback is received from the DB
+ * server. Once registered callback found, it's called
+ * by this handler. */
+static int ovs_db_table_update_cb(ovs_db_t *pdb, yajl_val jnode) {
+  ovs_callback_t *cb = NULL;
+  yajl_val jvalue;
+  yajl_val jparams;
+  yajl_val jtable_updates;
+  const char *params_path[] = {"params", NULL};
+  const char *id_path[] = {"id", NULL};
+
+  /* check & get request attributes */
+  if ((jparams = yajl_tree_get(jnode, params_path, yajl_t_array)) == NULL ||
+      (yajl_tree_get(jnode, id_path, yajl_t_null) == NULL)) {
+    OVS_ERROR("invalid OVS DB request received");
+    return (-1);
+  }
+
+  /* check array length: [<json-value>, <table-updates>] */
+  if ((YAJL_GET_ARRAY(jparams) == NULL) ||
+      (YAJL_GET_ARRAY(jparams)->len != 2)) {
+    OVS_ERROR("invalid OVS DB request received");
+    return (-1);
+  }
+
+  jvalue = YAJL_GET_ARRAY(jparams)->values[0];
+  jtable_updates = YAJL_GET_ARRAY(jparams)->values[1];
+  if ((!YAJL_IS_OBJECT(jtable_updates)) || (!YAJL_IS_STRING(jvalue))) {
+    OVS_ERROR("invalid OVS DB request id or table update received");
+    return (-1);
+  }
+
+  /* find registered callback based on <json-value> */
+  pthread_mutex_lock(&pdb->mutex);
+  cb = ovs_db_table_callback_get(pdb, jvalue);
+  if (cb == NULL || cb->table.call == NULL) {
+    OVS_ERROR("No OVS DB table update callback found");
+    pthread_mutex_unlock(&pdb->mutex);
+    return (-1);
+  }
+
+  /* call registered callback */
+  cb->table.call(jtable_updates);
+  pthread_mutex_unlock(&pdb->mutex);
+  return 0;
+}
+
+/* OVS DB result request handler.
+ * This callback is called by POLL thread if OVS DB
+ * result reply is received from the DB server.
+ * Once registered callback found, it's called
+ * by this handler. */
+static int ovs_db_result_cb(ovs_db_t *pdb, yajl_val jnode) {
+  ovs_callback_t *cb = NULL;
+  yajl_val jresult;
+  yajl_val jerror;
+  yajl_val jid;
+  const char *result_path[] = {"result", NULL};
+  const char *error_path[] = {"error", NULL};
+  const char *id_path[] = {"id", NULL};
+
+  jresult = yajl_tree_get(jnode, result_path, yajl_t_any);
+  jerror = yajl_tree_get(jnode, error_path, yajl_t_any);
+  jid = yajl_tree_get(jnode, id_path, yajl_t_string);
+
+  /* check & get result attributes */
+  if (!jresult || !jerror || !jid)
+    return (-1);
+
+  /* try to find registered callback */
+  pthread_mutex_lock(&pdb->mutex);
+  cb = ovs_db_table_callback_get(pdb, jid);
+  if (cb != NULL && cb->result.call != NULL) {
+    /* call registered callback */
+    cb->result.call(jresult, jerror);
+    /* unlock owner of the reply */
+    sem_post(&cb->result.sync);
+  }
+
+  pthread_mutex_unlock(&pdb->mutex);
+  return (0);
+}
+
+/* Handle JSON data (one request) and call
+ * appropriate event OVS DB handler. Currently,
+ * update callback 'ovs_db_table_update_cb' and
+ * result callback 'ovs_db_result_cb' is supported.
+ */
+static int ovs_db_json_data_process(ovs_db_t *pdb, const char *data,
+                                    size_t len) {
+  const char *method = NULL;
+  char yajl_errbuf[OVS_YAJL_ERROR_BUFFER_SIZE];
+  const char *method_path[] = {"method", NULL};
+  const char *result_path[] = {"result", NULL};
+  char *sjson = NULL;
+  yajl_val jnode, jval;
+
+  /* duplicate the data to make null-terminated string
+   * required for yajl_tree_parse() */
+  if ((sjson = calloc(1, len + 1)) == NULL)
+    return (-1);
+
+  sstrncpy(sjson, data, len + 1);
+  OVS_DEBUG("[len=%zu] %s", len, sjson);
+
+  /* parse json data */
+  jnode = yajl_tree_parse(sjson, yajl_errbuf, sizeof(yajl_errbuf));
+  if (jnode == NULL) {
+    OVS_ERROR("yajl_tree_parse() %s", yajl_errbuf);
+    sfree(sjson);
+    return (-1);
+  }
+
+  /* get method name */
+  if ((jval = yajl_tree_get(jnode, method_path, yajl_t_string)) != NULL) {
+    method = YAJL_GET_STRING(jval);
+    if (strcmp("echo", method) == 0) {
+      /* echo request from the server */
+      if (ovs_db_table_echo_cb(pdb, jnode) < 0)
+        OVS_ERROR("handle echo request failed");
+    } else if (strcmp("update", method) == 0) {
+      /* update notification */
+      if (ovs_db_table_update_cb(pdb, jnode) < 0)
+        OVS_ERROR("handle update notification failed");
+    }
+  } else if ((jval = yajl_tree_get(jnode, result_path, yajl_t_any)) != NULL) {
+    /* result notification */
+    if (ovs_db_result_cb(pdb, jnode) < 0)
+      OVS_ERROR("handle result reply failed");
+  } else
+    OVS_ERROR("connot find method or result failed");
+
+  /* release memory */
+  yajl_tree_free(jnode);
+  sfree(sjson);
+  return (0);
+}
+
+/*
+ * JSON reader implementation.
+ *
+ * This module process raw JSON data (byte stream) and
+ * returns fully-fledged JSON data which can be processed
+ * (parsed) by YAJL later.
+ */
+
+/* Allocate JSON reader instance */
+static ovs_json_reader_t *ovs_json_reader_alloc() {
+  ovs_json_reader_t *jreader = NULL;
+
+  if ((jreader = calloc(sizeof(ovs_json_reader_t), 1)) == NULL)
+    return NULL;
+
+  return jreader;
+}
+
+/* Push raw data into into the JSON reader for processing */
+static int ovs_json_reader_push_data(ovs_json_reader_t *jreader,
+                                     const char *data, size_t data_len) {
+  char *new_buff = NULL;
+  size_t available = jreader->buff_size - jreader->buff_offset;
+
+  /* check/update required memory space */
+  if (available < data_len) {
+    OVS_DEBUG("Reallocate buffer [size=%d, available=%d required=%d]",
+              (int)jreader->buff_size, (int)available, (int)data_len);
+
+    /* allocate new chunk of memory */
+    new_buff = realloc(jreader->buff_ptr, (jreader->buff_size + data_len));
+    if (new_buff == NULL)
+      return (-1);
+
+    /* point to new allocated memory */
+    jreader->buff_ptr = new_buff;
+    jreader->buff_size += data_len;
+  }
+
+  /* store input data */
+  memcpy(jreader->buff_ptr + jreader->buff_offset, data, data_len);
+  jreader->buff_offset += data_len;
+  return (0);
+}
+
+/* Pop one fully-fledged JSON if already exists. Returns 0 if
+ * completed JSON already exists otherwise negative value is
+ * returned */
+static int ovs_json_reader_pop(ovs_json_reader_t *jreader,
+                               const char **json_ptr, size_t *json_len_ptr) {
+  size_t nbraces = 0;
+  size_t json_len = 0;
+  char *json = NULL;
+
+  /* search open/close brace */
+  for (size_t i = jreader->json_offset; i < jreader->buff_offset; i++) {
+    if (jreader->buff_ptr[i] == '{') {
+      nbraces++;
+    } else if (jreader->buff_ptr[i] == '}')
+      if (nbraces)
+        if (!(--nbraces)) {
+          /* JSON data */
+          *json_ptr = jreader->buff_ptr + jreader->json_offset;
+          *json_len_ptr = json_len + 1;
+          jreader->json_offset = i + 1;
+          return (0);
+        }
+
+    /* increase JSON data length */
+    if (nbraces)
+      json_len++;
+  }
+
+  if (jreader->json_offset) {
+    if (jreader->json_offset < jreader->buff_offset) {
+      /* shift data to the beginning of the buffer
+       * and zero rest of the buffer data */
+      json = &jreader->buff_ptr[jreader->json_offset];
+      json_len = jreader->buff_offset - jreader->json_offset;
+      for (size_t i = 0; i < jreader->buff_size; i++)
+        jreader->buff_ptr[i] = ((i < json_len) ? (json[i]) : (0));
+      jreader->buff_offset = json_len;
+    } else
+      /* reset the buffer */
+      jreader->buff_offset = 0;
+
+    /* data is at the beginning of the buffer */
+    jreader->json_offset = 0;
+  }
+
+  return (-1);
+}
+
+/* Reset JSON reader. It is useful when start processing
+ * new raw data. E.g.: in case of lost stream connection.
+ */
+static void ovs_json_reader_reset(ovs_json_reader_t *jreader) {
+  if (jreader) {
+    jreader->buff_offset = 0;
+    jreader->json_offset = 0;
+  }
+}
+
+/* Release internal data allocated for JSON reader */
+static void ovs_json_reader_free(ovs_json_reader_t *jreader) {
+  if (jreader) {
+    free(jreader->buff_ptr);
+    free(jreader);
+  }
+}
+
+/* Reconnect to OVS DB and call the OVS DB post connection init callback
+ * if connection has been established.
+ */
+static void ovs_db_reconnect(ovs_db_t *pdb) {
+  const char *node_info = pdb->node;
+  struct addrinfo *result;
+
+  if (pdb->unix_path[0] != '\0') {
+    /* use UNIX socket instead of INET address */
+    node_info = pdb->unix_path;
+    result = calloc(1, sizeof(struct addrinfo));
+    struct sockaddr_un *sa_unix = calloc(1, sizeof(struct sockaddr_un));
+    if (result == NULL || sa_unix == NULL) {
+      sfree(result);
+      sfree(sa_unix);
+      return;
+    }
+    result->ai_family = AF_UNIX;
+    result->ai_socktype = SOCK_STREAM;
+    result->ai_addrlen = sizeof(*sa_unix);
+    result->ai_addr = (struct sockaddr *)sa_unix;
+    sa_unix->sun_family = result->ai_family;
+    sstrncpy(sa_unix->sun_path, pdb->unix_path, sizeof(sa_unix->sun_path));
+  } else {
+    /* inet socket address */
+    struct addrinfo hints;
+
+    /* setup criteria for selecting the socket address */
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+
+    /* get socket addresses */
+    int ret = getaddrinfo(pdb->node, pdb->service, &hints, &result);
+    if (ret != 0) {
+      OVS_ERROR("getaddrinfo(): %s", gai_strerror(ret));
+      return;
+    }
+  }
+  /* try to connect to the server */
+  for (struct addrinfo *rp = result; rp != NULL; rp = rp->ai_next) {
+    char errbuff[OVS_ERROR_BUFF_SIZE];
+    int sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
+    if (sock < 0) {
+      sstrerror(errno, errbuff, sizeof(errbuff));
+      OVS_DEBUG("socket(): %s", errbuff);
+      continue;
+    }
+    if (connect(sock, rp->ai_addr, rp->ai_addrlen) < 0) {
+      close(sock);
+      sstrerror(errno, errbuff, sizeof(errbuff));
+      OVS_DEBUG("connect(): %s [family=%d]", errbuff, rp->ai_family);
+    } else {
+      /* send notification to event thread */
+      ovs_db_event_post(pdb, OVS_DB_EVENT_CONN_ESTABLISHED);
+      pdb->sock = sock;
+      break;
+    }
+  }
+
+  if (pdb->sock < 0)
+    OVS_ERROR("connect to \"%s\" failed", node_info);
+
+  freeaddrinfo(result);
+}
+
+/* POLL worker thread.
+ * It listens on OVS DB connection for incoming
+ * requests/reply/events etc. Also, it reconnects to OVS DB
+ * if connection has been lost.
+ */
+static void *ovs_poll_worker(void *arg) {
+  ovs_db_t *pdb = (ovs_db_t *)arg; /* pointer to OVS DB */
+  ovs_json_reader_t *jreader = NULL;
+  struct pollfd poll_fd = {
+      .fd = pdb->sock, .events = POLLIN | POLLPRI, .revents = 0,
+  };
+
+  /* create JSON reader instance */
+  if ((jreader = ovs_json_reader_alloc()) == NULL) {
+    OVS_ERROR("initialize json reader failed");
+    return (NULL);
+  }
+
+  /* poll data */
+  while (ovs_db_poll_is_running(pdb)) {
+    char errbuff[OVS_ERROR_BUFF_SIZE];
+    poll_fd.fd = pdb->sock;
+    int poll_ret = poll(&poll_fd, 1, /* ms */ OVS_DB_POLL_TIMEOUT * 1000);
+    if (poll_ret < 0) {
+      sstrerror(errno, errbuff, sizeof(errbuff));
+      OVS_ERROR("poll(): %s", errbuff);
+      break;
+    } else if (poll_ret == 0) {
+      OVS_DEBUG("poll(): timeout");
+      if (pdb->sock < 0)
+        /* invalid fd, so try to reconnect */
+        ovs_db_reconnect(pdb);
+      continue;
+    }
+    if (poll_fd.revents & POLLNVAL) {
+      /* invalid file descriptor, clean-up */
+      ovs_db_callback_remove_all(pdb);
+      ovs_json_reader_reset(jreader);
+      /* setting poll FD to -1 tells poll() call to ignore this FD.
+       * In that case poll() call will return timeout all the time */
+      pdb->sock = (-1);
+    } else if ((poll_fd.revents & POLLERR) || (poll_fd.revents & POLLHUP)) {
+      /* connection is broken */
+      close(poll_fd.fd);
+      ovs_db_event_post(pdb, OVS_DB_EVENT_CONN_TERMINATED);
+      OVS_ERROR("poll() peer closed its end of the channel");
+    } else if ((poll_fd.revents & POLLIN) || (poll_fd.revents & POLLPRI)) {
+      /* read incoming data */
+      char buff[OVS_DB_POLL_READ_BLOCK_SIZE];
+      ssize_t nbytes = recv(poll_fd.fd, buff, sizeof(buff), 0);
+      if (nbytes < 0) {
+        sstrerror(errno, errbuff, sizeof(errbuff));
+        OVS_ERROR("recv(): %s", errbuff);
+        /* read error? Try to reconnect */
+        close(poll_fd.fd);
+        continue;
+      } else if (nbytes == 0) {
+        close(poll_fd.fd);
+        ovs_db_event_post(pdb, OVS_DB_EVENT_CONN_TERMINATED);
+        OVS_ERROR("recv() peer has performed an orderly shutdown");
+        continue;
+      }
+      /* read incoming data */
+      size_t json_len = 0;
+      const char *json = NULL;
+      OVS_DEBUG("recv(): received %zd bytes of data", nbytes);
+      ovs_json_reader_push_data(jreader, buff, nbytes);
+      while (!ovs_json_reader_pop(jreader, &json, &json_len))
+        /* process JSON data */
+        ovs_db_json_data_process(pdb, json, json_len);
+    }
+  }
+
+  OVS_DEBUG("poll thread has been completed");
+  ovs_json_reader_free(jreader);
+  return (NULL);
+}
+
+/* EVENT worker thread.
+ * Perform task based on incoming events. This
+ * task can be done asynchronously which allows to
+ * handle OVS DB callback like 'init_cb'.
+ */
+static void *ovs_event_worker(void *arg) {
+  ovs_db_t *pdb = (ovs_db_t *)arg;
+
+  while (pdb->event_thread.value != OVS_DB_EVENT_TERMINATE) {
+    /* wait for an event */
+    struct timespec ts;
+    clock_gettime(CLOCK_REALTIME, &ts);
+    ts.tv_sec += (OVS_DB_EVENT_TIMEOUT);
+    int ret = pthread_cond_timedwait(&pdb->event_thread.cond,
+                                     &pdb->event_thread.mutex, &ts);
+    if (!ret) {
+      /* handle the event */
+      OVS_DEBUG("handle event %d", pdb->event_thread.value);
+      switch (pdb->event_thread.value) {
+      case OVS_DB_EVENT_CONN_ESTABLISHED:
+        if (pdb->cb.post_conn_init)
+          pdb->cb.post_conn_init(pdb);
+        break;
+      case OVS_DB_EVENT_CONN_TERMINATED:
+        if (pdb->cb.post_conn_terminate)
+          pdb->cb.post_conn_terminate();
+        break;
+      default:
+        OVS_DEBUG("unknown event received");
+        break;
+      }
+    } else if (ret == ETIMEDOUT) {
+      /* wait timeout */
+      OVS_DEBUG("no event received (timeout)");
+      continue;
+    } else {
+      /* unexpected error */
+      OVS_ERROR("pthread_cond_timedwait() failed");
+      break;
+    }
+  }
+
+  OVS_DEBUG("event thread has been completed");
+  return (NULL);
+}
+
+/* Initialize EVENT thread */
+static int ovs_db_event_thread_init(ovs_db_t *pdb) {
+  pdb->event_thread.tid = (pthread_t)-1;
+  /* init event thread condition variable */
+  if (pthread_cond_init(&pdb->event_thread.cond, NULL)) {
+    return (-1);
+  }
+  /* init event thread mutex */
+  if (pthread_mutex_init(&pdb->event_thread.mutex, NULL)) {
+    pthread_cond_destroy(&pdb->event_thread.cond);
+    return (-1);
+  }
+  /* Hold the event thread mutex. It ensures that no events
+   * will be lost while thread is still starting. Once event
+   * thread is started and ready to accept events, it will release
+   * the mutex */
+  if (pthread_mutex_lock(&pdb->event_thread.mutex)) {
+    pthread_mutex_destroy(&pdb->event_thread.mutex);
+    pthread_cond_destroy(&pdb->event_thread.cond);
+    return (-1);
+  }
+  /* start event thread */
+  pthread_t tid;
+  if (plugin_thread_create(&tid, NULL, ovs_event_worker, pdb,
+                           "utils_ovs:event") != 0) {
+    pthread_mutex_unlock(&pdb->event_thread.mutex);
+    pthread_mutex_destroy(&pdb->event_thread.mutex);
+    pthread_cond_destroy(&pdb->event_thread.cond);
+    return (-1);
+  }
+  pdb->event_thread.tid = tid;
+  return (0);
+}
+
+/* Destroy EVENT thread */
+static int ovs_db_event_thread_destroy(ovs_db_t *pdb) {
+  if (pdb->event_thread.tid == (pthread_t)-1)
+    /* already destroyed */
+    return (0);
+  ovs_db_event_post(pdb, OVS_DB_EVENT_TERMINATE);
+  if (pthread_join(pdb->event_thread.tid, NULL) != 0)
+    return (-1);
+  /* Event thread always holds the thread mutex when
+   * performs some task (handles event) and releases it when
+   * while sleeping. Thus, if event thread exits, the mutex
+   * remains locked */
+  pthread_mutex_unlock(&pdb->event_thread.mutex);
+  pthread_mutex_destroy(&pdb->event_thread.mutex);
+  pthread_cond_destroy(&pdb->event_thread.cond);
+  pdb->event_thread.tid = (pthread_t)-1;
+  return (0);
+}
+
+/* Initialize POLL thread */
+static int ovs_db_poll_thread_init(ovs_db_t *pdb) {
+  pdb->poll_thread.tid = (pthread_t)-1;
+  /* init event thread mutex */
+  if (pthread_mutex_init(&pdb->poll_thread.mutex, NULL)) {
+    return (-1);
+  }
+  /* start poll thread */
+  pthread_t tid;
+  pdb->poll_thread.state = OVS_DB_POLL_STATE_RUNNING;
+  if (plugin_thread_create(&tid, NULL, ovs_poll_worker, pdb,
+                           "utils_ovs:poll") != 0) {
+    pthread_mutex_destroy(&pdb->poll_thread.mutex);
+    return (-1);
+  }
+  pdb->poll_thread.tid = tid;
+  return (0);
+}
+
+/* Destroy POLL thread */
+static int ovs_db_poll_thread_destroy(ovs_db_t *pdb) {
+  if (pdb->poll_thread.tid == (pthread_t)-1)
+    /* already destroyed */
+    return (0);
+  /* change thread state */
+  pthread_mutex_lock(&pdb->poll_thread.mutex);
+  pdb->poll_thread.state = OVS_DB_POLL_STATE_EXITING;
+  pthread_mutex_unlock(&pdb->poll_thread.mutex);
+  /* join the thread */
+  if (pthread_join(pdb->poll_thread.tid, NULL) != 0)
+    return (-1);
+  pthread_mutex_destroy(&pdb->poll_thread.mutex);
+  pdb->poll_thread.tid = (pthread_t)-1;
+  return (0);
+}
+
+/*
+ * Public OVS DB API implementation
+ */
+
+ovs_db_t *ovs_db_init(const char *node, const char *service,
+                      const char *unix_path, ovs_db_callback_t *cb) {
+  /* sanity check */
+  if (node == NULL || service == NULL || unix_path == NULL)
+    return (NULL);
+
+  /* allocate db data & fill it */
+  ovs_db_t *pdb = pdb = calloc(1, sizeof(*pdb));
+  if (pdb == NULL)
+    return (NULL);
+
+  /* store the OVS DB address */
+  sstrncpy(pdb->node, node, sizeof(pdb->node));
+  sstrncpy(pdb->service, service, sizeof(pdb->service));
+  sstrncpy(pdb->unix_path, unix_path, sizeof(pdb->unix_path));
+
+  /* setup OVS DB callbacks */
+  if (cb)
+    pdb->cb = *cb;
+
+  /* init OVS DB mutex attributes */
+  pthread_mutexattr_t mutex_attr;
+  if (pthread_mutexattr_init(&mutex_attr)) {
+    OVS_ERROR("OVS DB mutex attribute init failed");
+    sfree(pdb);
+    return (NULL);
+  }
+  /* set OVS DB mutex as recursive */
+  if (pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE)) {
+    OVS_ERROR("Failed to set OVS DB mutex as recursive");
+    pthread_mutexattr_destroy(&mutex_attr);
+    sfree(pdb);
+    return (NULL);
+  }
+  /* init OVS DB mutex */
+  if (pthread_mutex_init(&pdb->mutex, &mutex_attr)) {
+    OVS_ERROR("OVS DB mutex init failed");
+    pthread_mutexattr_destroy(&mutex_attr);
+    sfree(pdb);
+    return (NULL);
+  }
+  /* destroy mutex attributes */
+  pthread_mutexattr_destroy(&mutex_attr);
+
+  /* init event thread */
+  if (ovs_db_event_thread_init(pdb) < 0) {
+    ovs_db_destroy(pdb);
+    return (NULL);
+  }
+
+  /* init polling thread */
+  pdb->sock = -1;
+  if (ovs_db_poll_thread_init(pdb) < 0) {
+    ovs_db_destroy(pdb);
+    return (NULL);
+  }
+  return pdb;
+}
+
+int ovs_db_send_request(ovs_db_t *pdb, const char *method, const char *params,
+                        ovs_db_result_cb_t cb) {
+  int ret = 0;
+  yajl_gen_status yajl_gen_ret;
+  yajl_val jparams;
+  yajl_gen jgen;
+  ovs_callback_t *new_cb = NULL;
+  uint64_t uid;
+  char uid_buff[OVS_UID_STR_SIZE];
+  const char *req = NULL;
+  size_t req_len = 0;
+  struct timespec ts;
+
+  /* sanity check */
+  if (!pdb || !method || !params)
+    return (-1);
+
+  if ((jgen = yajl_gen_alloc(NULL)) == NULL)
+    return (-1);
+
+  /* try to parse params */
+  if ((jparams = yajl_tree_parse(params, NULL, 0)) == NULL) {
+    OVS_ERROR("params is not a JSON string");
+    yajl_gen_clear(jgen);
+    return (-1);
+  }
+
+  /* generate method field */
+  OVS_YAJL_CALL(yajl_gen_map_open, jgen);
+
+  OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "method");
+  OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, method);
+
+  /* generate params field */
+  OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "params");
+  OVS_YAJL_CALL(ovs_yajl_gen_val, jgen, jparams);
+  yajl_tree_free(jparams);
+
+  /* generate id field */
+  OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "id");
+  uid = ovs_uid_generate();
+  ssnprintf(uid_buff, sizeof(uid_buff), "%" PRIX64, uid);
+  OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, uid_buff);
+
+  OVS_YAJL_CALL(yajl_gen_map_close, jgen);
+
+  if (cb) {
+    /* register result callback */
+    if ((new_cb = calloc(1, sizeof(ovs_callback_t))) == NULL)
+      goto yajl_gen_failure;
+
+    /* add new callback to front */
+    sem_init(&new_cb->result.sync, 0, 0);
+    new_cb->result.call = cb;
+    new_cb->uid = uid;
+    ovs_db_callback_add(pdb, new_cb);
+  }
+
+  /* send the request */
+  OVS_YAJL_CALL(yajl_gen_get_buf, jgen, (const unsigned char **)&req, &req_len);
+  OVS_DEBUG("%s", req);
+  if (!ovs_db_data_send(pdb, req, req_len)) {
+    if (cb) {
+      /* wait for result */
+      clock_gettime(CLOCK_REALTIME, &ts);
+      ts.tv_sec += OVS_DB_SEND_REQ_TIMEOUT;
+      if (sem_timedwait(&new_cb->result.sync, &ts) < 0) {
+        OVS_ERROR("%s() no replay received within %d sec", __FUNCTION__,
+                  OVS_DB_SEND_REQ_TIMEOUT);
+        ret = (-1);
+      }
+    }
+  } else {
+    OVS_ERROR("ovs_db_data_send() failed");
+    ret = (-1);
+  }
+
+yajl_gen_failure:
+  if (new_cb) {
+    /* destroy callback */
+    sem_destroy(&new_cb->result.sync);
+    ovs_db_callback_remove(pdb, new_cb);
+  }
+
+  /* release memory */
+  yajl_gen_clear(jgen);
+  return (yajl_gen_ret != yajl_gen_status_ok) ? (-1) : ret;
+}
+
+int ovs_db_table_cb_register(ovs_db_t *pdb, const char *tb_name,
+                             const char **tb_column,
+                             ovs_db_table_cb_t update_cb,
+                             ovs_db_result_cb_t result_cb, unsigned int flags) {
+  yajl_gen jgen;
+  yajl_gen_status yajl_gen_ret;
+  ovs_callback_t *new_cb = NULL;
+  char uid_str[OVS_UID_STR_SIZE];
+  char *params;
+  size_t params_len;
+  int ovs_db_ret = 0;
+
+  /* sanity check */
+  if (pdb == NULL || tb_name == NULL || update_cb == NULL)
+    return (-1);
+
+  /* allocate new update callback */
+  if ((new_cb = calloc(1, sizeof(ovs_callback_t))) == NULL)
+    return (-1);
+
+  /* init YAJL generator */
+  if ((jgen = yajl_gen_alloc(NULL)) == NULL) {
+    sfree(new_cb);
+    return (-1);
+  }
+
+  /* add new callback to front */
+  new_cb->table.call = update_cb;
+  new_cb->uid = ovs_uid_generate();
+  ovs_db_callback_add(pdb, new_cb);
+
+  /* make update notification request
+   * [<db-name>, <json-value>, <monitor-requests>] */
+  OVS_YAJL_CALL(yajl_gen_array_open, jgen);
+  {
+    OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, OVS_DB_DEFAULT_DB_NAME);
+
+    /* uid string <json-value> */
+    ssnprintf(uid_str, sizeof(uid_str), "%" PRIX64, new_cb->uid);
+    OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, uid_str);
+
+    /* <monitor-requests> */
+    OVS_YAJL_CALL(yajl_gen_map_open, jgen);
+    {
+      OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, tb_name);
+      OVS_YAJL_CALL(yajl_gen_array_open, jgen);
+      {
+        /* <monitor-request> */
+        OVS_YAJL_CALL(yajl_gen_map_open, jgen);
+        {
+          if (tb_column) {
+            /* columns within the table to be monitored */
+            OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "columns");
+            OVS_YAJL_CALL(yajl_gen_array_open, jgen);
+            for (; *tb_column; tb_column++)
+              OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, *tb_column);
+            OVS_YAJL_CALL(yajl_gen_array_close, jgen);
+          }
+          /* specify select option */
+          OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "select");
+          {
+            OVS_YAJL_CALL(yajl_gen_map_open, jgen);
+            {
+              OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "initial");
+              OVS_YAJL_CALL(yajl_gen_bool, jgen,
+                            flags & OVS_DB_TABLE_CB_FLAG_INITIAL);
+              OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "insert");
+              OVS_YAJL_CALL(yajl_gen_bool, jgen,
+                            flags & OVS_DB_TABLE_CB_FLAG_INSERT);
+              OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "delete");
+              OVS_YAJL_CALL(yajl_gen_bool, jgen,
+                            flags & OVS_DB_TABLE_CB_FLAG_DELETE);
+              OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "modify");
+              OVS_YAJL_CALL(yajl_gen_bool, jgen,
+                            flags & OVS_DB_TABLE_CB_FLAG_MODIFY);
+            }
+            OVS_YAJL_CALL(yajl_gen_map_close, jgen);
+          }
+        }
+        OVS_YAJL_CALL(yajl_gen_map_close, jgen);
+      }
+      OVS_YAJL_CALL(yajl_gen_array_close, jgen);
+    }
+    OVS_YAJL_CALL(yajl_gen_map_close, jgen);
+  }
+  OVS_YAJL_CALL(yajl_gen_array_close, jgen);
+
+  /* make a request to subscribe to given table */
+  OVS_YAJL_CALL(yajl_gen_get_buf, jgen, (const unsigned char **)&params,
+                &params_len);
+  if (ovs_db_send_request(pdb, "monitor", params, result_cb) < 0) {
+    OVS_ERROR("Failed to subscribe to \"%s\" table", tb_name);
+    ovs_db_ret = (-1);
+  }
+
+yajl_gen_failure:
+  /* release memory */
+  yajl_gen_clear(jgen);
+  return ovs_db_ret;
+}
+
+int ovs_db_destroy(ovs_db_t *pdb) {
+  int ovs_db_ret = 0;
+  int ret = 0;
+
+  /* sanity check */
+  if (pdb == NULL)
+    return (-1);
+
+  /* try to lock the structure before releasing */
+  if ((ret = pthread_mutex_lock(&pdb->mutex))) {
+    OVS_ERROR("pthread_mutex_lock() DB mutex lock failed (%d)", ret);
+    return (-1);
+  }
+
+  /* stop poll thread */
+  if (ovs_db_event_thread_destroy(pdb) < 0) {
+    OVS_ERROR("destroy poll thread failed");
+    ovs_db_ret = (-1);
+  }
+
+  /* stop event thread */
+  if (ovs_db_poll_thread_destroy(pdb) < 0) {
+    OVS_ERROR("stop event thread failed");
+    ovs_db_ret = (-1);
+  }
+
+  /* unsubscribe callbacks */
+  ovs_db_callback_remove_all(pdb);
+
+  /* close connection */
+  if (pdb->sock >= 0)
+    close(pdb->sock);
+
+  /* release DB handler */
+  pthread_mutex_unlock(&pdb->mutex);
+  pthread_mutex_destroy(&pdb->mutex);
+  sfree(pdb);
+  return ovs_db_ret;
+}
+
+/*
+ * Public OVS utils API implementation
+ */
+
+/* Get YAJL value by key from YAJL dictionary
+ *
+ * EXAMPLE:
+ *  {
+ *    "key_a" : <YAJL return value>
+ *    "key_b" : <YAJL return value>
+ *  }
+ */
+yajl_val ovs_utils_get_value_by_key(yajl_val jval, const char *key) {
+  const char *obj_key = NULL;
+
+  /* check params */
+  if (!YAJL_IS_OBJECT(jval) || (key == NULL))
+    return NULL;
+
+  /* find a value by key */
+  for (size_t i = 0; i < YAJL_GET_OBJECT(jval)->len; i++) {
+    obj_key = YAJL_GET_OBJECT(jval)->keys[i];
+    if (strcmp(obj_key, key) == 0)
+      return YAJL_GET_OBJECT(jval)->values[i];
+  }
+
+  return NULL;
+}
+
+/* Get OVS DB map value by given map key
+ *
+ * FROM RFC7047:
+ *
+ *   <pair>
+ *     A 2-element JSON array that represents a pair within a database
+ *     map.  The first element is an <atom> that represents the key, and
+ *     the second element is an <atom> that represents the value.
+ *
+ *   <map>
+ *     A 2-element JSON array that represents a database map value.  The
+ *     first element of the array must be the string "map", and the
+ *     second element must be an array of zero or more <pair>s giving the
+ *     values in the map.  All of the <pair>s must have the same key and
+ *     value types.
+ *
+ * EXAMPLE:
+ *  [
+ *    "map", [
+ *             [ "key_a", <YAJL value>], [ "key_b", <YAJL value>], ...
+ *           ]
+ *  ]
+ */
+yajl_val ovs_utils_get_map_value(yajl_val jval, const char *key) {
+  size_t map_len = 0;
+  size_t array_len = 0;
+  yajl_val *map_values = NULL;
+  yajl_val *array_values = NULL;
+  const char *str_val = NULL;
+
+  /* check YAJL array */
+  if (!YAJL_IS_ARRAY(jval) || (key == NULL))
+    return NULL;
+
+  /* check a database map value (2-element, first one should be a string */
+  array_len = YAJL_GET_ARRAY(jval)->len;
+  array_values = YAJL_GET_ARRAY(jval)->values;
+  if ((array_len != 2) || (!YAJL_IS_STRING(array_values[0])) ||
+      (!YAJL_IS_ARRAY(array_values[1])))
+    return NULL;
+
+  /* check first element of the array */
+  str_val = YAJL_GET_STRING(array_values[0]);
+  if (strcmp("map", str_val) != 0)
+    return NULL;
+
+  /* try to find map value by map key */
+  map_len = YAJL_GET_ARRAY(array_values[1])->len;
+  map_values = YAJL_GET_ARRAY(array_values[1])->values;
+  for (size_t i = 0; i < map_len; i++) {
+    /* check YAJL array */
+    if (!YAJL_IS_ARRAY(map_values[i]))
+      break;
+
+    /* check a database pair value (2-element, first one represents a key
+     * and it should be a string in our case */
+    array_len = YAJL_GET_ARRAY(map_values[i])->len;
+    array_values = YAJL_GET_ARRAY(map_values[i])->values;
+    if ((array_len != 2) || (!YAJL_IS_STRING(array_values[0])))
+      break;
+
+    /* return map value if given key equals map key */
+    str_val = YAJL_GET_STRING(array_values[0]);
+    if (strcmp(key, str_val) == 0)
+      return array_values[1];
+  }
+  return NULL;
+}
diff --git a/src/utils_ovs.h b/src/utils_ovs.h
new file mode 100644 (file)
index 0000000..52c2f91
--- /dev/null
@@ -0,0 +1,236 @@
+/**
+ * collectd - src/utils_ovs.h
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *   Volodymyr Mytnyk <volodymyrx.mytnyk@intel.com>
+ *
+ * Description:
+ *  The OVS util module provides the following features:
+ *   - Implements the OVS DB communication transport specified
+ *     by RFC7047:
+ *     * Connect/disconnect to OVS DB;
+ *     * Recovery mechanism in case of OVS DB connection lost;
+ *     * Subscription mechanism to OVS DB table update events
+ *       (insert/modify/delete);
+ *     * Send custom JSON request to OVS DB (poll table data, etc.)
+ *     * Handling of echo request from OVS DB server to verify the
+ *       liveness of the connection.
+ *   - Provides YAJL helpers functions.
+ *
+ *  OVS DB API User Guide:
+ *    All OVS DB function/structure names begins from 'ovs_db_*' prefix. To
+ *   start using OVS DB API, client (plugin) should initialize the OVS DB
+ *   object (`ovs_db_t') by calling `ovs_db_init' function. It initializes
+ *   internal data and creates two main workers (threads). The result of the
+ *   function is a pointer to new OVS DB object which can be used by other
+ *   OVS DB API later and must be released by `ovs_db_destroy' function if
+ *   the object isn't needed anymore.
+ *    Once OVS DB API is initialized, the `init_cb' callback is called if
+ *   the connection to OVS DB has been established. This callback is called
+ *   every time the OVS DB is reconnected. So, if the client registers table
+ *   update event callbacks or does any other OVS DB setup that can be lost
+ *   after OVS DB reconnecting, it should be done in `init_cb' callback.
+ *    The `ovs_db_table_cb_register` function is used to register OVS DB
+ *   table update event callback and receive the table update notification
+ *   when requested event occurs (registered callback is called). See
+ *   function API for more info.
+ *    To send custom JSON-RPC request to OVS DB, the `ovs_db_send_request'
+ *   function is used. Please note, that connection to OVS DB should be
+ *   established otherwise the function will return error.
+ *    To verify the liveness of established connection, the OVS DB server
+ *   sends echo request to the client with a given interval. The OVS utils
+ *   takes care about this request and handles it properly.
+ **/
+
+#ifndef UTILS_OVS_H
+#define UTILS_OVS_H
+
+#include <yajl/yajl_gen.h>
+#include <yajl/yajl_tree.h>
+
+/* Forward declaration */
+typedef struct ovs_db_s ovs_db_t;
+
+/* OVS DB callback type declaration */
+typedef void (*ovs_db_table_cb_t)(yajl_val jupdates);
+typedef void (*ovs_db_result_cb_t)(yajl_val jresult, yajl_val jerror);
+
+/* OVS DB structures */
+struct ovs_db_callback_s {
+  /*
+   * This callback is called when OVS DB connection
+   * has been established and ready to use. Client
+   * can use this callback to configure OVS DB, e.g.
+   * to subscribe to table update notification or poll
+   * some OVS DB data. This field can be NULL.
+   */
+  void (*post_conn_init)(ovs_db_t *pdb);
+  /*
+   * This callback is called when OVS DB connection
+   * has been lost. This field can be NULL.
+   */
+  void (*post_conn_terminate)(void);
+};
+typedef struct ovs_db_callback_s ovs_db_callback_t;
+
+/* OVS DB defines */
+#define OVS_DB_ADDR_NODE_SIZE 256
+#define OVS_DB_ADDR_SERVICE_SIZE 128
+#define OVS_DB_ADDR_UNIX_SIZE 108
+
+/* OVS DB prototypes */
+
+/*
+ * NAME
+ *   ovs_db_init
+ *
+ * DESCRIPTION
+ *   Initialize OVS DB internal data. The `ovs_db_destroy' function
+ *   shall destroy the returned object.
+ *
+ * PARAMETERS
+ *   `node'        OVS DB Address.
+ *   `service'     OVS DB service name.
+ *   `unix'        OVS DB unix socket path.
+ *   `cb'          OVS DB callbacks.
+ *
+ * RETURN VALUE
+ *   New ovs_db_t object upon success or NULL if an error occurred.
+ */
+ovs_db_t *ovs_db_init(const char *node, const char *service,
+                      const char *unix_path, ovs_db_callback_t *cb);
+
+/*
+ * NAME
+ *   ovs_db_destroy
+ *
+ * DESCRIPTION
+ *   Destroy OVS DB object referenced by `pdb'.
+ *
+ * PARAMETERS
+ *   `pdb'         Pointer to OVS DB object.
+ *
+ * RETURN VALUE
+ *   Zero upon success or non-zero if an error occurred.
+ */
+int ovs_db_destroy(ovs_db_t *pdb);
+
+/*
+ * NAME
+ *   ovs_db_send_request
+ *
+ * DESCRIPTION
+ *   Send JSON request to OVS DB server.
+ *
+ * PARAMETERS
+ *   `pdb'         Pointer to OVS DB object.
+ *   `method'      Request method name.
+ *   `params'      Method params to be sent (JSON value as a string).
+ *   `cb'          Result callback of the request. If NULL, the request
+ *                 is sent asynchronously.
+ *
+ * RETURN VALUE
+ *   Zero upon success or non-zero if an error occurred.
+ */
+int ovs_db_send_request(ovs_db_t *pdb, const char *method, const char *params,
+                        ovs_db_result_cb_t cb);
+
+/* callback types */
+#define OVS_DB_TABLE_CB_FLAG_INITIAL 0x01U
+#define OVS_DB_TABLE_CB_FLAG_INSERT 0x02U
+#define OVS_DB_TABLE_CB_FLAG_DELETE 0x04U
+#define OVS_DB_TABLE_CB_FLAG_MODIFY 0x08U
+#define OVS_DB_TABLE_CB_FLAG_ALL 0x0FU
+
+/*
+ * NAME
+ *   ovs_db_table_cb_register
+ *
+ * DESCRIPTION
+ *   Subscribe a callback on OVS DB table event. It allows to
+ *   receive notifications (`update_cb' callback is called) of
+ *   changes to requested table.
+ *
+ * PARAMETERS
+ *   `pdb'         Pointer to OVS DB object.
+ *   `tb_name'     OVS DB Table name to be monitored.
+ *   `tb_column'   OVS DB Table columns to be monitored. Last
+ *                 element in the array should be NULL.
+ *   `update_cb'   Callback function that is called when
+ *                 requested table columns are changed.
+ *   `cb'          Result callback of the request. If NULL, the call
+ *                 becomes asynchronous.
+ *                 Useful, if OVS_DB_TABLE_CB_FLAG_INITIAL is set.
+ *   `flags'       Bit mask of:
+ *                   OVS_DB_TABLE_CB_FLAG_INITIAL Receive initial values in
+ *                                               result callback.
+ *                   OVS_DB_TABLE_CB_FLAG_INSERT  Receive table insert events.
+ *                   OVS_DB_TABLE_CB_FLAG_DELETE  Receive table remove events.
+ *                   OVS_DB_TABLE_CB_FLAG_MODIFY  Receive table update events.
+ *                   OVS_DB_TABLE_CB_FLAG_ALL     Receive all events.
+ *
+ * RETURN VALUE
+ *   Zero upon success or non-zero if an error occurred.
+ */
+int ovs_db_table_cb_register(ovs_db_t *pdb, const char *tb_name,
+                             const char **tb_column,
+                             ovs_db_table_cb_t update_cb,
+                             ovs_db_result_cb_t result_cb, unsigned int flags);
+
+/*
+ * OVS utils API
+ */
+
+/*
+ * NAME
+ *   ovs_utils_get_value_by_key
+ *
+ * DESCRIPTION
+ *   Get YAJL value by object name.
+ *
+ * PARAMETERS
+ *   `jval'        YAJL object value.
+ *   `key'         Object key name.
+ *
+ * RETURN VALUE
+ *   YAJL value upon success or NULL if key not found.
+ */
+yajl_val ovs_utils_get_value_by_key(yajl_val jval, const char *key);
+
+/*
+ * NAME
+ *   ovs_utils_get_map_value
+ *
+ * DESCRIPTION
+ *   Get OVS DB map value by given map key (rfc7047, "Notation" section).
+ *
+ * PARAMETERS
+ *   `jval'        A 2-element YAJL array that represents a OVS DB map value.
+ *   `key'         OVS DB map key name.
+ *
+ * RETURN VALUE
+ *   YAJL value upon success or NULL if key not found.
+ */
+yajl_val ovs_utils_get_map_value(yajl_val jval, const char *key);
+
+#endif
index ba37f03..a2a7380 100644 (file)
@@ -146,5 +146,3 @@ int parse_option(char **ret_buffer, char **ret_key, char **ret_value) {
 
   return (0);
 } /* int parse_option */
-
-/* vim: set sw=2 ts=8 tw=78 et : */
index a638e69..3dd0a79 100644 (file)
@@ -31,5 +31,3 @@ int parse_string(char **ret_buffer, char **ret_string);
 int parse_option(char **ret_buffer, char **ret_key, char **ret_value);
 
 #endif /* UTILS_PARSE_OPTION */
-
-/* vim: set sw=2 ts=8 tw=78 et : */
index 750d265..ae72575 100644 (file)
@@ -664,5 +664,3 @@ int cu_rrd_create_file(const char *filename, /* {{{ */
 
   return (status);
 } /* }}} int cu_rrd_create_file */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index 9bc67ae..d5f9a12 100644 (file)
@@ -51,5 +51,3 @@ int cu_rrd_create_file(const char *filename, const data_set_t *ds,
                        const value_list_t *vl, const rrdcreate_config_t *cfg);
 
 #endif /* UTILS_RRDCREATE_H */
-
-/* vim: set sw=2 sts=2 et : */
index 505c693..1a99384 100644 (file)
@@ -336,5 +336,3 @@ int tail_match_read(cu_tail_match_t *obj) {
 
   return (0);
 } /* int tail_match_read */
-
-/* vim: set sw=2 sts=2 ts=8 : */
index 09e3d40..03b70e9 100644 (file)
@@ -137,5 +137,3 @@ int tail_match_add_match_simple(cu_tail_match_t *obj, const char *regex,
  *   Zero on success, nonzero on failure.
 */
 int tail_match_read(cu_tail_match_t *obj);
-
-/* vim: set sw=2 sts=2 ts=8 : */
index 89c9e7d..546d481 100644 (file)
 #include <sys/sysctl.h>
 #endif
 
-#if HAVE_LIBHAL_H
-#include <libhal.h>
-#endif
-
 #define UUID_RAW_LENGTH 16
 #define UUID_PRINTABLE_COMPACT_LENGTH (UUID_RAW_LENGTH * 2)
 #define UUID_PRINTABLE_NORMAL_LENGTH (UUID_PRINTABLE_COMPACT_LENGTH + 4)
@@ -127,52 +123,6 @@ static char *uuid_get_from_sysctl(void) {
 }
 #endif
 
-#if HAVE_LIBHAL_H
-
-#define UUID_PATH "/org/freedesktop/Hal/devices/computer"
-#define UUID_PROPERTY "smbios.system.uuid"
-
-static char *uuid_get_from_hal(void) {
-  LibHalContext *ctx;
-
-  DBusError error;
-  DBusConnection *con;
-
-  dbus_error_init(&error);
-
-  if (!(con = dbus_bus_get(DBUS_BUS_SYSTEM, &error)))
-    goto bailout_nobus;
-
-  ctx = libhal_ctx_new();
-  libhal_ctx_set_dbus_connection(ctx, con);
-
-  if (!libhal_ctx_init(ctx, &error))
-    goto bailout;
-
-  if (!libhal_device_property_exists(ctx, UUID_PATH, UUID_PROPERTY, &error))
-    goto bailout;
-
-  char *uuid =
-      libhal_device_get_property_string(ctx, UUID_PATH, UUID_PROPERTY, &error);
-  if (looks_like_a_uuid(uuid))
-    return (uuid);
-
-bailout : {
-  DBusError ctxerror;
-  dbus_error_init(&ctxerror);
-  if (!(libhal_ctx_shutdown(ctx, &ctxerror)))
-    dbus_error_free(&ctxerror);
-}
-
-  libhal_ctx_free(ctx);
-
-bailout_nobus:
-  if (dbus_error_is_set(&error))
-    dbus_error_free(&error);
-  return (NULL);
-}
-#endif
-
 static char *uuid_get_from_file(const char *path) {
   FILE *file;
   char uuid[UUID_PRINTABLE_NORMAL_LENGTH + 1] = "";
@@ -215,11 +165,6 @@ static char *uuid_get_local(void) {
     return (uuid);
 #endif
 
-#if HAVE_LIBHAL_H
-  if ((uuid = uuid_get_from_hal()) != NULL)
-    return (uuid);
-#endif
-
   if ((uuid = uuid_get_from_dmidecode()) != NULL)
     return (uuid);
 
@@ -262,17 +207,3 @@ void module_register(void) {
                          STATIC_ARRAY_SIZE(config_keys));
   plugin_register_init("uuid", uuid_init);
 }
-
-/*
- * vim: set tabstop=4:
- * vim: set shiftwidth=4:
- * vim: set expandtab:
- */
-/*
- * Local variables:
- *  indent-tabs-mode: nil
- *  c-indent-level: 4
- *  c-basic-offset: 4
- *  tab-width: 4
- * End:
- */
index 41b60d8..3538e7e 100644 (file)
@@ -1331,5 +1331,3 @@ void module_register(void) /* {{{ */
   plugin_register_complex_config("varnish", varnish_config);
   plugin_register_init("varnish", varnish_init);
 } /* }}} */
-
-/* vim: set sw=8 noet fdm=marker : */
index c3c07a0..692088c 100644 (file)
 #include <libxml/parser.h>
 #include <libxml/tree.h>
 #include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
 
 /* Plugin name */
 #define PLUGIN_NAME "virt"
 
+#ifdef LIBVIR_CHECK_VERSION
+
+#if LIBVIR_CHECK_VERSION(0, 9, 5)
+#define HAVE_BLOCK_STATS_FLAGS 1
+#endif
+
+#if LIBVIR_CHECK_VERSION(0, 9, 11)
+#define HAVE_CPU_STATS 1
+#endif
+
+#endif /* LIBVIR_CHECK_VERSION */
+
 static const char *config_keys[] = {"Connection",
 
                                     "RefreshInterval",
@@ -52,6 +65,9 @@ static const char *config_keys[] = {"Connection",
 
                                     "PluginInstanceFormat",
 
+                                    "Instances",
+                                    "ExtraStats",
+
                                     NULL};
 #define NR_CONFIG_KEYS ((sizeof config_keys / sizeof config_keys[0]) - 1)
 
@@ -73,25 +89,12 @@ static ignorelist_t *il_interface_devices = NULL;
 static int ignore_device_match(ignorelist_t *, const char *domname,
                                const char *devpath);
 
-/* Actual list of domains found on last refresh. */
-static virDomainPtr *domains = NULL;
-static int nr_domains = 0;
-
-static void free_domains(void);
-static int add_domain(virDomainPtr dom);
-
 /* Actual list of block devices found on last refresh. */
 struct block_device {
   virDomainPtr dom; /* domain */
   char *path;       /* name of block device */
 };
 
-static struct block_device *block_devices = NULL;
-static int nr_block_devices = 0;
-
-static void free_block_devices(void);
-static int add_block_device(virDomainPtr dom, const char *path);
-
 /* Actual list of network interfaces found on last refresh. */
 struct interface_device {
   virDomainPtr dom; /* domain */
@@ -100,12 +103,52 @@ struct interface_device {
   char *number;     /* interface device number */
 };
 
-static struct interface_device *interface_devices = NULL;
-static int nr_interface_devices = 0;
+struct lv_read_state {
+  /* Actual list of domains found on last refresh. */
+  virDomainPtr *domains;
+  int nr_domains;
+
+  struct block_device *block_devices;
+  int nr_block_devices;
+
+  struct interface_device *interface_devices;
+  int nr_interface_devices;
+};
+
+static void free_domains(struct lv_read_state *state);
+static int add_domain(struct lv_read_state *state, virDomainPtr dom);
 
-static void free_interface_devices(void);
-static int add_interface_device(virDomainPtr dom, const char *path,
-                                const char *address, unsigned int number);
+static void free_block_devices(struct lv_read_state *state);
+static int add_block_device(struct lv_read_state *state, virDomainPtr dom,
+                            const char *path);
+
+static void free_interface_devices(struct lv_read_state *state);
+static int add_interface_device(struct lv_read_state *state, virDomainPtr dom,
+                                const char *path, const char *address,
+                                unsigned int number);
+
+#define METADATA_VM_PARTITION_URI "http://ovirt.org/ovirtmap/tag/1.0"
+#define METADATA_VM_PARTITION_ELEMENT "tag"
+#define METADATA_VM_PARTITION_PREFIX "ovirtmap"
+
+#define BUFFER_MAX_LEN 256
+#define PARTITION_TAG_MAX_LEN 32
+
+struct lv_read_instance {
+  struct lv_read_state read_state;
+  char tag[PARTITION_TAG_MAX_LEN];
+  size_t id;
+};
+
+struct lv_user_data {
+  struct lv_read_instance inst;
+  user_data_t ud;
+};
+
+#define NR_INSTANCES_DEFAULT 1
+#define NR_INSTANCES_MAX 128
+static int nr_instances = NR_INSTANCES_DEFAULT;
+static struct lv_user_data lv_read_user_data[NR_INSTANCES_MAX];
 
 /* HostnameFormat. */
 #define HF_MAX_FIELDS 3
@@ -128,6 +171,19 @@ enum bd_field { target, source };
 /* InterfaceFormat. */
 enum if_field { if_address, if_name, if_number };
 
+/* ExtraStats */
+#define EX_STATS_MAX_FIELDS 8
+enum ex_stats { ex_stats_none = 0, ex_stats_disk = 1, ex_stats_pcpu = 2 };
+static unsigned int extra_stats = ex_stats_none;
+
+struct ex_stats_item {
+  const char *name;
+  enum ex_stats flag;
+};
+static const struct ex_stats_item ex_stats_table[] = {
+    {"disk", ex_stats_disk}, {"pcpu", ex_stats_pcpu}, {NULL, ex_stats_none},
+};
+
 /* BlockDeviceFormatBasename */
 _Bool blockdevice_format_basename = 0;
 static enum bd_field blockdevice_format = target;
@@ -136,7 +192,72 @@ static enum if_field interface_format = if_name;
 /* Time that we last refreshed. */
 static time_t last_refresh = (time_t)0;
 
-static int refresh_lists(void);
+static int refresh_lists(struct lv_read_instance *inst);
+
+struct lv_info {
+  virDomainInfo di;
+  unsigned long long total_user_cpu_time;
+  unsigned long long total_syst_cpu_time;
+};
+
+struct lv_block_info {
+  virDomainBlockStatsStruct bi;
+
+  long long rd_total_times;
+  long long wr_total_times;
+
+  long long fl_req;
+  long long fl_total_times;
+};
+
+static void init_block_info(struct lv_block_info *binfo) {
+  if (binfo == NULL)
+    return;
+
+  binfo->bi.rd_req = -1;
+  binfo->bi.wr_req = -1;
+  binfo->bi.rd_bytes = -1;
+  binfo->bi.wr_bytes = -1;
+
+  binfo->rd_total_times = -1;
+  binfo->wr_total_times = -1;
+  binfo->fl_req = -1;
+  binfo->fl_total_times = -1;
+}
+
+#ifdef HAVE_BLOCK_STATS_FLAGS
+
+#define GET_BLOCK_INFO_VALUE(NAME, FIELD)                                      \
+  do {                                                                         \
+    if (!strcmp(param[i].field, NAME)) {                                       \
+      binfo->FIELD = param[i].value.l;                                         \
+      continue;                                                                \
+    }                                                                          \
+  } while (0)
+
+static int get_block_info(struct lv_block_info *binfo,
+                          virTypedParameterPtr param, int nparams) {
+  if (binfo == NULL || param == NULL)
+    return -1;
+
+  for (int i = 0; i < nparams; ++i) {
+    /* ignore type. Everything must be LLONG anyway. */
+    GET_BLOCK_INFO_VALUE("rd_operations", bi.rd_req);
+    GET_BLOCK_INFO_VALUE("wr_operations", bi.wr_req);
+    GET_BLOCK_INFO_VALUE("rd_bytes", bi.rd_bytes);
+    GET_BLOCK_INFO_VALUE("wr_bytes", bi.wr_bytes);
+    GET_BLOCK_INFO_VALUE("rd_total_times", rd_total_times);
+    GET_BLOCK_INFO_VALUE("wr_total_times", wr_total_times);
+    GET_BLOCK_INFO_VALUE("flush_operations", fl_req);
+    GET_BLOCK_INFO_VALUE("flush_total_times", fl_total_times);
+  }
+
+  return 0;
+}
+
+#undef GET_BLOCK_INFO_VALUE
+
+#endif /* HAVE_BLOCK_STATS_FLAGS */
 
 /* ERROR(...) macro for virterrors. */
 #define VIRT_ERROR(conn, s)                                                    \
@@ -147,6 +268,54 @@ static int refresh_lists(void);
       ERROR("%s: %s", (s), err->message);                                      \
   } while (0)
 
+static void init_lv_info(struct lv_info *info) {
+  if (info != NULL)
+    memset(info, 0, sizeof(*info));
+}
+
+static int lv_domain_info(virDomainPtr dom, struct lv_info *info) {
+#ifdef HAVE_CPU_STATS
+  virTypedParameterPtr param = NULL;
+  int nparams = 0;
+#endif /* HAVE_CPU_STATS */
+  int ret = virDomainGetInfo(dom, &(info->di));
+  if (ret != 0) {
+    return ret;
+  }
+
+#ifdef HAVE_CPU_STATS
+  nparams = virDomainGetCPUStats(dom, NULL, 0, -1, 1, 0);
+  if (nparams < 0) {
+    VIRT_ERROR(conn, "getting the CPU params count");
+    return -1;
+  }
+
+  param = calloc(nparams, sizeof(virTypedParameter));
+  if (param == NULL) {
+    ERROR("virt plugin: alloc(%i) for cpu parameters failed.", nparams);
+    return -1;
+  }
+
+  ret = virDomainGetCPUStats(dom, param, nparams, -1, 1, 0); // total stats.
+  if (ret < 0) {
+    virTypedParamsFree(param, nparams);
+    VIRT_ERROR(conn, "getting the disk params values");
+    return -1;
+  }
+
+  for (int i = 0; i < nparams; ++i) {
+    if (!strcmp(param[i].field, "user_time"))
+      info->total_user_cpu_time = param[i].value.ul;
+    else if (!strcmp(param[i].field, "system_time"))
+      info->total_syst_cpu_time = param[i].value.ul;
+  }
+
+  virTypedParamsFree(param, nparams);
+#endif /* HAVE_CPU_STATS */
+
+  return 0;
+}
+
 static void init_value_list(value_list_t *vl, virDomainPtr dom) {
   int n;
   const char *name;
@@ -253,6 +422,23 @@ static void memory_stats_submit(gauge_t value, virDomainPtr dom,
   submit(dom, "memory", tags[tag_index], &(value_t){.gauge = value}, 1);
 }
 
+static void submit_derive2(const char *type, derive_t v0, derive_t v1,
+                           virDomainPtr dom, const char *devname) {
+  value_t values[] = {
+      {.derive = v0}, {.derive = v1},
+  };
+
+  submit(dom, type, devname, values, STATIC_ARRAY_SIZE(values));
+} /* void submit_derive2 */
+
+static void pcpu_submit(virDomainPtr dom, struct lv_info *info) {
+#ifdef HAVE_CPU_STATS
+  if (extra_stats & ex_stats_pcpu)
+    submit_derive2("ps_cputime", info->total_user_cpu_time,
+                   info->total_syst_cpu_time, dom, NULL);
+#endif /* HAVE_CPU_STATS */
+}
+
 static void cpu_submit(unsigned long long value, virDomainPtr dom,
                        const char *type) {
   submit(dom, type, NULL, &(value_t){.derive = (derive_t)value}, 1);
@@ -267,20 +453,50 @@ static void vcpu_submit(derive_t value, virDomainPtr dom, int vcpu_nr,
   submit(dom, type, type_instance, &(value_t){.derive = value}, 1);
 }
 
-static void submit_derive2(const char *type, derive_t v0, derive_t v1,
-                           virDomainPtr dom, const char *devname) {
-  value_t values[] = {
-      {.derive = v0}, {.derive = v1},
-  };
-
-  submit(dom, type, devname, values, STATIC_ARRAY_SIZE(values));
-} /* void submit_derive2 */
+static void disk_submit(struct lv_block_info *binfo, virDomainPtr dom,
+                        const char *type_instance) {
+  char flush_type_instance[DATA_MAX_NAME_LEN];
+
+  ssnprintf(flush_type_instance, sizeof(flush_type_instance), "flush-%s",
+            type_instance);
+
+  if ((binfo->bi.rd_req != -1) && (binfo->bi.wr_req != -1))
+    submit_derive2("disk_ops", (derive_t)binfo->bi.rd_req,
+                   (derive_t)binfo->bi.wr_req, dom, type_instance);
+
+  if ((binfo->bi.rd_bytes != -1) && (binfo->bi.wr_bytes != -1))
+    submit_derive2("disk_octets", (derive_t)binfo->bi.rd_bytes,
+                   (derive_t)binfo->bi.wr_bytes, dom, type_instance);
+
+  if (extra_stats & ex_stats_disk) {
+    if ((binfo->rd_total_times != -1) && (binfo->wr_total_times != -1))
+      submit_derive2("disk_time", (derive_t)binfo->rd_total_times,
+                     (derive_t)binfo->wr_total_times, dom, type_instance);
+
+    if (binfo->fl_req != -1)
+      submit(dom, "total_requests", flush_type_instance,
+             &(value_t){.derive = (derive_t)binfo->fl_req}, 1);
+    if (binfo->fl_total_times != -1) {
+      derive_t value = binfo->fl_total_times / 1000; // ns -> ms
+      submit(dom, "total_time_in_ms", flush_type_instance,
+             &(value_t){.derive = value}, 1);
+    }
+  }
+}
 
-static int lv_init(void) {
-  if (virInitialize() != 0)
-    return -1;
-  else
-    return 0;
+static unsigned int parse_ex_stats_flags(char **exstats, int numexstats) {
+  unsigned int ex_stats_flags = ex_stats_none;
+  for (int i = 0; i < numexstats; i++) {
+    for (int j = 0; ex_stats_table[j].name != NULL; j++) {
+      if (strcasecmp(exstats[i], ex_stats_table[j].name) == 0) {
+        DEBUG(PLUGIN_NAME " plugin: enabling extra stats for '%s'",
+              ex_stats_table[j].name);
+        ex_stats_flags |= ex_stats_table[j].flag;
+        break;
+      }
+    }
+  }
+  return ex_stats_flags;
 }
 
 static int lv_config(const char *key, const char *value) {
@@ -453,13 +669,46 @@ static int lv_config(const char *key, const char *value) {
     return 0;
   }
 
+  if (strcasecmp(key, "Instances") == 0) {
+    char *eptr = NULL;
+    double val = strtod(value, &eptr);
+
+    if (*eptr != '\0') {
+      ERROR(PLUGIN_NAME " plugin: Invalid value for Instances = '%s'", value);
+      return 1;
+    }
+    if (val <= 0) {
+      ERROR(PLUGIN_NAME " plugin: Instances <= 0 makes no sense.");
+      return 1;
+    }
+    if (val > NR_INSTANCES_MAX) {
+      ERROR(PLUGIN_NAME " plugin: Instances=%f > NR_INSTANCES_MAX=%i"
+                        " use a lower setting or recompile the plugin.",
+            val, NR_INSTANCES_MAX);
+      return 1;
+    }
+
+    nr_instances = (int)val;
+    DEBUG(PLUGIN_NAME " plugin: configured %i instances", nr_instances);
+    return 0;
+  }
+
+  if (strcasecmp(key, "ExtraStats") == 0) {
+    char *localvalue = strdup(value);
+    if (localvalue != NULL) {
+      char *exstats[EX_STATS_MAX_FIELDS];
+      int numexstats =
+          strsplit(localvalue, exstats, STATIC_ARRAY_SIZE(exstats));
+      extra_stats = parse_ex_stats_flags(exstats, numexstats);
+      sfree(localvalue);
+    }
+  }
+
   /* Unrecognised option. */
   return -1;
 }
 
-static int lv_read(void) {
-  time_t t;
-
+static int lv_connect(void) {
   if (conn == NULL) {
     /* `conn_string == NULL' is acceptable. */
     conn = virConnectOpenReadOnly(conn_string);
@@ -472,16 +721,76 @@ static int lv_read(void) {
   }
   c_release(LOG_NOTICE, &conn_complain,
             PLUGIN_NAME " plugin: Connection established.");
+  return 0;
+}
+
+static void lv_disconnect(void) {
+  if (conn != NULL)
+    virConnectClose(conn);
+  conn = NULL;
+  WARNING(PLUGIN_NAME " plugin: closed connection to libvirt");
+}
+
+static int lv_domain_block_info(virDomainPtr dom, const char *path,
+                                struct lv_block_info *binfo) {
+#ifdef HAVE_BLOCK_STATS_FLAGS
+  virTypedParameterPtr params = NULL;
+  int nparams = 0;
+  int rc = -1;
+  int ret = virDomainBlockStatsFlags(dom, path, NULL, &nparams, 0);
+  if (ret < 0 || nparams == 0) {
+    VIRT_ERROR(conn, "getting the disk params count");
+    return -1;
+  }
+
+  params = calloc(nparams, sizeof(virTypedParameter));
+  if (params == NULL) {
+    ERROR("virt plugin: alloc(%i) for block=%s parameters failed.", nparams,
+          path);
+    return -1;
+  }
+  ret = virDomainBlockStatsFlags(dom, path, params, &nparams, 0);
+  if (ret < 0) {
+    VIRT_ERROR(conn, "getting the disk params values");
+    goto done;
+  }
+
+  rc = get_block_info(binfo, params, nparams);
+
+done:
+  virTypedParamsFree(params, nparams);
+  return rc;
+#else
+  return virDomainBlockStats(dom, path, &(binfo->bi), sizeof(binfo->bi));
+#endif /* HAVE_BLOCK_STATS_FLAGS */
+}
+
+static int lv_read(user_data_t *ud) {
+  time_t t;
+  struct lv_read_instance *inst = NULL;
+  struct lv_read_state *state = NULL;
+
+  if (ud->data == NULL) {
+    ERROR(PLUGIN_NAME " plugin: NULL userdata");
+    return -1;
+  }
+
+  inst = ud->data;
+  state = &inst->read_state;
+
+  if (inst->id == 0) {
+    if (lv_connect() < 0)
+      return -1;
+  }
 
   time(&t);
 
   /* Need to refresh domain or device lists? */
   if ((last_refresh == (time_t)0) ||
       ((interval > 0) && ((last_refresh + interval) <= t))) {
-    if (refresh_lists() != 0) {
-      if (conn != NULL)
-        virConnectClose(conn);
-      conn = NULL;
+    if (refresh_lists(inst) != 0) {
+      if (inst->id == 0)
+        lv_disconnect();
       return -1;
     }
     last_refresh = t;
@@ -501,34 +810,31 @@ static int lv_read(void) {
 #endif
 
   /* Get CPU usage, memory, VCPU usage for each domain. */
-  for (int i = 0; i < nr_domains; ++i) {
-    virDomainInfo info;
+  for (int i = 0; i < state->nr_domains; ++i) {
+    struct lv_info info;
     virVcpuInfoPtr vinfo = NULL;
     virDomainMemoryStatPtr minfo = NULL;
     int status;
 
-    status = virDomainGetInfo(domains[i], &info);
+    init_lv_info(&info);
+    status = lv_domain_info(state->domains[i], &info);
     if (status != 0) {
       ERROR(PLUGIN_NAME " plugin: virDomainGetInfo failed with status %i.",
             status);
       continue;
     }
 
-    if (info.state != VIR_DOMAIN_RUNNING) {
-      /* only gather stats for running domains */
-      continue;
-    }
-
-    cpu_submit(info.cpuTime, domains[i], "virt_cpu_total");
-    memory_submit((gauge_t)info.memory * 1024, domains[i]);
+    pcpu_submit(state->domains[i], &info);
+    cpu_submit(info.di.cpuTime, state->domains[i], "virt_cpu_total");
+    memory_submit((gauge_t)info.di.memory * 1024, state->domains[i]);
 
-    vinfo = malloc(info.nrVirtCpu * sizeof(vinfo[0]));
+    vinfo = malloc(info.di.nrVirtCpu * sizeof(vinfo[0]));
     if (vinfo == NULL) {
       ERROR(PLUGIN_NAME " plugin: malloc failed.");
       continue;
     }
 
-    status = virDomainGetVcpus(domains[i], vinfo, info.nrVirtCpu,
+    status = virDomainGetVcpus(state->domains[i], vinfo, info.di.nrVirtCpu,
                                /* cpu map = */ NULL, /* cpu map length = */ 0);
     if (status < 0) {
       ERROR(PLUGIN_NAME " plugin: virDomainGetVcpus failed with status %i.",
@@ -537,8 +843,9 @@ static int lv_read(void) {
       continue;
     }
 
-    for (int j = 0; j < info.nrVirtCpu; ++j)
-      vcpu_submit(vinfo[j].cpuTime, domains[i], vinfo[j].number, "virt_vcpu");
+    for (int j = 0; j < info.di.nrVirtCpu; ++j)
+      vcpu_submit(vinfo[j].cpuTime, state->domains[i], vinfo[j].number,
+                  "virt_vcpu");
 
     sfree(vinfo);
 
@@ -549,8 +856,8 @@ static int lv_read(void) {
       continue;
     }
 
-    status =
-        virDomainMemoryStats(domains[i], minfo, VIR_DOMAIN_MEMORY_STAT_NR, 0);
+    status = virDomainMemoryStats(state->domains[i], minfo,
+                                  VIR_DOMAIN_MEMORY_STAT_NR, 0);
 
     if (status < 0) {
       ERROR("virt plugin: virDomainMemoryStats failed with status %i.", status);
@@ -559,7 +866,7 @@ static int lv_read(void) {
     }
 
     for (int j = 0; j < status; j++) {
-      memory_stats_submit((gauge_t)minfo[j].val * 1024, domains[i],
+      memory_stats_submit((gauge_t)minfo[j].val * 1024, state->domains[i],
                           minfo[j].tag);
     }
 
@@ -567,78 +874,220 @@ static int lv_read(void) {
   }
 
   /* Get block device stats for each domain. */
-  for (int i = 0; i < nr_block_devices; ++i) {
-    struct _virDomainBlockStats stats;
+  for (int i = 0; i < state->nr_block_devices; ++i) {
+    struct block_device *bdev = &(state->block_devices[i]);
+    struct lv_block_info binfo;
+    init_block_info(&binfo);
 
-    if (virDomainBlockStats(block_devices[i].dom, block_devices[i].path, &stats,
-                            sizeof stats) != 0)
+    if (lv_domain_block_info(bdev->dom, bdev->path, &binfo) < 0)
       continue;
 
-    char *type_instance = NULL;
-    if (blockdevice_format_basename && blockdevice_format == source)
-      type_instance = strdup(basename(block_devices[i].path));
-    else
-      type_instance = strdup(block_devices[i].path);
-
-    if ((stats.rd_req != -1) && (stats.wr_req != -1))
-      submit_derive2("disk_ops", (derive_t)stats.rd_req, (derive_t)stats.wr_req,
-                     block_devices[i].dom, type_instance);
+    char *type_instance = bdev->path;
+    char *path = NULL;
+    if (blockdevice_format_basename && blockdevice_format == source) {
+      path = strdup(bdev->path);
+      if (path == NULL) {
+        WARNING(PLUGIN_NAME
+                " plugin: error extracting the basename for '%s', skipped",
+                bdev->path);
+        continue;
+      }
+      type_instance = basename(path);
+    }
 
-    if ((stats.rd_bytes != -1) && (stats.wr_bytes != -1))
-      submit_derive2("disk_octets", (derive_t)stats.rd_bytes,
-                     (derive_t)stats.wr_bytes, block_devices[i].dom,
-                     type_instance);
+    disk_submit(&binfo, bdev->dom, type_instance);
 
-    sfree(type_instance);
+    sfree(path);
   } /* for (nr_block_devices) */
 
   /* Get interface stats for each domain. */
-  for (int i = 0; i < nr_interface_devices; ++i) {
+  for (int i = 0; i < state->nr_interface_devices; ++i) {
     struct _virDomainInterfaceStats stats;
     char *display_name = NULL;
 
     switch (interface_format) {
     case if_address:
-      display_name = interface_devices[i].address;
+      display_name = state->interface_devices[i].address;
       break;
     case if_number:
-      display_name = interface_devices[i].number;
+      display_name = state->interface_devices[i].number;
       break;
     case if_name:
     default:
-      display_name = interface_devices[i].path;
+      display_name = state->interface_devices[i].path;
     }
 
-    if (virDomainInterfaceStats(interface_devices[i].dom,
-                                interface_devices[i].path, &stats,
+    if (virDomainInterfaceStats(state->interface_devices[i].dom,
+                                state->interface_devices[i].path, &stats,
                                 sizeof stats) != 0)
       continue;
 
     if ((stats.rx_bytes != -1) && (stats.tx_bytes != -1))
       submit_derive2("if_octets", (derive_t)stats.rx_bytes,
-                     (derive_t)stats.tx_bytes, interface_devices[i].dom,
+                     (derive_t)stats.tx_bytes, state->interface_devices[i].dom,
                      display_name);
 
     if ((stats.rx_packets != -1) && (stats.tx_packets != -1))
       submit_derive2("if_packets", (derive_t)stats.rx_packets,
-                     (derive_t)stats.tx_packets, interface_devices[i].dom,
-                     display_name);
+                     (derive_t)stats.tx_packets,
+                     state->interface_devices[i].dom, display_name);
 
     if ((stats.rx_errs != -1) && (stats.tx_errs != -1))
       submit_derive2("if_errors", (derive_t)stats.rx_errs,
-                     (derive_t)stats.tx_errs, interface_devices[i].dom,
+                     (derive_t)stats.tx_errs, state->interface_devices[i].dom,
                      display_name);
 
     if ((stats.rx_drop != -1) && (stats.tx_drop != -1))
       submit_derive2("if_dropped", (derive_t)stats.rx_drop,
-                     (derive_t)stats.tx_drop, interface_devices[i].dom,
+                     (derive_t)stats.tx_drop, state->interface_devices[i].dom,
                      display_name);
   } /* for (nr_interface_devices) */
 
   return 0;
 }
 
-static int refresh_lists(void) {
+static int lv_init_instance(size_t i, plugin_read_cb callback) {
+  struct lv_user_data *lv_ud = &(lv_read_user_data[i]);
+  struct lv_read_instance *inst = &(lv_ud->inst);
+
+  memset(lv_ud, 0, sizeof(*lv_ud));
+
+  ssnprintf(inst->tag, sizeof(inst->tag), "%s-%zu", PLUGIN_NAME, i);
+  inst->id = i;
+
+  user_data_t *ud = &(lv_ud->ud);
+  ud->data = inst;
+  ud->free_func = NULL;
+
+  INFO(PLUGIN_NAME " plugin: reader %s initialized", inst->tag);
+  return plugin_register_complex_read(NULL, inst->tag, callback, 0, ud);
+}
+
+static void lv_clean_read_state(struct lv_read_state *state) {
+  free_block_devices(state);
+  free_interface_devices(state);
+  free_domains(state);
+}
+
+static void lv_fini_instance(size_t i) {
+  struct lv_read_instance *inst = &(lv_read_user_data[i].inst);
+  struct lv_read_state *state = &(inst->read_state);
+
+  lv_clean_read_state(state);
+  INFO(PLUGIN_NAME " plugin: reader %s finalized", inst->tag);
+}
+
+static int lv_init(void) {
+  if (virInitialize() != 0)
+    return -1;
+
+  if (lv_connect() != 0)
+    return -1;
+
+  DEBUG(PLUGIN_NAME " plugin: starting %i instances", nr_instances);
+
+  for (int i = 0; i < nr_instances; ++i)
+    lv_init_instance(i, lv_read);
+
+  return 0;
+}
+
+/*
+ * returns 0 on success and <0 on error
+ */
+static int lv_domain_get_tag(xmlXPathContextPtr xpath_ctx, const char *dom_name,
+                             char *dom_tag) {
+  char xpath_str[BUFFER_MAX_LEN] = {'\0'};
+  xmlXPathObjectPtr xpath_obj = NULL;
+  xmlNodePtr xml_node = NULL;
+  int ret = -1;
+  int err;
+
+  err = xmlXPathRegisterNs(xpath_ctx,
+                           (const xmlChar *)METADATA_VM_PARTITION_PREFIX,
+                           (const xmlChar *)METADATA_VM_PARTITION_URI);
+  if (err) {
+    ERROR(PLUGIN_NAME " plugin: xmlXpathRegisterNs(%s, %s) failed on domain %s",
+          METADATA_VM_PARTITION_PREFIX, METADATA_VM_PARTITION_URI, dom_name);
+    goto done;
+  }
+
+  ssnprintf(xpath_str, sizeof(xpath_str), "/domain/metadata/%s:%s/text()",
+            METADATA_VM_PARTITION_PREFIX, METADATA_VM_PARTITION_ELEMENT);
+  xpath_obj = xmlXPathEvalExpression((xmlChar *)xpath_str, xpath_ctx);
+  if (xpath_obj == NULL) {
+    ERROR(PLUGIN_NAME " plugin: xmlXPathEval(%s) failed on domain %s",
+          xpath_str, dom_name);
+    goto done;
+  }
+
+  if (xpath_obj->type != XPATH_NODESET) {
+    ERROR(PLUGIN_NAME " plugin: xmlXPathEval(%s) unexpected return type %d "
+                      "(wanted %d) on domain %s",
+          xpath_str, xpath_obj->type, XPATH_NODESET, dom_name);
+    goto done;
+  }
+
+  /*
+   * from now on there is no real error, it's ok if a domain
+   * doesn't have the metadata partition tag.
+   */
+  ret = 0;
+  if (xpath_obj->nodesetval == NULL || xpath_obj->nodesetval->nodeNr != 1) {
+    DEBUG(PLUGIN_NAME " plugin: xmlXPathEval(%s) return nodeset size=%i "
+                      "expected=1 on domain %s",
+          xpath_str,
+          (xpath_obj->nodesetval == NULL) ? 0 : xpath_obj->nodesetval->nodeNr,
+          dom_name);
+  } else {
+    xml_node = xpath_obj->nodesetval->nodeTab[0];
+    sstrncpy(dom_tag, (const char *)xml_node->content, PARTITION_TAG_MAX_LEN);
+  }
+
+done:
+  /* deregister to clean up */
+  err = xmlXPathRegisterNs(xpath_ctx,
+                           (const xmlChar *)METADATA_VM_PARTITION_PREFIX, NULL);
+  if (err) {
+    /* we can't really recover here */
+    ERROR(PLUGIN_NAME
+          " plugin: deregistration of namespace %s failed for domain %s",
+          METADATA_VM_PARTITION_PREFIX, dom_name);
+  }
+  if (xpath_obj)
+    xmlXPathFreeObject(xpath_obj);
+
+  return ret;
+}
+
+static int is_known_tag(const char *dom_tag) {
+  for (int i = 0; i < nr_instances; ++i)
+    if (!strcmp(dom_tag, lv_read_user_data[i].inst.tag))
+      return 1;
+  return 0;
+}
+
+static int lv_instance_include_domain(struct lv_read_instance *inst,
+                                      const char *dom_name,
+                                      const char *dom_tag) {
+  if ((dom_tag[0] != '\0') && (strcmp(dom_tag, inst->tag) == 0))
+    return 1;
+
+  /* instance#0 will always be there, so it is in charge of extra duties */
+  if (inst->id == 0) {
+    if (dom_tag[0] == '\0' || !is_known_tag(dom_tag)) {
+      DEBUG(PLUGIN_NAME " plugin#%s: refreshing domain %s "
+                        "with unknown tag '%s'",
+            inst->tag, dom_name, dom_tag);
+      return 1;
+    }
+  }
+
+  return 0;
+}
+
+static int refresh_lists(struct lv_read_instance *inst) {
+  struct lv_read_state *state = &inst->read_state;
   int n;
 
   n = virConnectNumOfDomains(conn);
@@ -647,6 +1096,8 @@ static int refresh_lists(void) {
     return -1;
   }
 
+  lv_clean_read_state(state);
+
   if (n > 0) {
     int *domids;
 
@@ -664,10 +1115,6 @@ static int refresh_lists(void) {
       return -1;
     }
 
-    free_block_devices();
-    free_interface_devices();
-    free_domains();
-
     /* Fetch each domain and add it to the list, unless ignore. */
     for (int i = 0; i < n; ++i) {
       virDomainPtr dom = NULL;
@@ -676,6 +1123,9 @@ static int refresh_lists(void) {
       xmlDocPtr xml_doc = NULL;
       xmlXPathContextPtr xpath_ctx = NULL;
       xmlXPathObjectPtr xpath_obj = NULL;
+      char tag[PARTITION_TAG_MAX_LEN] = {'\0'};
+      virDomainInfo info;
+      int status;
 
       dom = virDomainLookupByID(conn, domids[i]);
       if (dom == NULL) {
@@ -690,14 +1140,21 @@ static int refresh_lists(void) {
         goto cont;
       }
 
-      if (il_domains && ignorelist_match(il_domains, name) != 0)
-        goto cont;
+      status = virDomainGetInfo(dom, &info);
+      if (status != 0) {
+        ERROR(PLUGIN_NAME " plugin: virDomainGetInfo failed with status %i.",
+              status);
+        continue;
+      }
 
-      if (add_domain(dom) < 0) {
-        ERROR(PLUGIN_NAME " plugin: malloc failed.");
-        goto cont;
+      if (info.state != VIR_DOMAIN_RUNNING) {
+        DEBUG(PLUGIN_NAME " plugin: skipping inactive domain %s", name);
+        continue;
       }
 
+      if (il_domains && ignorelist_match(il_domains, name) != 0)
+        goto cont;
+
       /* Get a list of devices for this domain. */
       xml = virDomainGetXMLDesc(dom, 0);
       if (!xml) {
@@ -714,11 +1171,24 @@ static int refresh_lists(void) {
 
       xpath_ctx = xmlXPathNewContext(xml_doc);
 
+      if (lv_domain_get_tag(xpath_ctx, name, tag) < 0) {
+        ERROR(PLUGIN_NAME " plugin: lv_domain_get_tag failed.");
+        goto cont;
+      }
+
+      if (!lv_instance_include_domain(inst, name, tag))
+        goto cont;
+
+      if (add_domain(state, dom) < 0) {
+        ERROR(PLUGIN_NAME " plugin: malloc failed.");
+        goto cont;
+      }
+
       /* Block devices. */
-      char *bd_xmlpath = "/domain/devices/disk/target[@dev]";
+      const char *bd_xmlpath = "/domain/devices/disk/target[@dev]";
       if (blockdevice_format == source)
         bd_xmlpath = "/domain/devices/disk/source[@dev]";
-      xpath_obj = xmlXPathEval((xmlChar *)bd_xmlpath, xpath_ctx);
+      xpath_obj = xmlXPathEval((const xmlChar *)bd_xmlpath, xpath_ctx);
 
       if (xpath_obj == NULL || xpath_obj->type != XPATH_NODESET ||
           xpath_obj->nodesetval == NULL)
@@ -739,7 +1209,7 @@ static int refresh_lists(void) {
             ignore_device_match(il_block_devices, name, path) != 0)
           goto cont2;
 
-        add_block_device(dom, path);
+        add_block_device(state, dom, path);
       cont2:
         if (path)
           xmlFree(path);
@@ -785,7 +1255,7 @@ static int refresh_lists(void) {
              ignore_device_match(il_interface_devices, name, address) != 0))
           goto cont3;
 
-        add_interface_device(dom, path, address, j + 1);
+        add_interface_device(state, dom, path, address, j + 1);
       cont3:
         if (path)
           xmlFree(path);
@@ -806,57 +1276,64 @@ static int refresh_lists(void) {
     sfree(domids);
   }
 
+  DEBUG(PLUGIN_NAME " plugin#%s: refreshing"
+                    " domains=%i block_devices=%i iface_devices=%i",
+        inst->tag, state->nr_domains, state->nr_block_devices,
+        state->nr_interface_devices);
+
   return 0;
 }
 
-static void free_domains(void) {
-  if (domains) {
-    for (int i = 0; i < nr_domains; ++i)
-      virDomainFree(domains[i]);
-    sfree(domains);
+static void free_domains(struct lv_read_state *state) {
+  if (state->domains) {
+    for (int i = 0; i < state->nr_domains; ++i)
+      virDomainFree(state->domains[i]);
+    sfree(state->domains);
   }
-  domains = NULL;
-  nr_domains = 0;
+  state->domains = NULL;
+  state->nr_domains = 0;
 }
 
-static int add_domain(virDomainPtr dom) {
+static int add_domain(struct lv_read_state *state, virDomainPtr dom) {
   virDomainPtr *new_ptr;
-  int new_size = sizeof(domains[0]) * (nr_domains + 1);
+  int new_size = sizeof(state->domains[0]) * (state->nr_domains + 1);
 
-  if (domains)
-    new_ptr = realloc(domains, new_size);
+  if (state->domains)
+    new_ptr = realloc(state->domains, new_size);
   else
     new_ptr = malloc(new_size);
 
   if (new_ptr == NULL)
     return -1;
 
-  domains = new_ptr;
-  domains[nr_domains] = dom;
-  return nr_domains++;
+  state->domains = new_ptr;
+  state->domains[state->nr_domains] = dom;
+  return state->nr_domains++;
 }
 
-static void free_block_devices(void) {
-  if (block_devices) {
-    for (int i = 0; i < nr_block_devices; ++i)
-      sfree(block_devices[i].path);
-    sfree(block_devices);
+static void free_block_devices(struct lv_read_state *state) {
+  if (state->block_devices) {
+    for (int i = 0; i < state->nr_block_devices; ++i)
+      sfree(state->block_devices[i].path);
+    sfree(state->block_devices);
   }
-  block_devices = NULL;
-  nr_block_devices = 0;
+  state->block_devices = NULL;
+  state->nr_block_devices = 0;
 }
 
-static int add_block_device(virDomainPtr dom, const char *path) {
+static int add_block_device(struct lv_read_state *state, virDomainPtr dom,
+                            const char *path) {
   struct block_device *new_ptr;
-  int new_size = sizeof(block_devices[0]) * (nr_block_devices + 1);
+  int new_size =
+      sizeof(state->block_devices[0]) * (state->nr_block_devices + 1);
   char *path_copy;
 
   path_copy = strdup(path);
   if (!path_copy)
     return -1;
 
-  if (block_devices)
-    new_ptr = realloc(block_devices, new_size);
+  if (state->block_devices)
+    new_ptr = realloc(state->block_devices, new_size);
   else
     new_ptr = malloc(new_size);
 
@@ -864,29 +1341,31 @@ static int add_block_device(virDomainPtr dom, const char *path) {
     sfree(path_copy);
     return -1;
   }
-  block_devices = new_ptr;
-  block_devices[nr_block_devices].dom = dom;
-  block_devices[nr_block_devices].path = path_copy;
-  return nr_block_devices++;
+  state->block_devices = new_ptr;
+  state->block_devices[state->nr_block_devices].dom = dom;
+  state->block_devices[state->nr_block_devices].path = path_copy;
+  return state->nr_block_devices++;
 }
 
-static void free_interface_devices(void) {
-  if (interface_devices) {
-    for (int i = 0; i < nr_interface_devices; ++i) {
-      sfree(interface_devices[i].path);
-      sfree(interface_devices[i].address);
-      sfree(interface_devices[i].number);
+static void free_interface_devices(struct lv_read_state *state) {
+  if (state->interface_devices) {
+    for (int i = 0; i < state->nr_interface_devices; ++i) {
+      sfree(state->interface_devices[i].path);
+      sfree(state->interface_devices[i].address);
+      sfree(state->interface_devices[i].number);
     }
-    sfree(interface_devices);
+    sfree(state->interface_devices);
   }
-  interface_devices = NULL;
-  nr_interface_devices = 0;
+  state->interface_devices = NULL;
+  state->nr_interface_devices = 0;
 }
 
-static int add_interface_device(virDomainPtr dom, const char *path,
-                                const char *address, unsigned int number) {
+static int add_interface_device(struct lv_read_state *state, virDomainPtr dom,
+                                const char *path, const char *address,
+                                unsigned int number) {
   struct interface_device *new_ptr;
-  int new_size = sizeof(interface_devices[0]) * (nr_interface_devices + 1);
+  int new_size =
+      sizeof(state->interface_devices[0]) * (state->nr_interface_devices + 1);
   char *path_copy, *address_copy, number_string[15];
 
   if ((path == NULL) || (address == NULL))
@@ -904,8 +1383,8 @@ static int add_interface_device(virDomainPtr dom, const char *path,
 
   snprintf(number_string, sizeof(number_string), "interface-%u", number);
 
-  if (interface_devices)
-    new_ptr = realloc(interface_devices, new_size);
+  if (state->interface_devices)
+    new_ptr = realloc(state->interface_devices, new_size);
   else
     new_ptr = malloc(new_size);
 
@@ -914,12 +1393,13 @@ static int add_interface_device(virDomainPtr dom, const char *path,
     sfree(address_copy);
     return -1;
   }
-  interface_devices = new_ptr;
-  interface_devices[nr_interface_devices].dom = dom;
-  interface_devices[nr_interface_devices].path = path_copy;
-  interface_devices[nr_interface_devices].address = address_copy;
-  interface_devices[nr_interface_devices].number = strdup(number_string);
-  return nr_interface_devices++;
+  state->interface_devices = new_ptr;
+  state->interface_devices[state->nr_interface_devices].dom = dom;
+  state->interface_devices[state->nr_interface_devices].path = path_copy;
+  state->interface_devices[state->nr_interface_devices].address = address_copy;
+  state->interface_devices[state->nr_interface_devices].number =
+      strdup(number_string);
+  return state->nr_interface_devices++;
 }
 
 static int ignore_device_match(ignorelist_t *il, const char *domname,
@@ -943,13 +1423,11 @@ static int ignore_device_match(ignorelist_t *il, const char *domname,
 }
 
 static int lv_shutdown(void) {
-  free_block_devices();
-  free_interface_devices();
-  free_domains();
+  for (int i = 0; i < nr_instances; ++i) {
+    lv_fini_instance(i);
+  }
 
-  if (conn != NULL)
-    virConnectClose(conn);
-  conn = NULL;
+  lv_disconnect();
 
   ignorelist_free(il_domains);
   il_domains = NULL;
@@ -964,10 +1442,5 @@ static int lv_shutdown(void) {
 void module_register(void) {
   plugin_register_config(PLUGIN_NAME, lv_config, config_keys, NR_CONFIG_KEYS);
   plugin_register_init(PLUGIN_NAME, lv_init);
-  plugin_register_read(PLUGIN_NAME, lv_read);
   plugin_register_shutdown(PLUGIN_NAME, lv_shutdown);
 }
-
-/*
- * vim: shiftwidth=4 tabstop=8 softtabstop=4 expandtab fdm=marker
- */
diff --git a/src/virt_test.c b/src/virt_test.c
new file mode 100644 (file)
index 0000000..cb3cc25
--- /dev/null
@@ -0,0 +1,207 @@
+/**
+ * collectd - src/virt_test.c
+ * Copyright (C) 2016 Francesco Romani <fromani at redhat.com>
+ * Based on
+ * collectd - src/ceph_test.c
+ * Copyright (C) 2015      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
+ * Free Software Foundation; only version 2 of the License is applicable.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <octo at collectd.org>
+ **/
+
+#include "virt.c" /* sic */
+#include "testing.h"
+
+#include <unistd.h>
+
+static const char minimal_xml[] =
+    ""
+    "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+    "<domain type=\"kvm\" xmlns:ovirt=\"http://ovirt.org/vm/tune/1.0\">"
+    "  <metadata/>"
+    "</domain>";
+
+static const char minimal_metadata_xml[] =
+    ""
+    "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+    "<domain type=\"kvm\" xmlns:ovirt=\"http://ovirt.org/vm/tune/1.0\">"
+    "  <metadata>"
+    "    <ovirtmap:tag "
+    "xmlns:ovirtmap=\"http://ovirt.org/ovirtmap/tag/1.0\">virt-0</ovirtmap:tag>"
+    "  </metadata>"
+    "</domain>";
+
+struct xml_state {
+  xmlDocPtr xml_doc;
+  xmlXPathContextPtr xpath_ctx;
+  xmlXPathObjectPtr xpath_obj;
+  char tag[PARTITION_TAG_MAX_LEN];
+};
+
+static int init_state(struct xml_state *st, const char *xml) {
+  memset(st, 0, sizeof(*st));
+
+  st->xml_doc = xmlReadDoc((const xmlChar *)xml, NULL, NULL, XML_PARSE_NONET);
+  if (st->xml_doc == NULL) {
+    return -1;
+  }
+  st->xpath_ctx = xmlXPathNewContext(st->xml_doc);
+  if (st->xpath_ctx == NULL) {
+    return -1;
+  }
+  return 0;
+}
+
+static void fini_state(struct xml_state *st) {
+  if (st->xpath_ctx) {
+    xmlXPathFreeContext(st->xpath_ctx);
+    st->xpath_ctx = NULL;
+  }
+  if (st->xml_doc) {
+    xmlFreeDoc(st->xml_doc);
+    st->xml_doc = NULL;
+  }
+}
+
+#define TAG "virt-0"
+
+DEF_TEST(lv_domain_get_tag_no_metadata_xml) {
+  int err;
+  struct xml_state st;
+  err = init_state(&st, minimal_xml);
+  EXPECT_EQ_INT(0, err);
+
+  err = lv_domain_get_tag(st.xpath_ctx, "test", st.tag);
+
+  EXPECT_EQ_INT(0, err);
+  EXPECT_EQ_STR("", st.tag);
+
+  fini_state(&st);
+  return 0;
+}
+
+DEF_TEST(lv_domain_get_tag_valid_xml) {
+  int err;
+  struct xml_state st;
+  err = init_state(&st, minimal_metadata_xml);
+  EXPECT_EQ_INT(0, err);
+
+  err = lv_domain_get_tag(st.xpath_ctx, "test", st.tag);
+
+  EXPECT_EQ_INT(0, err);
+  EXPECT_EQ_STR(TAG, st.tag);
+
+  return 0;
+}
+
+DEF_TEST(lv_default_instance_include_domain_without_tag) {
+  struct lv_read_instance *inst = NULL;
+  int ret;
+
+  ret = lv_init_instance(0, lv_read);
+  inst = &(lv_read_user_data[0].inst);
+  EXPECT_EQ_STR("virt-0", inst->tag);
+
+  ret = lv_instance_include_domain(inst, "testing", "");
+  EXPECT_EQ_INT(1, ret);
+
+  lv_fini_instance(0);
+  return 0;
+}
+
+DEF_TEST(lv_regular_instance_skip_domain_without_tag) {
+  struct lv_read_instance *inst = NULL;
+  int ret;
+
+  ret = lv_init_instance(1, lv_read);
+  inst = &(lv_read_user_data[1].inst);
+  EXPECT_EQ_STR("virt-1", inst->tag);
+
+  ret = lv_instance_include_domain(inst, "testing", "");
+  EXPECT_EQ_INT(0, ret);
+
+  lv_fini_instance(0);
+  return 0;
+}
+
+DEF_TEST(lv_include_domain_matching_tags) {
+  struct lv_read_instance *inst = NULL;
+  int ret;
+
+  ret = lv_init_instance(0, lv_read);
+  inst = &(lv_read_user_data[0].inst);
+  EXPECT_EQ_STR("virt-0", inst->tag);
+
+  ret = lv_instance_include_domain(inst, "testing", "virt-0");
+  EXPECT_EQ_INT(1, ret);
+
+  ret = lv_init_instance(1, lv_read);
+  inst = &(lv_read_user_data[1].inst);
+  EXPECT_EQ_STR("virt-1", inst->tag);
+
+  ret = lv_instance_include_domain(inst, "testing", "virt-1");
+  EXPECT_EQ_INT(1, ret);
+
+  lv_fini_instance(0);
+  lv_fini_instance(1);
+  return 0;
+}
+
+DEF_TEST(lv_default_instance_include_domain_with_unknown_tag) {
+  struct lv_read_instance *inst = NULL;
+  int ret;
+
+  ret = lv_init_instance(0, lv_read);
+  inst = &(lv_read_user_data[0].inst);
+  EXPECT_EQ_STR("virt-0", inst->tag);
+
+  ret = lv_instance_include_domain(inst, "testing", "unknownFormat-tag");
+  EXPECT_EQ_INT(1, ret);
+
+  lv_fini_instance(0);
+  return 0;
+}
+
+DEF_TEST(lv_regular_instance_skip_domain_with_unknown_tag) {
+  struct lv_read_instance *inst = NULL;
+  int ret;
+
+  ret = lv_init_instance(1, lv_read);
+  inst = &(lv_read_user_data[1].inst);
+  EXPECT_EQ_STR("virt-1", inst->tag);
+
+  ret = lv_instance_include_domain(inst, "testing", "unknownFormat-tag");
+  EXPECT_EQ_INT(0, ret);
+
+  lv_fini_instance(0);
+  return 0;
+}
+#undef TAG
+
+int main(void) {
+  RUN_TEST(lv_domain_get_tag_no_metadata_xml);
+  RUN_TEST(lv_domain_get_tag_valid_xml);
+
+  RUN_TEST(lv_default_instance_include_domain_without_tag);
+  RUN_TEST(lv_regular_instance_skip_domain_without_tag);
+  RUN_TEST(lv_include_domain_matching_tags);
+  RUN_TEST(lv_default_instance_include_domain_with_unknown_tag);
+  RUN_TEST(lv_regular_instance_skip_domain_with_unknown_tag);
+
+  END_TEST;
+}
+
+/* vim: set sw=2 sts=2 et : */
index cd9e7d2..0d7769b 100644 (file)
@@ -260,5 +260,3 @@ void module_register(void) {
   plugin_register_config("vmem", vmem_config, config_keys, config_keys_num);
   plugin_register_read("vmem", vmem_read);
 } /* void module_register */
-
-/* vim: set sw=2 sts=2 ts=8 : */
index c5a7fb3..96af6fc 100644 (file)
@@ -321,5 +321,3 @@ void module_register(void) {
   plugin_register_init("vserver", vserver_init);
   plugin_register_read("vserver", vserver_read);
 } /* void module_register(void) */
-
-/* vim: set ts=4 sw=4 noexpandtab : */
index b85ab47..3fac9cc 100644 (file)
@@ -583,5 +583,3 @@ static int wg_config(oconfig_item_t *ci) {
 void module_register(void) {
   plugin_register_complex_config("write_graphite", wg_config);
 }
-
-/* vim: set sw=4 ts=4 sts=4 tw=78 et : */
index c1b3f0b..c33ab54 100644 (file)
@@ -812,5 +812,3 @@ void module_register(void) /* {{{ */
   plugin_register_complex_config("write_http", wh_config);
   plugin_register_init("write_http", wh_init);
 } /* }}} void module_register */
-
-/* vim: set fdm=marker sw=8 ts=8 tw=78 et : */
index 2d34b21..5ecb182 100644 (file)
@@ -136,5 +136,3 @@ void module_register(void) {
   /* If config is supplied, the global wl_format will be set. */
   plugin_register_write("write_log", wl_write, NULL);
 }
-
-/* vim: set sw=4 ts=4 sts=4 tw=78 et : */
index e175e1f..10f7832 100644 (file)
 #include "plugin.h"
 #include "utils_cache.h"
 
-#if HAVE_STDINT_H
 #define MONGO_HAVE_STDINT 1
-#else
-#define MONGO_USE_LONG_LONG_INT 1
-#endif
 #include <mongo.h>
 
 #if (MONGO_MAJOR == 0) && (MONGO_MINOR < 8)
@@ -348,5 +344,3 @@ static int wm_config(oconfig_item_t *ci) /* {{{ */
 void module_register(void) {
   plugin_register_complex_config("write_mongodb", wm_config);
 }
-
-/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */
index 6b77712..61c43fe 100644 (file)
@@ -870,5 +870,3 @@ void module_register() {
                           /* user data = */ NULL);
   plugin_register_shutdown("write_prometheus", prom_shutdown);
 }
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
index 0a5c5df..9cff34a 100644 (file)
@@ -252,5 +252,3 @@ static int wr_config(oconfig_item_t *ci) /* {{{ */
 void module_register(void) {
   plugin_register_complex_config("write_redis", wr_config);
 }
-
-/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */
index 3835a3d..a51b4b5 100644 (file)
@@ -895,5 +895,3 @@ static int wrr_config(oconfig_item_t *ci) /* {{{ */
 void module_register(void) {
   plugin_register_complex_config("write_riemann", wrr_config);
 }
-
-/* vim: set sw=8 sts=8 ts=8 noet : */
index 452c291..8f6b4be 100644 (file)
@@ -34,8 +34,6 @@
 #include "utils_threshold.h"
 #include "write_riemann_threshold.h"
 
-#include <ltdl.h>
-
 /*
  * Threshold management
  * ====================
@@ -225,5 +223,3 @@ int write_riemann_threshold_check(const data_set_t *ds, const value_list_t *vl,
 
   return (0);
 } /* }}} int ut_check_threshold */
-
-/* vim: set sw=2 ts=8 sts=2 tw=78 et fdm=marker : */
index 72ed6bc..c0c0634 100644 (file)
@@ -1248,5 +1248,3 @@ static int sensu_config(oconfig_item_t *ci) /* {{{ */
 void module_register(void) {
   plugin_register_complex_config("write_sensu", sensu_config);
 }
-
-/* vim: set sw=8 sts=8 ts=8 noet : */
index 0c87c47..99c8427 100644 (file)
@@ -45,8 +45,8 @@
 
 #include "common.h"
 #include "plugin.h"
-
 #include "utils_cache.h"
+#include "utils_random.h"
 
 #include <netdb.h>
 
@@ -71,6 +71,8 @@
  * Private variables
  */
 struct wt_callback {
+  struct addrinfo *ai;
+  cdtime_t ai_last_update;
   int sock_fd;
 
   char *node;
@@ -86,8 +88,15 @@ struct wt_callback {
   cdtime_t send_buf_init_time;
 
   pthread_mutex_t send_lock;
+
+  _Bool connect_failed_log_enabled;
+  int connect_dns_failed_attempts_remaining;
+  cdtime_t next_random_ttl;
 };
 
+static cdtime_t resolve_interval = 0;
+static cdtime_t resolve_jitter = 0;
+
 /*
  * Functions
  */
@@ -144,9 +153,16 @@ static int wt_flush_nolock(cdtime_t timeout, struct wt_callback *cb) {
   return status;
 }
 
+static cdtime_t new_random_ttl() {
+  if (resolve_jitter == 0)
+    return 0;
+
+  return (cdtime_t)cdrand_range(0, (long)resolve_jitter);
+}
+
 static int wt_callback_init(struct wt_callback *cb) {
-  struct addrinfo *ai_list;
   int status;
+  cdtime_t now;
 
   const char *node = cb->node ? cb->node : WT_DEFAULT_NODE;
   const char *service = cb->service ? cb->service : WT_DEFAULT_SERVICE;
@@ -154,28 +170,68 @@ static int wt_callback_init(struct wt_callback *cb) {
   if (cb->sock_fd > 0)
     return 0;
 
-  struct addrinfo ai_hints = {.ai_family = AF_UNSPEC,
-                              .ai_flags = AI_ADDRCONFIG,
-                              .ai_socktype = SOCK_STREAM};
+  now = cdtime();
+  if (cb->ai) {
+    /* When we are here, we still have the IP in cache.
+     * If we have remaining attempts without calling the DNS, we update the
+     * last_update date so we keep the info until next time.
+     * If there is no more attempts, we need to flush the cache.
+     */
+
+    if ((cb->ai_last_update + resolve_interval + cb->next_random_ttl) < now) {
+      cb->next_random_ttl = new_random_ttl();
+      if (cb->connect_dns_failed_attempts_remaining > 0) {
+        /* Warning : this is run under send_lock mutex.
+         * This is why we do not use another mutex here.
+         * */
+        cb->ai_last_update = now;
+        cb->connect_dns_failed_attempts_remaining--;
+      } else {
+        freeaddrinfo(cb->ai);
+        cb->ai = NULL;
+      }
+    }
+  }
 
-  status = getaddrinfo(node, service, &ai_hints, &ai_list);
-  if (status != 0) {
-    ERROR("write_tsdb plugin: getaddrinfo (%s, %s) failed: %s", node, service,
-          gai_strerror(status));
-    return -1;
+  if (cb->ai == NULL) {
+    if ((cb->ai_last_update + resolve_interval + cb->next_random_ttl) >= now) {
+      DEBUG("write_tsdb plugin: too many getaddrinfo(%s, %s) failures", node,
+            service);
+      return (-1);
+    }
+    cb->ai_last_update = now;
+    cb->next_random_ttl = new_random_ttl();
+
+    struct addrinfo ai_hints = {
+        .ai_family = AF_UNSPEC,
+        .ai_flags = AI_ADDRCONFIG,
+        .ai_socktype = SOCK_STREAM,
+    };
+
+    status = getaddrinfo(node, service, &ai_hints, &cb->ai);
+    if (status != 0) {
+      if (cb->ai) {
+        freeaddrinfo(cb->ai);
+        cb->ai = NULL;
+      }
+      if (cb->connect_failed_log_enabled) {
+        ERROR("write_tsdb plugin: getaddrinfo(%s, %s) failed: %s", node,
+              service, gai_strerror(status));
+        cb->connect_failed_log_enabled = 0;
+      }
+      return -1;
+    }
   }
 
-  assert(ai_list != NULL);
-  for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL;
-       ai_ptr = ai_ptr->ai_next) {
-    cb->sock_fd =
-        socket(ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol);
+  assert(cb->ai != NULL);
+  for (struct addrinfo *ai = cb->ai; ai != NULL; ai = ai->ai_next) {
+    cb->sock_fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
     if (cb->sock_fd < 0)
       continue;
 
     set_sock_opts(cb->sock_fd);
 
-    status = connect(cb->sock_fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
+    status = connect(cb->sock_fd, ai->ai_addr, ai->ai_addrlen);
     if (status != 0) {
       close(cb->sock_fd);
       cb->sock_fd = -1;
@@ -185,8 +241,6 @@ static int wt_callback_init(struct wt_callback *cb) {
     break;
   }
 
-  freeaddrinfo(ai_list);
-
   if (cb->sock_fd < 0) {
     char errbuf[1024];
     ERROR("write_tsdb plugin: Connecting to %s:%s failed. "
@@ -195,6 +249,12 @@ static int wt_callback_init(struct wt_callback *cb) {
     return -1;
   }
 
+  if (0 == cb->connect_failed_log_enabled) {
+    WARNING("write_tsdb plugin: Connecting to %s:%s succeeded.", node, service);
+    cb->connect_failed_log_enabled = 1;
+  }
+  cb->connect_dns_failed_attempts_remaining = 1;
+
   wt_reset_buffer(cb);
 
   return 0;
@@ -522,10 +582,8 @@ static int wt_config_tsd(oconfig_item_t *ci) {
     return -1;
   }
   cb->sock_fd = -1;
-  cb->node = NULL;
-  cb->service = NULL;
-  cb->host_tags = NULL;
-  cb->store_rates = 0;
+  cb->connect_failed_log_enabled = 1;
+  cb->next_random_ttl = new_random_ttl();
 
   pthread_mutex_init(&cb->send_lock, NULL);
 
@@ -564,11 +622,18 @@ static int wt_config_tsd(oconfig_item_t *ci) {
 }
 
 static int wt_config(oconfig_item_t *ci) {
+  if ((resolve_interval == 0) && (resolve_jitter == 0))
+    resolve_interval = resolve_jitter = plugin_get_interval();
+
   for (int i = 0; i < ci->children_num; i++) {
     oconfig_item_t *child = ci->children + i;
 
     if (strcasecmp("Node", child->key) == 0)
       wt_config_tsd(child);
+    else if (strcasecmp("ResolveInterval", child->key) == 0)
+      cf_util_get_cdtime(child, &resolve_interval);
+    else if (strcasecmp("ResolveJitter", child->key) == 0)
+      cf_util_get_cdtime(child, &resolve_jitter);
     else {
       ERROR("write_tsdb plugin: Invalid configuration "
             "option: %s.",
@@ -582,5 +647,3 @@ static int wt_config(oconfig_item_t *ci) {
 void module_register(void) {
   plugin_register_complex_config("write_tsdb", wt_config);
 }
-
-/* vim: set sw=4 ts=4 sts=4 tw=78 et : */
index 87e3564..b06434d 100644 (file)
@@ -66,7 +66,3 @@ static int cxmms_read(void) {
 void module_register(void) {
   plugin_register_read("xmms", cxmms_read);
 } /* void module_register */
-
-/*
- * vim: shiftwidth=2:softtabstop=2:textwidth=78
- */
index af5130a..aff02b6 100644 (file)
@@ -75,7 +75,6 @@ static long long get_zfs_value(kstat_t *ksp, const char *key) {
 
   e = llist_search(ksp, key);
   if (e == NULL) {
-    ERROR("zfs_arc plugin: `llist_search` failed for key: '%s'.", key);
     return (-1);
   }
 
@@ -152,7 +151,7 @@ static int za_read_derive(kstat_t *ksp, const char *kstat_value,
                           const char *type, const char *type_instance) {
   long long tmp = get_zfs_value(ksp, (char *)kstat_value);
   if (tmp == -1LL) {
-    WARNING("zfs_arc plugin: Reading kstat value \"%s\" failed.", kstat_value);
+    DEBUG("zfs_arc plugin: Reading kstat value \"%s\" failed.", kstat_value);
     return (-1);
   }
 
@@ -165,7 +164,7 @@ static int za_read_gauge(kstat_t *ksp, const char *kstat_value,
                          const char *type, const char *type_instance) {
   long long tmp = get_zfs_value(ksp, (char *)kstat_value);
   if (tmp == -1LL) {
-    WARNING("zfs_arc plugin: Reading kstat value \"%s\" failed.", kstat_value);
+    DEBUG("zfs_arc plugin: Reading kstat value \"%s\" failed.", kstat_value);
     return (-1);
   }
 
@@ -212,6 +211,21 @@ static int za_read(void) {
     return (-1);
   }
 
+  // Ignore the first two lines because they contain information about
+  // the rest of the file.
+  // See kstat_seq_show_headers module/spl/spl-kstat.c of the spl kernel
+  // module.
+  if (fgets(buffer, sizeof(buffer), fh) == NULL) {
+    ERROR("zfs_arc plugin: \"%s\" does not contain a single line.", ZOL_ARCSTATS_FILE);
+    fclose(fh);
+    return (-1);
+  }
+  if (fgets(buffer, sizeof(buffer), fh) == NULL) {
+    ERROR("zfs_arc plugin: \"%s\" does not contain at least two lines.", ZOL_ARCSTATS_FILE);
+    fclose(fh);
+    return (-1);
+  }
+
   while (fgets(buffer, sizeof(buffer), fh) != NULL) {
     char *fields[3];
     value_t v;