*.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.*
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
test_*
# src/daemon/...
-src/daemon/collectd
+/collectd
+2016-12-12, Version 5.7.0
+ * Documentation: The Turbostat plugin section has been improved. Thanks
+ to Florian Forster
+ * Documentation: The semantics of the "TypesDB" option have been
+ improved. Thanks to Florian Forster.
+ * collectd: A generic interface for parsing the text protocol has been
+ added. Thanks to Sebastian Harl. #1749
+ * collectd: Threads now get named, making them easier to track using
+ tools such as top, ps, etc. Thanks to Manuel Luis SanmartĂn Rozada
+ and Marc Fournier. #547
+ * AMQP plugin, Write Graphite plugin, Write Kafka plugin: The new
+ "[Graphite]PreserveSeparator" option allows retaining the default dot
+ separator rather than escaping it. Thanks to Florian Forster. #419
+ * Battery plugin: A StateFS backend for gathering statistics has been
+ added. Thanks to Rinigus. #1795
+ * CPU plugin: CPU aggregation on AIX was fixed. Thanks to Chao Yang.
+ #1957
+ * Collectd::Unixsock: Fractional seconds support has been made more
+ robust. Thanks to Matthias Bethke. #2052
+ * DPDKStat plugin: This new plugin collects DPDK interface statistics.
+ Thanks to Maryam Tahhan, Harry van Haaren, Taras Chornyi and Kim
+ Jones. #1649
+ * gRPC plugin: The "DispatchValues" option has been renamed to
+ "PutValues". Thanks to Florian Forster.
+ * HDDTemp plugin: The 32 devices limit has been removed. Thanks to
+ Benjamin Gilbert. #631
+ * Hugepages plugin: This new plugin reports the number of used and free
+ hugepages on Linux. Thanks to Jaroslav Safka, Maryam Tahhan, Kim Jones
+ and Florian Forster. #1799
+ * Intel RDT plugin: This new plugin collects statistics exposed by
+ Intel's Resource Director Technology . Thanks to SerhiyX. #1970
+ * memcached plugin: The new "Address" option allows connecting to a
+ different server than specified by the "Host" option. Thanks to Pavel
+ Rochnyack. #1975
+ * nginx plugin: Support for reporting failed connections has been added.
+ Thanks to Pavel Rochnyack. #1609
+ * Perl plugin: Significant internal reworking has been made. The new
+ "RegisterLegacyFlush" option has been added. Thanks to Pavel
+ Rochnyack. #1731
+ * PostgreSQL plugin: Timestamps are now RFC 3339-formatted local time.
+ Thanks to Igor Peshansky and Dave Cunningham. #1918
+ * Processes plugin: Internal performance improvements have been made.
+ Thanks to Pavel Rochnyack. #1980, #1981
+ * RRDCacheD plugin: The plugin now tries to reconnect upon failed
+ operations. Thanks to Sebastian Harl. #1959
+ * SpamAssassin: The plugin can now run in Perl's "tainted mode" ("-T").
+ Thanks to Akos Vandra. #1962
+ * Tail plugin: Support for calculating latency distribution of matching
+ values has been added. Thanks to Pavel Rochnyack and Florian Forster.
+ #1700
+ * Tail plugin: The new "GaugePersist" option has been added. Thanks to
+ Florian Forster. #2015
+ * Target:Set, Target:Replace, Match:RegEx: MetaData support has been
+ added . Thanks to Igor Peshansky. #1922, #1923, #1930
+ * turbostat plugin: The new "LogicalCoreNames" option allows switching
+ to per-core naming rather than per-CPU. Thanks to Brock Johnson. #2056
+ * virt plugin: The new "BlockDeviceFormat" and
+ "BlockDeviceFormatBasename" options help controlling the names
+ reported for block-device metrics. Thanks to Deyan Chepishev. #2004
+ * Write Graphite plugin: A new "DropDuplicateFields" option has been
+ added. Thanks to Michael Leinartas. #1915
+ * Write Kafka plugin: The "Key Random" setting has been reintroduced.
+ Thanks to Florian Forster. #1977
+ * Write Log plugin: Support for formatting output in JSON has been
+ added, using the new "Format" configuration option. Thanks to Igor
+ Peshansky. #1924
+ * Write Prometheus plugin: This new plugin publishes values using an
+ embedded HTTP server, in a format compatible with Prometheus'
+ collectd_exporter. Thanks to Florian Forster. #1967
+
2016-11-30, Version 5.6.2
* collectd: A compile error on AIX has been fixed: "MSG_DONTWAIT" is not
available on AIX. Thanks to Chao Yang.
ACLOCAL_AMFLAGS = -I m4
+AM_YFLAGS = -d
-SUBDIRS = proto src bindings .
-EXTRA_DIST = contrib version-gen.sh testwrapper.sh
+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
+
+
+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
+
+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)
+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_DPDKSTAT
+pkglib_LTLIBRARIES += dpdkstat.la
+dpdkstat_la_SOURCES = src/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 = 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_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_FSCACHE
+pkglib_LTLIBRARIES += fscache.la
+fscache_la_SOURCES = src/fscache.c
+fscache_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 = $(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_LIBS = 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;
+
+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
-maintainer-clean-local:
- -rm -f INSTALL
- -rm -f aclocal.m4
+jar_DATA = collectd-api.jar generic-jmx.jar
+endif
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).
- 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
- write_mongodb
Sends data to MongoDB, a NoSQL database.
+ - write_prometheus
+ Publish values using an embedded HTTP server, in a format compatible
+ with Prometheus' collectd_exporter.
+
- write_redis
Sends the values to a Redis key-value database server.
Used by the `memcachec' plugin to connect to a memcache daemon.
<http://tangent.org/552/libmemcached.html>
+ * libmicrohttpd (optional)
+ Used by the write_prometheus plugin to run an http daemon.
+ <http://www.gnu.org/software/libmicrohttpd/>
+
* libmnl (optional)
Used by the `netlink' plugin.
<http://www.netfilter.org/projects/libmnl/>
<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)
+++ /dev/null
-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
-
+++ /dev/null
-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"
# For cpu modules
AC_CHECK_HEADERS([sys/dkstat.h])
-if test "x$ac_system" = "xDarwin"
-then
+if test "x$ac_system" = "xDarwin"; then
AC_CHECK_HEADERS(
[[ \
mach/mach_init.h \
]]
)
-if test "x$ac_system" = "xLinux"
-then
+if test "x$ac_system" = "xLinux"; then
# For hddtemp module
AC_CHECK_HEADERS([linux/major.h])
[have_clock_gettime="no"]
)
-if test "x$have_clock_gettime" = "xno"
-then
+if test "x$have_clock_gettime" = "xno"; then
AC_CHECK_LIB([rt], [clock_gettime],
[
clock_gettime_needs_rt="yes"
)
fi
-if test "x$have_clock_gettime" = "xno"
-then
+if test "x$have_clock_gettime" = "xno"; then
AC_CHECK_LIB([posix4], [clock_gettime],
[
clock_gettime_needs_posix4="yes"
)
fi
-if test "x$have_clock_gettime" = "xyes"
-then
+if test "x$have_clock_gettime" = "xyes"; then
AC_DEFINE([HAVE_CLOCK_GETTIME], [1], [Define if the clock_gettime(2) function is available.])
fi
AC_CHECK_FUNCS([thread_info], [have_thread_info="yes"], [have_thread_info="no"])
# Check for strptime {{{
-if test "x$GCC" = "xyes"
-then
+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
+if test "x$have_strptime" = "xyes"; then
AC_CACHE_CHECK([whether strptime is exported by default],
[c_cv_have_strptime_default],
[
)
fi
-if test "x$have_strptime" = "xyes" && test "x$c_cv_have_strptime_default" = "xno"
-then
+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],
[
fi
fi
-if test "x$GCC" = "xyes"
-then
+if test "x$GCC" = "xyes"; then
CFLAGS="$SAVE_CFLAGS"
fi
# }}} Check for strptime
AC_MSG_CHECKING([for sysctl kern.cp_times])
-if test -x /sbin/sysctl
-then
+if test -x /sbin/sysctl; then
/sbin/sysctl kern.cp_times >/dev/null 2>&1
if test $? -eq 0; then
AC_MSG_RESULT([yes])
fi
AC_MSG_CHECKING([for sysctl kern.cp_time])
-if test -x /sbin/sysctl
-then
+if test -x /sbin/sysctl; then
/sbin/sysctl kern.cp_time >/dev/null 2>&1
if test $? -eq 0
then
)
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>
- #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"]
- )
- ]
-)
+ 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>
+ #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"]
+ )
+ ]
+ )
fi
if test "x$c_cv_fp_layout_need_nothing" = "xyes"; then
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"
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],
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
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"
fi
with_libmodbus_libs="`$PKG_CONFIG --libs 'libmodbus'`"
- if test $? -ne 0
- then
+ if test $? -ne 0; then
with_libmodbus="no ($PKG_CONFIG failed)"
fi
fi
[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"
[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
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"
plugin_irq="yes"
plugin_load="yes"
plugin_lvm="yes"
+ plugin_mcelog="yes"
plugin_memory="yes"
plugin_nfs="yes"
plugin_numa="yes"
plugin_swap="yes"
fi
fi
+
if test "x$have_sysctlbyname" = "xyes"; then
plugin_contextswitch="yes"
plugin_cpu="yes"
plugin_log_logstash="yes"
fi
+if test "x$with_libyajl" = "xyes" && test "x$with_libyajl2" = "xyes"; then
+ plugin_ovs_events="yes"
+fi
+
if test "x$with_libperl" = "xyes" && test "x$c_cv_have_perl_ithreads" = "xyes"; then
plugin_perl="yes"
fi
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])
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.
AC_CONFIG_FILES([ \
Makefile \
- bindings/Makefile \
- bindings/java/Makefile \
- proto/Makefile \
- src/Makefile \
src/collectd.conf \
- src/daemon/Makefile \
- src/libcollectdclient/Makefile \
src/libcollectdclient/libcollectdclient.pc \
- src/liboconfig/Makefile \
])
AC_OUTPUT
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])
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])
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])
%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}
Summary: Statistics collection and monitoring daemon
Name: collectd
Version: 5.7.0
-Release: 2%{?dist}
+Release: 3%{?dist}
URL: https://collectd.org
Source: https://collectd.org/files/%{name}-%{version}.tar.bz2
License: GPLv2
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
%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
%{?_with_lvm} \
%{?_with_madwifi} \
%{?_with_mbmon} \
+ %{?_with_mcelog} \
%{?_with_md} \
%{?_with_memcachec} \
%{?_with_memcached} \
%if %{with_mbmon}
%{_libdir}/%{name}/mbmon.so
%endif
+%if %{with_mcelog}
+%{_libdir}/%{name}/mcelog.so
+%endif
%if %{with_md}
%{_libdir}/%{name}/md.so
%endif
%doc contrib/
%changelog
+* 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
--- /dev/null
+!.gitignore
+++ /dev/null
-EXTRA_DIST = collectd.proto types.proto prometheus.proto
+++ /dev/null
-SUBDIRS = libcollectdclient liboconfig 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)
-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_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 = dns.c utils_dns.c 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_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) 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_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 = 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_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 = 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)\"
-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 = $(BUILD_WITH_LIBPQ_LIBS)
-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_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 = 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_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 = 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) 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_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)
-
-# 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 = 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 = daemon/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 = 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
ssnprintf(filename, sizeof(filename), "%s/%s/%s", dir, power_supply,
basename);
- status = (int)read_file_contents(filename, buffer, buffer_size);
+ status = (int)read_file_contents(filename, buffer, buffer_size - 1);
if (status < 0)
return status;
+ buffer[status] = '\0';
+
strstripnewline(buffer);
return 0;
} /* }}} int sysfs_file_to_buffer */
char const *power_supply, char const *basename,
gauge_t *ret_value) {
int status;
- char buffer[32] = "";
+ char buffer[32];
status =
sysfs_file_to_buffer(dir, power_supply, basename, buffer, sizeof(buffer));
#@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
# Port "411"
#</Plugin>
+#<Plugin mcelog>
+# McelogClientSocket "/var/run/mcelog-client"
+# McelogLogfile "/var/log/mcelog"
+#</Plugin>
+
#<Plugin md>
# Device "/dev/md0"
# IgnoreSelected false
# </Database>
#</Plugin>
+#<Plugin ovs_events>
+# Port "6640"
+# Address "127.0.0.1"
+# Socket "/var/run/openvswitch/db.sock"
+# Interfaces "br0" "veth0"
+# SendNotification false
+#</Plugin>
+
#<Plugin perl>
# IncludeDir "/my/include/path"
# BaseName "Collectd::Plugins"
=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).
=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
+ </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.
+
+=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
Synopsis:
<Plugin write_tsdb>
+ ResolveInterval 60
+ ResolveJitter 60
<Node "example">
Host "tsd-1.my.domain"
Port "4242"
</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
+++ /dev/null
-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_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_complain.c utils_complain.h \
- utils_ignorelist.c utils_ignorelist.h \
- 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_CFLAGS = $(AM_CFLAGS)
-collectd_LDFLAGS = -export-dynamic
-collectd_LDADD = libavltree.la libcommon.la libheap.la -lm $(COMMON_LIBS) $(DLOPEN_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
-
-collectd_LDADD += $(top_builddir)/src/liboconfig/liboconfig.la
-collectd_DEPENDENCIES += $(top_builddir)/src/liboconfig/liboconfig.la
-
-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
ptr = (const char *)buf;
nleft = count;
- if (fd < 0)
- return (-1);
+ if (fd < 0) {
+ errno = EINVAL;
+ return errno;
+ }
/* checking for closed peer connection */
pfd.fd = fd;
if (poll(&pfd, 1, 0) > 0) {
char buffer[32];
if (recv(fd, buffer, sizeof(buffer), MSG_PEEK | MSG_DONTWAIT) == 0) {
- // if recv returns zero (even though poll() said there is data to be
- // read),
- // that means the connection has been closed
- return -1;
+ /* if recv returns zero (even though poll() said there is data to be
+ * read), that means the connection has been closed */
+ return errno ? errno : -1;
}
}
continue;
if (status < 0)
- return (status);
+ return errno ? errno : status;
nleft = nleft - ((size_t)status);
ptr = ptr + ((size_t)status);
if ((ci == NULL) || (ret_bool == NULL))
return (EINVAL);
- if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) {
+ if ((ci->values_num != 1) || ((ci->values[0].type != OCONFIG_TYPE_BOOLEAN) &&
+ (ci->values[0].type != OCONFIG_TYPE_STRING))) {
ERROR("cf_util_get_boolean: The %s option requires "
"exactly one boolean argument.",
ci->key);
return (-1);
}
- *ret_bool = ci->values[0].value.boolean ? 1 : 0;
+ switch (ci->values[0].type) {
+ case OCONFIG_TYPE_BOOLEAN:
+ *ret_bool = ci->values[0].value.boolean ? 1 : 0;
+ break;
+ case OCONFIG_TYPE_STRING:
+ WARNING("cf_util_get_boolean: Using string value `%s' for boolean option "
+ "`%s' is deprecated and will be removed in future releases. "
+ "Use unquoted true or false instead.",
+ ci->values[0].value.string, ci->key);
+
+ if (IS_TRUE(ci->values[0].value.string))
+ *ret_bool = 1;
+ else if (IS_FALSE(ci->values[0].value.string))
+ *ret_bool = 0;
+ else {
+ ERROR("cf_util_get_boolean: Cannot parse string value `%s' of the `%s' "
+ "option as a boolean value.",
+ ci->values[0].value.string, ci->key);
+ return (-1);
+ }
+ break;
+ }
return (0);
} /* }}} int cf_util_get_boolean */
have_seed = 1;
}
-double cdrand_d() {
+double cdrand_d(void) {
double r;
pthread_mutex_lock(&lock);
return (r);
}
-uint32_t cdrand_u() {
+uint32_t cdrand_u(void) {
long r;
pthread_mutex_lock(&lock);
*
* 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
*
* 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.
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 %lu ms "
- "is set",
+ 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;
if (err) {
ERROR("dpdkstat semaphore init failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- goto fail_close;
+ 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_close;
+ goto fail;
}
g_configuration->xstats = NULL;
if (pid > 0) {
close(g_configuration->helper_pipes[1]);
g_configuration->helper_pid = pid;
- DEBUG("dpdkstat: helper pid %lu", (long)g_configuration->helper_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) {
} /* static void *collect (void *) */
static void *open_connection(void __attribute__((unused)) * arg) {
- struct sockaddr_un addr;
-
const char *path = (NULL == sock_file) ? SOCK_PATH : sock_file;
const char *group = (NULL == sock_group) ? COLLECTD_GRP_NAME : sock_group;
pthread_exit((void *)1);
}
- addr.sun_family = AF_UNIX;
+ struct sockaddr_un addr = {
+ .sun_family = AF_UNIX
+ };
sstrncpy(addr.sun_path, path, (size_t)(UNIX_PATH_MAX - 1));
errno = 0;
+++ /dev/null
-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
+++ /dev/null
-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
--- /dev/null
+/*-
+ * 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", .tid = 0,
+};
+
+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 = 0;
+
+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("%s: Invalid configuration option: \"%s\".", MCELOG_PLUGIN,
+ 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("%s: Invalid configuration option: \"%s\".", MCELOG_PLUGIN,
+ child->key);
+ return -1;
+ }
+ } else {
+ ERROR("%s: Invalid configuration option: \"%s\".", MCELOG_PLUGIN,
+ 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) {
+ if (shutdown(self->sock_fd, SHUT_RDWR) != 0) {
+ char errbuf[MCELOG_BUFF_SIZE];
+ ERROR("%s: Socket shutdown failed: %s", MCELOG_PLUGIN,
+ sstrerror(errno, errbuf, sizeof(errbuf)));
+ ret = -1;
+ }
+ close(self->sock_fd);
+ }
+ 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 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("%s: Could not create a socket. %s", MCELOG_PLUGIN,
+ 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("%s: Failed to set the socket timeout option.", MCELOG_PLUGIN);
+
+ /* 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("%s: Failed to connect to mcelog server. %s", MCELOG_PLUGIN,
+ sstrerror(errno, errbuff, sizeof(errbuff)));
+ self->close(self);
+ ret = -1;
+ } else
+ ret = 0;
+
+ pthread_rwlock_unlock(&self->lock);
+ return ret;
+}
+
+static void mcelog_dispatch_notification(notification_t n) {
+ sstrncpy(n.host, hostname_g, sizeof(n.host));
+ sstrncpy(n.type, "gauge", sizeof(n.type));
+ plugin_dispatch_notification(&n);
+}
+
+static int mcelog_prepare_notification(notification_t *n,
+ mcelog_memory_rec_t mr) {
+ if (n == NULL)
+ return (-1);
+
+ if (plugin_notification_meta_add_string(n, MCELOG_SOCKET_STR, mr.location) <
+ 0) {
+ ERROR("%s: add memory location meta data failed", MCELOG_PLUGIN);
+ return (-1);
+ }
+ if (strlen(mr.dimm_name) > 0)
+ if (plugin_notification_meta_add_string(n, MCELOG_DIMM_NAME, mr.dimm_name) <
+ 0) {
+ ERROR("%s: add DIMM name meta data failed", MCELOG_PLUGIN);
+ return (-1);
+ }
+ if (plugin_notification_meta_add_signed_int(n, MCELOG_CORRECTED_ERR,
+ mr.corrected_err_total) < 0) {
+ ERROR("%s: add corrected errors meta data failed", MCELOG_PLUGIN);
+ return (-1);
+ }
+ if (plugin_notification_meta_add_signed_int(
+ n, "corrected memory timed errors", mr.corrected_err_timed) < 0) {
+ ERROR("%s: add corrected timed errors meta data failed", MCELOG_PLUGIN);
+ return (-1);
+ }
+ if (plugin_notification_meta_add_string(n, "corrected errors time period",
+ mr.corrected_err_timed_period) < 0) {
+ ERROR("%s: add corrected errors period meta data failed", MCELOG_PLUGIN);
+ return (-1);
+ }
+ if (plugin_notification_meta_add_signed_int(n, MCELOG_UNCORRECTED_ERR,
+ mr.uncorrected_err_total) < 0) {
+ ERROR("%s: add corrected errors meta data failed", MCELOG_PLUGIN);
+ return (-1);
+ }
+ if (plugin_notification_meta_add_signed_int(
+ n, "uncorrected memory timed errors", mr.uncorrected_err_timed) < 0) {
+ ERROR("%s: add corrected timed errors meta data failed", MCELOG_PLUGIN);
+ return (-1);
+ }
+ if (plugin_notification_meta_add_string(n, "uncorrected errors time period",
+ mr.uncorrected_err_timed_period) <
+ 0) {
+ ERROR("%s: add corrected errors period meta data failed", MCELOG_PLUGIN);
+ return (-1);
+ }
+
+ return (0);
+}
+
+static int mcelog_submit(mcelog_memory_rec_t mr) {
+
+ value_list_t vl = VALUE_LIST_INIT;
+ vl.values_len = 1;
+ vl.time = cdtime();
+
+ sstrncpy(vl.plugin, MCELOG_PLUGIN, sizeof(vl.plugin));
+ sstrncpy(vl.type, "errors", sizeof(vl.type));
+ if (strlen(mr.dimm_name) > 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));
+
+ sstrncpy(vl.type_instance, "corrected_memory_errors",
+ sizeof(vl.type_instance));
+ vl.values = &(value_t){.derive = (derive_t)mr.corrected_err_total};
+ 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("%s: Got SOCKET INFO %s", MCELOG_PLUGIN, 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("%s: Got DIMM NAME %s", MCELOG_PLUGIN,
+ 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("%s: Got corrected error total %d", MCELOG_PLUGIN,
+ 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("%s: Got timed corrected errors %d in %s", MCELOG_PLUGIN,
+ 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("%s: Got uncorrected error total %d", MCELOG_PLUGIN,
+ 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("%s: Got timed uncorrected errors %d in %s", MCELOG_PLUGIN,
+ 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("%s: Connection to socket is broken", MCELOG_PLUGIN);
+ if (poll_fd.revents & (POLLERR | POLLHUP)) {
+ notification_t n = {
+ NOTIF_FAILURE, cdtime(), "", "", MCELOG_PLUGIN, "", "", "", NULL};
+ ssnprintf(n.message, sizeof(n.message),
+ "Connection to mcelog socket is broken.");
+ sstrncpy(n.type_instance, "mcelog_status", sizeof(n.type_instance));
+ mcelog_dispatch_notification(n);
+ }
+ pthread_rwlock_unlock(&self->lock);
+ return -1;
+ }
+
+ if (!(poll_fd.revents & (POLLIN | POLLPRI))) {
+ INFO("%s: No data to read", MCELOG_PLUGIN);
+ 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) {
+ int res = 0;
+ /* blocking call */
+ res = socket_adapter.receive(&socket_adapter, pp_file);
+ if (res < 0) {
+ socket_adapter.close(&socket_adapter);
+ if (socket_adapter.reinit(&socket_adapter) != 0) {
+ socket_adapter.close(&socket_adapter);
+ usleep(MCELOG_POLL_TIMEOUT);
+ }
+ 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)) {
+ notification_t n = {NOTIF_OKAY, cdtime(), "", "", MCELOG_PLUGIN,
+ "", "", "", NULL};
+ ssnprintf(n.message, sizeof(n.message), "Got memory errors info.");
+ sstrncpy(n.type_instance, "memory_erros", sizeof(n.type_instance));
+ if (mcelog_prepare_notification(&n, memory_record) == 0)
+ mcelog_dispatch_notification(n);
+ if (mcelog_submit(memory_record) != 0)
+ ERROR("%s: Failed to submit memory errors", MCELOG_PLUGIN);
+ 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("%s: Cannot connect to client socket", MCELOG_PLUGIN);
+ return -1;
+ }
+
+ if (plugin_thread_create(&g_mcelog_config.tid, NULL, poll_worker, NULL,
+ NULL) != 0) {
+ ERROR("%s: Error creating poll thread.", MCELOG_PLUGIN);
+ 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("%s: SENT DUMP REQUEST FAILED", MCELOG_PLUGIN);
+ else
+ DEBUG("%s: SENT DUMP REQUEST OK", MCELOG_PLUGIN);
+ return ret;
+}
+
+static int mcelog_read(__attribute__((unused)) user_data_t *ud) {
+ DEBUG("%s: %s", MCELOG_PLUGIN, __FUNCTION__);
+
+ if (get_memory_machine_checks() != 0)
+ ERROR("%s: MACHINE CHECK INFO NOT AVAILABLE", MCELOG_PLUGIN);
+
+ 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("%s: Stopping thread failed.", MCELOG_PLUGIN);
+ 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);
+}
const char *type, const char *type_inst, double d,
cdtime_t timestamp, cdtime_t interval) {
return (submit_values(host, plugin_inst, type, type_inst,
- &(value_t){.gauge = counter}, 1, timestamp, interval));
+ &(value_t){.gauge = d}, 1, timestamp, interval));
} /* }}} int submit_uint64 */
/* Calculate hit ratio from old and new counters and submit the resulting
static int cna_handle_snapvault_data(const char *hostname, /* {{{ */
cfg_snapvault_t *cfg_snapvault,
na_elem_t *data, cdtime_t interval) {
- na_elem_iter_t status_iter;
-
- status = na_elem_child(data, "status-list");
- if (!status) {
+ na_elem_t *status_list = na_elem_child(data, "status-list");
+ if (status_list == NULL) {
ERROR("netapp plugin: SnapVault status record missing status-list");
return (0);
}
- status_iter = na_child_iterator(status);
+ na_elem_iter_t status_iter = na_child_iterator(status_list);
for (na_elem_t *status = na_iterator_next(&status_iter); status != NULL;
status = na_iterator_next(&status_iter)) {
const char *dest_sys, *dest_path, *src_sys, *src_path;
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;
#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;
#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;
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;
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;
--- /dev/null
+/**
+ * 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 */
+};
+
+/* 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) {
+ 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 {
+ ERROR(OVS_EVENTS_PLUGIN ": option '%s' is not allowed here", child->key);
+ ovs_events_config_free();
+ return (-1);
+ }
+ }
+ 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 (int 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 (int 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 (int 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_complex_read(NULL, OVS_EVENTS_PLUGIN, ovs_events_plugin_read,
+ 0, NULL);
+ plugin_register_shutdown(OVS_EVENTS_PLUGIN, ovs_events_plugin_shutdown);
+}
REPLACE_FIELD("%{type_instance}", vl->type_instance);
if (vl->meta != NULL) {
- char **meta_toc;
+ char **meta_toc = NULL;
int meta_entries = meta_data_toc(vl->meta, &meta_toc);
+ if (meta_entries <= 0)
+ return;
+
for (int i = 0; i < meta_entries; i++) {
char meta_name[DATA_MAX_NAME_LEN];
char *value_str;
ERROR("Target `set': Unable to get replacement metadata value `%s'.",
key);
strarray_free(meta_toc, (size_t)meta_entries);
+ meta_data_destroy(new_meta);
return (status);
}
if (status) {
ERROR("Target `set': Unable to set metadata value `%s'.", key);
strarray_free(meta_toc, (size_t)meta_entries);
+ meta_data_destroy(new_meta);
return (status);
}
}
print_to_socket(fh, "%zu Threshold found\n", i);
if (threshold.host[0] != 0)
- print_to_socket(fh, "Host: %s\n", threshold.host) if (
- threshold.plugin[0] !=
- 0) print_to_socket(fh, "Plugin: %s\n",
- threshold.plugin) if (threshold.plugin_instance[0] !=
- 0)
- print_to_socket(fh, "Plugin Instance: %s\n",
- threshold.plugin_instance) if (threshold.type[0] != 0)
- print_to_socket(fh, "Type: %s\n", threshold.type) if (
- threshold.type_instance[0] !=
- 0) print_to_socket(fh, "Type Instance: %s\n",
- threshold
- .type_instance) if (threshold.data_source
- [0] != 0)
- print_to_socket(
- fh, "Data Source: %s\n",
- threshold.data_source) if (!isnan(threshold.warning_min))
- print_to_socket(
- fh, "Warning Min: %g\n",
- threshold
- .warning_min) if (!isnan(threshold.warning_max))
- print_to_socket(
- fh, "Warning Max: %g\n",
- threshold
- .warning_max) if (!isnan(threshold.failure_min))
- print_to_socket(
- fh, "Failure Min: %g\n",
- threshold
- .failure_min) if (!isnan(threshold
- .failure_max))
- print_to_socket(
- fh, "Failure Max: %g\n",
- threshold.failure_max) if (threshold
- .hysteresis >
- 0.0)
- print_to_socket(
- fh, "Hysteresis: %g\n",
- threshold.hysteresis) if (threshold
- .hits > 1)
- print_to_socket(fh, "Hits: %i\n",
- threshold.hits)
-
- return (0);
+ print_to_socket(fh, "Host: %s\n", threshold.host);
+ if (threshold.plugin[0] != 0)
+ print_to_socket(fh, "Plugin: %s\n", threshold.plugin);
+ if (threshold.plugin_instance[0] != 0)
+ print_to_socket(fh, "Plugin Instance: %s\n", threshold.plugin_instance);
+ if (threshold.type[0] != 0)
+ print_to_socket(fh, "Type: %s\n", threshold.type);
+ if (threshold.type_instance[0] != 0)
+ print_to_socket(fh, "Type Instance: %s\n", threshold.type_instance);
+ if (threshold.data_source[0] != 0)
+ print_to_socket(fh, "Data Source: %s\n", threshold.data_source);
+ if (!isnan(threshold.warning_min))
+ print_to_socket(fh, "Warning Min: %g\n", threshold.warning_min);
+ if (!isnan(threshold.warning_max))
+ print_to_socket(fh, "Warning Max: %g\n", threshold.warning_max);
+ if (!isnan(threshold.failure_min))
+ print_to_socket(fh, "Failure Min: %g\n", threshold.failure_min);
+ if (!isnan(threshold.failure_max))
+ print_to_socket(fh, "Failure Max: %g\n", threshold.failure_max);
+ if (threshold.hysteresis > 0.0)
+ print_to_socket(fh, "Hysteresis: %g\n", threshold.hysteresis);
+ if (threshold.hits > 1)
+ print_to_socket(fh, "Hits: %i\n", threshold.hits);
+
+ return (0);
} /* int handle_getthreshold */
--- /dev/null
+/**
+ * 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;
+
+ 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 (int 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 (int 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;
+ yajl_val jtable_update;
+ size_t obj_len = 0;
+ const char *table_name = NULL;
+ 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 (int 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 (int 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 unix_prefix[] = "unix:";
+ const char *node_info = pdb->node;
+ struct addrinfo *result;
+ struct sockaddr_un saunix;
+
+ 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 = -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 < 0)
+ /* 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 = -1;
+ return (0);
+}
+
+/* Initialize POLL thread */
+static int ovs_db_poll_thread_init(ovs_db_t *pdb) {
+ pdb->poll_thread.tid = -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 < 0)
+ /* 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 = -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 **)¶ms,
+ ¶ms_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 (int 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 (int 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;
+}
--- /dev/null
+/**
+ * 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
return -1;
}
+static int lv_connect(void) {
+ if (conn == NULL) {
+ /* `conn_string == NULL' is acceptable. */
+ conn = virConnectOpenReadOnly(conn_string);
+ if (conn == NULL) {
+ c_complain(LOG_ERR, &conn_complain,
+ PLUGIN_NAME " plugin: Unable to connect: "
+ "virConnectOpenReadOnly failed.");
+ return -1;
+ }
+ }
+ 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_read(user_data_t *ud) {
time_t t;
struct lv_read_instance *inst = NULL;
inst = ud->data;
state = &inst->read_state;
- if (inst->id == 0 && conn == NULL) {
- /* `conn_string == NULL' is acceptable. */
- conn = virConnectOpenReadOnly(conn_string);
- if (conn == NULL) {
- c_complain(LOG_ERR, &conn_complain,
- PLUGIN_NAME " plugin: Unable to connect: "
- "virConnectOpenReadOnly failed.");
+ if (inst->id == 0) {
+ if (lv_connect() < 0)
return -1;
- }
}
- c_release(LOG_NOTICE, &conn_complain,
- PLUGIN_NAME " plugin: Connection established.");
time(&t);
if ((last_refresh == (time_t)0) ||
((interval > 0) && ((last_refresh + interval) <= t))) {
if (refresh_lists(inst) != 0) {
- if (conn != NULL)
- virConnectClose(conn);
- conn = NULL;
+ if (inst->id == 0)
+ lv_disconnect();
return -1;
}
last_refresh = t;
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)
}
/* 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)
lv_fini_instance(i);
}
- if (conn != NULL)
- virConnectClose(conn);
- conn = NULL;
+ lv_disconnect();
ignorelist_free(il_domains);
il_domains = NULL;
return fam;
}
- if (!allocate)
+ if (!allocate) {
+ sfree(name);
return NULL;
+ }
fam = metric_family_create(name, ds, vl, ds_index);
if (fam == NULL) {
#include "common.h"
#include "plugin.h"
-
#include "utils_cache.h"
+#include "utils_random.h"
#include <netdb.h>
* Private variables
*/
struct wt_callback {
+ struct addrinfo *ai;
+ cdtime_t ai_last_update;
int sock_fd;
char *node;
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
*/
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;
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;
break;
}
- freeaddrinfo(ai_list);
-
if (cb->sock_fd < 0) {
char errbuf[1024];
ERROR("write_tsdb plugin: Connecting to %s:%s failed. "
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;
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);
}
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.",
#!/bin/sh
-DEFAULT_VERSION="5.6.2.git"
+DEFAULT_VERSION="5.7.0.git"
if [ -d .git ]; then
VERSION="`git describe --dirty=+ --abbrev=7 2> /dev/null | grep collectd | sed -e 's/^collectd-//' -e 's/-/./g'`"