From: Ruben Kerkhof Date: Fri, 14 Apr 2017 12:34:20 +0000 (+0200) Subject: Merge branch 'collectd-5.7' X-Git-Tag: collectd-5.8.0~195 X-Git-Url: https://git.octo.it/?p=collectd.git;a=commitdiff_plain;h=2b4445ea9b4b978468d75864f98e8137ba628dec;hp=42b8d7550d029ed9aef6f25e3eb2009c1f18b144 Merge branch 'collectd-5.7' --- diff --git a/.gitignore b/.gitignore index 8154d733..2911069a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ Makefile.in /aclocal.m4 /autom4te.cache /autom4te.cache +/build-aux/ /compile /config.guess /config.sub @@ -12,8 +13,15 @@ Makefile.in /install-sh /libltdl/ /ltmain.sh +/m4/libtool.m4 +/m4/ltargz.m4 +/m4/ltdl.m4 +/m4/lt~obsolete.m4 +/m4/ltoptions.m4 +/m4/ltsugar.m4 +/m4/ltversion.m4 /missing -src/config.h.in +/src/config.h.in # configure stuff: Makefile @@ -29,12 +37,13 @@ src/stamp-h1 *.la *.lo *.o +.dirstamp .libs/ .deps/ -src/collectd-nagios -src/collectd-tg -src/collectdctl -src/collectdmon +/collectd-nagios +/collectd-tg +/collectdctl +/collectdmon src/*.1 src/*.5 src/.pod2man.tmp.* @@ -51,26 +60,28 @@ src/liboconfig/parser.h src/liboconfig/scanner.c # protobuf stuff: -src/*.pb-c.[ch] -src/*.grpc.pb.cc -src/*.pb.cc -src/*.pb.h +*.pb-c.[ch] +*.grpc.pb.cc +*.pb.cc +*.pb.h # make dist stuff: /collectd-*.tar.gz /collectd-*.tar.bz2 # perl stuff: -bindings/.perl-directory-stamp +/.perl-directory-stamp bindings/perl/Collectd/pm_to_blib bindings/perl/blib/ bindings/perl/pm_to_blib -bindings/buildperl +/buildperl # java stuff -bindings/java/java-build-stamp -bindings/java/org/collectd/api/*.class -bindings/java/org/collectd/java/*.class +*.jar +/org/collectd/api/*.class +/org/collectd/java/*.class +/bindings/java/java-build-stamp +/classnoinst.stamp # python stuff *.pyc @@ -94,4 +105,4 @@ src/test-suite.log test_* # src/daemon/... -src/daemon/collectd +/collectd diff --git a/.travis.yml b/.travis.yml index 03d9dded..fc250cbb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,12 +16,15 @@ before_install: libganglia1-dev libgcrypt11-dev libglib2.0-dev + libgps-dev libhiredis-dev libi2c-dev libldap2-dev libltdl-dev + liblua5.2-dev liblvm2-dev libmemcached-dev + libmicrohttpd-dev libmnl-dev libmodbus-dev libmosquitto0-dev @@ -53,4 +56,4 @@ before_install: perl protobuf-c-compiler python-dev -script: sh build.sh && ./configure --with-python=/usr/bin/python && make distcheck DISTCHECK_CONFIGURE_FLAGS="--with-python=/usr/bin/python" +script: sh build.sh && ./configure && make distcheck diff --git a/AUTHORS b/AUTHORS index 8962e775..d866c700 100644 --- a/AUTHORS +++ b/AUTHORS @@ -294,6 +294,9 @@ Sjoerd van der Berg Stefan Hacker - teamspeak2 plugin. +Steven Bell + - nut plugin. + Sven Trenkel - netapp plugin. - python plugin. diff --git a/Makefile.am b/Makefile.am index 03bdd39a..1f18d231 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,23 +1,2012 @@ -ACLOCAL_AMFLAGS = -I libltdl/m4 +ACLOCAL_AMFLAGS = -I m4 +AM_YFLAGS = -d -SUBDIRS = -if BUILD_INCLUDED_LTDL -SUBDIRS += libltdl +BUILT_SOURCES = \ + src/libcollectdclient/collectd/lcc_features.h \ + src/liboconfig/parser.h \ + $(dist_man_MANS) + + +CLEANFILES = \ + .perl-directory-stamp \ + bindings/buildperl/Collectd.pm \ + bindings/buildperl/Collectd/Plugins/OpenVZ.pm \ + bindings/buildperl/Collectd/Unixsock.pm \ + bindings/buildperl/Makefile.PL \ + collectd-api.jar \ + collectd.grpc.pb.cc \ + collectd.grpc.pb.h \ + collectd.pb.cc \ + collectd.pb.h \ + generic-jmx.jar \ + org/collectd/api/*.class \ + org/collectd/java/*.class \ + prometheus.pb-c.c \ + prometheus.pb-c.h \ + src/pinba.pb-c.c \ + src/pinba.pb-c.h \ + types.pb.cc \ + types.pb.h + + +EXTRA_DIST = \ + bindings/perl/Makefile.PL \ + bindings/perl/lib/Collectd.pm \ + bindings/perl/lib/Collectd/Plugins/Monitorus.pm \ + bindings/perl/lib/Collectd/Plugins/OpenVZ.pm \ + bindings/perl/lib/Collectd/Unixsock.pm \ + bindings/perl/uninstall_mod.pl \ + contrib \ + proto/collectd.proto \ + proto/prometheus.proto \ + proto/types.proto \ + src/collectd-email.pod \ + src/collectd-exec.pod \ + src/collectd-java.pod \ + src/collectd-lua.pod \ + src/collectd-nagios.pod \ + src/collectd-perl.pod \ + src/collectd-python.pod \ + src/collectd-snmp.pod \ + src/collectd-tg.pod \ + src/collectd-threshold.pod \ + src/collectd-unixsock.pod \ + src/collectd.conf.pod \ + src/collectd.pod \ + src/collectdctl.pod \ + src/collectdmon.pod \ + src/pinba.proto \ + src/postgresql_default.conf \ + src/types.db \ + src/types.db.pod \ + src/valgrind.FreeBSD.suppress \ + testwrapper.sh \ + version-gen.sh + + +dist_man_MANS = \ + src/collectd.1 \ + src/collectd.conf.5 \ + src/collectd-email.5 \ + src/collectd-exec.5 \ + src/collectdctl.1 \ + src/collectd-java.5 \ + src/collectd-lua.5 \ + src/collectdmon.1 \ + src/collectd-nagios.1 \ + src/collectd-perl.5 \ + src/collectd-python.5 \ + src/collectd-snmp.5 \ + src/collectd-tg.1 \ + src/collectd-threshold.5 \ + src/collectd-unixsock.5 \ + src/types.db.5 + + +nodist_pkgconfig_DATA = \ + src/libcollectdclient/libcollectdclient.pc + +pkginclude_HEADERS = \ + src/libcollectdclient/collectd/client.h \ + src/libcollectdclient/collectd/network.h \ + src/libcollectdclient/collectd/network_buffer.h \ + src/libcollectdclient/collectd/lcc_features.h + +lib_LTLIBRARIES = libcollectdclient.la + + +sbin_PROGRAMS = \ + collectd \ + collectdmon + + +bin_PROGRAMS = \ + collectd-nagios \ + collectd-tg \ + collectdctl + + +noinst_LTLIBRARIES = \ + libavltree.la \ + libcmds.la \ + libcommon.la \ + libformat_graphite.la \ + libformat_json.la \ + libheap.la \ + libignorelist.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 '\' + + +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_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 + +libignorelist_la_SOURCES = \ + src/utils_ignorelist.c \ + src/utils_ignorelist.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_time.c \ + src/daemon/utils_time.h + +libplugin_mock_la_CPPFLAGS = $(AM_CPPFLAGS) -DMOCK_TIME +libplugin_mock_la_LIBADD = libcommon.la libignorelist.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 = libignorelist.la libmount.la +endif + +if BUILD_PLUGIN_CHRONY +pkglib_LTLIBRARIES += chrony.la +chrony_la_SOURCES = src/chrony.c +chrony_la_LDFLAGS = $(PLUGIN_LDFLAGS) +chrony_la_LIBADD = -lm +endif + +if BUILD_PLUGIN_CONNTRACK +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 = libignorelist.la 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 = libignorelist.la +if BUILD_WITH_LIBKSTAT +disk_la_LIBADD += -lkstat +endif +if BUILD_WITH_LIBDEVINFO +disk_la_LIBADD += -ldevinfo +endif +if BUILD_WITH_LIBIOKIT +disk_la_LDFLAGS += -framework IOKit +endif +if BUILD_WITH_LIBSTATGRAB +disk_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) +disk_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) +endif +if BUILD_WITH_LIBUDEV +disk_la_CPPFLAGS += $(BUILD_WITH_LIBUDEV_CPPFLAGS) +disk_la_LDFLAGS += $(BUILD_WITH_LIBUDEV_LDFLAGS) +disk_la_LIBADD += $(BUILD_WITH_LIBUDEV_LIBS) +endif +if BUILD_FREEBSD +disk_la_LIBADD += -ldevstat -lgeom +endif +if BUILD_WITH_PERFSTAT +disk_la_LIBADD += -lperfstat +endif +endif + +if BUILD_PLUGIN_DNS +pkglib_LTLIBRARIES += dns.la +dns_la_SOURCES = \ + src/dns.c \ + src/utils_dns.c \ + src/utils_dns.h +dns_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBPCAP_CPPFLAGS) +dns_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBPCAP_LDFLAGS) +dns_la_LIBADD = $(BUILD_WITH_LIBPCAP_LIBS) +endif + +if BUILD_PLUGIN_DPDKEVENTS +pkglib_LTLIBRARIES += dpdkevents.la +dpdkevents_la_SOURCES = src/dpdkevents.c src/utils_dpdk.c src/utils_dpdk.h +dpdkevents_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBDPDK_CPPFLAGS) +dpdkevents_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBDPDK_LDFLAGS) +dpdkevents_la_LIBADD = -ldpdk +endif + +if BUILD_PLUGIN_DPDKSTAT +pkglib_LTLIBRARIES += dpdkstat.la +dpdkstat_la_SOURCES = src/dpdkstat.c src/utils_dpdk.c src/utils_dpdk.h +dpdkstat_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBDPDK_CPPFLAGS) +dpdkstat_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBDPDK_LDFLAGS) +dpdkstat_la_LIBADD = -ldpdk +endif + +if BUILD_PLUGIN_DRBD +pkglib_LTLIBRARIES += drbd.la +drbd_la_SOURCES = src/drbd.c +drbd_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_EMAIL +pkglib_LTLIBRARIES += email.la +email_la_SOURCES = src/email.c +email_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_ENTROPY +pkglib_LTLIBRARIES += entropy.la +entropy_la_SOURCES = src/entropy.c +entropy_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_EXEC +pkglib_LTLIBRARIES += exec.la +exec_la_SOURCES = src/exec.c +exec_la_LDFLAGS = $(PLUGIN_LDFLAGS) +exec_la_LIBADD = libcmds.la +endif + +if BUILD_PLUGIN_ETHSTAT +pkglib_LTLIBRARIES += ethstat.la +ethstat_la_SOURCES = src/ethstat.c +ethstat_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_FHCOUNT +pkglib_LTLIBRARIES += fhcount.la +fhcount_la_SOURCES = src/fhcount.c +fhcount_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_FILECOUNT +pkglib_LTLIBRARIES += filecount.la +filecount_la_SOURCES = src/filecount.c +filecount_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_FSCACHE +pkglib_LTLIBRARIES += fscache.la +fscache_la_SOURCES = src/fscache.c +fscache_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_GMOND +pkglib_LTLIBRARIES += gmond.la +gmond_la_SOURCES = src/gmond.c +gmond_la_CPPFLAGS = $(AM_CPPFLAGS) $(GANGLIA_CPPFLAGS) +gmond_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(GANGLIA_LDFLAGS) +gmond_la_LIBADD = $(GANGLIA_LIBS) +endif + +if BUILD_PLUGIN_GPS +pkglib_LTLIBRARIES += gps.la +gps_la_SOURCES = src/gps.c +gps_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBGPS_CFLAGS) +gps_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBGPS_LDFLAGS) +gps_la_LIBADD = -lpthread $(BUILD_WITH_LIBGPS_LIBS) +endif + +if BUILD_PLUGIN_GRPC +pkglib_LTLIBRARIES += grpc.la +grpc_la_SOURCES = src/grpc.cc +nodist_grpc_la_SOURCES = \ + collectd.grpc.pb.cc \ + collectd.pb.cc \ + types.pb.cc +grpc_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBGRPCPP_CPPFLAGS) $(BUILD_WITH_LIBPROTOBUF_CPPFLAGS) +grpc_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBGRPCPP_LDFLAGS) $(BUILD_WITH_LIBPROTOBUF_LDFLAGS) +grpc_la_LIBADD = $(BUILD_WITH_LIBGRPCPP_LIBS) $(BUILD_WITH_LIBPROTOBUF_LIBS) +endif + +if BUILD_PLUGIN_HDDTEMP +pkglib_LTLIBRARIES += hddtemp.la +hddtemp_la_SOURCES = src/hddtemp.c +hddtemp_la_LDFLAGS = $(PLUGIN_LDFLAGS) +hddtemp_la_LIBADD = +if BUILD_WITH_LIBSOCKET +hddtemp_la_LIBADD += -lsocket +endif +endif + +if BUILD_PLUGIN_HUGEPAGES +pkglib_LTLIBRARIES += hugepages.la +hugepages_la_SOURCES = src/hugepages.c +hugepages_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_INTEL_RDT +pkglib_LTLIBRARIES += intel_rdt.la +intel_rdt_la_SOURCES = src/intel_rdt.c +intel_rdt_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBPQOS_CPPFLAGS) +intel_rdt_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBPQOS_LDFLAGS) +intel_rdt_la_LIBADD = $(BUILD_WITH_LIBPQOS_LIBS) +endif + +if BUILD_PLUGIN_INTERFACE +pkglib_LTLIBRARIES += interface.la +interface_la_SOURCES = src/interface.c +interface_la_CFLAGS = $(AM_CFLAGS) +interface_la_LDFLAGS = $(PLUGIN_LDFLAGS) +interface_la_LIBADD = libignorelist.la +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 = libignorelist.la $(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) +irq_la_LIBADD = libignorelist.la +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) +madwifi_la_LIBADD = libignorelist.la +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 -SUBDIRS += proto src bindings . +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) +md_la_LIBADD = libignorelist.la +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 = libignorelist.la $(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 = libignorelist.la $(LIBNETAPP_LIBS) +endif + +if BUILD_PLUGIN_NETLINK +pkglib_LTLIBRARIES += netlink.la +netlink_la_SOURCES = src/netlink.c +netlink_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBMNL_CFLAGS) +netlink_la_LDFLAGS = $(PLUGIN_LDFLAGS) +netlink_la_LIBADD = $(BUILD_WITH_LIBMNL_LIBS) +endif + +if BUILD_PLUGIN_NETWORK +pkglib_LTLIBRARIES += network.la +network_la_SOURCES = \ + src/network.c \ + src/network.h \ + src/utils_fbhash.c \ + src/utils_fbhash.h +network_la_CPPFLAGS = $(AM_CPPFLAGS) +network_la_LDFLAGS = $(PLUGIN_LDFLAGS) +network_la_LIBADD = +if BUILD_WITH_LIBSOCKET +network_la_LIBADD += -lsocket +endif +if BUILD_WITH_LIBGCRYPT +network_la_CPPFLAGS += $(GCRYPT_CPPFLAGS) +network_la_LDFLAGS += $(GCRYPT_LDFLAGS) +network_la_LIBADD += $(GCRYPT_LIBS) +endif +endif + +if BUILD_PLUGIN_NFS +pkglib_LTLIBRARIES += nfs.la +nfs_la_SOURCES = src/nfs.c +nfs_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_NGINX +pkglib_LTLIBRARIES += nginx.la +nginx_la_SOURCES = src/nginx.c +nginx_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS) +nginx_la_LDFLAGS = $(PLUGIN_LDFLAGS) +nginx_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) +endif + +if BUILD_PLUGIN_NOTIFY_DESKTOP +pkglib_LTLIBRARIES += notify_desktop.la +notify_desktop_la_SOURCES = src/notify_desktop.c +notify_desktop_la_CFLAGS = $(AM_CFLAGS) $(LIBNOTIFY_CFLAGS) +notify_desktop_la_LDFLAGS = $(PLUGIN_LDFLAGS) +notify_desktop_la_LIBADD = $(LIBNOTIFY_LIBS) +endif + +if BUILD_PLUGIN_NOTIFY_EMAIL +pkglib_LTLIBRARIES += notify_email.la +notify_email_la_SOURCES = src/notify_email.c +notify_email_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBESMTP_CPPFLAGS) +notify_email_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBESMTP_LDFLAGS) +notify_email_la_LIBADD = $(BUILD_WITH_LIBESMTP_LIBS) +endif + +if BUILD_PLUGIN_NOTIFY_NAGIOS +pkglib_LTLIBRARIES += notify_nagios.la +notify_nagios_la_SOURCES = src/notify_nagios.c +notify_nagios_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_NTPD +pkglib_LTLIBRARIES += ntpd.la +ntpd_la_SOURCES = src/ntpd.c +ntpd_la_LDFLAGS = $(PLUGIN_LDFLAGS) +ntpd_la_LIBADD = +if BUILD_WITH_LIBSOCKET +ntpd_la_LIBADD += -lsocket +endif +endif + +if BUILD_PLUGIN_NUMA +pkglib_LTLIBRARIES += numa.la +numa_la_SOURCES = src/numa.c +numa_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_NUT +pkglib_LTLIBRARIES += nut.la +nut_la_SOURCES = src/nut.c +nut_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBUPSCLIENT_CFLAGS) +nut_la_LDFLAGS = $(PLUGIN_LDFLAGS) +nut_la_LIBADD = $(BUILD_WITH_LIBUPSCLIENT_LIBS) +endif + +if BUILD_PLUGIN_OLSRD +pkglib_LTLIBRARIES += olsrd.la +olsrd_la_SOURCES = src/olsrd.c +olsrd_la_LDFLAGS = $(PLUGIN_LDFLAGS) +olsrd_la_LIBADD = +if BUILD_WITH_LIBSOCKET +olsrd_la_LIBADD += -lsocket +endif +endif + +if BUILD_PLUGIN_ONEWIRE +pkglib_LTLIBRARIES += onewire.la +onewire_la_SOURCES = src/onewire.c +onewire_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBOWCAPI_CPPFLAGS) +onewire_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBOWCAPI_LDFLAGS) +onewire_la_LIBADD = libignorelist.la $(BUILD_WITH_LIBOWCAPI_LIBS) +endif + +if BUILD_PLUGIN_OPENLDAP +pkglib_LTLIBRARIES += openldap.la +openldap_la_SOURCES = src/openldap.c +openldap_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBLDAP_CPPFLAGS) +openldap_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBLDAP_LDFLAGS) +openldap_la_LIBADD = -lldap +endif + +if BUILD_PLUGIN_OPENVPN +pkglib_LTLIBRARIES += openvpn.la +openvpn_la_SOURCES = src/openvpn.c +openvpn_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_ORACLE +pkglib_LTLIBRARIES += oracle.la +oracle_la_SOURCES = \ + src/oracle.c \ + src/utils_db_query.c \ + src/utils_db_query.h +oracle_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_ORACLE_CPPFLAGS) +oracle_la_LIBADD = $(BUILD_WITH_ORACLE_LIBS) +oracle_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_OVS_EVENTS +pkglib_LTLIBRARIES += ovs_events.la +ovs_events_la_SOURCES = \ + src/ovs_events.c \ + src/utils_ovs.c \ + src/utils_ovs.h +ovs_events_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS) +ovs_events_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS) +ovs_events_la_LIBADD = $(BUILD_WITH_LIBYAJL_LIBS) +endif + +if BUILD_PLUGIN_OVS_STATS +pkglib_LTLIBRARIES += ovs_stats.la +ovs_stats_la_SOURCES = \ + src/ovs_stats.c \ + src/utils_ovs.c \ + src/utils_ovs.h +ovs_stats_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS) +ovs_stats_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS) +ovs_stats_la_LIBADD = $(BUILD_WITH_LIBYAJL_LIBS) +endif + +if BUILD_PLUGIN_PERL +pkglib_LTLIBRARIES += perl.la +perl_la_SOURCES = src/perl.c +# 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) +protocols_la_LIBADD = libignorelist.la +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 = libignorelist.la $(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 = libignorelist.la $(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 -AM_CPPFLAGS = $(LTDLINCL) +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) +thermal_la_LIBADD = libignorelist.la +endif + +if BUILD_PLUGIN_THRESHOLD +pkglib_LTLIBRARIES += threshold.la +threshold_la_SOURCES = src/threshold.c +threshold_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_TOKYOTYRANT +pkglib_LTLIBRARIES += tokyotyrant.la +tokyotyrant_la_SOURCES = src/tokyotyrant.c +tokyotyrant_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBTOKYOTYRANT_CPPFLAGS) +tokyotyrant_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBTOKYOTYRANT_LDFLAGS) +tokyotyrant_la_LIBADD = $(BUILD_WITH_LIBTOKYOTYRANT_LIBS) +if BUILD_WITH_LIBSOCKET +tokyotyrant_la_LIBADD += -lsocket +endif +endif + +if BUILD_PLUGIN_TURBOSTAT +pkglib_LTLIBRARIES += turbostat.la +turbostat_la_SOURCES = src/turbostat.c +turbostat_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_UNIXSOCK +pkglib_LTLIBRARIES += unixsock.la +unixsock_la_SOURCES = src/unixsock.c +unixsock_la_LDFLAGS = $(PLUGIN_LDFLAGS) +unixsock_la_LIBADD = libcmds.la +endif + +if BUILD_PLUGIN_UPTIME +pkglib_LTLIBRARIES += uptime.la +uptime_la_SOURCES = src/uptime.c +uptime_la_CFLAGS = $(AM_CFLAGS) +uptime_la_LDFLAGS = $(PLUGIN_LDFLAGS) +uptime_la_LIBADD = +if BUILD_WITH_LIBKSTAT +uptime_la_LIBADD += -lkstat +endif +if BUILD_WITH_PERFSTAT +uptime_la_LIBADD += -lperfstat +endif +endif + +if BUILD_PLUGIN_USERS +pkglib_LTLIBRARIES += users.la +users_la_SOURCES = src/users.c +users_la_CFLAGS = $(AM_CFLAGS) +users_la_LDFLAGS = $(PLUGIN_LDFLAGS) +users_la_LIBADD = +if BUILD_WITH_LIBSTATGRAB +users_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) +users_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) +endif +endif + +if BUILD_PLUGIN_UUID +pkglib_LTLIBRARIES += uuid.la +uuid_la_SOURCES = src/uuid.c +uuid_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_VARNISH +pkglib_LTLIBRARIES += varnish.la +varnish_la_SOURCES = src/varnish.c +varnish_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBVARNISH_CFLAGS) +varnish_la_LDFLAGS = $(PLUGIN_LDFLAGS) +varnish_la_LIBADD = $(BUILD_WITH_LIBVARNISH_LIBS) +endif + +if BUILD_PLUGIN_VIRT +pkglib_LTLIBRARIES += virt.la +virt_la_SOURCES = src/virt.c +virt_la_CFLAGS = $(AM_CFLAGS) \ + $(BUILD_WITH_LIBVIRT_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS) +virt_la_LDFLAGS = $(PLUGIN_LDFLAGS) +virt_la_LIBADD = libignorelist.la $(BUILD_WITH_LIBVIRT_LIBS) $(BUILD_WITH_LIBXML2_LIBS) + +# TODO: enable once we support only modern libvirts which depends on libnl-3 +# the libvirt on wheezy is linked in libnl v1, and there is a small leak here, +# 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 -EXTRA_DIST = contrib version-gen.sh testwrapper.sh +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_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBMONGOC_CFLAGS) +write_mongodb_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBMONGOC_LDFLAGS) +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 '\' $@ >/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 '\' $@ >/dev/null 2>&1; \ + then \ + echo "$@ has some POD errors!"; false; \ + fi + +V_PROTOC = $(v_protoc_@AM_V@) +v_protoc_ = $(v_protoc_@AM_DEFAULT_V@) +v_protoc_0 = @echo " PROTOC " $@; + +AM_V_PROTOC_C = $(am__v_PROTOC_C_@AM_V@) +am__v_PROTOC_C_ = $(am__v_PROTOC_C_@AM_DEFAULT_V@) +am__v_PROTOC_C_0 = @echo " PROTOC-C" $@; +am__v_PROTOC_C_1 = + +# Protocol buffer for the "pinba" plugin. +if BUILD_PLUGIN_PINBA +BUILT_SOURCES += src/pinba.pb-c.c src/pinba.pb-c.h + +src/pinba.pb-c.c src/pinba.pb-c.h: $(srcdir)/src/pinba.proto + $(AM_V_PROTOC_C)$(PROTOC_C) -I$(srcdir) --c_out . $(srcdir)/src/pinba.proto +endif + +# Protocol buffer for the "write_prometheus" plugin. +if BUILD_PLUGIN_WRITE_PROMETHEUS +BUILT_SOURCES += prometheus.pb-c.c prometheus.pb-c.h + +prometheus.pb-c.c prometheus.pb-c.h: $(srcdir)/proto/prometheus.proto + $(AM_V_PROTOC_C)$(PROTOC_C) -I$(srcdir)/proto --c_out=$(builddir) $(srcdir)/proto/prometheus.proto +endif + +if HAVE_PROTOC3 +if HAVE_GRPC_CPP +BUILT_SOURCES += collectd.grpc.pb.cc collectd.pb.cc types.pb.cc + +collectd.grpc.pb.cc: $(srcdir)/proto/collectd.proto $(srcdir)/proto/types.proto + $(V_PROTOC)$(PROTOC) -I$(srcdir)/proto \ + --grpc_out=$(builddir) --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN) $< + +collectd.pb.cc: $(srcdir)/proto/collectd.proto $(srcdir)/proto/types.proto + $(V_PROTOC)$(PROTOC) -I$(srcdir)/proto --cpp_out=$(builddir) $< + +types.pb.cc: $(srcdir)/proto/types.proto + $(V_PROTOC)$(PROTOC) -I$(srcdir)/proto --cpp_out=$(builddir) $< +endif +endif install-exec-hook: $(mkinstalldirs) $(DESTDIR)$(localstatedir)/run $(mkinstalldirs) $(DESTDIR)$(localstatedir)/lib/$(PACKAGE_NAME) $(mkinstalldirs) $(DESTDIR)$(localstatedir)/log + $(mkinstalldirs) $(DESTDIR)$(sysconfdir) + if test -e $(DESTDIR)$(sysconfdir)/collectd.conf; \ + then \ + $(INSTALL) -m 0640 $(srcdir)/src/collectd.conf $(DESTDIR)$(sysconfdir)/collectd.conf.pkg-orig; \ + else \ + $(INSTALL) -m 0640 $(srcdir)/src/collectd.conf $(DESTDIR)$(sysconfdir)/collectd.conf; \ + fi; \ + $(mkinstalldirs) $(DESTDIR)$(pkgdatadir) + $(INSTALL) -m 0644 $(srcdir)/src/types.db $(DESTDIR)$(pkgdatadir)/types.db; + $(INSTALL) -m 0644 $(srcdir)/src/postgresql_default.conf \ + $(DESTDIR)$(pkgdatadir)/postgresql_default.conf; + +uninstall-hook: + rm -f $(DESTDIR)$(pkgdatadir)/types.db; + rm -f $(DESTDIR)$(sysconfdir)/collectd.conf + rm -f $(DESTDIR)$(pkgdatadir)/postgresql_default.conf; -maintainer-clean-local: - -rm -f -r libltdl - -rm -f INSTALL - -rm -f aclocal.m4 +all-local: @PERL_BINDINGS@ + +install-exec-local: + [ ! -f buildperl/Makefile ] || ( cd buildperl && $(MAKE) install ) + +# Perl 'make uninstall' does not work as well as wanted. +# So we do the work here. +uninstall-local: + @PERL@ -I$(DESTDIR)$(prefix) $(srcdir)/bindings/perl/uninstall_mod.pl Collectd + find $(DESTDIR)$(prefix) -name "perllocal.pod" -exec rm {} \; + +clean-local: + rm -rf buildperl + +perl: buildperl/Makefile + cd buildperl && $(MAKE) + +buildperl/Makefile: .perl-directory-stamp buildperl/Makefile.PL \ + $(top_builddir)/config.status + @# beautify the output a bit + @echo 'cd buildperl && @PERL@ Makefile.PL @PERL_BINDINGS_OPTIONS@' + @cd buildperl && ( if ! @PERL@ Makefile.PL @PERL_BINDINGS_OPTIONS@; then \ + echo ""; \ + echo 'Check whether you have set $$PERL_MM_OPT in your environment and try using ./configure --with-perl-bindings=""'; \ + echo ""; \ + fi ) + +buildperl/Makefile.PL: .perl-directory-stamp $(top_builddir)/config.status + +.perl-directory-stamp: + if test ! -d buildperl; then \ + mkdir -p buildperl/Collectd/Plugins; \ + cp $(srcdir)/bindings/perl/lib/Collectd.pm buildperl/; \ + cp $(srcdir)/bindings/perl/Makefile.PL buildperl/; \ + cp $(srcdir)/bindings/perl/lib/Collectd/Unixsock.pm buildperl/Collectd/; \ + cp $(srcdir)/bindings/perl/lib/Collectd/Plugins/OpenVZ.pm buildperl/Collectd/Plugins/; \ + fi + touch $@ + +.PHONY: perl + + +if BUILD_WITH_JAVA +dist_noinst_JAVA = \ + bindings/java/org/collectd/api/Collectd.java \ + bindings/java/org/collectd/api/CollectdConfigInterface.java \ + bindings/java/org/collectd/api/CollectdFlushInterface.java \ + bindings/java/org/collectd/api/CollectdInitInterface.java \ + bindings/java/org/collectd/api/CollectdLogInterface.java \ + bindings/java/org/collectd/api/CollectdMatchFactoryInterface.java \ + bindings/java/org/collectd/api/CollectdMatchInterface.java \ + bindings/java/org/collectd/api/CollectdNotificationInterface.java \ + bindings/java/org/collectd/api/CollectdReadInterface.java \ + bindings/java/org/collectd/api/CollectdShutdownInterface.java \ + bindings/java/org/collectd/api/CollectdTargetFactoryInterface.java \ + bindings/java/org/collectd/api/CollectdTargetInterface.java \ + bindings/java/org/collectd/api/CollectdWriteInterface.java \ + bindings/java/org/collectd/api/DataSet.java \ + bindings/java/org/collectd/api/DataSource.java \ + bindings/java/org/collectd/api/Notification.java \ + bindings/java/org/collectd/api/OConfigItem.java \ + bindings/java/org/collectd/api/OConfigValue.java \ + bindings/java/org/collectd/api/PluginData.java \ + bindings/java/org/collectd/api/ValueList.java \ + bindings/java/org/collectd/java/GenericJMX.java \ + bindings/java/org/collectd/java/GenericJMXConfConnection.java \ + bindings/java/org/collectd/java/GenericJMXConfMBean.java \ + bindings/java/org/collectd/java/GenericJMXConfValue.java \ + bindings/java/org/collectd/java/JMXMemory.java + +collectd-api.jar: classnoinst.stamp + $(JAR) cf $(JARFLAGS) $@ org/collectd/api/*.class + +generic-jmx.jar: classnoinst.stamp + $(JAR) cf $(JARFLAGS) $@ org/collectd/java/*.class + +jar_DATA = collectd-api.jar generic-jmx.jar +endif diff --git a/README b/README index 803fbaaf..18602816 100644 --- a/README +++ b/README @@ -198,14 +198,19 @@ Features Queries very detailed usage statistics from wireless LAN adapters and interfaces that use the Atheros chipset and the MadWifi driver. - - md - Linux software-RAID device information (number of active, failed, spare - and missing disks). - - mbmon Motherboard sensors: temperature, fan speed and voltage information, using mbmon(1). + - mcelog + Monitor machine check exceptions (hardware errors detected by hardware + and reported to software) reported by mcelog and generate appropriate + notifications when machine check exceptions are detected. + + - md + Linux software-RAID device information (number of active, failed, spare + and missing disks). + - memcachec Query and parse data from a memcache daemon (memcached). @@ -283,6 +288,22 @@ Features - oracle Query data from an Oracle database. + - ovs_events + The plugin monitors the link status of Open vSwitch (OVS) connected + interfaces, dispatches the values to collectd and sends the notification + whenever the link state change occurs in the OVS database. It requires + YAJL library to be installed. + Detailed instructions for installing and setting up Open vSwitch, see + OVS documentation. + + + - ovs_stats + The plugin collects the statistics of OVS connected bridges and + interfaces. It requires YAJL library to be installed. + Detailed instructions for installing and setting up Open vSwitch, see + OVS documentation. + + - perl The perl plugin implements a Perl-interpreter into collectd. You can write your own plugins in Perl and return arbitrary values using this @@ -750,10 +771,6 @@ Prerequisites Used by the `gps' plugin. - * libhal (optional) - If present, the `uuid' plugin will check for UUID from HAL. - - * libi2c-dev (optional) Used for the plugin `barometer', provides just the i2c-dev.h header file for user space i2c development. @@ -925,8 +942,8 @@ Prerequisites * 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', + 'ovs_stats' and `log_logstash' plugins. * libvarnish (optional) @@ -981,7 +998,6 @@ To generate the `configure` script, you'll need the following dependencies: - flex - bison - libtool -- libtool-ltdl - pkg-config The `build.sh' script takes no arguments. diff --git a/bindings/Makefile.am b/bindings/Makefile.am deleted file mode 100644 index 07373e87..00000000 --- a/bindings/Makefile.am +++ /dev/null @@ -1,69 +0,0 @@ -SUBDIRS = - -if BUILD_WITH_JAVA -SUBDIRS += java -endif - -EXTRA_DIST = perl/Makefile.PL \ - perl/uninstall_mod.pl \ - perl/lib/Collectd.pm \ - perl/lib/Collectd/Unixsock.pm \ - perl/lib/Collectd/Plugins/Monitorus.pm \ - perl/lib/Collectd/Plugins/OpenVZ.pm - -CLEANFILES = \ - buildperl/Collectd.pm \ - buildperl/Collectd/Plugins/OpenVZ.pm \ - buildperl/Collectd/Unixsock.pm \ - buildperl/Makefile.PL \ - .perl-directory-stamp - -DISTCLEANFILES = \ - buildperl/Collectd.pm \ - buildperl/Collectd/Plugins/OpenVZ.pm \ - buildperl/Collectd/Unixsock.pm \ - buildperl/Makefile.PL \ - .perl-directory-stamp - -all-local: @PERL_BINDINGS@ - - -install-exec-local: - [ ! -f buildperl/Makefile ] || ( cd buildperl && $(MAKE) install ) - -# Perl 'make uninstall' does not work as well as wanted. -# So we do the work here. -uninstall-local: - @PERL@ -I$(DESTDIR)$(prefix) $(srcdir)/perl/uninstall_mod.pl Collectd - find $(DESTDIR)$(prefix) -name "perllocal.pod" -exec rm {} \; - -clean-local: - rm -rf buildperl - -perl: buildperl/Makefile - cd buildperl && $(MAKE) - -buildperl/Makefile: .perl-directory-stamp buildperl/Makefile.PL \ - $(top_builddir)/config.status - @# beautify the output a bit - @echo 'cd buildperl && @PERL@ Makefile.PL @PERL_BINDINGS_OPTIONS@' - @cd buildperl && ( if ! @PERL@ Makefile.PL @PERL_BINDINGS_OPTIONS@; then \ - echo ""; \ - echo 'Check whether you have set $$PERL_MM_OPT in your environment and try using ./configure --with-perl-bindings=""'; \ - echo ""; \ - fi ) - -buildperl/Makefile.PL: .perl-directory-stamp $(top_builddir)/config.status - -.perl-directory-stamp: - if test ! -d buildperl; then \ - mkdir -p buildperl/Collectd/Plugins; \ - cp $(srcdir)/perl/lib/Collectd.pm buildperl/; \ - cp $(srcdir)/perl/Makefile.PL buildperl/; \ - cp $(srcdir)/perl/lib/Collectd/Unixsock.pm buildperl/Collectd/; \ - cp $(srcdir)/perl/lib/Collectd/Plugins/OpenVZ.pm buildperl/Collectd/Plugins/; \ - fi - touch $@ - -.PHONY: perl - diff --git a/bindings/java/Makefile.am b/bindings/java/Makefile.am deleted file mode 100644 index 8d2e49d7..00000000 --- a/bindings/java/Makefile.am +++ /dev/null @@ -1,53 +0,0 @@ -EXTRA_DIST = org/collectd/api/CollectdConfigInterface.java \ - org/collectd/api/CollectdFlushInterface.java \ - org/collectd/api/CollectdInitInterface.java \ - org/collectd/api/Collectd.java \ - org/collectd/api/CollectdLogInterface.java \ - org/collectd/api/CollectdMatchFactoryInterface.java \ - org/collectd/api/CollectdMatchInterface.java \ - org/collectd/api/CollectdNotificationInterface.java \ - org/collectd/api/CollectdReadInterface.java \ - org/collectd/api/CollectdShutdownInterface.java \ - org/collectd/api/CollectdTargetFactoryInterface.java \ - org/collectd/api/CollectdTargetInterface.java \ - org/collectd/api/CollectdWriteInterface.java \ - org/collectd/api/DataSet.java \ - org/collectd/api/DataSource.java \ - org/collectd/api/Notification.java \ - org/collectd/api/OConfigItem.java \ - org/collectd/api/OConfigValue.java \ - org/collectd/api/PluginData.java \ - org/collectd/api/ValueList.java \ - org/collectd/java/GenericJMXConfConnection.java \ - org/collectd/java/GenericJMXConfMBean.java \ - org/collectd/java/GenericJMXConfValue.java \ - org/collectd/java/GenericJMX.java \ - org/collectd/java/JMXMemory.java - -java-build-stamp: $(srcdir)/org/collectd/api/*.java $(srcdir)/org/collectd/java/*.java - $(JAVAC) -d "." "$(srcdir)/org/collectd/api"/*.java - $(JAVAC) -d "." "$(srcdir)/org/collectd/java"/*.java - mkdir -p .libs - $(JAR) cf .libs/collectd-api.jar "org/collectd/api"/*.class - $(JAR) cf .libs/generic-jmx.jar "org/collectd/java"/*.class - touch "$@" - -all-local: java-build-stamp - -install-exec-local: java-build-stamp - mkdir -p "$(DESTDIR)$(pkgdatadir)/java" - $(INSTALL) -m 644 .libs/collectd-api.jar \ - "$(DESTDIR)$(pkgdatadir)/java" - $(INSTALL) -m 644 .libs/generic-jmx.jar \ - "$(DESTDIR)$(pkgdatadir)/java" - -uninstall-local: - rm -f "$(DESTDIR)$(pkgdatadir)/java/collectd-api.jar" - rm -f "$(DESTDIR)$(pkgdatadir)/java/generic-jmx.jar" - rmdir "$(DESTDIR)$(pkgdatadir)/java" || true - -clean-local: - rm -f "org/collectd/api"/*.class - rm -f "org/collectd/java"/*.class - rm -f .libs - rm -f "java-build-stamp" diff --git a/bindings/java/org/collectd/java/GenericJMXConfValue.java b/bindings/java/org/collectd/java/GenericJMXConfValue.java index 63b76282..6d3d688e 100644 --- a/bindings/java/org/collectd/java/GenericJMXConfValue.java +++ b/bindings/java/org/collectd/java/GenericJMXConfValue.java @@ -30,6 +30,8 @@ import java.util.Arrays; import java.util.List; import java.util.Collection; import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; import java.util.Iterator; import java.util.ArrayList; @@ -128,6 +130,14 @@ class GenericJMXConfValue { return (BigInteger.ZERO.add ((BigInteger) obj)); } + else if (obj instanceof AtomicInteger) + { + return (new Integer(((AtomicInteger) obj).get())); + } + else if (obj instanceof AtomicLong) + { + return (new Long(((AtomicLong) obj).get())); + } return (null); } /* }}} Number genericObjectToNumber */ diff --git a/build.sh b/build.sh index 57f3d444..40f5361d 100755 --- a/build.sh +++ b/build.sh @@ -18,12 +18,7 @@ EOF done } -check_for_application lex bison autoheader aclocal automake autoconf - -# Actually we don't need the pkg-config executable, but we need the M4 macros. -# We check for `pkg-config' here and hope that M4 macros will then be -# available, too. -check_for_application pkg-config +check_for_application lex bison autoheader aclocal automake autoconf pkg-config libtoolize="" libtoolize --version >/dev/null 2>/dev/null @@ -54,6 +49,6 @@ set -x autoheader \ && aclocal \ -&& $libtoolize --ltdl --copy --force \ +&& $libtoolize --copy --force \ && automake --add-missing --copy \ && autoconf diff --git a/clean.sh b/clean.sh index 6780cdab..ac3c3105 100755 --- a/clean.sh +++ b/clean.sh @@ -15,7 +15,6 @@ true \ && rm -f configure \ && rm -f depcomp \ && rm -f install-sh \ -&& rm -f -r libltdl \ && rm -f libtool \ && rm -f ltmain.sh \ && rm -f Makefile \ diff --git a/configure.ac b/configure.ac index 9d49d915..320572d0 100644 --- a/configure.ac +++ b/configure.ac @@ -3,34 +3,15 @@ AC_PREREQ([2.60]) AC_INIT([collectd],[m4_esyscmd(./version-gen.sh)]) AC_CONFIG_SRCDIR(src/target_set.c) AC_CONFIG_HEADERS(src/config.h) -AC_CONFIG_AUX_DIR([libltdl/config]) +AC_CONFIG_AUX_DIR([build-aux]) +AC_CONFIG_MACRO_DIR([m4]) dnl older automake's default of ARFLAGS=cru is noisy on newer binutils; dnl we don't really need the 'u' even in older toolchains. Then there is dnl older libtool, which spelled it AR_FLAGS m4_divert_text([DEFAULTS], [: "${ARFLAGS=cr} ${AR_FLAGS=cr}"]) -m4_ifdef([LT_PACKAGE_VERSION], - # libtool >= 2.2 - [ - LT_CONFIG_LTDL_DIR([libltdl]) - LT_INIT([dlopen]) - LTDL_INIT([convenience]) - AC_DEFINE(LIBTOOL_VERSION, 2, [Define to used libtool version.]) - ] -, - # libtool <= 1.5 - [ - AC_LIBLTDL_CONVENIENCE - AC_SUBST(LTDLINCL) - AC_SUBST(LIBLTDL) - AC_LIBTOOL_DLOPEN - AC_CONFIG_SUBDIRS(libltdl) - AC_DEFINE(LIBTOOL_VERSION, 1, [Define to used libtool version.]) - ] -) - -AM_CONDITIONAL([BUILD_INCLUDED_LTDL], [test "x$LTDLDEPS" != "x"]) +LT_INIT([dlopen disable-static]) AM_INIT_AUTOMAKE([subdir-objects tar-pax dist-bzip2 no-dist-gzip foreign]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) @@ -53,10 +34,8 @@ AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_MAKE_SET AM_PROG_CC_C_O -AM_CONDITIONAL(COMPILER_IS_GCC, test "x$GCC" = "xyes") +AM_CONDITIONAL([COMPILER_IS_GCC], [test "x$GCC" = "xyes"]) -AC_DISABLE_STATIC -AC_PROG_LIBTOOL AC_PROG_LEX AC_PROG_YACC @@ -67,78 +46,60 @@ m4_pattern_forbid([^_?PKG_[A-Z_]+$],[*** pkg.m4 missing, please install pkg-conf PKG_PROG_PKG_CONFIG -AC_CACHE_CHECK([if bison is the parser generator], - [collectd_cv_prog_bison], - [AS_IF([$YACC --version 2>/dev/null | $EGREP -q '^bison '], - [collectd_cv_prog_bison=yes], [collectd_cv_prog_bison=no] - )] +AC_CACHE_CHECK([if Bison is the parser generator], + [collectd_cv_prog_bison], + [ + AS_IF([$YACC --version 2>/dev/null | $EGREP -q '^bison '], + [collectd_cv_prog_bison=yes], + [collectd_cv_prog_bison=no] + ) + ] ) -if test "x$collectd_cv_prog_bison" = "xno" && test ! -f "${srcdir}/src/liboconfig/parser.c" -then - AC_MSG_ERROR([bison is missing and you do not have ${srcdir}/src/liboconfig/parser.c. Please install bison]) +if test "x$collectd_cv_prog_bison" = "xno" && test ! -f "${srcdir}/src/liboconfig/parser.c"; then + AC_MSG_ERROR([bison is missing and you do not have ${srcdir}/src/liboconfig/parser.c. Please install bison]) fi -AC_ARG_VAR([PROTOC], [path to the protoc binary]) -AC_PATH_PROG([PROTOC], [protoc]) -have_protoc3="no" -if test "x$PROTOC" != "x"; then - AC_MSG_CHECKING([for protoc 3.0.0+]) - if $PROTOC --version | $EGREP libprotoc.3 >/dev/null; then - protoc3="yes (`$PROTOC --version`)" - have_protoc3="yes" - else - protoc3="no (`$PROTOC --version`)" - fi - AC_MSG_RESULT([$protoc3]) -fi -AM_CONDITIONAL(HAVE_PROTOC3, test "x$have_protoc3" = "xyes") +AS_IF([test "x$lt_cv_dlopen" = "xno"], + [AC_MSG_ERROR([Your system does not support dlopen])] +) -AC_ARG_VAR([GRPC_CPP_PLUGIN], [path to the grpc_cpp_plugin binary]) -AC_PATH_PROG([GRPC_CPP_PLUGIN], [grpc_cpp_plugin]) -AM_CONDITIONAL(HAVE_GRPC_CPP, test "x$GRPC_CPP_PLUGIN" != "x") +AC_SUBST([DLOPEN_LIBS], [$lt_cv_dlopen_libs]) -AC_ARG_VAR([PROTOC_C], [path to the protoc-c binary]) -AC_PATH_PROG([PROTOC_C], [protoc-c]) -if test "x$PROTOC_C" = "x" -then - have_protoc_c="no (protoc-c compiler not found)" -else - have_protoc_c="yes" -fi AC_MSG_CHECKING([for kernel type ($host_os)]) case $host_os in - *linux*) - AC_DEFINE([KERNEL_LINUX], 1, [True if program is to be compiled for a Linux kernel]) - ac_system="Linux" - ;; - *solaris*) - AC_DEFINE([KERNEL_SOLARIS], 1, [True if program is to be compiled for a Solaris kernel]) - ac_system="Solaris" - ;; - *darwin*) - AC_DEFINE([KERNEL_DARWIN], 1, [True if program is to be compiled for a Darwin kernel]) - ac_system="Darwin" - ;; - *openbsd*) - AC_DEFINE([KERNEL_OPENBSD], 1, [True if program is to be compiled for an OpenBSD kernel]) - ac_system="OpenBSD" - ;; - *netbsd*) - AC_DEFINE([KERNEL_NETBSD], 1, [True if program is to be compiled for a NetBSD kernel]) - ac_system="NetBSD" - ;; - *aix*) - AC_DEFINE([KERNEL_AIX], 1, [True if program is to be compiled for a AIX kernel]) - ac_system="AIX" - ;; - *freebsd*) - AC_DEFINE([KERNEL_FREEBSD], 1, [True if program is to be compiled for a FreeBSD kernel]) - ac_system="FreeBSD" - ;; - *) - ac_system="unknown" + *aix*) + AC_DEFINE([KERNEL_AIX], [1], [True if program is to be compiled for a AIX kernel]) + ac_system="AIX" + ;; + *darwin*) + AC_DEFINE([KERNEL_DARWIN], [1], [True if program is to be compiled for a Darwin kernel]) + ac_system="Darwin" + ;; + *freebsd*) + AC_DEFINE([KERNEL_FREEBSD], [1], [True if program is to be compiled for a FreeBSD kernel]) + ac_system="FreeBSD" + ;; + *linux*) + AC_DEFINE([KERNEL_LINUX], [1], [True if program is to be compiled for a Linux kernel]) + ac_system="Linux" + ;; + *netbsd*) + AC_DEFINE([KERNEL_NETBSD], [1], [True if program is to be compiled for a NetBSD kernel]) + ac_system="NetBSD" + ;; + *openbsd*) + AC_DEFINE([KERNEL_OPENBSD], [1], [True if program is to be compiled for an OpenBSD kernel]) + ac_system="OpenBSD" + ;; + *solaris*) + AC_DEFINE([KERNEL_SOLARIS], [1], [True if program is to be compiled for a Solaris kernel]) + ac_system="Solaris" + ;; + *) + ac_system="unknown" + ;; esac AC_MSG_RESULT([$ac_system]) @@ -149,77 +110,55 @@ AM_CONDITIONAL([BUILD_LINUX], [test "x$ac_system" = "xLinux"]) AM_CONDITIONAL([BUILD_OPENBSD], [test "x$ac_system" = "xOpenBSD"]) AM_CONDITIONAL([BUILD_SOLARIS], [test "x$ac_system" = "xSolaris"]) -if test "x$ac_system" = "xLinux" -then - AC_ARG_VAR([KERNEL_DIR], [path to Linux kernel sources]) - if test -z "$KERNEL_DIR" - then - KERNEL_DIR="/lib/modules/`uname -r`/source" - fi +if test "x$ac_system" = "xLinux"; then + AC_ARG_VAR([KERNEL_DIR], [path to Linux kernel sources]) + if test "x$KERNEL_DIR" = "x"; then + KERNEL_DIR="/lib/modules/`uname -r`/source" + fi + KERNEL_CFLAGS="-I$KERNEL_DIR/include" + AC_SUBST([KERNEL_CFLAGS]) +fi + +if test "x$ac_system" = "xSolaris"; then + AC_DEFINE([_POSIX_PTHREAD_SEMANTICS], [1], [Define to enforce POSIX thread semantics under Solaris.]) + AC_DEFINE([_REENTRANT], [1], [Define to enable reentrancy interfaces.]) - KERNEL_CFLAGS="-I$KERNEL_DIR/include" - AC_SUBST(KERNEL_CFLAGS) + AC_MSG_CHECKING([whether compiler builds 64bit binaries]) + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM( + [ + #ifndef _LP64 + # error "Compiler not in 64bit mode." + #endif + ] + ) + ], + [AC_MSG_RESULT([yes])], + [ + AC_MSG_RESULT([no]) + AC_MSG_NOTICE([Solaris detected. Please consider building a 64-bit binary.]) + ] + ) fi -if test "x$ac_system" = "xSolaris" -then - AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, [Define to enforce POSIX thread semantics under Solaris.]) - AC_DEFINE(_REENTRANT, 1, [Define to enable reentrancy interfaces.]) - - AC_MSG_CHECKING([whether compiler builds 64bit binaries]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ - #ifndef _LP64 - # error "Compiler not in 64bit mode." - #endif - ])], - [AC_MSG_RESULT([yes])], - [ - AC_MSG_RESULT([no]) - AC_MSG_NOTICE([Solaris detected. Please consider building a 64-bit binary.]) - ]) -fi - -if test "x$ac_system" = "xAIX" -then - AC_DEFINE(_THREAD_SAFE_ERRNO, 1, [Define to use the thread-safe version of errno under AIX.]) +if test "x$ac_system" = "xAIX"; then + AC_DEFINE([_THREAD_SAFE_ERRNO], [1], [Define to use the thread-safe version of errno under AIX.]) fi # Where to install .pc files. pkgconfigdir="${libdir}/pkgconfig" -AC_SUBST(pkgconfigdir) - -# Check for standards compliance mode -AC_ARG_ENABLE(standards, - AS_HELP_STRING([--enable-standards], [Enable standards compliance mode]), - [enable_standards="$enableval"], - [enable_standards="no"]) -if test "x$enable_standards" = "xyes" -then - AC_DEFINE(_ISOC99_SOURCE, 1, [Define to enforce ISO C99 compliance.]) - AC_DEFINE(_POSIX_C_SOURCE, 200809L, [Define to enforce POSIX.1-2008 compliance.]) - AC_DEFINE(_XOPEN_SOURCE, 700, [Define to enforce X/Open 7 (XSI) compliance.]) - AC_DEFINE(_REENTRANT, 1, [Define to enable reentrancy interfaces.]) - if test "x$GCC" = "xyes" - then - CFLAGS="$CFLAGS -std=c99" - fi -fi -AM_CONDITIONAL(BUILD_FEATURE_STANDARDS, test "x$enable_standards" = "xyes") +AC_SUBST([pkgconfigdir]) # # Checks for header files. # -AC_HEADER_STDC AC_HEADER_SYS_WAIT AC_HEADER_DIRENT -AC_HEADER_STDBOOL -AC_CHECK_HEADERS([ \ +AC_CHECK_HEADERS_ONCE([ \ arpa/inet.h \ - assert.h \ - ctype.h \ endian.h \ - errno.h \ fcntl.h \ fnmatch.h \ fs_info.h \ @@ -228,9 +167,6 @@ AC_CHECK_HEADERS([ \ kstat.h \ kvm.h \ libgen.h \ - limits.h \ - locale.h \ - math.h \ mntent.h \ mnttab.h \ netdb.h \ @@ -239,9 +175,6 @@ AC_CHECK_HEADERS([ \ pthread_np.h \ pwd.h \ regex.h \ - signal.h \ - stdarg.h \ - stdio.h \ sys/fs_types.h \ sys/fstyp.h \ sys/ioctl.h \ @@ -260,450 +193,469 @@ AC_CHECK_HEADERS([ \ sys/vfstab.h \ sys/vmmeter.h \ syslog.h \ - wordexp.h \ + wordexp.h ]) -# For entropy plugin on newer NetBSD -AC_CHECK_HEADERS(sys/rndio.h, [], [], -[#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_SYS_IOCTL_H -# include -#endif -#if HAVE_SYS_PARAM_H -# include -#endif -]) +if test "x$ac_system" = "xNetBSD"; then + # For entropy plugin on newer NetBSD + AC_CHECK_HEADERS([sys/rndio.h], [], [], + [[ + #if HAVE_SYS_TYPES_H + # include + #endif + #if HAVE_SYS_IOCTL_H + # include + #endif + #if HAVE_SYS_PARAM_H + # include + #endif + ]] + ) +fi # For ping library -AC_CHECK_HEADERS(netinet/in_systm.h, [], [], -[#if HAVE_STDINT_H -# include -#endif -#if HAVE_SYS_TYPES_H -# include -#endif -]) -AC_CHECK_HEADERS(netinet/in.h, [], [], -[#if HAVE_STDINT_H -# include -#endif -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_NETINET_IN_SYSTM_H -# include -#endif -]) -AC_CHECK_HEADERS(netinet/ip.h, [], [], -[#if HAVE_STDINT_H -# include -#endif -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_NETINET_IN_SYSTM_H -# include -#endif -#if HAVE_NETINET_IN_H -# include -#endif -]) -AC_CHECK_HEADERS(netinet/ip_icmp.h, [], [], -[#if HAVE_STDINT_H -# include -#endif -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_NETINET_IN_SYSTM_H -# include -#endif -#if HAVE_NETINET_IN_H -# include -#endif -#if HAVE_NETINET_IP_H -# include -#endif -]) -AC_CHECK_HEADERS(netinet/ip_var.h, [], [], -[#if HAVE_STDINT_H -# include -#endif -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_NETINET_IN_SYSTM_H -# include -#endif -#if HAVE_NETINET_IN_H -# include -#endif -#if HAVE_NETINET_IP_H -# include -#endif -]) -AC_CHECK_HEADERS(netinet/ip6.h, [], [], -[#if HAVE_STDINT_H -# include -#endif -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_NETINET_IN_SYSTM_H -# include -#endif -#if HAVE_NETINET_IN_H -# include -#endif -]) -AC_CHECK_HEADERS(netinet/icmp6.h, [], [], -[#if HAVE_STDINT_H -# include -#endif -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_NETINET_IN_SYSTM_H -# include -#endif -#if HAVE_NETINET_IN_H -# include -#endif -#if HAVE_NETINET_IP6_H -# include -#endif -]) -AC_CHECK_HEADERS(netinet/tcp.h, [], [], -[#if HAVE_STDINT_H -# include -#endif -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_NETINET_IN_SYSTM_H -# include -#endif -#if HAVE_NETINET_IN_H -# include -#endif -#if HAVE_NETINET_IP_H -# include -#endif -]) -AC_CHECK_HEADERS(netinet/udp.h, [], [], -[#if HAVE_STDINT_H -# include -#endif -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_NETINET_IN_SYSTM_H -# include -#endif -#if HAVE_NETINET_IN_H -# include -#endif -#if HAVE_NETINET_IP_H -# include -#endif -]) - -have_ip6_ext="no" -AC_CHECK_TYPES([struct ip6_ext], [have_ip6_ext="yes"], [have_ip6_ext="no"], -[#if HAVE_STDINT_H -# include -#endif -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_NETINET_IN_SYSTM_H -# include -#endif -#if HAVE_NETINET_IN_H -# include -#endif -#if HAVE_NETINET_IP6_H -# include -#endif -]) +AC_CHECK_HEADERS([netinet/in_systm.h], [], [], + [[ + #include + #if HAVE_SYS_TYPES_H + # include + #endif + ]] +) -if test "x$have_ip6_ext" = "xno"; then - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -DSOLARIS2=8" - - AC_CHECK_TYPES([struct ip6_ext], - [have_ip6_ext="yes, with -DSOLARIS2=8"], - [have_ip6_ext="no"], -[#if HAVE_STDINT_H -# include -#endif -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_NETINET_IN_SYSTM_H -# include -#endif -#if HAVE_NETINET_IN_H -# include -#endif -#if HAVE_NETINET_IP6_H -# include -#endif -]) +AC_CHECK_HEADERS([netinet/in.h], [], [], + [[ + #include + #if HAVE_SYS_TYPES_H + # include + #endif + #if HAVE_NETINET_IN_SYSTM_H + # include + #endif + ]] +) - if test "x$have_ip6_ext" = "xno"; then - CFLAGS="$SAVE_CFLAGS" - fi -fi +AC_CHECK_HEADERS([netinet/ip.h], [], [], + [[ + #include + #if HAVE_SYS_TYPES_H + # include + #endif + #if HAVE_NETINET_IN_SYSTM_H + # include + #endif + #if HAVE_NETINET_IN_H + # include + #endif + ]] +) -# For cpu modules -AC_CHECK_HEADERS(sys/dkstat.h) -if test "x$ac_system" = "xDarwin" -then - AC_CHECK_HEADERS(mach/mach_init.h mach/host_priv.h mach/mach_error.h mach/mach_host.h mach/mach_port.h mach/mach_types.h mach/message.h mach/processor_set.h mach/processor.h mach/processor_info.h mach/task.h mach/thread_act.h mach/vm_region.h mach/vm_map.h mach/vm_prot.h mach/vm_statistics.h mach/kern_return.h) - AC_CHECK_HEADERS(CoreFoundation/CoreFoundation.h IOKit/IOKitLib.h IOKit/IOTypes.h IOKit/ps/IOPSKeys.h IOKit/IOBSD.h IOKit/storage/IOBlockStorageDriver.h) - # For the battery plugin - AC_CHECK_HEADERS(IOKit/ps/IOPowerSources.h, [], [], -[ -#if HAVE_IOKIT_IOKITLIB_H -# include -#endif -#if HAVE_IOKIT_IOTYPES_H -# include -#endif -]) +AC_CHECK_HEADERS([netinet/ip_icmp.h], [], [], + [[ + #include + #if HAVE_SYS_TYPES_H + # include + #endif + #if HAVE_NETINET_IN_SYSTM_H + # include + #endif + #if HAVE_NETINET_IN_H + # include + #endif + #if HAVE_NETINET_IP_H + # include + #endif + ]] +) -fi +AC_CHECK_HEADERS([netinet/ip_var.h], [], [], + [[ + #include + #if HAVE_SYS_TYPES_H + # include + #endif + #if HAVE_NETINET_IN_SYSTM_H + # include + #endif + #if HAVE_NETINET_IN_H + # include + #endif + #if HAVE_NETINET_IP_H + # include + #endif + ]] +) -AC_CHECK_HEADERS(sys/sysctl.h, [], [], -[ -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_SYS_PARAM_H -# include -#endif -]) +AC_CHECK_HEADERS([netinet/ip6.h], [], [], + [[ + #include + #if HAVE_SYS_TYPES_H + # include + #endif + #if HAVE_NETINET_IN_SYSTM_H + # include + #endif + #if HAVE_NETINET_IN_H + # include + #endif + ]] +) -AC_MSG_CHECKING([for sysctl kern.cp_times]) -if test -x /sbin/sysctl -then - /sbin/sysctl kern.cp_times >/dev/null 2>&1 - if test $? -eq 0 - then - AC_MSG_RESULT([yes]) - AC_DEFINE(HAVE_SYSCTL_KERN_CP_TIMES, 1, - [Define if sysctl supports kern.cp_times]) - else - AC_MSG_RESULT([no]) - fi -else - AC_MSG_RESULT([no]) -fi +AC_CHECK_HEADERS([netinet/icmp6.h], [], [], + [[ + #include + #if HAVE_SYS_TYPES_H + # include + #endif + #if HAVE_NETINET_IN_SYSTM_H + # include + #endif + #if HAVE_NETINET_IN_H + # include + #endif + #if HAVE_NETINET_IP6_H + # include + #endif + ]] +) -AC_MSG_CHECKING([for sysctl kern.cp_time]) -if test -x /sbin/sysctl -then - /sbin/sysctl kern.cp_time >/dev/null 2>&1 - if test $? -eq 0 - then - AC_MSG_RESULT([yes]) - AC_DEFINE(HAVE_SYSCTL_KERN_CP_TIME, 1, - [Define if sysctl supports kern.cp_time]) - else - AC_MSG_RESULT([no]) - fi -else - AC_MSG_RESULT([no]) -fi +AC_CHECK_HEADERS([netinet/tcp.h], [], [], + [[ + #include + #if HAVE_SYS_TYPES_H + # include + #endif + #if HAVE_NETINET_IN_SYSTM_H + # include + #endif + #if HAVE_NETINET_IN_H + # include + #endif + #if HAVE_NETINET_IP_H + # include + #endif + ]] +) -# For hddtemp module -AC_CHECK_HEADERS(linux/major.h) +AC_CHECK_HEADERS([netinet/udp.h], [], [], + [[ + #include + #if HAVE_SYS_TYPES_H + # include + #endif + #if HAVE_NETINET_IN_SYSTM_H + # include + #endif + #if HAVE_NETINET_IN_H + # include + #endif + #if HAVE_NETINET_IP_H + # include + #endif + ]] +) -# For md module (Linux only) -if test "x$ac_system" = "xLinux" -then - AC_CHECK_HEADERS(linux/raid/md_u.h, - [have_linux_raid_md_u_h="yes"], - [have_linux_raid_md_u_h="no"], -[ -#include -#include -#include -]) - AC_CHECK_HEADERS([sys/sysmacros.h]) -else - have_linux_raid_md_u_h="no" -fi +# For cpu modules +AC_CHECK_HEADERS([sys/dkstat.h]) +if test "x$ac_system" = "xDarwin"; then + AC_CHECK_HEADERS( + [[ \ + mach/mach_init.h \ + mach/host_priv.h \ + mach/mach_error.h \ + mach/mach_host.h \ + mach/mach_port.h \ + mach/mach_types.h \ + mach/message.h \ + mach/processor_set.h \ + mach/processor.h \ + mach/processor_info.h \ + mach/task.h \ + mach/thread_act.h \ + mach/vm_region.h \ + mach/vm_map.h \ + mach/vm_prot.h \ + mach/vm_statistics.h \ + mach/kern_return.h \ + CoreFoundation/CoreFoundation.h \ + IOKit/IOKitLib.h \ + IOKit/IOTypes.h \ + IOKit/ps/IOPSKeys.h \ + IOKit/IOBSD.h \ + IOKit/storage/IOBlockStorageDriver.h + ]] + ) -# For the wireless module -have_linux_wireless_h="no" -if test "x$ac_system" = "xLinux" -then - AC_CHECK_HEADERS(linux/wireless.h, - [have_linux_wireless_h="yes"], - [have_linux_wireless_h="no"], -[ -#include -#include -#include -]) + # For the battery plugin + AC_CHECK_HEADERS([IOKit/ps/IOPowerSources.h], [], [], + [[ + #if HAVE_IOKIT_IOKITLIB_H + # include + #endif + #if HAVE_IOKIT_IOTYPES_H + # include + #endif + ]] + ) fi -# For the swap module -have_sys_swap_h="yes" -AC_CHECK_HEADERS(sys/swap.h vm/anon.h, [], [have_sys_swap_h="no"], -[ -#undef _FILE_OFFSET_BITS -#undef _LARGEFILE64_SOURCE -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_SYS_PARAM_H -# include -#endif -]) - -# For load module -# For the processes plugin -# For users module -AC_CHECK_HEADERS(sys/loadavg.h linux/config.h utmp.h utmpx.h) +AC_CHECK_HEADERS([sys/sysctl.h], [], [], + [[ + #if HAVE_SYS_TYPES_H + # include + #endif + #if HAVE_SYS_PARAM_H + # include + #endif + ]] +) # For interface plugin -AC_CHECK_HEADERS(ifaddrs.h) -AC_CHECK_HEADERS(net/if.h, [], [], -[ -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_SYS_SOCKET_H -# include -#endif -]) -AC_CHECK_HEADERS(linux/if.h, [], [], -[ -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_SYS_SOCKET_H -# include -#endif -]) -AC_CHECK_HEADERS(linux/inet_diag.h, [], [], -[ -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_SYS_SOCKET_H -# include -#endif -#if HAVE_LINUX_INET_DIAG_H -# include -#endif -]) -AC_CHECK_HEADERS(linux/netdevice.h, [], [], -[ -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_SYS_SOCKET_H -# include -#endif -#if HAVE_LINUX_IF_H -# include -#endif -]) +AC_CHECK_HEADERS([ifaddrs.h]) +AC_CHECK_HEADERS([net/if.h], [], [], + [[ + #if HAVE_SYS_TYPES_H + # include + #endif + #if HAVE_SYS_SOCKET_H + # include + #endif + ]] +) + +if test "x$ac_system" = "xLinux"; then + # For hddtemp module + AC_CHECK_HEADERS([linux/major.h]) + + # For md module (Linux only) + AC_CHECK_HEADERS([linux/raid/md_u.h], + [have_linux_raid_md_u_h="yes"], + [have_linux_raid_md_u_h="no"], + [[ + #include + #include + #include + ]] + ) + AC_CHECK_HEADERS([sys/sysmacros.h]) + + AC_CHECK_HEADERS([linux/wireless.h], + [have_linux_wireless_h="yes"], + [have_linux_wireless_h="no"], + [[ + #include + #include + #include + ]] + ) -# For ethstat module -AC_CHECK_HEADERS(linux/sockios.h, + AC_CHECK_HEADERS([linux/if.h], [], [], + [[ + #if HAVE_SYS_TYPES_H + # include + #endif + #if HAVE_SYS_SOCKET_H + # include + #endif + ]] + ) + + AC_CHECK_HEADERS([linux/inet_diag.h], [], [], + [[ + #if HAVE_SYS_TYPES_H + # include + #endif + #if HAVE_SYS_SOCKET_H + # include + #endif + ]] + ) + + AC_CHECK_HEADERS([linux/netdevice.h], [], [], + [[ + #if HAVE_SYS_TYPES_H + # include + #endif + #if HAVE_SYS_SOCKET_H + # include + #endif + #if HAVE_LINUX_IF_H + # include + #endif + ]] + ) + + # For ethstat module + AC_CHECK_HEADERS([linux/sockios.h], [have_linux_sockios_h="yes"], [have_linux_sockios_h="no"], - [ -#if HAVE_SYS_IOCTL_H -# include -#endif -#if HAVE_NET_IF_H -# include -#endif - ]) -AC_CHECK_HEADERS(linux/ethtool.h, + [[ + #if HAVE_SYS_IOCTL_H + # include + #endif + #if HAVE_NET_IF_H + # include + #endif + ]] + ) + + AC_CHECK_HEADERS([linux/ethtool.h], [have_linux_ethtool_h="yes"], [have_linux_ethtool_h="no"], - [ -#if HAVE_SYS_IOCTL_H -# include -#endif -#if HAVE_NET_IF_H -# include -#endif -#if HAVE_LINUX_SOCKIOS_H -# include -#endif - ]) - -# For ipvs module -have_linux_ip_vs_h="no" -have_net_ip_vs_h="no" -have_ip_vs_h="no" -ip_vs_h_needs_kernel_cflags="no" -if test "x$ac_system" = "xLinux" -then - AC_CHECK_HEADERS(linux/ip_vs.h, [have_linux_ip_vs_h="yes"]) - AC_CHECK_HEADERS(net/ip_vs.h, [have_net_ip_vs_h="yes"]) - AC_CHECK_HEADERS(ip_vs.h, [have_ip_vs_h="yes"]) + [[ + #if HAVE_SYS_IOCTL_H + # include + #endif + #if HAVE_NET_IF_H + # include + #endif + #if HAVE_LINUX_SOCKIOS_H + # include + #endif + ]] + ) - if test "x$have_linux_ip_vs_h$have_net_ip_vs_h$have_ip_vs_h" = "xnonono" && test -d "$KERNEL_DIR" - then - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $KERNEL_CFLAGS" + # For ipvs module + AC_CHECK_HEADERS([linux/ip_vs.h], [have_linux_ip_vs_h="yes"], [have_linux_ip_vs="no"]) + AC_CHECK_HEADERS([net/ip_vs.h], [have_net_ip_vs_h="yes"], [have_net_ip_vs_h="no"]) + AC_CHECK_HEADERS([ip_vs.h], [have_ip_vs_h="yes"], [have_ip_vs_h="no"]) + + ip_vs_h_needs_kernel_cflags="no" + + if test "x$have_linux_ip_vs_h$have_net_ip_vs_h$have_ip_vs_h" = "xnonono" && test -d "$KERNEL_DIR"; then + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $KERNEL_CFLAGS" + + AC_MSG_NOTICE([Did not find ip_vs.h. Trying again using headers from $KERNEL_DIR.]) + + AC_CHECK_HEADERS([linux/ip_vs.h], [have_linux_ip_vs_h="yes"]) + AC_CHECK_HEADERS([net/ip_vs.h], [have_net_ip_vs_h="yes"]) + AC_CHECK_HEADERS([ip_vs.h], [have_ip_vs_h="yes"]) + + if test "x$have_linux_ip_vs_h" = "xyes" || test "x$have_net_ip_vs_h" = "xyes" || test "x$have_ip_vs_h" = "xyes"; then + ip_vs_h_needs_kernel_cflags="yes" + fi + + CFLAGS="$SAVE_CFLAGS" + fi + + # For the email plugin + AC_CHECK_HEADERS([linux/un.h], [], [], + [[ + #if HAVE_SYS_SOCKET_H + # include + #endif + ]] + ) + # For the turbostat plugin + AC_CHECK_HEADERS([asm/msr-index.h], + [have_asm_msrindex_h="yes"], + [have_asm_msrindex_h="no"] + ) + + if test "x$have_asm_msrindex_h" = "xyes"; then + AC_CACHE_CHECK([whether asm/msr-index.h has MSR_PKG_C10_RESIDENCY], + [c_cv_have_usable_asm_msrindex_h], + [ + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM( + [[#include]], + [[ + int y = MSR_PKG_C10_RESIDENCY; + return(y); + ]] + ) + ], + [c_cv_have_usable_asm_msrindex_h="yes"], + [c_cv_have_usable_asm_msrindex_h="no"], + ) + ] + ) + fi + + AC_CHECK_HEADERS([cpuid.h], + [have_cpuid_h="yes"], + [have_cpuid_h="no (cpuid.h not found)"] + ) + + AC_CHECK_HEADERS([sys/capability.h], + [have_capability="yes"], + [have_capability="no ( not found)"] + ) - AC_MSG_NOTICE([Did not find ip_vs.h. Trying again using headers from $KERNEL_DIR.]) + if test "x$have_capability" = "xyes"; then + AC_CHECK_LIB([cap], [cap_get_proc], + [have_capability="yes"], + [have_capability="no (cap_get_proc() not found)"] + ) + fi - AC_CHECK_HEADERS(linux/ip_vs.h, [have_linux_ip_vs_h="yes"]) - AC_CHECK_HEADERS(net/ip_vs.h, [have_net_ip_vs_h="yes"]) - AC_CHECK_HEADERS(ip_vs.h, [have_ip_vs_h="yes"]) + if test "x$have_capability" = "xyes"; then + AC_CHECK_DECL([CAP_IS_SUPPORTED], + [have_capability="yes"], + [have_capability="no (CAP_IS_SUPPORTED not found)"], + [[#include ]] + ) + fi - if test "x$have_linux_ip_vs_h" = "xyes" || test "x$have_net_ip_vs_h" = "xyes" || test "x$have_ip_vs_h" = "xyes" - then - ip_vs_h_needs_kernel_cflags="yes" - fi + if test "x$have_capability" = "xyes"; then + AC_DEFINE([HAVE_CAPABILITY], [1], [Define to 1 if you have cap_get_proc() (-lcap).]) + fi - CFLAGS="$SAVE_CFLAGS" - fi +else + have_linux_raid_md_u_h="no" + have_linux_wireless_h="no" fi -AM_CONDITIONAL(IP_VS_H_NEEDS_KERNEL_CFLAGS, test "x$ip_vs_h_needs_kernel_cflags" = "xyes") + +AM_CONDITIONAL([IP_VS_H_NEEDS_KERNEL_CFLAGS], [test "x$ip_vs_h_needs_kernel_cflags" = "xyes"]) +AM_CONDITIONAL([BUILD_WITH_CAPABILITY], [test "x$have_capability" = "xyes"]) + +# For the swap module +have_sys_swap_h="yes" +AC_CHECK_HEADERS([sys/swap.h vm/anon.h], + [], + [have_sys_swap_h="no"], + [[ + #undef _FILE_OFFSET_BITS + #undef _LARGEFILE64_SOURCE + #if HAVE_SYS_TYPES_H + # include + #endif + #if HAVE_SYS_PARAM_H + # include + #endif + ]] +) + +# For load module +# For the processes plugin +# For users module +AC_CHECK_HEADERS([sys/loadavg.h linux/config.h utmp.h utmpx.h]) # For quota module -AC_CHECK_HEADERS(sys/ucred.h, [], [], -[ -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_SYS_PARAM_H -# include -#endif -]) +AC_CHECK_HEADERS([sys/ucred.h], [], [], + [[ + #if HAVE_SYS_TYPES_H + # include + #endif + #if HAVE_SYS_PARAM_H + # include + #endif + ]] +) # For mount interface -AC_CHECK_HEADERS(sys/mount.h, [], [], -[ -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_SYS_PARAM_H -# include -#endif -]) - -# For the email plugin -AC_CHECK_HEADERS(linux/un.h, [], [], -[ -#if HAVE_SYS_SOCKET_H -# include -#endif -]) +AC_CHECK_HEADERS([sys/mount.h], [], [], + [[ + #if HAVE_SYS_TYPES_H + # include + #endif + #if HAVE_SYS_PARAM_H + # include + #endif + ]] +) # --enable-xfs {{{ AC_ARG_ENABLE([xfs], @@ -727,128 +679,95 @@ fi # }}} # For the dns plugin -AC_CHECK_HEADERS(arpa/nameser.h) -AC_CHECK_HEADERS(arpa/nameser_compat.h, [], [], -[ -#if HAVE_ARPA_NAMESER_H -# include -#endif -]) +AC_CHECK_HEADERS([arpa/nameser.h]) +AC_CHECK_HEADERS([arpa/nameser_compat.h], [], [], + [[ + #if HAVE_ARPA_NAMESER_H + # include + #endif + ]] +) -AC_CHECK_HEADERS(net/if_arp.h, [], [], -[#if HAVE_SYS_SOCKET_H -# include -#endif -]) -AC_CHECK_HEADERS(net/ppp_defs.h) -AC_CHECK_HEADERS(net/if_ppp.h, [], [], -[#if HAVE_NET_PPP_DEFS_H -# include -#endif -]) -AC_CHECK_HEADERS(netinet/if_ether.h, [], [], -[#if HAVE_STDINT_H -# include -#endif -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_SYS_SOCKET_H -# include -#endif -#if HAVE_NET_IF_H -# include -#endif -#if HAVE_NETINET_IN_H -# include -#endif -]) +AC_CHECK_HEADERS([net/if_arp.h], [], [], + [[ + #if HAVE_SYS_SOCKET_H + # include + #endif + ]] +) -have_net_pfvar_h="no" -AC_CHECK_HEADERS(net/pfvar.h, - [have_net_pfvar_h="yes"], - [have_net_pfvar_h="no"], -[ -#if HAVE_SYS_IOCTL_H -# include -#endif -#if HAVE_SYS_SOCKET_H -# include -#endif -#if HAVE_NET_IF_H -# include -#endif -#if HAVE_NETINET_IN_H -# include -#endif -]) +AC_CHECK_HEADERS([net/ppp_defs.h]) +AC_CHECK_HEADERS([net/if_ppp.h], [], [], + [[ + #if HAVE_NET_PPP_DEFS_H + # include + #endif + ]] +) + +AC_CHECK_HEADERS([netinet/if_ether.h], [], [], + [[ + #include + #if HAVE_SYS_TYPES_H + # include + #endif + #if HAVE_SYS_SOCKET_H + # include + #endif + #if HAVE_NET_IF_H + # include + #endif + #if HAVE_NETINET_IN_H + # include + #endif + ]] +) + +AC_CHECK_HEADERS([net/pfvar.h], + [have_net_pfvar_h="yes"], + [have_net_pfvar_h="no"], + [[ + #if HAVE_SYS_IOCTL_H + # include + #endif + #if HAVE_SYS_SOCKET_H + # include + #endif + #if HAVE_NET_IF_H + # include + #endif + #if HAVE_NETINET_IN_H + # include + #endif + ]] +) # For the multimeter plugin -have_termios_h="no" -AC_CHECK_HEADERS(termios.h, [have_termios_h="yes"]) +AC_CHECK_HEADERS([termios.h], + [have_termios_h="yes"], + [have_termios_h="no"] +) # For cpusleep plugin AC_CACHE_CHECK([whether clock_boottime and clock_monotonic are supported], - [c_cv_have_clock_boottime_monotonic], - AC_COMPILE_IFELSE([AC_LANG_PROGRAM( -[[ -#include -]], -[[ - struct timespec b, m; - clock_gettime(CLOCK_BOOTTIME, &b ); - clock_gettime(CLOCK_MONOTONIC, &m ); -]] - )], - [c_cv_have_clock_boottime_monotonic="yes"], - [c_cv_have_clock_boottime_monotonic="no"])) - - -# For the turbostat plugin -have_asm_msrindex_h="no" -AC_CHECK_HEADERS(asm/msr-index.h, [have_asm_msrindex_h="yes"]) - -if test "x$have_asm_msrindex_h" = "xyes" -then - AC_CACHE_CHECK([whether asm/msr-index.h has MSR_PKG_C10_RESIDENCY], - [c_cv_have_usable_asm_msrindex_h], - AC_COMPILE_IFELSE([AC_LANG_PROGRAM( -[[[ -#include -]]], -[[[ -int y = MSR_PKG_C10_RESIDENCY; -return(y); -]]] - )], - [c_cv_have_usable_asm_msrindex_h="yes"], - [c_cv_have_usable_asm_msrindex_h="no"], - ) - ) -fi - -have_cpuid_h="no" -AC_CHECK_HEADERS(cpuid.h, [have_cpuid_h="yes"]) - -have_capability="yes" -AC_CHECK_HEADERS(sys/capability.h, - [have_capability="yes"], - [have_capability="no ( not found)"]) -if test "x$have_capability" = "xyes"; then -AC_CHECK_LIB(cap, cap_get_proc, - [have_capability="yes"], - [have_capability="no (cap_get_proc() not found)"]) -fi -if test "x$have_capability" = "xyes"; then -AC_CHECK_DECL([CAP_IS_SUPPORTED], - [have_capability="yes"], - [have_capability="no (CAP_IS_SUPPORTED not found)"], - [[#include ]]) -fi -if test "x$have_capability" = "xyes"; then - AC_DEFINE(HAVE_CAPABILITY, 1, [Define to 1 if you have cap_get_proc() (-lcap).]) -fi -AM_CONDITIONAL(BUILD_WITH_CAPABILITY, test "x$have_capability" = "xyes") + [c_cv_have_clock_boottime_monotonic], + [ + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[ + struct timespec b, m; + clock_gettime(CLOCK_BOOTTIME, &b ); + clock_gettime(CLOCK_MONOTONIC, &m ); + ]] + ) + ], + [c_cv_have_clock_boottime_monotonic="yes"], + [c_cv_have_clock_boottime_monotonic="no"] + ) + ] +) + # # Checks for typedefs, structures, and compiler characteristics. @@ -859,1412 +778,1602 @@ AC_TYPE_SIZE_T AC_TYPE_UID_T AC_HEADER_TIME +test_cxx_flags() { + AC_LANG_PUSH([C++]) + AC_LANG_CONFTEST( + [AC_LANG_SOURCE([[int main(void){}]]) ] + ) + $CXX -c conftest.cpp $CXXFLAGS $@ > /dev/null 2> /dev/null + ret=$? + rm -f conftest.o + AC_LANG_POP([C++]) + return $ret +} + # # Checks for library functions. # -AC_CHECK_FUNCS(gettimeofday select strdup strtol getaddrinfo getnameinfo strchr memcpy strstr strcmp strncmp strncpy strlen strncasecmp strcasecmp openlog closelog sysconf setenv if_indextoname setlocale asprintf) +AC_CHECK_FUNCS_ONCE([ \ + asprintf \ + closelog \ + getaddrinfo \ + getgrnam_r \ + getnameinfo \ + getpwnam_r \ + gettimeofday \ + if_indextoname \ + openlog \ + regcomp \ + regerror \ + regexec \ + regfree \ + select \ + setenv \ + setgroups \ + strcasecmp \ + strdup \ + strncasecmp \ + sysconf + ] +) AC_FUNC_STRERROR_R -test_cxx_flags() { - AC_LANG_PUSH([C++]) - AC_LANG_CONFTEST([ - AC_LANG_SOURCE([[int main(void){}]]) - ]) - $CXX -c conftest.cpp $CXXFLAGS $@ > /dev/null 2> /dev/null - ret=$? - rm -f conftest.o - AC_LANG_POP([C++]) - return $ret -} - SAVE_CFLAGS="$CFLAGS" # Emulate behavior of src/Makefile.am -if test "x$GCC" = "xyes" -then - CFLAGS="$CFLAGS -Wall -Werror" +if test "x$GCC" = "xyes"; then + CFLAGS="$CFLAGS -Wall -Werror" fi AC_CACHE_CHECK([for strtok_r], [c_cv_have_strtok_r_default], - AC_LINK_IFELSE( - [AC_LANG_PROGRAM( -[[[ -#include -#include -#include -]]], -[[[ - char buffer[] = "foo,bar,baz"; - char *token; - char *dummy; - char *saveptr; - - dummy = buffer; - saveptr = NULL; - while ((token = strtok_r (dummy, ",", &saveptr)) != NULL) - { - dummy = NULL; - printf ("token = %s;\n", token); - } -]]] - )], - [c_cv_have_strtok_r_default="yes"], - [c_cv_have_strtok_r_default="no"] - ) + [ + AC_LINK_IFELSE( + [ + AC_LANG_PROGRAM( + [[ + #include + #include + #include + ]], + [[ + char buffer[] = "foo,bar,baz"; + char *token; + char *dummy; + char *saveptr; + + dummy = buffer; + saveptr = NULL; + while ((token = strtok_r (dummy, ",", &saveptr)) != NULL) + { + dummy = NULL; + printf ("token = %s;\n", token); + } + ]] + ) + ], + [c_cv_have_strtok_r_default="yes"], + [c_cv_have_strtok_r_default="no"] + ) + ] ) -if test "x$c_cv_have_strtok_r_default" = "xno" -then +if test "x$c_cv_have_strtok_r_default" = "xno"; then CFLAGS="$CFLAGS -D_REENTRANT=1" AC_CACHE_CHECK([if strtok_r needs _REENTRANT], [c_cv_have_strtok_r_reentrant], - AC_LINK_IFELSE( - [AC_LANG_PROGRAM( -[[[ -#include -#include -#include -]]], -[[[ - char buffer[] = "foo,bar,baz"; - char *token; - char *dummy; - char *saveptr; - - dummy = buffer; - saveptr = NULL; - while ((token = strtok_r (dummy, ",", &saveptr)) != NULL) - { - dummy = NULL; - printf ("token = %s;\n", token); - } -]]] - )], - [c_cv_have_strtok_r_reentrant="yes"], - [AC_MSG_FAILURE([strtok_r isn't available. Please file a bugreport!])] - ) + [ + AC_LINK_IFELSE( + [ + AC_LANG_PROGRAM( + [[ + #include + #include + #include + ]], + [[ + char buffer[] = "foo,bar,baz"; + char *token; + char *dummy; + char *saveptr; + + dummy = buffer; + saveptr = NULL; + while ((token = strtok_r (dummy, ",", &saveptr)) != NULL) + { + dummy = NULL; + printf ("token = %s;\n", token); + } + ]] + ) + ], + [c_cv_have_strtok_r_reentrant="yes"], + [AC_MSG_FAILURE([strtok_r is not available. Please file a bugreport!])] + ) + ] ) fi CFLAGS="$SAVE_CFLAGS" -if test "x$c_cv_have_strtok_r_reentrant" = "xyes" -then - CFLAGS="$CFLAGS -D_REENTRANT=1" +if test "x$c_cv_have_strtok_r_reentrant" = "xyes"; then + CFLAGS="$CFLAGS -D_REENTRANT=1" fi -AC_CHECK_FUNCS(getpwnam_r getgrnam_r setgroups regcomp regerror regexec regfree) - -socket_needs_socket="no" -AC_CHECK_FUNCS(socket, [], AC_CHECK_LIB(socket, socket, [socket_needs_socket="yes"], AC_MSG_ERROR(cannot find socket))) -AM_CONDITIONAL(BUILD_WITH_LIBSOCKET, test "x$socket_needs_socket" = "xyes") +AC_CHECK_FUNCS([socket], + [], + [ + AC_CHECK_LIB([socket], [socket], + [socket_needs_socket="yes"], + [AC_MSG_ERROR([cannot find socket() in libsocket])] + ) + ] +) +AM_CONDITIONAL([BUILD_WITH_LIBSOCKET], [test "x$socket_needs_socket" = "xyes"]) -clock_gettime_needs_rt="no" clock_gettime_needs_posix4="no" -have_clock_gettime="no" -AC_CHECK_FUNCS(clock_gettime, [have_clock_gettime="yes"]) -if test "x$have_clock_gettime" = "xno" -then - AC_CHECK_LIB(rt, clock_gettime, [clock_gettime_needs_rt="yes" - have_clock_gettime="yes"]) -fi -if test "x$have_clock_gettime" = "xno" -then - AC_CHECK_LIB(posix4, clock_gettime, [clock_gettime_needs_posix4="yes" - have_clock_gettime="yes"]) -fi -if test "x$have_clock_gettime" = "xyes" -then - AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [Define if the clock_gettime(2) function is available.]) +AC_CHECK_FUNCS([clock_gettime], + [have_clock_gettime="yes"], + [have_clock_gettime="no"] +) + +if test "x$have_clock_gettime" = "xno"; then + AC_CHECK_LIB([rt], [clock_gettime], + [ + clock_gettime_needs_rt="yes" + have_clock_gettime="yes" + ] + ) fi -nanosleep_needs_rt="no" -nanosleep_needs_posix4="no" -AC_CHECK_FUNCS(nanosleep, - [], - AC_CHECK_LIB(rt, nanosleep, - [nanosleep_needs_rt="yes"], - AC_CHECK_LIB(posix4, nanosleep, - [nanosleep_needs_posix4="yes"], - AC_MSG_ERROR(cannot find nanosleep)))) - -AM_CONDITIONAL(BUILD_WITH_LIBRT, test "x$clock_gettime_needs_rt" = "xyes" || test "x$nanosleep_needs_rt" = "xyes") -AM_CONDITIONAL(BUILD_WITH_LIBPOSIX4, test "x$clock_gettime_needs_posix4" = "xyes" || test "x$nanosleep_needs_posix4" = "xyes") - -AC_CHECK_FUNCS(sysctl, [have_sysctl="yes"], [have_sysctl="no"]) -AC_CHECK_FUNCS(sysctlbyname, [have_sysctlbyname="yes"], [have_sysctlbyname="no"]) -AC_CHECK_FUNCS(host_statistics, [have_host_statistics="yes"], [have_host_statistics="no"]) -AC_CHECK_FUNCS(processor_info, [have_processor_info="yes"], [have_processor_info="no"]) -AC_CHECK_FUNCS(thread_info, [have_thread_info="yes"], [have_thread_info="no"]) -AC_CHECK_FUNCS(statfs, [have_statfs="yes"], [have_statfs="no"]) -AC_CHECK_FUNCS(statvfs, [have_statvfs="yes"], [have_statvfs="no"]) -AC_CHECK_FUNCS(getifaddrs, [have_getifaddrs="yes"], [have_getifaddrs="no"]) -AC_CHECK_FUNCS(getloadavg, [have_getloadavg="yes"], [have_getloadavg="no"]) -AC_CHECK_FUNCS(syslog, [have_syslog="yes"], [have_syslog="no"]) -AC_CHECK_FUNCS(getutent, [have_getutent="yes"], [have_getutent="no"]) -AC_CHECK_FUNCS(getutxent, [have_getutxent="yes"], [have_getutxent="no"]) +if test "x$have_clock_gettime" = "xno"; then + AC_CHECK_LIB([posix4], [clock_gettime], + [ + clock_gettime_needs_posix4="yes" + have_clock_gettime="yes" + ] + ) +fi -# Check for strptime {{{ -if test "x$GCC" = "xyes" -then - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Wall -Wextra -Werror" +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(strptime, [have_strptime="yes"], [have_strptime="no"]) -if test "x$have_strptime" = "xyes" -then - AC_CACHE_CHECK([whether strptime is exported by default], - [c_cv_have_strptime_default], - AC_COMPILE_IFELSE([AC_LANG_PROGRAM( -[[[ -#include -]]], -[[[ - struct tm stm; - (void) strptime ("2010-12-30%13:42:42", "%Y-%m-%dT%T", &stm); -]]] - )], - [c_cv_have_strptime_default="yes"], - [c_cv_have_strptime_default="no"])) -fi -if test "x$have_strptime" = "xyes" && test "x$c_cv_have_strptime_default" = "xno" -then - AC_CACHE_CHECK([whether strptime needs standards mode], - [c_cv_have_strptime_standards], - AC_COMPILE_IFELSE([AC_LANG_PROGRAM( -[[[ -#ifndef _ISOC99_SOURCE -# define _ISOC99_SOURCE 1 -#endif -#ifndef _POSIX_C_SOURCE -# define _POSIX_C_SOURCE 200112L -#endif -#ifndef _XOPEN_SOURCE -# define _XOPEN_SOURCE 500 -#endif -#include -]]], -[[[ - struct tm stm; - (void) strptime ("2010-12-30%13:42:42", "%Y-%m-%dT%T", &stm); -]]] - )], - [c_cv_have_strptime_standards="yes"], - [c_cv_have_strptime_standards="no"])) - - if test "x$c_cv_have_strptime_standards" = "xyes" - then - AC_DEFINE([STRPTIME_NEEDS_STANDARDS], 1, [Set to true if strptime is only exported in X/Open mode (GNU libc).]) - else - have_strptime="no" - fi +AC_CHECK_FUNCS([nanosleep], [], + AC_CHECK_LIB([rt], [nanosleep], + [nanosleep_needs_rt="yes"], + [ + AC_CHECK_LIB([posix4], [nanosleep], + [nanosleep_needs_posix4="yes"], + [AC_MSG_ERROR([cannot find nanosleep])] + ) + ] + ) +) + +AM_CONDITIONAL([BUILD_WITH_LIBRT], [test "x$clock_gettime_needs_rt" = "xyes" || test "x$nanosleep_needs_rt" = "xyes"]) +AM_CONDITIONAL([BUILD_WITH_LIBPOSIX4], [test "x$clock_gettime_needs_posix4" = "xyes" || test "x$nanosleep_needs_posix4" = "xyes"]) + +AC_CHECK_FUNCS([getifaddrs], [have_getifaddrs="yes"], [have_getifaddrs="no"]) +AC_CHECK_FUNCS([getloadavg], [have_getloadavg="yes"], [have_getloadavg="no"]) +AC_CHECK_FUNCS([getutent], [have_getutent="yes"], [have_getutent="no"]) +AC_CHECK_FUNCS([getutxent], [have_getutxent="yes"], [have_getutxent="no"]) +AC_CHECK_FUNCS([host_statistics], [have_host_statistics="yes"], [have_host_statistics="no"]) +AC_CHECK_FUNCS([processor_info], [have_processor_info="yes"], [have_processor_info="no"]) +AC_CHECK_FUNCS([statfs], [have_statfs="yes"], [have_statfs="no"]) +AC_CHECK_FUNCS([statvfs], [have_statvfs="yes"], [have_statvfs="no"]) +AC_CHECK_FUNCS([sysctl], [have_sysctl="yes"], [have_sysctl="no"]) +AC_CHECK_FUNCS([sysctlbyname], [have_sysctlbyname="yes"], [have_sysctlbyname="no"]) +AC_CHECK_FUNCS([syslog], [have_syslog="yes"], [have_syslog="no"]) +AC_CHECK_FUNCS([thread_info], [have_thread_info="yes"], [have_thread_info="no"]) + +# Check for strptime {{{ +if test "x$GCC" = "xyes"; then + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wall -Wextra -Werror" fi -if test "x$GCC" = "xyes" -then - CFLAGS="$SAVE_CFLAGS" +AC_CHECK_FUNCS([strptime], [have_strptime="yes"], [have_strptime="no"]) +if test "x$have_strptime" = "xyes"; then + AC_CACHE_CHECK([whether strptime is exported by default], + [c_cv_have_strptime_default], + [ + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM( + [[#include ]], + [[ + struct tm stm; + (void)strptime ("2010-12-30%13:42:42", "%Y-%m-%dT%T", &stm); + ]] + ) + ], + [c_cv_have_strptime_default="yes"], + [c_cv_have_strptime_default="no"]) + ] + ) +fi + +if test "x$have_strptime" = "xyes" && test "x$c_cv_have_strptime_default" = "xno"; then + AC_CACHE_CHECK([whether strptime needs standards mode], + [c_cv_have_strptime_standards], + [ + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM( + [[ + #ifndef _ISOC99_SOURCE + # define _ISOC99_SOURCE 1 + #endif + #ifndef _POSIX_C_SOURCE + # define _POSIX_C_SOURCE 200112L + #endif + #ifndef _XOPEN_SOURCE + # define _XOPEN_SOURCE 500 + #endif + #include + ]], + [[ + struct tm stm; + (void)strptime ("2010-12-30%13:42:42", "%Y-%m-%dT%T", &stm); + ]] + ) + ], + [c_cv_have_strptime_standards="yes"], + [c_cv_have_strptime_standards="no"] + ) + ] + ) + + if test "x$c_cv_have_strptime_standards" = "xyes"; then + AC_DEFINE([STRPTIME_NEEDS_STANDARDS], [1], + [Set to true if strptime is only exported in X/Open mode (GNU libc).] + ) + else + have_strptime="no" + fi +fi + +if test "x$GCC" = "xyes"; then + CFLAGS="$SAVE_CFLAGS" fi # }}} Check for strptime -AC_CHECK_FUNCS(swapctl, [have_swapctl="yes"], [have_swapctl="no"]) +AC_MSG_CHECKING([for sysctl kern.cp_times]) +if test -x /sbin/sysctl; then + /sbin/sysctl kern.cp_times >/dev/null 2>&1 + if test $? -eq 0; then + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_SYSCTL_KERN_CP_TIMES], [1], [Define if sysctl supports kern.cp_times]) + else + AC_MSG_RESULT([no]) + fi +else + AC_MSG_RESULT([no]) +fi + +AC_MSG_CHECKING([for sysctl kern.cp_time]) +if test -x /sbin/sysctl; then + /sbin/sysctl kern.cp_time >/dev/null 2>&1 + if test $? -eq 0 + then + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_SYSCTL_KERN_CP_TIME], [1], [Define if sysctl supports kern.cp_time]) + else + AC_MSG_RESULT([no]) + fi +else + AC_MSG_RESULT([no]) +fi + +AC_CHECK_FUNCS([swapctl], [have_swapctl="yes"], [have_swapctl="no"]) if test "x$have_swapctl" = "xyes"; then - AC_CACHE_CHECK([whether swapctl takes two arguments], - [c_cv_have_swapctl_two_args], - AC_COMPILE_IFELSE([AC_LANG_PROGRAM( -[[[ -#if HAVE_SYS_SWAP_H && !defined(_LP64) && _FILE_OFFSET_BITS == 64 -# undef _FILE_OFFSET_BITS -# undef _LARGEFILE64_SOURCE -#endif -#include -#include -#include -#include -]]], -[[[ -int num = swapctl(0, NULL); -]]] - )], - [c_cv_have_swapctl_two_args="yes"], - [c_cv_have_swapctl_two_args="no"] - ) - ) - AC_CACHE_CHECK([whether swapctl takes three arguments], - [c_cv_have_swapctl_three_args], - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( -[[[ -#if HAVE_SYS_SWAP_H && !defined(_LP64) && _FILE_OFFSET_BITS == 64 -# undef _FILE_OFFSET_BITS -# undef _LARGEFILE64_SOURCE -#endif -#include -#include -#include -#include -]]], -[[[ -int num = swapctl(0, NULL, 0); -]]] - )], - [c_cv_have_swapctl_three_args="yes"], - [c_cv_have_swapctl_three_args="no"] - ) - ) + AC_CACHE_CHECK([whether swapctl takes two arguments], + [c_cv_have_swapctl_two_args], + [ + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM( + [[ + #if HAVE_SYS_SWAP_H && !defined(_LP64) && _FILE_OFFSET_BITS == 64 + # undef _FILE_OFFSET_BITS + # undef _LARGEFILE64_SOURCE + #endif + #include + #include + #include + #include + ]], + [[int num = swapctl(0, NULL);]] + ) + ], + [c_cv_have_swapctl_two_args="yes"], + [c_cv_have_swapctl_two_args="no"] + ) + ] + ) + + AC_CACHE_CHECK([whether swapctl takes three arguments], + [c_cv_have_swapctl_three_args], + [ + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM( + [[ + #if HAVE_SYS_SWAP_H && !defined(_LP64) && _FILE_OFFSET_BITS == 64 + # undef _FILE_OFFSET_BITS + # undef _LARGEFILE64_SOURCE + #endif + #include + #include + #include + #include + ]], + [[int num = swapctl(0, NULL, 0);]] + ) + ], + [c_cv_have_swapctl_three_args="yes"], + [c_cv_have_swapctl_three_args="no"] + ) + ] + ) fi + # Check for different versions of `swapctl' here.. if test "x$have_swapctl" = "xyes"; then - if test "x$c_cv_have_swapctl_two_args" = "xyes"; then - AC_DEFINE(HAVE_SWAPCTL_TWO_ARGS, 1, - [Define if the function swapctl exists and takes two arguments.]) - fi - if test "x$c_cv_have_swapctl_three_args" = "xyes"; then - AC_DEFINE(HAVE_SWAPCTL_THREE_ARGS, 1, - [Define if the function swapctl exists and takes three arguments.]) - fi + if test "x$c_cv_have_swapctl_two_args" = "xyes"; then + AC_DEFINE([HAVE_SWAPCTL_TWO_ARGS], [1], [Define if the function swapctl exists and takes two arguments.]) + fi + + if test "x$c_cv_have_swapctl_three_args" = "xyes"; then + AC_DEFINE([HAVE_SWAPCTL_THREE_ARGS], [1], [Define if the function swapctl exists and takes three arguments.]) + fi fi # Check for NAN -AC_ARG_WITH(nan-emulation, [AS_HELP_STRING([--with-nan-emulation], [use emulated NAN. For crosscompiling only.])], -[ - if test "x$withval" = "xno"; then - nan_type="none" - else if test "x$withval" = "xyes"; then - nan_type="zero" - else - nan_type="$withval" - fi; fi -], -[nan_type="none"]) +AC_ARG_WITH([nan-emulation], + [AS_HELP_STRING([--with-nan-emulation], [use emulated NAN. For crosscompiling only.])], + [ + if test "x$withval" = "xno"; then + nan_type="none" + else if test "x$withval" = "xyes"; then + nan_type="zero" + else + nan_type="$withval" + fi; fi + ], + [nan_type="none"] +) + if test "x$nan_type" = "xnone"; then AC_CACHE_CHECK([whether NAN is defined by default], [c_cv_have_nan_default], - AC_COMPILE_IFELSE([AC_LANG_PROGRAM( -[[[ -#include -#include -static double foo = NAN; -]]], -[[[ - if (isnan (foo)) - return 0; - else - return 1; -]]] - )], - [c_cv_have_nan_default="yes"], - [c_cv_have_nan_default="no"] - ) + [ + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM( + [[ + #include + #include + static double foo = NAN; + ]], + [[ + if (isnan (foo)) + return 0; + return 1; + ]] + ) + ], + [c_cv_have_nan_default="yes"], + [c_cv_have_nan_default="no"] + ) + ] ) - if test "x$c_cv_have_nan_default" = "xyes" - then - nan_type="default" - fi fi + +if test "x$c_cv_have_nan_default" = "xyes"; then + nan_type="default" +fi + if test "x$nan_type" = "xnone"; then AC_CACHE_CHECK([whether NAN is defined by __USE_ISOC99], [c_cv_have_nan_isoc], - AC_COMPILE_IFELSE([AC_LANG_PROGRAM( -[[[ -#include -#define __USE_ISOC99 1 -#include -static double foo = NAN; -]]], -[[[ - if (isnan (foo)) - return 0; - else - return 1; -]]] - )], - [c_cv_have_nan_isoc="yes"], - [c_cv_have_nan_isoc="no"] - ) + [ + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM( + [[ + #include + #define __USE_ISOC99 1 + #include + static double foo = NAN; + ]], + [[ + if (isnan (foo)) + return 0; + return 1; + ]] + ) + ], + [c_cv_have_nan_isoc="yes"], + [c_cv_have_nan_isoc="no"] + ) + ] ) - if test "x$c_cv_have_nan_isoc" = "xyes" - then - nan_type="isoc99" - fi fi + +if test "x$c_cv_have_nan_isoc" = "xyes"; then + nan_type="isoc99" +fi + if test "x$nan_type" = "xnone"; then - SAVE_LDFLAGS=$LDFLAGS + SAVE_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -lm" AC_CACHE_CHECK([whether NAN can be defined by 0/0], [c_cv_have_nan_zero], - AC_RUN_IFELSE([AC_LANG_PROGRAM( -[[[ -#include -#include -#ifdef NAN -# undef NAN -#endif -#define NAN (0.0 / 0.0) -#ifndef isnan -# define isnan(f) ((f) != (f)) -#endif -static double foo = NAN; -]]], -[[[ - if (isnan (foo)) - return 0; - else - return 1; -]]] - )], - [c_cv_have_nan_zero="yes"], - [c_cv_have_nan_zero="no"] - ) + [ + AC_RUN_IFELSE( + [ + AC_LANG_PROGRAM( + [[ + #include + #include + #ifdef NAN + # undef NAN + #endif + #define NAN (0.0 / 0.0) + #ifndef isnan + # define isnan(f) ((f) != (f)) + #endif + static double foo = NAN; + ]], + [[ + if (isnan (foo)) + return 0; + return 1; + ]] + ) + ], + [c_cv_have_nan_zero="yes"], + [c_cv_have_nan_zero="no"] + ) + ] ) LDFLAGS=$SAVE_LDFLAGS - if test "x$c_cv_have_nan_zero" = "xyes" - then - nan_type="zero" - fi +fi + +if test "x$c_cv_have_nan_zero" = "xyes"; then + nan_type="zero" fi if test "x$nan_type" = "xdefault"; then - AC_DEFINE(NAN_STATIC_DEFAULT, 1, - [Define if NAN is defined by default and can initialize static variables.]) + AC_DEFINE([NAN_STATIC_DEFAULT], [1], + [Define if NAN is defined by default and can initialize static variables.] + ) else if test "x$nan_type" = "xisoc99"; then - AC_DEFINE(NAN_STATIC_ISOC, 1, - [Define if NAN is defined by __USE_ISOC99 and can initialize static variables.]) + AC_DEFINE([NAN_STATIC_ISOC], [1], + [Define if NAN is defined by __USE_ISOC99 and can initialize static variables.] + ) else if test "x$nan_type" = "xzero"; then - AC_DEFINE(NAN_ZERO_ZERO, 1, - [Define if NAN can be defined as (0.0 / 0.0)]) + AC_DEFINE([NAN_ZERO_ZERO], [1], + [Define if NAN can be defined as (0.0 / 0.0)] + ) else AC_MSG_ERROR([Didn't find out how to statically initialize variables to NAN. Sorry.]) fi; fi; fi -AC_ARG_WITH(fp-layout, [AS_HELP_STRING([--with-fp-layout], [set the memory layout of doubles. For crosscompiling only.])], -[ - if test "x$withval" = "xnothing"; then - fp_layout_type="nothing" - else if test "x$withval" = "xendianflip"; then - fp_layout_type="endianflip" - else if test "x$withval" = "xintswap"; then - fp_layout_type="intswap" - else - AC_MSG_ERROR([Invalid argument for --with-fp-layout. Valid arguments are: nothing, endianflip, intswap]); -fi; fi; fi -], -[fp_layout_type="unknown"]) +AC_ARG_WITH([fp-layout], + [ + AS_HELP_STRING([--with-fp-layout], + [set the memory layout of doubles. For crosscompiling only.] + ) + ], + [ + if test "x$withval" = "xnothing"; then + fp_layout_type="nothing" + else if test "x$withval" = "xendianflip"; then + fp_layout_type="endianflip" + else if test "x$withval" = "xintswap"; then + fp_layout_type="intswap" + else + AC_MSG_ERROR([Invalid argument for --with-fp-layout. Valid arguments are: nothing, endianflip, intswap]); + fi; fi; fi + ], + [fp_layout_type="unknown"] +) if test "x$fp_layout_type" = "xunknown"; then AC_CACHE_CHECK([if doubles are stored in x86 representation], [c_cv_fp_layout_need_nothing], - AC_RUN_IFELSE([AC_LANG_PROGRAM( -[[[ -#include -#include -#include -#if HAVE_STDINT_H -# include -#endif -#if HAVE_INTTYPES_H -# include -#endif -#if HAVE_STDBOOL_H -# include -#endif -]]], -[[[ - uint64_t i0; - uint64_t i1; - uint8_t c[8]; - double d; - - d = 8.642135e130; - memcpy ((void *) &i0, (void *) &d, 8); - - i1 = i0; - memcpy ((void *) c, (void *) &i1, 8); - - if ((c[0] == 0x2f) && (c[1] == 0x25) - && (c[2] == 0xc0) && (c[3] == 0xc7) - && (c[4] == 0x43) && (c[5] == 0x2b) - && (c[6] == 0x1f) && (c[7] == 0x5b)) - return (0); - else - return (1); -]]] - )], - [c_cv_fp_layout_need_nothing="yes"], - [c_cv_fp_layout_need_nothing="no"] - ) + [ + AC_RUN_IFELSE( + [ + AC_LANG_PROGRAM( + [[ + #include + #include + #include + #include + #include + #include + ]], + [[ + uint64_t i0; + uint64_t i1; + uint8_t c[8]; + double d; + + d = 8.642135e130; + memcpy ((void *) &i0, (void *) &d, 8); + + i1 = i0; + memcpy ((void *) c, (void *) &i1, 8); + + if ((c[0] == 0x2f) && (c[1] == 0x25) + && (c[2] == 0xc0) && (c[3] == 0xc7) + && (c[4] == 0x43) && (c[5] == 0x2b) + && (c[6] == 0x1f) && (c[7] == 0x5b)) + return (0); + return (1); + ]] + ) + ], + [c_cv_fp_layout_need_nothing="yes"], + [c_cv_fp_layout_need_nothing="no"] + ) + ] ) - if test "x$c_cv_fp_layout_need_nothing" = "xyes"; then - fp_layout_type="nothing" - fi fi + +if test "x$c_cv_fp_layout_need_nothing" = "xyes"; then + fp_layout_type="nothing" +fi + if test "x$fp_layout_type" = "xunknown"; then AC_CACHE_CHECK([if endianflip converts to x86 representation], [c_cv_fp_layout_need_endianflip], - AC_RUN_IFELSE([AC_LANG_PROGRAM( -[[[ -#include -#include -#include -#if HAVE_STDINT_H -# include -#endif -#if HAVE_INTTYPES_H -# include -#endif -#if HAVE_STDBOOL_H -# include -#endif -#define endianflip(A) ((((uint64_t)(A) & 0xff00000000000000LL) >> 56) | \ - (((uint64_t)(A) & 0x00ff000000000000LL) >> 40) | \ - (((uint64_t)(A) & 0x0000ff0000000000LL) >> 24) | \ - (((uint64_t)(A) & 0x000000ff00000000LL) >> 8) | \ - (((uint64_t)(A) & 0x00000000ff000000LL) << 8) | \ - (((uint64_t)(A) & 0x0000000000ff0000LL) << 24) | \ - (((uint64_t)(A) & 0x000000000000ff00LL) << 40) | \ - (((uint64_t)(A) & 0x00000000000000ffLL) << 56)) -]]], -[[[ - uint64_t i0; - uint64_t i1; - uint8_t c[8]; - double d; - - d = 8.642135e130; - memcpy ((void *) &i0, (void *) &d, 8); - - i1 = endianflip (i0); - memcpy ((void *) c, (void *) &i1, 8); - - if ((c[0] == 0x2f) && (c[1] == 0x25) - && (c[2] == 0xc0) && (c[3] == 0xc7) - && (c[4] == 0x43) && (c[5] == 0x2b) - && (c[6] == 0x1f) && (c[7] == 0x5b)) - return (0); - else - return (1); -]]] - )], - [c_cv_fp_layout_need_endianflip="yes"], - [c_cv_fp_layout_need_endianflip="no"] + [ + AC_RUN_IFELSE( + [ + AC_LANG_PROGRAM( + [[ + #include + #include + #include + #include + #include + #include + #define endianflip(A) ((((uint64_t)(A) & 0xff00000000000000LL) >> 56) | \ + (((uint64_t)(A) & 0x00ff000000000000LL) >> 40) | \ + (((uint64_t)(A) & 0x0000ff0000000000LL) >> 24) | \ + (((uint64_t)(A) & 0x000000ff00000000LL) >> 8) | \ + (((uint64_t)(A) & 0x00000000ff000000LL) << 8) | \ + (((uint64_t)(A) & 0x0000000000ff0000LL) << 24) | \ + (((uint64_t)(A) & 0x000000000000ff00LL) << 40) | \ + (((uint64_t)(A) & 0x00000000000000ffLL) << 56)) + ]], + [[ + uint64_t i0; + uint64_t i1; + uint8_t c[8]; + double d; + + d = 8.642135e130; + memcpy ((void *) &i0, (void *) &d, 8); + + i1 = endianflip (i0); + memcpy ((void *) c, (void *) &i1, 8); + + if ((c[0] == 0x2f) && (c[1] == 0x25) + && (c[2] == 0xc0) && (c[3] == 0xc7) + && (c[4] == 0x43) && (c[5] == 0x2b) + && (c[6] == 0x1f) && (c[7] == 0x5b)) + return (0); + return (1); + ]] + ) + ], + [c_cv_fp_layout_need_endianflip="yes"], + [c_cv_fp_layout_need_endianflip="no"] + ] ) ) - if test "x$c_cv_fp_layout_need_endianflip" = "xyes"; then - fp_layout_type="endianflip" - fi fi + +if test "x$c_cv_fp_layout_need_endianflip" = "xyes"; then + fp_layout_type="endianflip" +fi + if test "x$fp_layout_type" = "xunknown"; then AC_CACHE_CHECK([if intswap converts to x86 representation], [c_cv_fp_layout_need_intswap], - AC_RUN_IFELSE([AC_LANG_PROGRAM( -[[[ -#include -#include -#include -#if HAVE_STDINT_H -# include -#endif -#if HAVE_INTTYPES_H -# include -#endif -#if HAVE_STDBOOL_H -# include -#endif -#define intswap(A) ((((uint64_t)(A) & 0xffffffff00000000LL) >> 32) | \ - (((uint64_t)(A) & 0x00000000ffffffffLL) << 32)) -]]], -[[[ - uint64_t i0; - uint64_t i1; - uint8_t c[8]; - double d; - - d = 8.642135e130; - memcpy ((void *) &i0, (void *) &d, 8); - - i1 = intswap (i0); - memcpy ((void *) c, (void *) &i1, 8); - - if ((c[0] == 0x2f) && (c[1] == 0x25) - && (c[2] == 0xc0) && (c[3] == 0xc7) - && (c[4] == 0x43) && (c[5] == 0x2b) - && (c[6] == 0x1f) && (c[7] == 0x5b)) - return (0); - else - return (1); -]]] - )], - [c_cv_fp_layout_need_intswap="yes"], - [c_cv_fp_layout_need_intswap="no"] - ) + [ + AC_RUN_IFELSE( + [ + AC_LANG_PROGRAM( + [[ + #include + #include + #include + #include + #include + #include + #define intswap(A) ((((uint64_t)(A) & 0xffffffff00000000LL) >> 32) | \ + (((uint64_t)(A) & 0x00000000ffffffffLL) << 32)) + ]], + [[ + uint64_t i0; + uint64_t i1; + uint8_t c[8]; + double d; + + d = 8.642135e130; + memcpy ((void *) &i0, (void *) &d, 8); + + i1 = intswap (i0); + memcpy ((void *) c, (void *) &i1, 8); + + if ((c[0] == 0x2f) && (c[1] == 0x25) + && (c[2] == 0xc0) && (c[3] == 0xc7) + && (c[4] == 0x43) && (c[5] == 0x2b) + && (c[6] == 0x1f) && (c[7] == 0x5b)) + return (0); + return (1); + ]] + ) + ], + [c_cv_fp_layout_need_intswap="yes"], + [c_cv_fp_layout_need_intswap="no"] + ) + ] ) - if test "x$c_cv_fp_layout_need_intswap" = "xyes"; then - fp_layout_type="intswap" - fi +fi + +if test "x$c_cv_fp_layout_need_intswap" = "xyes"; then + fp_layout_type="intswap" fi if test "x$fp_layout_type" = "xnothing"; then - AC_DEFINE(FP_LAYOUT_NEED_NOTHING, 1, - [Define if doubles are stored in x86 representation.]) + AC_DEFINE([FP_LAYOUT_NEED_NOTHING], [1], + [Define if doubles are stored in x86 representation.] + ) else if test "x$fp_layout_type" = "xendianflip"; then - AC_DEFINE(FP_LAYOUT_NEED_ENDIANFLIP, 1, - [Define if endianflip is needed to convert to x86 representation.]) + AC_DEFINE([FP_LAYOUT_NEED_ENDIANFLIP], [1], + [Define if endianflip is needed to convert to x86 representation.] + ) else if test "x$fp_layout_type" = "xintswap"; then - AC_DEFINE(FP_LAYOUT_NEED_INTSWAP, 1, - [Define if intswap is needed to convert to x86 representation.]) + AC_DEFINE([FP_LAYOUT_NEED_INTSWAP], [1], + [Define if intswap is needed to convert to x86 representation.] + ) else AC_MSG_ERROR([Didn't find out how doubles are stored in memory. Sorry.]) fi; fi; fi +# For cpusleep plugin +AC_CACHE_CHECK([whether clock_boottime and clock_monotonic are supported], + [c_cv_have_clock_boottime_monotonic], + [ + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[ + struct timespec b, m; + clock_gettime(CLOCK_BOOTTIME, &b ); + clock_gettime(CLOCK_MONOTONIC, &m ); + ]] + ) + ], + [c_cv_have_clock_boottime_monotonic="yes"], + [c_cv_have_clock_boottime_monotonic="no"] + ) + ] +) + # --with-useragent {{{ -AC_ARG_WITH(useragent, [AS_HELP_STRING([--with-useragent@<:@=AGENT@:>@], [User agent to use on http requests])], -[ - if test "x$withval" != "xno" && test "x$withval" != "xyes" - then - AC_DEFINE_UNQUOTED(COLLECTD_USERAGENT, ["$withval"], [User agent for http requests]) +AC_ARG_WITH([useragent], + [AS_HELP_STRING([--with-useragent@<:@=AGENT@:>@], [User agent to use on http requests])], + [ + if test "x$withval" != "xno" && test "x$withval" != "xyes"; then + AC_DEFINE_UNQUOTED([COLLECTD_USERAGENT], ["$withval"], [User agent for http requests]) fi -]) + ] +) # }}} # --with-data-max-name-len {{{ -AC_ARG_WITH(data-max-name-len, [AS_HELP_STRING([--with-data-max-name-len@<:@=VALUE@:>@], [Maximum length of data buffers])], -[ - if test "x$withval" != "x" && test $withval -gt 0 - then - AC_DEFINE_UNQUOTED(DATA_MAX_NAME_LEN, [$withval], [Maximum length of data buffers]) +AC_ARG_WITH([data-max-name-len], + [AS_HELP_STRING([--with-data-max-name-len@<:@=VALUE@:>@], [Maximum length of data buffers])], + [ + if test "x$withval" != "x" && test $withval -gt 0; then + AC_DEFINE_UNQUOTED([DATA_MAX_NAME_LEN], [$withval], [Maximum length of data buffers]) else - AC_MSG_ERROR([DATA_MAX_NAME_LEN must be a positive integer -- $withval given]) + AC_MSG_ERROR([DATA_MAX_NAME_LEN must be a positive integer -- $withval given]) fi -], -[ AC_DEFINE(DATA_MAX_NAME_LEN, 128, [Maximum length of data buffers])] + ], + [AC_DEFINE([DATA_MAX_NAME_LEN], [128], [Maximum length of data buffers])] ) # }}} -have_getfsstat="no" -AC_CHECK_FUNCS(getfsstat, [have_getfsstat="yes"]) -have_getvfsstat="no" -AC_CHECK_FUNCS(getvfsstat, [have_getvfsstat="yes"]) -have_listmntent="no" -AC_CHECK_FUNCS(listmntent, [have_listmntent="yes"]) -have_getmntent_r="no" -AC_CHECK_FUNCS(getmntent_r, [have_getmntent_r="yes"]) - -have_getmntent="no" -AC_CHECK_FUNCS(getmntent, [have_getmntent="c"]) +AC_CHECK_FUNCS([getfsstat], [have_getfsstat="yes"], [have_getfsstat="no"]) +AC_CHECK_FUNCS(getvfsstat, [have_getvfsstat="yes"], [have_getvfsstat="no"]) +AC_CHECK_FUNCS(listmntent, [have_listmntent="yes"], [have_listmntent="no"]) +AC_CHECK_FUNCS(getmntent_r, [have_getmntent_r="yes"], [have_getmntent_r="no"]) + +AC_CHECK_FUNCS(getmntent, [have_getmntent="libc"], [have_getmntent="no"]) if test "x$have_getmntent" = "xno"; then - AC_CHECK_LIB(sun, getmntent, [have_getmntent="sun"]) + AC_CHECK_LIB([sun], [getmntent], + [have_getmntent="sun"], + [have_gemntent="no"] + ) fi + if test "x$have_getmntent" = "xno"; then - AC_CHECK_LIB(seq, getmntent, [have_getmntent="seq"]) + AC_CHECK_LIB([seq], [getmntent], + [have_getmntent="seq"], + [have_getmntent="no"] + ) fi + if test "x$have_getmntent" = "xno"; then - AC_CHECK_LIB(gen, getmntent, [have_getmntent="gen"]) -fi - -if test "x$have_getmntent" = "xc"; then - AC_CACHE_CHECK([whether getmntent takes one argument], - [c_cv_have_one_getmntent], - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( -[[[ -#include "$srcdir/src/utils_mount.h" -]]], -[[[ -FILE *fh; -struct mntent *me; -fh = setmntent ("/etc/mtab", "r"); -me = getmntent (fh); -return(me->mnt_passno); -]]] - )], - [c_cv_have_one_getmntent="yes"], - [c_cv_have_one_getmntent="no"] - ) - ) - AC_CACHE_CHECK([whether getmntent takes two arguments], - [c_cv_have_two_getmntent], - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( -[[[ -#include "$srcdir/src/utils_mount.h" -]]], -[[[ - FILE *fh; - struct mnttab mt; - int status; - fh = fopen ("/etc/mnttab", "r"); - status = getmntent (fh, &mt); - return(status); -]]] - )], - [c_cv_have_two_getmntent="yes"], - [c_cv_have_two_getmntent="no"] - ) - ) + AC_CHECK_LIB([gen], [getmntent], + [have_getmntent="gen"], + [have_getmntent="no"] + ) +fi + +if test "x$have_getmntent" = "xlibc"; then + AC_CACHE_CHECK([whether getmntent takes one argument], + [c_cv_have_one_getmntent], + [ + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM( + [[#include "$srcdir/src/utils_mount.h"]], + [[ + FILE *fh; + struct mntent *me; + fh = setmntent ("/etc/mtab", "r"); + me = getmntent (fh); + return(me->mnt_passno); + ]] + ) + ], + [c_cv_have_one_getmntent="yes"], + [c_cv_have_one_getmntent="no"] + ) + ] + ) + + AC_CACHE_CHECK([whether getmntent takes two arguments], + [c_cv_have_two_getmntent], + [ + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM( + [[#include "$srcdir/src/utils_mount.h"]], + [[ + FILE *fh; + struct mnttab mt; + int status; + fh = fopen ("/etc/mnttab", "r"); + status = getmntent (fh, &mt); + return(status); + ]] + ) + ], + [c_cv_have_two_getmntent="yes"], + [c_cv_have_two_getmntent="no"] + ) + ] + ) fi # Check for different versions of `getmntent' here.. -if test "x$have_getmntent" = "xc"; then - if test "x$c_cv_have_one_getmntent" = "xyes"; then - AC_DEFINE(HAVE_ONE_GETMNTENT, 1, - [Define if the function getmntent exists and takes one argument.]) - fi - if test "x$c_cv_have_two_getmntent" = "xyes"; then - AC_DEFINE(HAVE_TWO_GETMNTENT, 1, - [Define if the function getmntent exists and takes two arguments.]) - fi +if test "x$have_getmntent" = "xlibc"; then + if test "x$c_cv_have_one_getmntent" = "xyes"; then + AC_DEFINE([HAVE_ONE_GETMNTENT], [1], + [Define if the function getmntent exists and takes one argument.] + ) + fi + + if test "x$c_cv_have_two_getmntent" = "xyes"; then + AC_DEFINE([HAVE_TWO_GETMNTENT], [1], + [Define if the function getmntent exists and takes two arguments.] + ) + fi fi + if test "x$have_getmntent" = "xsun"; then - AC_DEFINE(HAVE_SUN_GETMNTENT, 1, - [Define if the function getmntent exists. It is the version from libsun.]) -fi -if test "x$have_getmntent" = "xseq"; then - AC_DEFINE(HAVE_SEQ_GETMNTENT, 1, - [Define if the function getmntent exists. It is the version from libseq.]) + AC_DEFINE([HAVE_SUN_GETMNTENT], [1], + [Define if the function getmntent exists. It is the version from libsun.] + ) fi + if test "x$have_getmntent" = "xgen"; then - AC_DEFINE(HAVE_GEN_GETMNTENT, 1, - [Define if the function getmntent exists. It is the version from libgen.]) + AC_DEFINE([HAVE_GEN_GETMNTENT], [1], + [Define if the function getmntent exists. It is the version from libgen.] + ) fi # Check for htonll -AC_CACHE_CHECK([if have htonll defined], - [c_cv_have_htonll], - AC_LINK_IFELSE([AC_LANG_PROGRAM( -[[[ -#include -#include -#if HAVE_INTTYPES_H -# include -#endif -]]], -[[[ - return htonll(0); -]]] - )], - [c_cv_have_htonll="yes"], - [c_cv_have_htonll="no"] - ) +AC_CACHE_CHECK([whether htonll is defined], + [c_cv_have_htonll], + [ + AC_LINK_IFELSE( + [ + AC_LANG_PROGRAM( + [[ + #include + #include + #include + ]], + [[return htonll(0);]] + ) + ], + [c_cv_have_htonll="yes"], + [c_cv_have_htonll="no"] + ) + ] ) -if test "x$c_cv_have_htonll" = "xyes" -then - AC_DEFINE(HAVE_HTONLL, 1, [Define if the function htonll exists.]) + +if test "x$c_cv_have_htonll" = "xyes"; then + AC_DEFINE([HAVE_HTONLL], [1], [Define if the function htonll exists.]) fi # Check for structures AC_CHECK_MEMBERS([struct if_data.ifi_ibytes, struct if_data.ifi_opackets, struct if_data.ifi_ierrors], - [AC_DEFINE(HAVE_STRUCT_IF_DATA, 1, [Define if struct if_data exists and is usable.])], - [], - [ - #include - #include - #include - ]) + [AC_DEFINE([HAVE_STRUCT_IF_DATA], [1], [Define if struct if_data exists and is usable.])], + [], + [[ + #include + #include + #include + ]] +) + AC_CHECK_MEMBERS([struct net_device_stats.rx_bytes, struct net_device_stats.tx_packets, struct net_device_stats.rx_errors], - [AC_DEFINE(HAVE_STRUCT_NET_DEVICE_STATS, 1, [Define if struct net_device_stats exists and is usable.])], - [], - [ - #include - #include - #include - #include - ]) -AC_CHECK_MEMBERS([struct inet_diag_req.id, struct inet_diag_req.idiag_states], - [AC_DEFINE(HAVE_STRUCT_LINUX_INET_DIAG_REQ, 1, [Define if struct inet_diag_req exists and is usable.])], - [], - [ - #include - ]) + [AC_DEFINE([HAVE_STRUCT_NET_DEVICE_STATS], [1], [Define if struct net_device_stats exists and is usable.])], + [], + [[ + #include + #include + #include + #include + ]] +) +AC_CHECK_MEMBERS([struct inet_diag_req.id, struct inet_diag_req.idiag_states], + [AC_DEFINE([HAVE_STRUCT_LINUX_INET_DIAG_REQ], [1], [Define if struct inet_diag_req exists and is usable.])], + [], + [[#include ]] +) AC_CHECK_MEMBERS([struct ip_mreqn.imr_ifindex], [], - [], - [ - #include - #include - ]) + [], + [[ + #include + #include + ]] +) AC_CHECK_MEMBERS([struct kinfo_proc.ki_pid, struct kinfo_proc.ki_rssize, struct kinfo_proc.ki_rusage], - [ - AC_DEFINE(HAVE_STRUCT_KINFO_PROC_FREEBSD, 1, - [Define if struct kinfo_proc exists in the FreeBSD variant.]) - have_struct_kinfo_proc_freebsd="yes" - ], - [ - have_struct_kinfo_proc_freebsd="no" - ], - [ -#include -#include -#include -#include - ]) + [ + AC_DEFINE([HAVE_STRUCT_KINFO_PROC_FREEBSD], [1], [Define if struct kinfo_proc exists in the FreeBSD variant.]) + have_struct_kinfo_proc_freebsd="yes" + ], + [], + [[ + #include + #include + #include + #include + ]] +) AC_CHECK_MEMBERS([struct kinfo_proc.p_pid, struct kinfo_proc.p_vm_rssize], - [ - AC_DEFINE(HAVE_STRUCT_KINFO_PROC_OPENBSD, 1, - [Define if struct kinfo_proc exists in the OpenBSD variant.]) - have_struct_kinfo_proc_openbsd="yes" - ], - [ - have_struct_kinfo_proc_openbsd="no" - ], - [ -#include -#include -#include - ]) - + [ + AC_DEFINE([HAVE_STRUCT_KINFO_PROC_OPENBSD], [1], [Define if struct kinfo_proc exists in the OpenBSD variant.]) + have_struct_kinfo_proc_openbsd="yes" + ], + [], + [[ + #include + #include + #include + ]] +) AC_CHECK_MEMBERS([struct kinfo_proc2.p_pid, struct kinfo_proc2.p_uru_maxrss], - [ - AC_DEFINE(HAVE_STRUCT_KINFO_PROC2_NETBSD, 1, - [Define if struct kinfo_proc2 exists in the NetBSD variant.]) - have_struct_kinfo_proc2_netbsd="yes" - ], - [ - have_struct_kinfo_proc2_netbsd="no" - ], - [ -#include -#include -#include - ]) - - - -AC_CHECK_MEMBERS([struct udphdr.uh_dport, struct udphdr.uh_sport], [], [], -[#define _BSD_SOURCE -#define _DEFAULT_SOURCE -#if HAVE_STDINT_H -# include -#endif -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_NETINET_IN_SYSTM_H -# include -#endif -#if HAVE_NETINET_IN_H -# include -#endif -#if HAVE_NETINET_IP_H -# include -#endif -#if HAVE_NETINET_UDP_H -# include -#endif -]) -AC_CHECK_MEMBERS([struct udphdr.dest, struct udphdr.source], [], [], -[#define _BSD_SOURCE -#define _DEFAULT_SOURCE -#if HAVE_STDINT_H -# include -#endif -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_NETINET_IN_SYSTM_H -# include -#endif -#if HAVE_NETINET_IN_H -# include -#endif -#if HAVE_NETINET_IP_H -# include -#endif -#if HAVE_NETINET_UDP_H -# include -#endif -]) - + [ + AC_DEFINE([HAVE_STRUCT_KINFO_PROC2_NETBSD], [1], [Define if struct kinfo_proc2 exists in the NetBSD variant.]) + have_struct_kinfo_proc2_netbsd="yes" + ], + [], + [[ + #include + #include + #include + ]] +) + +AC_CHECK_MEMBERS([struct udphdr.uh_dport, struct udphdr.uh_sport], + [], + [], + [[ + #define _BSD_SOURCE + #define _DEFAULT_SOURCE + #include + #if HAVE_SYS_TYPES_H + # include + #endif + #if HAVE_NETINET_IN_SYSTM_H + # include + #endif + #if HAVE_NETINET_IN_H + # include + #endif + #if HAVE_NETINET_IP_H + # include + #endif + #if HAVE_NETINET_UDP_H + # include + #endif + ]] +) + +AC_CHECK_MEMBERS([struct udphdr.dest, struct udphdr.source], + [], + [], + [[ + #define _BSD_SOURCE + #define _DEFAULT_SOURCE + #include + #if HAVE_SYS_TYPES_H + # include + #endif + #if HAVE_NETINET_IN_SYSTM_H + # include + #endif + #if HAVE_NETINET_IN_H + # include + #endif + #if HAVE_NETINET_IP_H + # include + #endif + #if HAVE_NETINET_UDP_H + # include + #endif + ]] +) + AC_CHECK_MEMBERS([kstat_io_t.nwritten, kstat_io_t.writes, kstat_io_t.nwrites, kstat_io_t.wtime], - [], - [], - [ -#if HAVE_KSTAT_H -# include -#endif - ]) + [], + [], + [[# include ]] +) # check for pthread_setname_np SAVE_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -lpthread" AC_MSG_CHECKING([for pthread_setname_np]) - have_pthread_setname_np="no" - AC_LINK_IFELSE([AC_LANG_PROGRAM( -[[ -#define _GNU_SOURCE -#include -]], -[[ - pthread_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_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_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_set_name_np((pthread_t) {0}, "conftest");]] + ) + ], + [ + have_pthread_set_name_np="yes" + AC_DEFINE(HAVE_PTHREAD_SET_NAME_NP, 1, [pthread_set_name_np() is available.]) + ] +) AC_MSG_RESULT([$have_pthread_set_name_np]) LDFLAGS="$SAVE_LDFLAGS" -# -# Checks for libraries begin here -# +AC_CHECK_TYPES([struct ip6_ext], + [have_ip6_ext="yes"], + [have_ip6_ext="no"], + [[ + #include + #if HAVE_SYS_TYPES_H + # include + #endif + #if HAVE_NETINET_IN_SYSTM_H + # include + #endif + #if HAVE_NETINET_IN_H + # include + #endif + #if HAVE_NETINET_IP6_H + # include + #endif + ]] +) -with_libresolv="yes" -AC_CHECK_LIB(resolv, res_search, -[ - AC_DEFINE(HAVE_LIBRESOLV, 1, [Define to 1 if you have the 'resolv' library (-lresolv).]) -], -[with_libresolv="no"]) -AM_CONDITIONAL(BUILD_WITH_LIBRESOLV, test "x$with_libresolv" = "xyes") +if test "x$have_ip6_ext" = "xno"; then + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -DSOLARIS2=8" + AC_CHECK_TYPES([struct ip6_ext], + [have_ip6_ext="yes, with -DSOLARIS2=8"], + [have_ip6_ext="no"], + [[ + #include + #if HAVE_SYS_TYPES_H + # include + #endif + #if HAVE_NETINET_IN_SYSTM_H + # include + #endif + #if HAVE_NETINET_IN_H + # include + #endif + #if HAVE_NETINET_IP6_H + # include + #endif + ]] + ) + if test "x$have_ip6_ext" = "xno"; then + CFLAGS="$SAVE_CFLAGS" + fi +fi -dnl Check for HAL (hardware abstraction library) -with_libhal="no" -PKG_CHECK_MODULES([HAL], [hal], - [ - SAVE_LIBS="$LIBS" - LIBS="$HAL_LIBS $LIBS" - AC_CHECK_LIB([hal], [libhal_device_property_exists], - [ - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$HAL_CFLAGS $CPPFLAGS" - AC_CHECK_HEADERS([libhal.h], - [ - with_libhal="yes" - BUILD_WITH_LIBHAL_CFLAGS="$HAL_CFLAGS" - BUILD_WITH_LIBHAL_LIBS="$HAL_LIBS" - ]) - CPPFLAGS="$SAVE_CPPFLAGS" - ], - [ : ] - ) - LIBS="$SAVE_LIBS" - ], - [ : ] -) -AC_SUBST(BUILD_WITH_LIBHAL_CFLAGS) -AC_SUBST(BUILD_WITH_LIBHAL_LIBS) +# libi2c-dev +if test "x$ac_system" = "xLinux"; then + AC_CHECK_DECL([i2c_smbus_read_i2c_block_data], + [with_libi2c="yes"], + [with_libi2c="no (symbol i2c_smbus_read_i2c_block_data not found - have you installed libi2c-dev ?)"], + [[ + #include + #include + ]] + ) +else + with_libi2c="no (Linux only)" +fi +# +# Checks for libraries begin here +# +# Check for libpthread SAVE_LIBS="$LIBS" AC_CHECK_LIB([pthread], [pthread_create], [], - [AC_MSG_ERROR([Symbol 'pthread_create' not found in libpthread"])], + [AC_MSG_ERROR([Symbol 'pthread_create' not found in libpthread])], [] ) PTHREAD_LIBS="$LIBS" LIBS="$SAVE_LIBS" +AC_SUBST([PTHREAD_LIBS]) AC_CHECK_HEADERS([pthread.h], [], [AC_MSG_ERROR([pthread.h not found])] ) -AC_SUBST([PTHREAD_LIBS]) m4_divert_once([HELP_WITH], [ -collectd additional packages:]) +Collectd additional packages:]) -if test "x$ac_system" = "xAIX" -then - with_perfstat="yes" - with_procinfo="yes" +if test "x$ac_system" = "xAIX"; then + with_perfstat="yes" + with_procinfo="yes" else - with_perfstat="no (AIX only)" - with_procinfo="no (AIX only)" + with_perfstat="no (AIX only)" + with_procinfo="no (AIX only)" fi -if test "x$with_perfstat" = "xyes" -then - AC_CHECK_LIB(perfstat, perfstat_reset, [with_perfstat="yes"], [with_perfstat="no (perfstat not found)"], []) -# AC_CHECK_HEADERS(sys/protosw.h libperfstat.h,, [with_perfstat="no (perfstat not found)"]) +if test "x$with_perfstat" = "xyes"; then + AC_CHECK_LIB([perfstat], [perfstat_reset], + [with_perfstat="yes"], + [with_perfstat="no (perfstat not found)"] + ) fi -if test "x$with_perfstat" = "xyes" -then - AC_DEFINE(HAVE_PERFSTAT, 1, [Define to 1 if you have the 'perfstat' library (-lperfstat)]) - # struct members pertaining to donation have been added to libperfstat somewhere between AIX5.3ML5 and AIX5.3ML9 - AC_CHECK_MEMBER([perfstat_partition_type_t.b.donate_enabled], [], [], [[#include @], [Path to aquatools-ng source code.])], -[ - if test "x$withval" = "xyes" - then - with_libaquaero5="yes" - else if test "x$withval" = "xno" - then - with_libaquaero5="no" - else - with_libaquaero5="yes" - LIBAQUAERO5_CFLAGS="$LIBAQUAERO5_CFLAGS -I$withval/src" - LIBAQUAERO5_LDFLAGS="$LIBAQUAERO5_LDFLAGS -L$withval/obj" - fi; fi -], -[with_libaquaero5="yes"]) +AC_ARG_WITH([libaquaero5], + [AS_HELP_STRING([--with-libaquaero5@<:@=PREFIX@:>@], [Path to aquatools-ng source code.])], + [ + if test "x$withval" = "xyes"; then + with_libaquaero5="yes" + else if test "x$withval" = "xno"; then + with_libaquaero5="no" + else + with_libaquaero5="yes" + LIBAQUAERO5_CFLAGS="$LIBAQUAERO5_CFLAGS -I$withval/src" + LIBAQUAERO5_LDFLAGS="$LIBAQUAERO5_LDFLAGS -L$withval/obj" + fi; fi + ], + [with_libaquaero5="yes"] +) SAVE_CPPFLAGS="$CPPFLAGS" SAVE_LDFLAGS="$LDFLAGS" - CPPFLAGS="$CPPFLAGS $LIBAQUAERO5_CFLAGS" LDFLAGS="$LDFLAGS $LIBAQUAERO5_LDFLAGS" -if test "x$with_libaquaero5" = "xyes" -then - if test "x$LIBAQUAERO5_CFLAGS" != "x" - then - AC_MSG_NOTICE([libaquaero5 CPPFLAGS: $LIBAQUAERO5_CFLAGS]) - fi - AC_CHECK_HEADERS(libaquaero5.h, - [with_libaquaero5="yes"], - [with_libaquaero5="no (libaquaero5.h not found)"]) +if test "x$with_libaquaero5" = "xyes"; then + if test "x$LIBAQUAERO5_CFLAGS" != "x"; then + AC_MSG_NOTICE([libaquaero5 CPPFLAGS: $LIBAQUAERO5_CFLAGS]) + fi + AC_CHECK_HEADERS([libaquaero5.h], + [with_libaquaero5="yes"], + [with_libaquaero5="no (libaquaero5.h not found)"] + ) fi -if test "x$with_libaquaero5" = "xyes" -then - if test "x$LIBAQUAERO5_LDFLAGS" != "x" - then - AC_MSG_NOTICE([libaquaero5 LDFLAGS: $LIBAQUAERO5_LDFLAGS]) - fi - AC_CHECK_LIB(aquaero5, libaquaero5_poll, - [with_libaquaero5="yes"], - [with_libaquaero5="no (symbol 'libaquaero5_poll' not found)"]) + +if test "x$with_libaquaero5" = "xyes"; then + if test "x$LIBAQUAERO5_LDFLAGS" != "x"; then + AC_MSG_NOTICE([libaquaero5 LDFLAGS: $LIBAQUAERO5_LDFLAGS]) + fi + AC_CHECK_LIB([aquaero5], libaquaero5_poll, + [with_libaquaero5="yes"], + [with_libaquaero5="no (symbol 'libaquaero5_poll' not found)"] + ) fi CPPFLAGS="$SAVE_CPPFLAGS" LDFLAGS="$SAVE_LDFLAGS" -if test "x$with_libaquaero5" = "xyes" -then - BUILD_WITH_LIBAQUAERO5_CFLAGS="$LIBAQUAERO5_CFLAGS" - BUILD_WITH_LIBAQUAERO5_LDFLAGS="$LIBAQUAERO5_LDFLAGS" - AC_SUBST(BUILD_WITH_LIBAQUAERO5_CFLAGS) - AC_SUBST(BUILD_WITH_LIBAQUAERO5_LDFLAGS) +if test "x$with_libaquaero5" = "xyes"; then + BUILD_WITH_LIBAQUAERO5_CFLAGS="$LIBAQUAERO5_CFLAGS" + BUILD_WITH_LIBAQUAERO5_LDFLAGS="$LIBAQUAERO5_LDFLAGS" fi -AM_CONDITIONAL(BUILD_WITH_LIBAQUAERO5, test "x$with_libaquaero5" = "xyes") +AC_SUBST([BUILD_WITH_LIBAQUAERO5_CFLAGS]) +AC_SUBST([BUILD_WITH_LIBAQUAERO5_LDFLAGS]) # }}} # --with-libhiredis {{{ -AC_ARG_WITH(libhiredis, [AS_HELP_STRING([--with-libhiredis@<:@=PREFIX@:>@], - [Path to libhiredis.])], -[ - if test "x$withval" = "xyes" - then - with_libhiredis="yes" - else if test "x$withval" = "xno" - then - with_libhiredis="no" - else - with_libhiredis="yes" - LIBHIREDIS_CPPFLAGS="$LIBHIREDIS_CPPFLAGS -I$withval/include" - LIBHIREDIS_LDFLAGS="$LIBHIREDIS_LDFLAGS -L$withval/lib" - fi; fi -], -[with_libhiredis="yes"]) +AC_ARG_WITH([libhiredis], + [AS_HELP_STRING([--with-libhiredis@<:@=PREFIX@:>@], [Path to libhiredis.])], + [ + if test "x$withval" = "xyes"; then + with_libhiredis="yes" + else if test "x$withval" = "xno"; then + with_libhiredis="no" + else + with_libhiredis="yes" + LIBHIREDIS_CPPFLAGS="$LIBHIREDIS_CPPFLAGS -I$withval/include" + LIBHIREDIS_LDFLAGS="$LIBHIREDIS_LDFLAGS -L$withval/lib" + fi; fi + ], + [with_libhiredis="yes"] +) SAVE_CPPFLAGS="$CPPFLAGS" SAVE_LDFLAGS="$LDFLAGS" - CPPFLAGS="$CPPFLAGS $LIBHIREDIS_CPPFLAGS" LDFLAGS="$LDFLAGS $LIBHIREDIS_LDFLAGS" -if test "x$with_libhiredis" = "xyes" -then - if test "x$LIBHIREDIS_CPPFLAGS" != "x" - then - AC_MSG_NOTICE([libhiredis CPPFLAGS: $LIBHIREDIS_CPPFLAGS]) - fi - AC_CHECK_HEADERS(hiredis/hiredis.h, - [with_libhiredis="yes"], - [with_libhiredis="no (hiredis.h not found)"]) +if test "x$with_libhiredis" = "xyes"; then + if test "x$LIBHIREDIS_CPPFLAGS" != "x"; then + AC_MSG_NOTICE([libhiredis CPPFLAGS: $LIBHIREDIS_CPPFLAGS]) + fi + AC_CHECK_HEADERS([hiredis/hiredis.h], + [with_libhiredis="yes"], + [with_libhiredis="no (hiredis.h not found)"] + ) fi -if test "x$with_libhiredis" = "xyes" -then - if test "x$LIBHIREDIS_LDFLAGS" != "x" - then - AC_MSG_NOTICE([libhiredis LDFLAGS: $LIBHIREDIS_LDFLAGS]) - fi - AC_CHECK_LIB(hiredis, redisCommand, - [with_libhiredis="yes"], - [with_libhiredis="no (symbol 'redisCommand' not found)"]) +if test "x$with_libhiredis" = "xyes"; then + if test "x$LIBHIREDIS_LDFLAGS" != "x"; then + AC_MSG_NOTICE([libhiredis LDFLAGS: $LIBHIREDIS_LDFLAGS]) + fi + AC_CHECK_LIB([hiredis], [redisCommand], + [with_libhiredis="yes"], + [with_libhiredis="no (symbol 'redisCommand' not found)"] + ) fi CPPFLAGS="$SAVE_CPPFLAGS" LDFLAGS="$SAVE_LDFLAGS" -if test "x$with_libhiredis" = "xyes" -then - BUILD_WITH_LIBHIREDIS_CPPFLAGS="$LIBHIREDIS_CPPFLAGS" - BUILD_WITH_LIBHIREDIS_LDFLAGS="$LIBHIREDIS_LDFLAGS" - AC_SUBST(BUILD_WITH_LIBHIREDIS_CPPFLAGS) - AC_SUBST(BUILD_WITH_LIBHIREDIS_LDFLAGS) +if test "x$with_libhiredis" = "xyes"; then + BUILD_WITH_LIBHIREDIS_CPPFLAGS="$LIBHIREDIS_CPPFLAGS" + BUILD_WITH_LIBHIREDIS_LDFLAGS="$LIBHIREDIS_LDFLAGS" fi -AM_CONDITIONAL(BUILD_WITH_LIBHIREDIS, test "x$with_libhiredis" = "xyes") + +AC_SUBST([BUILD_WITH_LIBHIREDIS_CPPFLAGS]) +AC_SUBST([BUILD_WITH_LIBHIREDIS_LDFLAGS]) # }}} # --with-libcurl {{{ with_curl_config="curl-config" with_curl_cflags="" with_curl_libs="" -AC_ARG_WITH(libcurl, [AS_HELP_STRING([--with-libcurl@<:@=PREFIX@:>@], [Path to libcurl.])], -[ - if test "x$withval" = "xno" - then - with_libcurl="no" - else if test "x$withval" = "xyes" - then - with_libcurl="yes" - else - if test -f "$withval" && test -x "$withval" - then - with_curl_config="$withval" - with_libcurl="yes" - else if test -x "$withval/bin/curl-config" - then - with_curl_config="$withval/bin/curl-config" - with_libcurl="yes" - fi; fi - with_libcurl="yes" - fi; fi -], -[ - with_libcurl="yes" -]) -if test "x$with_libcurl" = "xyes" -then - with_curl_cflags=`$with_curl_config --cflags 2>/dev/null` - curl_config_status=$? +AC_ARG_WITH(libcurl, + [AS_HELP_STRING([--with-libcurl@<:@=PREFIX@:>@], [Path to libcurl.])], + [ + if test "x$withval" = "xno"; then + with_libcurl="no" + else if test "x$withval" = "xyes"; then + with_libcurl="yes" + else + if test -f "$withval" && test -x "$withval"; then + with_curl_config="$withval" + with_libcurl="yes" + else if test -x "$withval/bin/curl-config"; then + with_curl_config="$withval/bin/curl-config" + with_libcurl="yes" + fi; fi + with_libcurl="yes" + fi; fi + ], + [with_libcurl="yes"] +) - if test $curl_config_status -ne 0 - then - with_libcurl="no ($with_curl_config failed)" - else - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $with_curl_cflags" +if test "x$with_libcurl" = "xyes"; then + with_curl_cflags=`$with_curl_config --cflags 2>/dev/null` + curl_config_status=$? - AC_CHECK_HEADERS(curl/curl.h, [], [with_libcurl="no (curl/curl.h not found)"], []) + if test $curl_config_status -ne 0; then + with_libcurl="no ($with_curl_config failed)" + else + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_curl_cflags" - CPPFLAGS="$SAVE_CPPFLAGS" - fi + AC_CHECK_HEADERS([curl/curl.h], + [with_libcurl="yes"], + [with_libcurl="no (curl/curl.h not found)"] + ) + + CPPFLAGS="$SAVE_CPPFLAGS" + fi fi -if test "x$with_libcurl" = "xyes" -then - with_curl_libs=`$with_curl_config --libs 2>/dev/null` - curl_config_status=$? - if test $curl_config_status -ne 0 - then - with_libcurl="no ($with_curl_config failed)" - else - AC_CHECK_LIB(curl, curl_easy_init, - [with_libcurl="yes"], - [with_libcurl="no (symbol 'curl_easy_init' not found)"], - [$with_curl_libs]) - AC_CHECK_DECL(CURLOPT_USERNAME, - [have_curlopt_username="yes"], - [have_curlopt_username="no"], - [[#include ]]) - AC_CHECK_DECL(CURLOPT_TIMEOUT_MS, - [have_curlopt_timeout="yes"], - [have_curlopt_timeout="no"], - [[#include ]]) - fi +if test "x$with_libcurl" = "xyes"; then + with_curl_libs=`$with_curl_config --libs 2>/dev/null` + curl_config_status=$? + + if test $curl_config_status -ne 0; then + with_libcurl="no ($with_curl_config failed)" + else + AC_CHECK_LIB([curl], [curl_easy_init], + [with_libcurl="yes"], + [with_libcurl="no (symbol 'curl_easy_init' not found)"], + [$with_curl_libs] + ) + + AC_CHECK_DECL([CURLOPT_USERNAME], + [have_curlopt_username="yes"], + [have_curlopt_username="no"], + [[#include ]] + ) + + AC_CHECK_DECL(CURLOPT_TIMEOUT_MS, + [have_curlopt_timeout="yes"], + [have_curlopt_timeout="no"], + [[#include ]] + ) + fi fi -if test "x$with_libcurl" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - SAVE_LDFLAGS="$LDFLAGS" - CPPFLAGS="$CPPFLAGS $with_curl_cflags" - LDFLAGS="$LDFLAGS $with_curl_libs" - AC_CACHE_CHECK([for CURLINFO_APPCONNECT_TIME], - [c_cv_have_curlinfo_appconnect_time], - AC_LINK_IFELSE([AC_LANG_PROGRAM( -[[ -#include -]], -[[ -int val = CURLINFO_APPCONNECT_TIME; -return val; -]] - )], - [c_cv_have_curlinfo_appconnect_time="yes"], - [c_cv_have_curlinfo_appconnect_time="no"] - ) - ) - CPPFLAGS="$SAVE_CPPFLAGS" - LDFLAGS="$SAVE_LDFLAGS" + +if test "x$with_libcurl" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + SAVE_LDFLAGS="$LDFLAGS" + CPPFLAGS="$CPPFLAGS $with_curl_cflags" + LDFLAGS="$LDFLAGS $with_curl_libs" + AC_CACHE_CHECK([for CURLINFO_APPCONNECT_TIME], + [c_cv_have_curlinfo_appconnect_time], + [ + AC_LINK_IFELSE( + [ + AC_LANG_PROGRAM( + [[#include ]], + [[ + int val = CURLINFO_APPCONNECT_TIME; + return val; + ]] + ) + ], + [c_cv_have_curlinfo_appconnect_time="yes"], + [c_cv_have_curlinfo_appconnect_time="no"] + ) + ] + ) + CPPFLAGS="$SAVE_CPPFLAGS" + LDFLAGS="$SAVE_LDFLAGS" fi -AM_CONDITIONAL(BUILD_WITH_LIBCURL, test "x$with_libcurl" = "xyes") -if test "x$c_cv_have_curlinfo_appconnect_time" = "xyes" -then - AC_DEFINE(HAVE_CURLINFO_APPCONNECT_TIME, 1, [Define if curl.h defines CURLINFO_APPCONNECT_TIME.]) + +if test "x$c_cv_have_curlinfo_appconnect_time" = "xyes"; then + AC_DEFINE([HAVE_CURLINFO_APPCONNECT_TIME], [1], + [Define if curl.h defines CURLINFO_APPCONNECT_TIME.] + ) fi -if test "x$with_libcurl" = "xyes" -then - BUILD_WITH_LIBCURL_CFLAGS="$with_curl_cflags" - BUILD_WITH_LIBCURL_LIBS="$with_curl_libs" - AC_SUBST(BUILD_WITH_LIBCURL_CFLAGS) - AC_SUBST(BUILD_WITH_LIBCURL_LIBS) +if test "x$with_libcurl" = "xyes"; then + BUILD_WITH_LIBCURL_CFLAGS="$with_curl_cflags" + BUILD_WITH_LIBCURL_LIBS="$with_curl_libs" - if test "x$have_curlopt_username" = "xyes" - then - AC_DEFINE(HAVE_CURLOPT_USERNAME, 1, [Define if libcurl supports CURLOPT_USERNAME option.]) - fi + if test "x$have_curlopt_username" = "xyes"; then + AC_DEFINE([HAVE_CURLOPT_USERNAME], [1], + [Define if libcurl supports CURLOPT_USERNAME option.] + ) + fi - if test "x$have_curlopt_timeout" = "xyes" - then - AC_DEFINE(HAVE_CURLOPT_TIMEOUT_MS, 1, [Define if libcurl supports CURLOPT_TIMEOUT_MS option.]) - fi + if test "x$have_curlopt_timeout" = "xyes"; then + AC_DEFINE([HAVE_CURLOPT_TIMEOUT_MS], [1], + [Define if libcurl supports CURLOPT_TIMEOUT_MS option.] + ) + fi fi + +AC_SUBST(BUILD_WITH_LIBCURL_CFLAGS) +AC_SUBST(BUILD_WITH_LIBCURL_LIBS) # }}} # --with-libdbi {{{ -with_libdbi_cppflags="" -with_libdbi_ldflags="" -AC_ARG_WITH(libdbi, [AS_HELP_STRING([--with-libdbi@<:@=PREFIX@:>@], [Path to libdbi.])], -[ - if test "x$withval" != "xno" && test "x$withval" != "xyes" - then - with_libdbi_cppflags="-I$withval/include" - with_libdbi_ldflags="-L$withval/lib" - with_libdbi="yes" - else - with_libdbi="$withval" - fi -], -[ - with_libdbi="yes" -]) -if test "x$with_libdbi" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $with_libdbi_cppflags" +AC_ARG_WITH([libdbi], + [AS_HELP_STRING([--with-libdbi@<:@=PREFIX@:>@], [Path to libdbi.])], + [ + if test "x$withval" != "xno" && test "x$withval" != "xyes"; then + with_libdbi_cppflags="-I$withval/include" + with_libdbi_ldflags="-L$withval/lib" + with_libdbi="yes" + else + with_libdbi="$withval" + fi + ], + [with_libdbi="yes"] +) - AC_CHECK_HEADERS(dbi/dbi.h, [with_libdbi="yes"], [with_libdbi="no (dbi/dbi.h not found)"]) +if test "x$with_libdbi" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_libdbi_cppflags" - CPPFLAGS="$SAVE_CPPFLAGS" + AC_CHECK_HEADERS([dbi/dbi.h], + [with_libdbi="yes"], + [with_libdbi="no (dbi/dbi.h not found)"] + ) + + CPPFLAGS="$SAVE_CPPFLAGS" fi -if test "x$with_libdbi" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - SAVE_LDFLAGS="$LDFLAGS" - CPPFLAGS="$CPPFLAGS $with_libdbi_cppflags" - LDFLAGS="$LDFLAGS $with_libdbi_ldflags" - AC_CHECK_LIB(dbi, dbi_initialize, [with_libdbi="yes"], [with_libdbi="no (Symbol 'dbi_initialize' not found)"]) +if test "x$with_libdbi" = "xyes"; then + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $with_libdbi_ldflags" - CPPFLAGS="$SAVE_CPPFLAGS" - LDFLAGS="$SAVE_LDFLAGS" + AC_CHECK_LIB([dbi], [dbi_initialize], + [with_libdbi="yes"], + [with_libdbi="no (Symbol 'dbi_initialize' not found)"] + ) + + LDFLAGS="$SAVE_LDFLAGS" fi -if test "x$with_libdbi" = "xyes" -then - BUILD_WITH_LIBDBI_CPPFLAGS="$with_libdbi_cppflags" - BUILD_WITH_LIBDBI_LDFLAGS="$with_libdbi_ldflags" - BUILD_WITH_LIBDBI_LIBS="-ldbi" - AC_SUBST(BUILD_WITH_LIBDBI_CPPFLAGS) - AC_SUBST(BUILD_WITH_LIBDBI_LDFLAGS) - AC_SUBST(BUILD_WITH_LIBDBI_LIBS) -fi -AM_CONDITIONAL(BUILD_WITH_LIBDBI, test "x$with_libdbi" = "xyes") + +BUILD_WITH_LIBDBI_CPPFLAGS="$with_libdbi_cppflags" +BUILD_WITH_LIBDBI_LDFLAGS="$with_libdbi_ldflags" +BUILD_WITH_LIBDBI_LIBS="-ldbi" +AC_SUBST(BUILD_WITH_LIBDBI_CPPFLAGS) +AC_SUBST(BUILD_WITH_LIBDBI_LDFLAGS) +AC_SUBST(BUILD_WITH_LIBDBI_LIBS) # }}} # --with-libesmtp {{{ -AC_ARG_WITH(libesmtp, [AS_HELP_STRING([--with-libesmtp@<:@=PREFIX@:>@], [Path to libesmtp.])], -[ - if test "x$withval" != "xno" && test "x$withval" != "xyes" - then - LDFLAGS="$LDFLAGS -L$withval/lib" - CPPFLAGS="$CPPFLAGS -I$withval/include -D_THREAD_SAFE" - with_libesmtp="yes" - else - with_libesmtp="$withval" - fi -], -[ - with_libesmtp="yes" -]) -if test "x$with_libesmtp" = "xyes" -then - AC_CHECK_LIB(esmtp, smtp_create_session, - [ - AC_DEFINE(HAVE_LIBESMTP, 1, [Define to 1 if you have the esmtp library (-lesmtp).]) - ], [with_libesmtp="no (libesmtp not found)"]) -fi -if test "x$with_libesmtp" = "xyes" -then - AC_CHECK_HEADERS(libesmtp.h, - [ - AC_DEFINE(HAVE_LIBESMTP_H, 1, [Define to 1 if you have the header file.]) - ], [with_libesmtp="no (libesmtp.h not found)"]) -fi -if test "x$with_libesmtp" = "xyes" -then - collect_libesmtp=1 -else - collect_libesmtp=0 -fi -AC_DEFINE_UNQUOTED(COLLECT_LIBESMTP, [$collect_libesmtp], - [Wether or not to use the esmtp library]) -AM_CONDITIONAL(BUILD_WITH_LIBESMTP, test "x$with_libesmtp" = "xyes") -# }}} +AC_ARG_WITH([libesmtp], + [AS_HELP_STRING([--with-libesmtp@<:@=PREFIX@:>@], [Path to libesmtp.])], + [ + if test "x$withval" != "xno" && test "x$withval" != "xyes"; then + with_libesmtp_cppflags="-I$withval/include" + with_libesmtp_ldflags="-L$withval/lib" + with_libesmtp="yes" + else + with_libesmtp="$withval" + fi + ], + [with_libesmtp="yes"] +) -# --with-libganglia {{{ -AC_ARG_WITH(libganglia, [AS_HELP_STRING([--with-libganglia@<:@=PREFIX@:>@], [Path to libganglia.])], -[ - if test -f "$withval" && test -x "$withval" - then - with_libganglia_config="$withval" - with_libganglia="yes" - else if test -f "$withval/bin/ganglia-config" && test -x "$withval/bin/ganglia-config" - then - with_libganglia_config="$withval/bin/ganglia-config" - with_libganglia="yes" - else if test -d "$withval" - then - GANGLIA_CPPFLAGS="-I$withval/include" - GANGLIA_LDFLAGS="-L$withval/lib" - with_libganglia="yes" - else - with_libganglia="$withval" - fi; fi; fi -], -[ - with_libganglia="yes" -]) +if test "x$with_libesmtp" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_libesmtp_cppflags" -if test "x$with_libganglia" = "xyes" -then - if test "x$with_libganglia_config" != "x" - then - if test "x$GANGLIA_CPPFLAGS" = "x" - then - GANGLIA_CPPFLAGS=`"$with_libganglia_config" --cflags 2>/dev/null` - fi - - if test "x$GANGLIA_LDFLAGS" = "x" - then - GANGLIA_LDFLAGS=`"$with_libganglia_config" --ldflags 2>/dev/null` - fi - - if test "x$GANGLIA_LIBS" = "x" - then - GANGLIA_LIBS=`"$with_libganglia_config" --libs 2>/dev/null` - fi - else - GANGLIA_LIBS="-lganglia" - fi + AC_CHECK_HEADERS([libesmtp.h], + [with_libesmtp="yes"], + [with_libesmtp="no (libesmtp.h not found)"] + ) + + CPPFLAGS="$SAVE_CPPFLAGS" +fi + +if test "x$with_libesmtp" = "xyes"; then + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $with_esmtp_ldflags" + + AC_CHECK_LIB([esmtp], [smtp_create_session], + [with_libesmtp="yes"], + [with_libesmtp="no (Symbol 'smtp_create_session' not found)"] + ) + + LDFLAGS="$SAVE_LDFLAGS" +fi + +BUILD_WITH_LIBESMTP_CPPFLAGS="$with_libesmtp_cppflags" +BUILD_WITH_LIBESMTP_LDFLAGS="$with_libesmtp_ldflags" +BUILD_WITH_LIBESMTP_LIBS="-lesmtp" +AC_SUBST(BUILD_WITH_LIBESMTP_CPPFLAGS) +AC_SUBST(BUILD_WITH_LIBESMTP_LDFLAGS) +AC_SUBST(BUILD_WITH_LIBESMTP_LIBS) +# }}} + +# --with-libganglia {{{ +AC_ARG_WITH([libganglia], + [AS_HELP_STRING([--with-libganglia@<:@=PREFIX@:>@], [Path to libganglia.])], + [ + if test -f "$withval" && test -x "$withval"; then + with_libganglia_config="$withval" + with_libganglia="yes" + else if test -f "$withval/bin/ganglia-config" && test -x "$withval/bin/ganglia-config"; then + with_libganglia_config="$withval/bin/ganglia-config" + with_libganglia="yes" + else if test -d "$withval"; then + GANGLIA_CPPFLAGS="-I$withval/include" + GANGLIA_LDFLAGS="-L$withval/lib" + with_libganglia="yes" + else + with_libganglia="$withval" + fi; fi; fi + ], + [with_libganglia="yes"] +) + +if test "x$with_libganglia" = "xyes"; then + if test "x$with_libganglia_config" != "x"; then + if test "x$GANGLIA_CPPFLAGS" = "x"; then + GANGLIA_CPPFLAGS=`"$with_libganglia_config" --cflags 2>/dev/null` + fi + + if test "x$GANGLIA_LDFLAGS" = "x"; then + GANGLIA_LDFLAGS=`"$with_libganglia_config" --ldflags 2>/dev/null` + fi + + if test "x$GANGLIA_LIBS" = "x"; then + GANGLIA_LIBS=`"$with_libganglia_config" --libs 2>/dev/null` + fi + else + GANGLIA_LIBS="-lganglia" + fi fi SAVE_CPPFLAGS="$CPPFLAGS" @@ -2272,22 +2381,18 @@ SAVE_LDFLAGS="$LDFLAGS" CPPFLAGS="$CPPFLAGS $GANGLIA_CPPFLAGS" LDFLAGS="$LDFLAGS $GANGLIA_LDFLAGS" -if test "x$with_libganglia" = "xyes" -then - AC_CHECK_HEADERS(gm_protocol.h, - [ - AC_DEFINE(HAVE_GM_PROTOCOL_H, 1, - [Define to 1 if you have the header file.]) - ], [with_libganglia="no (gm_protocol.h not found)"]) +if test "x$with_libganglia" = "xyes"; then + AC_CHECK_HEADERS([gm_protocol.h], + [with_libganglia="yes"], + [with_libganglia="no (gm_protocol.h not found)"] + ) fi -if test "x$with_libganglia" = "xyes" -then - AC_CHECK_LIB(ganglia, xdr_Ganglia_value_msg, - [ - AC_DEFINE(HAVE_LIBGANGLIA, 1, - [Define to 1 if you have the ganglia library (-lganglia).]) - ], [with_libganglia="no (symbol xdr_Ganglia_value_msg not found)"]) +if test "x$with_libganglia" = "xyes"; then + AC_CHECK_LIB([ganglia], [xdr_Ganglia_value_msg], + [with_libganglia="yes"], + [with_libganglia="no (symbol xdr_Ganglia_value_msg not found)"] + ) fi CPPFLAGS="$SAVE_CPPFLAGS" @@ -2296,49 +2401,44 @@ LDFLAGS="$SAVE_LDFLAGS" AC_SUBST(GANGLIA_CPPFLAGS) AC_SUBST(GANGLIA_LDFLAGS) AC_SUBST(GANGLIA_LIBS) -AM_CONDITIONAL(BUILD_WITH_LIBGANGLIA, test "x$with_libganglia" = "xyes") # }}} # --with-libgcrypt {{{ GCRYPT_CPPFLAGS="$GCRYPT_CPPFLAGS" GCRYPT_LDFLAGS="$GCRYPT_LDFLAGS" GCRYPT_LIBS="$GCRYPT_LIBS" -AC_ARG_WITH(libgcrypt, [AS_HELP_STRING([--with-libgcrypt@<:@=PREFIX@:>@], [Path to libgcrypt.])], -[ - if test -f "$withval" && test -x "$withval" - then - with_libgcrypt_config="$withval" - with_libgcrypt="yes" - else if test -f "$withval/bin/gcrypt-config" && test -x "$withval/bin/gcrypt-config" - then - with_libgcrypt_config="$withval/bin/gcrypt-config" - with_libgcrypt="yes" - else if test -d "$withval" - then - GCRYPT_CPPFLAGS="$GCRYPT_CPPFLAGS -I$withval/include" - GCRYPT_LDFLAGS="$GCRYPT_LDFLAGS -L$withval/lib" - with_libgcrypt="yes" - else - with_libgcrypt_config="gcrypt-config" - with_libgcrypt="$withval" - fi; fi; fi -], -[ - with_libgcrypt_config="libgcrypt-config" - with_libgcrypt="yes" -]) +AC_ARG_WITH([libgcrypt], + [AS_HELP_STRING([--with-libgcrypt@<:@=PREFIX@:>@], [Path to libgcrypt.])], + [ + if test -f "$withval" && test -x "$withval"; then + with_libgcrypt_config="$withval" + with_libgcrypt="yes" + else if test -f "$withval/bin/gcrypt-config" && test -x "$withval/bin/gcrypt-config"; then + with_libgcrypt_config="$withval/bin/gcrypt-config" + with_libgcrypt="yes" + else if test -d "$withval"; then + GCRYPT_CPPFLAGS="$GCRYPT_CPPFLAGS -I$withval/include" + GCRYPT_LDFLAGS="$GCRYPT_LDFLAGS -L$withval/lib" + with_libgcrypt="yes" + else + with_libgcrypt_config="gcrypt-config" + with_libgcrypt="$withval" + fi; fi; fi + ], + [ + with_libgcrypt_config="libgcrypt-config" + with_libgcrypt="yes" + ] +) -if test "x$with_libgcrypt" = "xyes" && test "x$with_libgcrypt_config" != "x" -then - if test "x$GCRYPT_CPPFLAGS" = "x" - then - GCRYPT_CPPFLAGS=`"$with_libgcrypt_config" --cflags 2>/dev/null` - fi +if test "x$with_libgcrypt" = "xyes" && test "x$with_libgcrypt_config" != "x"; then + if test "x$GCRYPT_CPPFLAGS" = "x"; then + GCRYPT_CPPFLAGS=`"$with_libgcrypt_config" --cflags 2>/dev/null` + fi - if test "x$GCRYPT_LIBS" = "x" - then - GCRYPT_LIBS=`"$with_libgcrypt_config" --libs 2>/dev/null` - fi + if test "x$GCRYPT_LIBS" = "x"; then + GCRYPT_LIBS=`"$with_libgcrypt_config" --libs 2>/dev/null` + fi fi SAVE_CPPFLAGS="$CPPFLAGS" @@ -2348,118 +2448,108 @@ CPPFLAGS="$CPPFLAGS $GCRYPT_CPPFLAGS" LDFLAGS="$LDFLAGS $GCRYPT_LDFLAGS" LIBS="$LIBS $GCRYPT_LIBS" -if test "x$with_libgcrypt" = "xyes" -then - if test "x$GCRYPT_CPPFLAGS" != "x" - then - AC_MSG_NOTICE([gcrypt CPPFLAGS: $GCRYPT_CPPFLAGS]) - fi - AC_CHECK_HEADERS(gcrypt.h, - [with_libgcrypt="yes"], - [with_libgcrypt="no (gcrypt.h not found)"]) +if test "x$with_libgcrypt" = "xyes"; then + if test "x$GCRYPT_CPPFLAGS" != "x"; then + AC_MSG_NOTICE([gcrypt CPPFLAGS: $GCRYPT_CPPFLAGS]) + fi + AC_CHECK_HEADERS([gcrypt.h], + [with_libgcrypt="yes"], + [with_libgcrypt="no (gcrypt.h not found)"] + ) fi -if test "x$with_libgcrypt" = "xyes" -then - AC_CHECK_LIB(gcrypt, gcry_md_hash_buffer, - [with_libgcrypt="yes"], - [with_libgcrypt="no (symbol gcry_md_hash_buffer not found)"]) +if test "x$with_libgcrypt" = "xyes"; then + AC_CHECK_LIB(gcrypt, gcry_md_hash_buffer, + [with_libgcrypt="yes"], + [with_libgcrypt="no (symbol gcry_md_hash_buffer not found)"] + ) fi CPPFLAGS="$SAVE_CPPFLAGS" LDFLAGS="$SAVE_LDFLAGS" LIBS="$SAVE_LIBS" -if test "x$with_libgcrypt" = "xyes" -then - AC_DEFINE(HAVE_LIBGCRYPT, 1, [Define to 1 if you have the gcrypt library (-lgcrypt).]) -fi - -AC_SUBST(GCRYPT_CPPFLAGS) -AC_SUBST(GCRYPT_LDFLAGS) -AC_SUBST(GCRYPT_LIBS) -AM_CONDITIONAL(BUILD_WITH_LIBGCRYPT, test "x$with_libgcrypt" = "xyes") +AC_SUBST([GCRYPT_CPPFLAGS]) +AC_SUBST([GCRYPT_LDFLAGS]) +AC_SUBST([GCRYPT_LIBS]) +AM_CONDITIONAL([BUILD_WITH_LIBGCRYPT], [test "x$with_libgcrypt" = "xyes"]) # }}} # --with-libgps {{{ -with_libgps_cflags="" -with_libgps_ldflags="" -AC_ARG_WITH(libgps, [AS_HELP_STRING([--with-libgps@<:@=PREFIX@:>@], [Path to libgps.])], -[ - if test "x$withval" != "xno" && test "x$withval" != "xyes" - then - with_libgps_cflags="-I$withval/include" - with_libgps_ldflags="-L$withval/lib" - with_libgps="yes" - else - with_libgps="$withval" - fi -], -[ - with_libgps="yes" -]) -if test "x$with_libgps" = "xyes" -then - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $with_libgps_cflags" +AC_ARG_WITH([libgps], + [AS_HELP_STRING([--with-libgps@<:@=PREFIX@:>@], [Path to libgps.])], + [ + if test "x$withval" != "xno" && test "x$withval" != "xyes"; then + with_libgps_cflags="-I$withval/include" + with_libgps_ldflags="-L$withval/lib" + with_libgps="yes" + else + with_libgps="$withval" + fi + ], + [with_libgps="yes"] +) + +if test "x$with_libgps" = "xyes"; then + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $with_libgps_cflags" - AC_CHECK_HEADERS(gps.h, [with_libgps="yes"], [with_libgps="no (gps.h not found)"]) + AC_CHECK_HEADERS([gps.h], + [with_libgps="yes"], + [with_libgps="no (gps.h not found)"] + ) - CFLAGS="$SAVE_CFLAGS" + CFLAGS="$SAVE_CFLAGS" fi -if test "x$with_libgps" = "xyes" -then - SAVE_CFLAGS="$CFLAGS" - SAVE_LDFLAGS="$LDFLAGS" - CFLAGS="$CFLAGS $with_libgps_cflags" - LDFLAGS="$LDFLAGS $with_libgps_ldflags" - AC_CHECK_LIB(gps, gps_open, [with_libgps="yes"], [with_libgps="no (symbol gps_open not found)"]) +if test "x$with_libgps" = "xyes"; then + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $with_libgps_ldflags" - CFLAGS="$SAVE_CFLAGS" - LDFLAGS="$SAVE_LDFLAGS" + AC_CHECK_LIB([gps], [gps_open], + [with_libgps="yes"], + [with_libgps="no (symbol gps_open not found)"] + ) + + LDFLAGS="$SAVE_LDFLAGS" fi -if test "x$with_libgps" = "xyes" -then - BUILD_WITH_LIBGPS_CFLAGS="$with_libgps_cflags" - BUILD_WITH_LIBGPS_LDFLAGS="$with_libgps_ldflags" - BUILD_WITH_LIBGPS_LIBS="-lgps" - AC_SUBST(BUILD_WITH_LIBGPS_CFLAGS) - AC_SUBST(BUILD_WITH_LIBGPS_LDFLAGS) - AC_SUBST(BUILD_WITH_LIBGPS_LIBS) -fi -AM_CONDITIONAL(BUILD_WITH_LIBGPS, test "x$with_libgps" = "xyes") + +if test "x$with_libgps" = "xyes"; then + BUILD_WITH_LIBGPS_CFLAGS="$with_libgps_cflags" + BUILD_WITH_LIBGPS_LDFLAGS="$with_libgps_ldflags" + BUILD_WITH_LIBGPS_LIBS="-lgps" +fi + +AC_SUBST([BUILD_WITH_LIBGPS_CFLAGS]) +AC_SUBST([BUILD_WITH_LIBGPS_LDFLAGS]) +AC_SUBST([BUILD_WITH_LIBGPS_LIBS]) + # }}} # --with-libgrpc++ {{{ -with_libgrpcpp_cppflags="" -with_libgrpcpp_ldflags="" -AC_ARG_WITH([libgrpc++], [AS_HELP_STRING([--with-libgrpc++@<:@=PREFIX@:>@], [Path to libgrpc++.])], +AC_ARG_WITH([libgrpc++], + [AS_HELP_STRING([--with-libgrpc++@<:@=PREFIX@:>@], [Path to libgrpc++.])], [ with_grpcpp="$withval" - if test "x$withval" != "xno" && test "x$withval" != "xyes" - then + if test "x$withval" != "xno" && test "x$withval" != "xyes"; then with_libgrpcpp_cppflags="-I$withval/include" with_libgrpcpp_ldflags="-L$withval/lib" with_libgrpcpp="yes" fi - if test "x$withval" = "xno" - then + if test "x$withval" = "xno"; then with_libgrpcpp="no (disabled on command line)" fi ], [withval="yes"] ) -if test "x$withval" = "xyes" -then +if test "x$withval" = "xyes"; then PKG_CHECK_MODULES([GRPCPP], [grpc++], [with_libgrpcpp="yes"], [with_libgrpcpp="no (pkg-config could not find libgrpc++)"] ) fi -if test "x$withval" != "xno" -then +if test "x$withval" != "xno"; then AC_MSG_CHECKING([whether $CXX accepts -std=c++11]) if test_cxx_flags -std=c++11; then AC_MSG_RESULT([yes]) @@ -2469,40 +2559,40 @@ then fi fi -if test "x$with_libgrpcpp" = "xyes" -then +if test "x$with_libgrpcpp" = "xyes"; then AC_LANG_PUSH(C++) SAVE_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-std=c++11 $with_libgrpcpp_cppflags $GRPCPP_CFLAGS $CPPFLAGS" - AC_CHECK_HEADERS([grpc++/grpc++.h], [], + AC_CHECK_HEADERS([grpc++/grpc++.h], + [with_libgrpcpp="yes"], [with_libgrpcpp="no ( not found)"] ) CPPFLAGS="$SAVE_CPPFLAGS" AC_LANG_POP(C++) fi -if test "x$with_libgrpcpp" = "xyes" -then + +if test "x$with_libgrpcpp" = "xyes"; then AC_LANG_PUSH(C++) SAVE_CPPFLAGS="$CPPFLAGS" SAVE_LDFLAGS="$LDFLAGS" SAVE_LIBS="$LIBS" CPPFLAGS="-std=c++11 $with_libgrpcpp_cppflags $GRPCPP_CFLAGS $CPPFLAGS" LDFLAGS="$with_libgrpcpp_ldflags" - if test "x$GRPCPP_LIBS" = "x" - then + if test "x$GRPCPP_LIBS" = "x"; then LIBS="-lgrpc++" else LIBS="$GRPCPP_LIBS" fi AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[#include ]], - [[grpc::ServerBuilder sb;]] - )], + [ + AC_LANG_PROGRAM( + [[#include ]], + [[grpc::ServerBuilder sb;]] + ) + ], [ with_libgrpcpp="yes" - if test "x$GRPCPP_LIBS" = "x" - then + if test "x$GRPCPP_LIBS" = "x"; then GRPCPP_LIBS="-lgrpc++" fi ], @@ -2513,6 +2603,7 @@ then LIBS="$SAVE_LIBS" AC_LANG_POP(C++) fi + BUILD_WITH_LIBGRPCPP_CPPFLAGS="-std=c++11 $with_libgrpcpp_cppflags $GRPCPP_CFLAGS" BUILD_WITH_LIBGRPCPP_LDFLAGS="$with_libgrpcpp_ldflags" BUILD_WITH_LIBGRPCPP_LIBS="$GRPCPP_LIBS" @@ -2521,94 +2612,94 @@ AC_SUBST([BUILD_WITH_LIBGRPCPP_LDFLAGS]) AC_SUBST([BUILD_WITH_LIBGRPCPP_LIBS]) # }}} +AC_ARG_VAR([GRPC_CPP_PLUGIN], [path to the grpc_cpp_plugin binary]) +AC_PATH_PROG([GRPC_CPP_PLUGIN], [grpc_cpp_plugin]) +AM_CONDITIONAL([HAVE_GRPC_CPP], [test "x$GRPC_CPP_PLUGIN" != "x"]) + # --with-libiptc {{{ -AC_ARG_WITH(libiptc, [AS_HELP_STRING([--with-libiptc@<:@=PREFIX@:>@], [Path to libiptc.])], -[ - if test "x$withval" = "xyes" - then - with_libiptc="pkgconfig" - else if test "x$withval" = "xno" - then - with_libiptc="no" - else - with_libiptc="yes" - with_libiptc_cflags="-I$withval/include" - with_libiptc_libs="-L$withval/lib" - fi; fi -], -[ - if test "x$ac_system" = "xLinux" - then - with_libiptc="pkgconfig" - else - with_libiptc="no (Linux only)" - fi -]) +AC_ARG_WITH([libiptc], + [AS_HELP_STRING([--with-libiptc@<:@=PREFIX@:>@], [Path to libiptc.])], + [ + if test "x$withval" = "xyes"; then + with_libiptc="pkgconfig" + else if test "x$withval" = "xno"; then + with_libiptc="no" + else + with_libiptc="yes" + with_libiptc_cflags="-I$withval/include" + with_libiptc_libs="-L$withval/lib" + fi; fi + ], + [ + if test "x$ac_system" = "xLinux"; then + with_libiptc="pkgconfig" + else + with_libiptc="no (Linux only)" + fi + ] +) -if test "x$with_libiptc" = "xpkgconfig" -then - $PKG_CONFIG --exists 'libiptc' 2>/dev/null - if test $? -ne 0 - then - with_libiptc="no (pkg-config doesn't know libiptc)" - fi +if test "x$with_libiptc" = "xpkgconfig"; then + $PKG_CONFIG --exists 'libiptc' 2>/dev/null + if test $? -ne 0; then + with_libiptc="no (pkg-config doesn't know libiptc)" + fi fi -if test "x$with_libiptc" = "xpkgconfig" -then - with_libiptc_cflags="`$PKG_CONFIG --cflags 'libiptc'`" - if test $? -ne 0 - then - with_libiptc="no ($PKG_CONFIG failed)" - fi - with_libiptc_libs="`$PKG_CONFIG --libs 'libiptc'`" - if test $? -ne 0 - then - with_libiptc="no ($PKG_CONFIG failed)" - fi + +if test "x$with_libiptc" = "xpkgconfig"; then + with_libiptc_cflags="`$PKG_CONFIG --cflags 'libiptc'`" + if test $? -ne 0; then + with_libiptc="no ($PKG_CONFIG failed)" + fi + + with_libiptc_libs="`$PKG_CONFIG --libs 'libiptc'`" + if test $? -ne 0; then + with_libiptc="no ($PKG_CONFIG failed)" + fi fi SAVE_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $with_libiptc_cflags" # check whether the header file for libiptc is available. -if test "x$with_libiptc" = "xpkgconfig" -then - AC_CHECK_HEADERS(libiptc/libiptc.h libiptc/libip6tc.h, , - [with_libiptc="no (header file missing)"]) +if test "x$with_libiptc" = "xpkgconfig"; then + AC_CHECK_HEADERS([libiptc/libiptc.h libiptc/libip6tc.h], + [], + [with_libiptc="no (header file missing)"] + ) fi + # If the header file is available, check for the required type declaractions. # They may be missing in old versions of libiptc. In that case, they will be # declared in the iptables plugin. -if test "x$with_libiptc" = "xpkgconfig" -then - AC_CHECK_TYPES([iptc_handle_t, ip6tc_handle_t], [], []) +if test "x$with_libiptc" = "xpkgconfig"; then + AC_CHECK_TYPES([iptc_handle_t, ip6tc_handle_t], [], []) fi + # Check for the iptc_init symbol in the library. # This could be in iptc or ip4tc -if test "x$with_libiptc" = "xpkgconfig" -then - SAVE_LIBS="$LIBS" - AC_SEARCH_LIBS(iptc_init, [iptc ip4tc], - [with_libiptc="pkgconfig"], - [with_libiptc="no"], - [$with_libiptc_libs]) - LIBS="$SAVE_LIBS" -fi -if test "x$with_libiptc" = "xpkgconfig" -then - with_libiptc="yes" +if test "x$with_libiptc" = "xpkgconfig"; then + SAVE_LIBS="$LIBS" + AC_SEARCH_LIBS([iptc_init], [iptc ip4tc], + [with_libiptc="pkgconfig"], + [with_libiptc="no"], + [$with_libiptc_libs] + ) + LIBS="$SAVE_LIBS" +fi + +if test "x$with_libiptc" = "xpkgconfig"; then + with_libiptc="yes" fi CPPFLAGS="$SAVE_CPPFLAGS" -AM_CONDITIONAL(BUILD_WITH_LIBIPTC, test "x$with_libiptc" = "xyes") -if test "x$with_libiptc" = "xyes" -then - BUILD_WITH_LIBIPTC_CPPFLAGS="$with_libiptc_cflags" - BUILD_WITH_LIBIPTC_LDFLAGS="$with_libiptc_libs" - AC_SUBST(BUILD_WITH_LIBIPTC_CPPFLAGS) - AC_SUBST(BUILD_WITH_LIBIPTC_LDFLAGS) +if test "x$with_libiptc" = "xyes"; then + BUILD_WITH_LIBIPTC_CPPFLAGS="$with_libiptc_cflags" + BUILD_WITH_LIBIPTC_LDFLAGS="$with_libiptc_libs" fi +AC_SUBST([BUILD_WITH_LIBIPTC_CPPFLAGS]) +AC_SUBST([BUILD_WITH_LIBIPTC_LDFLAGS]) # }}} # --with-libdpdk {{{ @@ -2617,171 +2708,170 @@ AC_ARG_VAR([LIBDPDK_LDFLAGS], [Linker flags for libdpdk]) AC_ARG_WITH([libdpdk], [AS_HELP_STRING([--without-libdpdk], [Disable libdpdk.])]) -if test "x$with_libdpdk" != "xno" -then - if test "x$LIBDPDK_CPPFLAGS" = "x" - then - LIBDPDK_CPPFLAGS="-I/usr/include/dpdk" - fi - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$LIBDPDK_CPPFLAGS $CPPFLAGS" - AC_CHECK_HEADERS([rte_config.h], - [with_libdpdk="yes"], - [with_libdpdk="no (rte_config.h not found)"] - ) - CPPFLAGS="$SAVE_CPPFLAGS" +if test "x$with_libdpdk" != "xno"; then + if test "x$LIBDPDK_CPPFLAGS" = "x"; then + LIBDPDK_CPPFLAGS="-I/usr/include/dpdk" + fi + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$LIBDPDK_CPPFLAGS $CPPFLAGS" + AC_CHECK_HEADERS([rte_config.h], + [ + with_libdpdk="yes" + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM( + [[ + #include + #if RTE_VERSION < RTE_VERSION_NUM(16,7,0,0) + #error "required DPDK >= 16.07" + #endif + ]], + [[ + return 0; + ]] + ) + ], + [dpdk_keepalive="yes"], + [dpdk_keepalive="no (DPDK version < 16.07)"] + ) + ], + [with_libdpdk="no (rte_config.h not found)"] + ) + CPPFLAGS="$SAVE_CPPFLAGS" fi -if test "x$with_libdpdk" = "xyes" -then - SAVE_LDFLAGS="$LDFLAGS" - LDFLAGS="$LIBDPDK_LDFLAGS $LDFLAGS" - AC_CHECK_LIB([dpdk], [rte_eal_init], - [with_libdpdk="yes"], - [with_libdpdk="no (symbol 'rte_eal_init' not found)"] - ) - LDFLAGS="$SAVE_LDFLAGS" +if test "x$with_libdpdk" = "xyes"; then + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LIBDPDK_LDFLAGS $LDFLAGS" + AC_CHECK_LIB([dpdk], [rte_eal_init], + [with_libdpdk="yes"], + [with_libdpdk="no (symbol 'rte_eal_init' not found)"] + ) + LDFLAGS="$SAVE_LDFLAGS" fi # }}} # --with-java {{{ with_java_home="$JAVA_HOME" -if test "x$with_java_home" = "x" -then - with_java_home="/usr/lib/jvm" +if test "x$with_java_home" = "x"; then + with_java_home="/usr/lib/jvm" fi + JAVAC="$JAVAC" JAR="$JAR" -AC_ARG_WITH(java, [AS_HELP_STRING([--with-java@<:@=PREFIX@:>@], [Path to Java home.])], -[ - if test "x$withval" = "xno" - then - with_java="no" - else if test "x$withval" = "xyes" - then - with_java="yes" - else - with_java_home="$withval" - with_java="yes" - fi; fi -], -[with_java="yes"]) -if test "x$with_java" = "xyes" -then - if test -d "$with_java_home" - then - AC_MSG_CHECKING([for jni.h]) - TMPVAR=`find -L "$with_java_home" -name jni.h -type f -exec 'dirname' '{}' ';' 2>/dev/null | LC_ALL=C sort | head -n 1` - if test "x$TMPVAR" != "x" - then - AC_MSG_RESULT([found in $TMPVAR]) - JAVA_CPPFLAGS="$JAVA_CPPFLAGS -I$TMPVAR" - else - AC_MSG_RESULT([not found]) - fi - - AC_MSG_CHECKING([for jni_md.h]) - TMPVAR=`find -L "$with_java_home" -name jni_md.h -type f -exec 'dirname' '{}' ';' 2>/dev/null | LC_ALL=C sort | head -n 1` - if test "x$TMPVAR" != "x" - then - AC_MSG_RESULT([found in $TMPVAR]) - JAVA_CPPFLAGS="$JAVA_CPPFLAGS -I$TMPVAR" - else - AC_MSG_RESULT([not found]) - fi - - AC_MSG_CHECKING([for libjvm.so]) - TMPVAR=`find -L "$with_java_home" -type f \( -name libjvm.so -o -name libjvm.dylib \) -exec 'dirname' '{}' ';' 2>/dev/null | LC_ALL=C sort | head -n 1` - if test "x$TMPVAR" != "x" - then - AC_MSG_RESULT([found in $TMPVAR]) - JAVA_LDFLAGS="$JAVA_LDFLAGS -L$TMPVAR -Wl,-rpath -Wl,$TMPVAR" - else - AC_MSG_RESULT([not found]) - fi - - if test "x$JAVAC" = "x" - then - AC_MSG_CHECKING([for javac]) - TMPVAR=`find -L "$with_java_home" -name javac -type f 2>/dev/null | LC_ALL=C sort | head -n 1` - if test "x$TMPVAR" != "x" - then - JAVAC="$TMPVAR" - AC_MSG_RESULT([$JAVAC]) - else - AC_MSG_RESULT([not found]) - fi - fi - if test "x$JAR" = "x" - then - AC_MSG_CHECKING([for jar]) - TMPVAR=`find -L "$with_java_home" -name jar -type f 2>/dev/null | LC_ALL=C sort | head -n 1` - if test "x$TMPVAR" != "x" - then - JAR="$TMPVAR" - AC_MSG_RESULT([$JAR]) - else - AC_MSG_RESULT([not found]) - fi - fi - else if test "x$with_java_home" != "x" - then - AC_MSG_WARN([JAVA_HOME: No such directory: $with_java_home]) - fi; fi +AC_ARG_WITH([java], + [AS_HELP_STRING([--with-java@<:@=PREFIX@:>@], [Path to Java home.])], + [ + if test "x$withval" = "xno"; then + with_java="no" + else if test "x$withval" = "xyes"; then + with_java="yes" + else + with_java_home="$withval" + with_java="yes" + fi; fi + ], + [with_java="yes"] +) + +if test "x$with_java" = "xyes"; then + if test -d "$with_java_home"; then + AC_MSG_CHECKING([for jni.h]) + TMPVAR=`find -L "$with_java_home" -name jni.h -type f -exec 'dirname' '{}' ';' 2>/dev/null | LC_ALL=C sort | head -n 1` + if test "x$TMPVAR" != "x"; then + AC_MSG_RESULT([found in $TMPVAR]) + JAVA_CPPFLAGS="$JAVA_CPPFLAGS -I$TMPVAR" + else + AC_MSG_RESULT([not found]) + fi + + AC_MSG_CHECKING([for jni_md.h]) + TMPVAR=`find -L "$with_java_home" -name jni_md.h -type f -exec 'dirname' '{}' ';' 2>/dev/null | LC_ALL=C sort | head -n 1` + if test "x$TMPVAR" != "x"; then + AC_MSG_RESULT([found in $TMPVAR]) + JAVA_CPPFLAGS="$JAVA_CPPFLAGS -I$TMPVAR" + else + AC_MSG_RESULT([not found]) + fi + + AC_MSG_CHECKING([for libjvm.so]) + TMPVAR=`find -L "$with_java_home" -type f \( -name libjvm.so -o -name libjvm.dylib \) -exec 'dirname' '{}' ';' 2>/dev/null | LC_ALL=C sort | head -n 1` + if test "x$TMPVAR" != "x"; then + AC_MSG_RESULT([found in $TMPVAR]) + JAVA_LDFLAGS="$JAVA_LDFLAGS -L$TMPVAR -Wl,-rpath -Wl,$TMPVAR" + else + AC_MSG_RESULT([not found]) + fi + + if test "x$JAVAC" = "x"; then + AC_MSG_CHECKING([for javac]) + TMPVAR=`find -L "$with_java_home" -name javac -type f 2>/dev/null | LC_ALL=C sort | head -n 1` + if test "x$TMPVAR" != "x"; then + JAVAC="$TMPVAR" + AC_MSG_RESULT([$JAVAC]) + else + AC_MSG_RESULT([not found]) + fi + fi + + if test "x$JAR" = "x"; then + AC_MSG_CHECKING([for jar]) + TMPVAR=`find -L "$with_java_home" -name jar -type f 2>/dev/null | LC_ALL=C sort | head -n 1` + if test "x$TMPVAR" != "x"; then + JAR="$TMPVAR" + AC_MSG_RESULT([$JAR]) + else + AC_MSG_RESULT([not found]) + fi + fi + else if test "x$with_java_home" != "x"; then + AC_MSG_WARN([JAVA_HOME: No such directory: $with_java_home]) + fi; fi fi -if test "x$JAVA_CPPFLAGS" != "x" -then - AC_MSG_NOTICE([Building with JAVA_CPPFLAGS set to: $JAVA_CPPFLAGS]) +if test "x$JAVA_CPPFLAGS" != "x"; then + AC_MSG_NOTICE([Building with JAVA_CPPFLAGS set to: $JAVA_CPPFLAGS]) fi -if test "x$JAVA_CFLAGS" != "x" -then - AC_MSG_NOTICE([Building with JAVA_CFLAGS set to: $JAVA_CFLAGS]) +if test "x$JAVA_CFLAGS" != "x"; then + AC_MSG_NOTICE([Building with JAVA_CFLAGS set to: $JAVA_CFLAGS]) fi -if test "x$JAVA_LDFLAGS" != "x" -then - AC_MSG_NOTICE([Building with JAVA_LDFLAGS set to: $JAVA_LDFLAGS]) +if test "x$JAVA_LDFLAGS" != "x"; then + AC_MSG_NOTICE([Building with JAVA_LDFLAGS set to: $JAVA_LDFLAGS]) fi -if test "x$JAVA_LIBS" != "x" -then - AC_MSG_NOTICE([Building with JAVA_LIBS set to: $JAVA_LIBS]) +if test "x$JAVA_LIBS" != "x"; then + AC_MSG_NOTICE([Building with JAVA_LIBS set to: $JAVA_LIBS]) fi -if test "x$JAVAC" = "x" -then - with_javac_path="$PATH" - if test "x$with_java_home" != "x" - then - with_javac_path="$with_java_home:with_javac_path" - if test -d "$with_java_home/bin" - then - with_javac_path="$with_java_home/bin:with_javac_path" - fi - fi +if test "x$JAVAC" = "x"; then + with_javac_path="$PATH" + if test "x$with_java_home" != "x"; then + with_javac_path="$with_java_home:with_javac_path" + if test -d "$with_java_home/bin"; then + with_javac_path="$with_java_home/bin:with_javac_path" + fi + fi - AC_PATH_PROG(JAVAC, javac, [], "$with_javac_path") + AC_PATH_PROG([JAVAC], [javac], [], "$with_javac_path") fi -if test "x$JAVAC" = "x" -then - with_java="no (javac not found)" + +if test "x$JAVAC" = "x"; then + with_java="no (javac not found)" fi -if test "x$JAR" = "x" -then - with_jar_path="$PATH" - if test "x$with_java_home" != "x" - then - with_jar_path="$with_java_home:$with_jar_path" - if test -d "$with_java_home/bin" - then - with_jar_path="$with_java_home/bin:$with_jar_path" - fi - fi - AC_PATH_PROG(JAR, jar, [], "$with_jar_path") +if test "x$JAR" = "x"; then + with_jar_path="$PATH" + if test "x$with_java_home" != "x"; then + with_jar_path="$with_java_home:$with_jar_path" + if test -d "$with_java_home/bin"; then + with_jar_path="$with_java_home/bin:$with_jar_path" + fi + fi + + AC_PATH_PROG([JAR], [jar], [], "$with_jar_path") fi -if test "x$JAR" = "x" -then - with_java="no (jar not found)" + +if test "x$JAR" = "x"; then + with_java="no (jar not found)" fi SAVE_CPPFLAGS="$CPPFLAGS" @@ -2793,21 +2883,23 @@ CFLAGS="$CFLAGS $JAVA_CFLAGS" LDFLAGS="$LDFLAGS $JAVA_LDFLAGS" LIBS="$LIBS $JAVA_LIBS" -if test "x$with_java" = "xyes" -then - AC_CHECK_HEADERS(jni.h, [], [with_java="no (jni.h not found)"]) +if test "x$with_java" = "xyes"; then + AC_CHECK_HEADERS([jni.h], + [with_jave="yes"], + [with_java="no (jni.h not found)"]) fi -if test "x$with_java" = "xyes" -then - AC_CHECK_LIB(jvm, JNI_CreateJavaVM, - [with_java="yes"], - [with_java="no (Symbol 'JNI_CreateJavaVM' not found)"], - [$JAVA_LIBS $PTHREAD_LIBS]) + +if test "x$with_java" = "xyes"; then + AC_CHECK_LIB([jvm], [JNI_CreateJavaVM], + [with_java="yes"], + [with_java="no (Symbol 'JNI_CreateJavaVM' not found)"], + [$JAVA_LIBS $PTHREAD_LIBS] + ) fi -if test "x$with_java" = "xyes" -then - JAVA_LIBS="$JAVA_LIBS -ljvm" - AC_MSG_NOTICE([Building with JAVA_LIBS set to: $JAVA_LIBS]) + +if test "x$with_java" = "xyes"; then + JAVA_LIBS="$JAVA_LIBS -ljvm" + AC_MSG_NOTICE([Building with JAVA_LIBS set to: $JAVA_LIBS]) fi CPPFLAGS="$SAVE_CPPFLAGS" @@ -2815,29 +2907,29 @@ CFLAGS="$SAVE_CFLAGS" LDFLAGS="$SAVE_LDFLAGS" LIBS="$SAVE_LIBS" -AC_SUBST(JAVA_CPPFLAGS) -AC_SUBST(JAVA_CFLAGS) -AC_SUBST(JAVA_LDFLAGS) -AC_SUBST(JAVA_LIBS) -AM_CONDITIONAL(BUILD_WITH_JAVA, test "x$with_java" = "xyes") +AC_SUBST([JAVA_CPPFLAGS]) +AC_SUBST([JAVA_CFLAGS]) +AC_SUBST([JAVA_LDFLAGS]) +AC_SUBST([JAVA_LIBS]) +AM_CONDITIONAL([BUILD_WITH_JAVA], [test "x$with_java" = "xyes"]) # }}} # --with-libldap {{{ -AC_ARG_WITH(libldap, [AS_HELP_STRING([--with-libldap@<:@=PREFIX@:>@], [Path to libldap.])], -[ - if test "x$withval" = "xyes" - then - with_libldap="yes" - else if test "x$withval" = "xno" - then - with_libldap="no" - else - with_libldap="yes" - LIBLDAP_CPPFLAGS="$LIBLDAP_CPPFLAGS -I$withval/include" - LIBLDAP_LDFLAGS="$LIBLDAP_LDFLAGS -L$withval/lib" - fi; fi -], -[with_libldap="yes"]) +AC_ARG_WITH([libldap], + [AS_HELP_STRING([--with-libldap@<:@=PREFIX@:>@], [Path to libldap.])], + [ + if test "x$withval" = "xyes"; then + with_libldap="yes" + else if test "x$withval" = "xno"; then + with_libldap="no" + else + with_libldap="yes" + LIBLDAP_CPPFLAGS="$LIBLDAP_CPPFLAGS -I$withval/include" + LIBLDAP_LDFLAGS="$LIBLDAP_LDFLAGS -L$withval/lib" + fi; fi + ], + [with_libldap="yes"] +) SAVE_CPPFLAGS="$CPPFLAGS" SAVE_LDFLAGS="$LDFLAGS" @@ -2845,26 +2937,26 @@ SAVE_LDFLAGS="$LDFLAGS" CPPFLAGS="$CPPFLAGS $LIBLDAP_CPPFLAGS" LDFLAGS="$LDFLAGS $LIBLDAP_LDFLAGS" -if test "x$with_libldap" = "xyes" -then - if test "x$LIBLDAP_CPPFLAGS" != "x" - then - AC_MSG_NOTICE([libldap CPPFLAGS: $LIBLDAP_CPPFLAGS]) - fi - AC_CHECK_HEADERS(ldap.h, - [with_libldap="yes"], - [with_libldap="no ('ldap.h' not found)"]) -fi -if test "x$with_libldap" = "xyes" -then - if test "x$LIBLDAP_LDFLAGS" != "x" - then - AC_MSG_NOTICE([libldap LDFLAGS: $LIBLDAP_LDFLAGS]) - fi - AC_CHECK_LIB(ldap, ldap_initialize, - [with_libldap="yes"], - [with_libldap="no (symbol 'ldap_initialize' not found)"]) +if test "x$with_libldap" = "xyes"; then + if test "x$LIBLDAP_CPPFLAGS" != "x"; then + AC_MSG_NOTICE([libldap CPPFLAGS: $LIBLDAP_CPPFLAGS]) + fi + AC_CHECK_HEADERS([ldap.h], + [with_libldap="yes"], + [with_libldap="no ('ldap.h' not found)"] + ) +fi + +if test "x$with_libldap" = "xyes"; then + if test "x$LIBLDAP_LDFLAGS" != "x"; then + AC_MSG_NOTICE([libldap LDFLAGS: $LIBLDAP_LDFLAGS]) + fi + + AC_CHECK_LIB([ldap], [ldap_initialize], + [with_libldap="yes"], + [with_libldap="no (symbol 'ldap_initialize' not found)"] + ) fi CPPFLAGS="$SAVE_CPPFLAGS" @@ -2872,12 +2964,11 @@ LDFLAGS="$SAVE_LDFLAGS" if test "x$with_libldap" = "xyes" then - BUILD_WITH_LIBLDAP_CPPFLAGS="$LIBLDAP_CPPFLAGS" - BUILD_WITH_LIBLDAP_LDFLAGS="$LIBLDAP_LDFLAGS" - AC_SUBST(BUILD_WITH_LIBLDAP_CPPFLAGS) - AC_SUBST(BUILD_WITH_LIBLDAP_LDFLAGS) + BUILD_WITH_LIBLDAP_CPPFLAGS="$LIBLDAP_CPPFLAGS" + BUILD_WITH_LIBLDAP_LDFLAGS="$LIBLDAP_LDFLAGS" fi -AM_CONDITIONAL(BUILD_WITH_LIBLDAP, test "x$with_libldap" = "xyes") +AC_SUBST([BUILD_WITH_LIBLDAP_CPPFLAGS]) +AC_SUBST([BUILD_WITH_LIBLDAP_LDFLAGS]) # }}} # --with-liblua {{{ @@ -2895,7 +2986,7 @@ else PKG_CHECK_MODULES([LUA], [lua-5.3], [with_liblua="yes"], [ - PKG_CHECK_MODULES([LUA], [lua5.3], + PKG_CHECK_MODULES([LUA], [lua5.3], [with_liblua="yes"], [ PKG_CHECK_MODULES([LUA], [lua-5.2], @@ -2961,114 +3052,117 @@ AC_SUBST(BUILD_WITH_LIBLUA_LIBS) # }}} # --with-liblvm2app {{{ -with_liblvm2app_cppflags="" -with_liblvm2app_ldflags="" -AC_ARG_WITH(liblvm2app, [AS_HELP_STRING([--with-liblvm2app@<:@=PREFIX@:>@], [Path to liblvm2app.])], -[ - if test "x$withval" = "xno" - then - with_liblvm2app="no" - else - with_liblvm2app="yes" - if test "x$withval" != "xyes" - then - with_liblvm2app_cppflags="-I$withval/include" - with_liblvm2app_ldflags="-L$withval/lib" - fi - fi -], -[ - if test "x$ac_system" = "xLinux" - then - with_liblvm2app="yes" - else - with_liblvm2app="no (Linux only library)" - fi -]) -if test "x$with_liblvm2app" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $with_liblvm2app_cppflags" +AC_ARG_WITH([liblvm2app], + [AS_HELP_STRING([--with-liblvm2app@<:@=PREFIX@:>@], [Path to liblvm2app.])], + [ + if test "x$withval" = "xno"; then + with_liblvm2app="no" + else + with_liblvm2app="yes" + if test "x$withval" != "xyes"; then + with_liblvm2app_cppflags="-I$withval/include" + with_liblvm2app_ldflags="-L$withval/lib" + fi + fi + ], + [ + if test "x$ac_system" = "xLinux"; then + with_liblvm2app="yes" + else + with_liblvm2app="no (Linux only library)" + fi + ] +) + +if test "x$with_liblvm2app" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_liblvm2app_cppflags" - AC_CHECK_HEADERS(lvm2app.h, [with_liblvm2app="yes"], [with_liblvm2app="no (lvm2app.h not found)"]) + AC_CHECK_HEADERS([lvm2app.h], + [with_liblvm2app="yes"], + [with_liblvm2app="no (lvm2app.h not found)"] + ) - CPPFLAGS="$SAVE_CPPFLAGS" + CPPFLAGS="$SAVE_CPPFLAGS" fi -if test "x$with_liblvm2app" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - SAVE_LDFLAGS="$LDFLAGS" - CPPFLAGS="$CPPFLAGS $with_liblvm2app_cppflags" - LDFLAGS="$LDFLAGS $with_liblvm2app_ldflags" +if test "x$with_liblvm2app" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + SAVE_LDFLAGS="$LDFLAGS" + CPPFLAGS="$CPPFLAGS $with_liblvm2app_cppflags" + LDFLAGS="$LDFLAGS $with_liblvm2app_ldflags" + + AC_CHECK_LIB([lvm2app], [lvm_lv_get_property], + [with_liblvm2app="yes"], + [with_liblvm2app="no (Symbol 'lvm_lv_get_property' not found)"] + ) - AC_CHECK_LIB(lvm2app, lvm_lv_get_property, [with_liblvm2app="yes"], [with_liblvm2app="no (Symbol 'lvm_lv_get_property' not found)"]) + CPPFLAGS="$SAVE_CPPFLAGS" + LDFLAGS="$SAVE_LDFLAGS" +fi - CPPFLAGS="$SAVE_CPPFLAGS" - LDFLAGS="$SAVE_LDFLAGS" +if test "x$with_liblvm2app" = "xyes"; then + BUILD_WITH_LIBLVM2APP_CPPFLAGS="$with_liblvm2app_cppflags" + BUILD_WITH_LIBLVM2APP_LDFLAGS="$with_liblvm2app_ldflags" + BUILD_WITH_LIBLVM2APP_LIBS="-llvm2app" fi -if test "x$with_liblvm2app" = "xyes" -then - BUILD_WITH_LIBLVM2APP_CPPFLAGS="$with_liblvm2app_cppflags" - BUILD_WITH_LIBLVM2APP_LDFLAGS="$with_liblvm2app_ldflags" - BUILD_WITH_LIBLVM2APP_LIBS="-llvm2app" - AC_SUBST(BUILD_WITH_LIBLVM2APP_CPPFLAGS) - AC_SUBST(BUILD_WITH_LIBLVM2APP_LDFLAGS) - AC_SUBST(BUILD_WITH_LIBLVM2APP_LIBS) - AC_DEFINE(HAVE_LIBLVM2APP, 1, [Define if liblvm2app is present and usable.]) -fi -AM_CONDITIONAL(BUILD_WITH_LIBLVM2APP, test "x$with_liblvm2app" = "xyes") + +AC_SUBST([BUILD_WITH_LIBLVM2APP_CPPFLAGS]) +AC_SUBST([BUILD_WITH_LIBLVM2APP_LDFLAGS]) +AC_SUBST([BUILD_WITH_LIBLVM2APP_LIBS]) # }}} # --with-libmemcached {{{ -with_libmemcached_cppflags="" -with_libmemcached_ldflags="" -AC_ARG_WITH(libmemcached, [AS_HELP_STRING([--with-libmemcached@<:@=PREFIX@:>@], [Path to libmemcached.])], -[ - if test "x$withval" != "xno" && test "x$withval" != "xyes" - then - with_libmemcached_cppflags="-I$withval/include" - with_libmemcached_ldflags="-L$withval/lib" - with_libmemcached="yes" - else - with_libmemcached="$withval" - fi -], -[ - with_libmemcached="yes" -]) -if test "x$with_libmemcached" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $with_libmemcached_cppflags" +AC_ARG_WITH([libmemcached], + [AS_HELP_STRING([--with-libmemcached@<:@=PREFIX@:>@], [Path to libmemcached.])], + [ + if test "x$withval" != "xno" && test "x$withval" != "xyes"; then + with_libmemcached_cppflags="-I$withval/include" + with_libmemcached_ldflags="-L$withval/lib" + with_libmemcached="yes" + else + with_libmemcached="$withval" + fi + ], + [with_libmemcached="yes"] +) - AC_CHECK_HEADERS(libmemcached/memcached.h, [with_libmemcached="yes"], [with_libmemcached="no (libmemcached/memcached.h not found)"]) +if test "x$with_libmemcached" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_libmemcached_cppflags" - CPPFLAGS="$SAVE_CPPFLAGS" + AC_CHECK_HEADERS([libmemcached/memcached.h], + [with_libmemcached="yes"], + [with_libmemcached="no (libmemcached/memcached.h not found)"] + ) + + CPPFLAGS="$SAVE_CPPFLAGS" fi -if test "x$with_libmemcached" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - SAVE_LDFLAGS="$LDFLAGS" - CPPFLAGS="$CPPFLAGS $with_libmemcached_cppflags" - LDFLAGS="$LDFLAGS $with_libmemcached_ldflags" - AC_CHECK_LIB(memcached, memcached_create, [with_libmemcached="yes"], [with_libmemcached="no (Symbol 'memcached_create' not found)"]) +if test "x$with_libmemcached" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + SAVE_LDFLAGS="$LDFLAGS" + CPPFLAGS="$CPPFLAGS $with_libmemcached_cppflags" + LDFLAGS="$LDFLAGS $with_libmemcached_ldflags" - CPPFLAGS="$SAVE_CPPFLAGS" - LDFLAGS="$SAVE_LDFLAGS" + AC_CHECK_LIB([memcached], [memcached_create], + [with_libmemcached="yes"], + [with_libmemcached="no (Symbol 'memcached_create' not found)"] + ) + + CPPFLAGS="$SAVE_CPPFLAGS" + LDFLAGS="$SAVE_LDFLAGS" fi -if test "x$with_libmemcached" = "xyes" -then - BUILD_WITH_LIBMEMCACHED_CPPFLAGS="$with_libmemcached_cppflags" - BUILD_WITH_LIBMEMCACHED_LDFLAGS="$with_libmemcached_ldflags" - BUILD_WITH_LIBMEMCACHED_LIBS="-lmemcached" - AC_SUBST(BUILD_WITH_LIBMEMCACHED_CPPFLAGS) - AC_SUBST(BUILD_WITH_LIBMEMCACHED_LDFLAGS) - AC_SUBST(BUILD_WITH_LIBMEMCACHED_LIBS) - AC_DEFINE(HAVE_LIBMEMCACHED, 1, [Define if libmemcached is present and usable.]) -fi -AM_CONDITIONAL(BUILD_WITH_LIBMEMCACHED, test "x$with_libmemcached" = "xyes") + +if test "x$with_libmemcached" = "xyes"; then + BUILD_WITH_LIBMEMCACHED_CPPFLAGS="$with_libmemcached_cppflags" + BUILD_WITH_LIBMEMCACHED_LDFLAGS="$with_libmemcached_ldflags" + BUILD_WITH_LIBMEMCACHED_LIBS="-lmemcached" +fi + +AC_SUBST([BUILD_WITH_LIBMEMCACHED_CPPFLAGS]) +AC_SUBST([BUILD_WITH_LIBMEMCACHED_LDFLAGS]) +AC_SUBST([BUILD_WITH_LIBMEMCACHED_LIBS]) # }}} # --with-libmicrohttpd {{{ @@ -3076,29 +3170,25 @@ with_libmicrohttpd_cppflags="" with_libmicrohttpd_ldflags="" AC_ARG_WITH([libmicrohttpd], [AS_HELP_STRING([--with-libmicrohttpd@<:@=PREFIX@:>@], [Path to libmicrohttpd.])], [ - if test "x$withval" != "xno" && test "x$withval" != "xyes" - then + if test "x$withval" != "xno" && test "x$withval" != "xyes"; then with_libmicrohttpd_cppflags="-I$withval/include" with_libmicrohttpd_ldflags="-L$withval/lib" with_libmicrohttpd="yes" fi - if test "x$withval" = "xno" - then + if test "x$withval" = "xno"; then with_libmicrohttpd="no (disabled on command line)" fi ], [withval="yes"] ) -if test "x$withval" = "xyes" -then -PKG_CHECK_MODULES([MICROHTTPD], [libmicrohttpd], - [with_libmicrohttpd="yes"], - [with_libmicrohttpd="no (pkg-config could not find libmicrohttpd)"] -) +if test "x$withval" = "xyes"; then + PKG_CHECK_MODULES([MICROHTTPD], [libmicrohttpd], + [with_libmicrohttpd="yes"], + [with_libmicrohttpd="no (pkg-config could not find libmicrohttpd)"] + ) fi -if test "x$MICROHTTPD_LIBS" = "x" -then +if test "x$MICROHTTPD_LIBS" = "x"; then MICROHTTPD_LIBS="-lmicrohttpd" fi @@ -3109,18 +3199,18 @@ CPPFLAGS="$with_libmicrohttpd_cppflags $MICROHTTPD_CFLAGS" LDFLAGS="$with_libmicrohttpd_ldflags $LDFLAGS" LIBS="$LIBS $MICROHTTPD_LIBS" -if test "x$with_libmicrohttpd" = "xyes" -then +if test "x$with_libmicrohttpd" = "xyes"; then AC_CHECK_HEADERS([microhttpd.h], - [with_libmicrohttpd="yes"], - [with_libmicrohttpd="no ( not found)"]) + [with_libmicrohttpd="yes"], + [with_libmicrohttpd="no ( 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" @@ -3136,473 +3226,454 @@ AC_SUBST([BUILD_WITH_LIBMICROHTTPD_LIBS]) # }}} # --with-libmodbus {{{ -with_libmodbus_config="" -with_libmodbus_cflags="" -with_libmodbus_libs="" -AC_ARG_WITH(libmodbus, [AS_HELP_STRING([--with-libmodbus@<:@=PREFIX@:>@], [Path to the modbus library.])], -[ - if test "x$withval" = "xno" - then - with_libmodbus="no" - else if test "x$withval" = "xyes" - then - with_libmodbus="use_pkgconfig" - else if test -d "$with_libmodbus/lib" - then - AC_MSG_NOTICE([Not checking for libmodbus: Manually configured]) - with_libmodbus_cflags="-I$withval/include" - with_libmodbus_libs="-L$withval/lib -lmodbus" - with_libmodbus="yes" - fi; fi; fi -], -[with_libmodbus="use_pkgconfig"]) +AC_ARG_WITH([libmodbus], + [AS_HELP_STRING([--with-libmodbus@<:@=PREFIX@:>@], [Path to the modbus library.])], + [ + if test "x$withval" = "xno"; then + with_libmodbus="no" + else if test "x$withval" = "xyes"; then + with_libmodbus="use_pkgconfig" + else if test -d "$with_libmodbus/lib"; then + AC_MSG_NOTICE([Not checking for libmodbus: Manually configured]) + with_libmodbus_cflags="-I$withval/include" + with_libmodbus_libs="-L$withval/lib -lmodbus" + with_libmodbus="yes" + fi; fi; fi + ], + [with_libmodbus="use_pkgconfig"] +) # configure using pkg-config -if test "x$with_libmodbus" = "xuse_pkgconfig" -then - AC_MSG_NOTICE([Checking for libmodbus using $PKG_CONFIG]) - $PKG_CONFIG --exists 'libmodbus' 2>/dev/null - if test $? -ne 0 - then - with_libmodbus="no (pkg-config doesn't know libmodbus)" - fi +if test "x$with_libmodbus" = "xuse_pkgconfig"; then + AC_MSG_NOTICE([Checking for libmodbus using $PKG_CONFIG]) + $PKG_CONFIG --exists 'libmodbus' 2>/dev/null + if test $? -ne 0; then + with_libmodbus="no (pkg-config doesn't know libmodbus)" + fi fi -if test "x$with_libmodbus" = "xuse_pkgconfig" -then - with_libmodbus_cflags="`$PKG_CONFIG --cflags 'libmodbus'`" - if test $? -ne 0 - then - with_libmodbus="no ($PKG_CONFIG failed)" - fi - with_libmodbus_libs="`$PKG_CONFIG --libs 'libmodbus'`" - if test $? -ne 0 - then - with_libmodbus="no ($PKG_CONFIG failed)" - fi + +if test "x$with_libmodbus" = "xuse_pkgconfig"; then + with_libmodbus_cflags="`$PKG_CONFIG --cflags 'libmodbus'`" + if test $? -ne 0; then + with_libmodbus="no ($PKG_CONFIG failed)" + fi + + with_libmodbus_libs="`$PKG_CONFIG --libs 'libmodbus'`" + if test $? -ne 0; then + with_libmodbus="no ($PKG_CONFIG failed)" + fi fi -if test "x$with_libmodbus" = "xuse_pkgconfig" -then - with_libmodbus="yes" + +if test "x$with_libmodbus" = "xuse_pkgconfig"; then + with_libmodbus="yes" fi -# with_libmodbus_cflags and with_libmodbus_libs are set up now, let's do -# the actual checks. -if test "x$with_libmodbus" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $with_libmodbus_cflags" +if test "x$with_libmodbus" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_libmodbus_cflags" - AC_CHECK_HEADERS(modbus.h, [], [with_libmodbus="no (modbus.h not found)"]) + AC_CHECK_HEADERS([modbus.h], + [with_libmodbus="yes"], + [with_libmodbus="no (modbus.h not found)"] + ) - CPPFLAGS="$SAVE_CPPFLAGS" + CPPFLAGS="$SAVE_CPPFLAGS" fi -if test "x$with_libmodbus" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - SAVE_LDFLAGS="$LDFLAGS" - CPPFLAGS="$CPPFLAGS $with_libmodbus_cflags" - LDFLAGS="$LDFLAGS $with_libmodbus_libs" +if test "x$with_libmodbus" = "xyes"; then + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $with_libmodbus_libs" - AC_CHECK_LIB(modbus, modbus_connect, - [with_libmodbus="yes"], - [with_libmodbus="no (symbol modbus_connect not found)"]) + AC_CHECK_LIB([modbus], [modbus_connect], + [with_libmodbus="yes"], + [with_libmodbus="no (symbol modbus_connect not found)"] + ) - CPPFLAGS="$SAVE_CPPFLAGS" - LDFLAGS="$SAVE_LDFLAGS" + LDFLAGS="$SAVE_LDFLAGS" fi -if test "x$with_libmodbus" = "xyes" -then - BUILD_WITH_LIBMODBUS_CFLAGS="$with_libmodbus_cflags" - BUILD_WITH_LIBMODBUS_LIBS="$with_libmodbus_libs" - AC_SUBST(BUILD_WITH_LIBMODBUS_CFLAGS) - AC_SUBST(BUILD_WITH_LIBMODBUS_LIBS) + +if test "x$with_libmodbus" = "xyes"; then + BUILD_WITH_LIBMODBUS_CFLAGS="$with_libmodbus_cflags" + BUILD_WITH_LIBMODBUS_LIBS="$with_libmodbus_libs" fi + +AC_SUBST([BUILD_WITH_LIBMODBUS_CFLAGS]) +AC_SUBST([BUILD_WITH_LIBMODBUS_LIBS]) # }}} # --with-libmongoc {{{ -AC_ARG_WITH(libmongoc, [AS_HELP_STRING([--with-libmongoc@<:@=PREFIX@:>@], [Path to libmongoc.])], -[ - if test "x$withval" = "xyes" - then - with_libmongoc="yes" - else if test "x$withval" = "xno" - then - with_libmongoc="no" - else - with_libmongoc="yes" - LIBMONGOC_CPPFLAGS="$LIBMONGOC_CPPFLAGS -I$withval/include" - LIBMONGOC_LDFLAGS="$LIBMONGOC_LDFLAGS -L$withval/lib" - fi; fi -], -[with_libmongoc="yes"]) +AC_ARG_WITH([libmongoc], + [AS_HELP_STRING([--with-libmongoc@<:@=PREFIX@:>@], [Path to libmongoc.])], + [ + if test "x$withval" = "xyes"; then + with_libmongoc="yes" + else if test "x$withval" = "xno"; then + with_libmongoc="no" + else + with_libmongoc="no" + fi; fi + ], + [with_libmongoc="yes"] +) -SAVE_CPPFLAGS="$CPPFLAGS" -SAVE_LDFLAGS="$LDFLAGS" +if test "x$with_libmongoc" = "xyes"; then + PKG_CHECK_MODULES([LIBMONGOC], [libmongoc-1.0], + [with_libmongoc="yes"], + [with_libmongoc="no (pkg-config could not find libmongoc)"] + ) +fi -CPPFLAGS="$CPPFLAGS $LIBMONGOC_CPPFLAGS" -LDFLAGS="$LDFLAGS $LIBMONGOC_LDFLAGS" +if test "x$with_libmongoc" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" -if test "x$with_libmongoc" = "xyes" -then - if test "x$LIBMONGOC_CPPFLAGS" != "x" - then - AC_MSG_NOTICE([libmongoc CPPFLAGS: $LIBMONGOC_CPPFLAGS]) - fi - AC_CHECK_HEADERS(mongo.h, - [with_libmongoc="yes"], - [with_libmongoc="no ('mongo.h' not found)"], -[#if HAVE_STDINT_H -# define MONGO_HAVE_STDINT 1 -#else -# define MONGO_USE_LONG_LONG_INT 1 -#endif -]) -fi -if test "x$with_libmongoc" = "xyes" -then - if test "x$LIBMONGOC_LDFLAGS" != "x" - then - AC_MSG_NOTICE([libmongoc LDFLAGS: $LIBMONGOC_LDFLAGS]) - fi - AC_CHECK_LIB(mongoc, mongo_run_command, - [with_libmongoc="yes"], - [with_libmongoc="no (symbol 'mongo_run_command' not found)"]) + CPPFLAGS="$CPPFLAGS $LIBMONGOC_CFLAGS" + + if test "x$CPPFLAGS" != "x"; then + AC_MSG_NOTICE([libmongoc CPPFLAGS: $LIBMONGOC_CFLAGS]) + fi + + AC_CHECK_HEADERS([mongoc.h], + [with_libmongoc="yes"], + [with_libmongoc="no ('mongoc.h' not found)"] + ) + + CPPFLAGS="$SAVE_CPPFLAGS" fi -CPPFLAGS="$SAVE_CPPFLAGS" -LDFLAGS="$SAVE_LDFLAGS" +if test "x$with_libmongoc" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + SAVE_LDFLAGS="$LDFLAGS" -if test "x$with_libmongoc" = "xyes" -then - BUILD_WITH_LIBMONGOC_CPPFLAGS="$LIBMONGOC_CPPFLAGS" - BUILD_WITH_LIBMONGOC_LDFLAGS="$LIBMONGOC_LDFLAGS" - AC_SUBST(BUILD_WITH_LIBMONGOC_CPPFLAGS) - AC_SUBST(BUILD_WITH_LIBMONGOC_LDFLAGS) + CPPFLAGS="$CPPFLAGS $LIBMONGOC_CFLAGS" + LDFLAGS="$LDFLAGS $LIBMONGOC_LDFLAGS" + + if test "x$LIBMONGOC_LDFLAGS" != "x"; then + AC_MSG_NOTICE([libmongoc LDFLAGS: $LIBMONGOC_LDFLAGS]) + fi + + AC_CHECK_LIB([mongoc-1.0], [mongoc_init], + [with_libmongoc="yes"], + [with_libmongoc="no (symbol 'mongoc_init' not found)"] + ) + + CPPFLAGS="$SAVE_CPPFLAGS" + LDFLAGS="$SAVE_LDFLAGS" +fi + +if test "x$with_libmongoc" = "xyes"; then + BUILD_WITH_LIBMONGOC_CFLAGS="$LIBMONGOC_CFLAGS" + BUILD_WITH_LIBMONGOC_LDFLAGS="$LIBMONGOC_LDFLAGS" fi -AM_CONDITIONAL(BUILD_WITH_LIBMONGOC, test "x$with_libmongoc" = "xyes") + +AC_SUBST([BUILD_WITH_LIBMONGOC_CFLAGS]) +AC_SUBST([BUILD_WITH_LIBMONGOC_LDFLAGS]) # }}} # --with-libmosquitto {{{ -with_libmosquitto_cppflags="" -with_libmosquitto_ldflags="" -AC_ARG_WITH(libmosquitto, [AS_HELP_STRING([--with-libmosquitto@<:@=PREFIX@:>@], [Path to libmosquitto.])], -[ - if test "x$withval" != "xno" && test "x$withval" != "xyes" - then - with_libmosquitto_cppflags="-I$withval/include" - with_libmosquitto_ldflags="-L$withval/lib" - with_libmosquitto="yes" - else - with_libmosquitto="$withval" - fi -], -[ - with_libmosquitto="yes" -]) -if test "x$with_libmosquitto" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $with_libmosquitto_cppflags" +AC_ARG_WITH([libmosquitto], + [AS_HELP_STRING([--with-libmosquitto@<:@=PREFIX@:>@], [Path to libmosquitto.])], + [ + if test "x$withval" != "xno" && test "x$withval" != "xyes"; then + with_libmosquitto_cppflags="-I$withval/include" + with_libmosquitto_ldflags="-L$withval/lib" + with_libmosquitto="yes" + else + with_libmosquitto="$withval" + fi + ], + [with_libmosquitto="yes"] +) - AC_CHECK_HEADERS(mosquitto.h, [with_libmosquitto="yes"], [with_libmosquitto="no (mosquitto.h not found)"]) +if test "x$with_libmosquitto" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_libmosquitto_cppflags" - CPPFLAGS="$SAVE_CPPFLAGS" + AC_CHECK_HEADERS([mosquitto.h], + [with_libmosquitto="yes"], + [with_libmosquitto="no (mosquitto.h not found)"] + ) + + CPPFLAGS="$SAVE_CPPFLAGS" fi -if test "x$with_libmosquitto" = "xyes" -then - SAVE_LDFLAGS="$LDFLAGS" - SAVE_CPPFLAGS="$CPPFLAGS" - LDFLAGS="$LDFLAGS $with_libmosquitto_ldflags" - CPPFLAGS="$CPPFLAGS $with_libmosquitto_cppflags" - AC_CHECK_LIB(mosquitto, mosquitto_connect, [with_libmosquitto="yes"], [with_libmosquitto="no (libmosquitto not found)"]) +if test "x$with_libmosquitto" = "xyes"; then + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $with_libmosquitto_ldflags" - LDFLAGS="$SAVE_LDFLAGS" - CPPFLAGS="$SAVE_CPPFLAGS" + AC_CHECK_LIB([mosquitto], [mosquitto_connect], + [with_libmosquitto="yes"], + [with_libmosquitto="no (libmosquitto not found)"] + ) + + LDFLAGS="$SAVE_LDFLAGS" fi -if test "x$with_libmosquitto" = "xyes" -then - BUILD_WITH_LIBMOSQUITTO_CPPFLAGS="$with_libmosquitto_cppflags" - BUILD_WITH_LIBMOSQUITTO_LDFLAGS="$with_libmosquitto_ldflags" - BUILD_WITH_LIBMOSQUITTO_LIBS="-lmosquitto" - AC_SUBST(BUILD_WITH_LIBMOSQUITTO_CPPFLAGS) - AC_SUBST(BUILD_WITH_LIBMOSQUITTO_LDFLAGS) - AC_SUBST(BUILD_WITH_LIBMOSQUITTO_LIBS) + +if test "x$with_libmosquitto" = "xyes"; then + BUILD_WITH_LIBMOSQUITTO_CPPFLAGS="$with_libmosquitto_cppflags" + BUILD_WITH_LIBMOSQUITTO_LDFLAGS="$with_libmosquitto_ldflags" + BUILD_WITH_LIBMOSQUITTO_LIBS="-lmosquitto" fi + +AC_SUBST([BUILD_WITH_LIBMOSQUITTO_CPPFLAGS]) +AC_SUBST([BUILD_WITH_LIBMOSQUITTO_LDFLAGS]) +AC_SUBST([BUILD_WITH_LIBMOSQUITTO_LIBS]) # }}} # --with-libmysql {{{ with_mysql_config="mysql_config" -with_mysql_cflags="" -with_mysql_libs="" -AC_ARG_WITH(libmysql, [AS_HELP_STRING([--with-libmysql@<:@=PREFIX@:>@], [Path to libmysql.])], -[ - if test "x$withval" = "xno" - then - with_libmysql="no" - else if test "x$withval" = "xyes" - then - with_libmysql="yes" - else - if test -f "$withval" && test -x "$withval"; - then - with_mysql_config="$withval" - else if test -x "$withval/bin/mysql_config" - then - with_mysql_config="$withval/bin/mysql_config" - fi; fi - with_libmysql="yes" - fi; fi -], -[ - with_libmysql="yes" -]) -if test "x$with_libmysql" = "xyes" -then - with_mysql_cflags=`$with_mysql_config --include 2>/dev/null` - mysql_config_status=$? +AC_ARG_WITH([libmysql], + [AS_HELP_STRING([--with-libmysql@<:@=PREFIX@:>@], [Path to libmysql.])], + [ + if test "x$withval" = "xno"; then + with_libmysql="no" + else if test "x$withval" = "xyes"; then + with_libmysql="yes" + else + if test -f "$withval" && test -x "$withval"; then + with_mysql_config="$withval" + else if test -x "$withval/bin/mysql_config"; then + with_mysql_config="$withval/bin/mysql_config" + fi; fi + with_libmysql="yes" + fi; fi + ], + [with_libmysql="yes"] +) - if test $mysql_config_status -ne 0 - then - with_libmysql="no ($with_mysql_config failed)" - else - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $with_mysql_cflags" +if test "x$with_libmysql" = "xyes"; then + with_mysql_cflags=`$with_mysql_config --include 2>/dev/null` + if test $? -ne 0; then + with_libmysql="no ($with_mysql_config failed)" + else + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_mysql_cflags" - have_mysql_h="no" - have_mysql_mysql_h="no" - AC_CHECK_HEADERS(mysql.h, [have_mysql_h="yes"]) + AC_CHECK_HEADERS([mysql.h], + [have_mysql_h="yes"], + [have_mysql_h="no"] + ) - if test "x$have_mysql_h" = "xno" - then - AC_CHECK_HEADERS(mysql/mysql.h, [have_mysql_mysql_h="yes"]) - fi + if test "x$have_mysql_h" != "xyes"; then + AC_CHECK_HEADERS([mysql/mysql.h], + [have_mysql_mysql_h="yes"], + [], + ) + fi - if test "x$have_mysql_h$have_mysql_mysql_h" = "xnono" - then - with_libmysql="no (mysql.h not found)" - fi + if test "x$have_mysql_h" != "xyes" && test "x$have_mysql_mysql_h" != "xyes"; then + with_libmysql="no (mysql.h not found)" + fi - CPPFLAGS="$SAVE_CPPFLAGS" - fi + CPPFLAGS="$SAVE_CPPFLAGS" + fi fi -if test "x$with_libmysql" = "xyes" -then - with_mysql_libs=`$with_mysql_config --libs_r 2>/dev/null` - mysql_config_status=$? - if test $mysql_config_status -ne 0 - then - with_libmysql="no ($with_mysql_config failed)" - else - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $with_mysql_cflags" - SAVE_LIBS="$LIBS" - LIBS="$with_mysql_libs" - AC_SEARCH_LIBS([mysql_get_server_version], - [], - [with_libmysql="yes"], - [with_libmysql="no (symbol 'mysql_get_server_version' not found)"], - []) - CPPFLAGS="$SAVE_CPPFLAGS" - LIBS="$SAVE_LIBS" - fi +if test "x$with_libmysql" = "xyes"; then + with_mysql_libs=`$with_mysql_config --libs_r 2>/dev/null` + if test $? -ne 0; then + with_libmysql="no ($with_mysql_config failed)" + else + SAVE_LIBS="$LIBS" + LIBS="$with_mysql_libs" + + AC_SEARCH_LIBS([mysql_get_server_version], + [], + [with_libmysql="yes"], + [with_libmysql="no (symbol 'mysql_get_server_version' not found in ${LIBS})"], + [] + ) + LIBS="$SAVE_LIBS" + fi fi -if test "x$with_libmysql" = "xyes" -then - BUILD_WITH_LIBMYSQL_CFLAGS="$with_mysql_cflags" - BUILD_WITH_LIBMYSQL_LIBS="$with_mysql_libs" - AC_SUBST(BUILD_WITH_LIBMYSQL_CFLAGS) - AC_SUBST(BUILD_WITH_LIBMYSQL_LIBS) + +if test "x$with_libmysql" = "xyes"; then + BUILD_WITH_LIBMYSQL_CFLAGS="$with_mysql_cflags" + BUILD_WITH_LIBMYSQL_LIBS="$with_mysql_libs" fi -AM_CONDITIONAL(BUILD_WITH_LIBMYSQL, test "x$with_libmysql" = "xyes") + +AC_SUBST([BUILD_WITH_LIBMYSQL_CFLAGS]) +AC_SUBST([BUILD_WITH_LIBMYSQL_LIBS]) # }}} # --with-libmnl {{{ -with_libmnl_cflags="" -with_libmnl_libs="" -AC_ARG_WITH(libmnl, [AS_HELP_STRING([--with-libmnl@<:@=PREFIX@:>@], [Path to libmnl.])], -[ - echo "libmnl: withval = $withval" - if test "x$withval" = "xyes" - then - with_libmnl="yes" - else if test "x$withval" = "xno" - then - with_libmnl="no" - else - if test -d "$withval/include" - then - with_libmnl_cflags="-I$withval/include" - with_libmnl_libs="-L$withval/lib -lmnl" - with_libmnl="yes" - else - AC_MSG_ERROR("no such directory: $withval/include") - fi - fi; fi -], -[ - if test "x$ac_system" = "xLinux" - then - with_libmnl="yes" - else - with_libmnl="no (Linux only library)" - fi -]) -if test "x$with_libmnl" = "xyes" -then - if $PKG_CONFIG --exists libmnl 2>/dev/null; then - with_libmnl_cflags="$with_libmnl_ldflags `$PKG_CONFIG --cflags libmnl`" - with_libmnl_libs="$with_libmnl_libs `$PKG_CONFIG --libs libmnl`" - fi +AC_ARG_WITH([libmnl], + [AS_HELP_STRING([--with-libmnl@<:@=PREFIX@:>@], [Path to libmnl.])], + [ + if test "x$withval" = "xyes"; then + with_libmnl="yes" + else if test "x$withval" = "xno"; then + with_libmnl="no" + else + if test -d "$withval/include"; then + with_libmnl_cflags="-I$withval/include" + with_libmnl_libs="-L$withval/lib -lmnl" + with_libmnl="yes" + else + AC_MSG_ERROR("no such directory: $withval/include") + fi + fi; fi + ], + [ + if test "x$ac_system" = "xLinux"; then + with_libmnl="yes" + else + with_libmnl="no (Linux only library)" + fi + ] +) - AC_CHECK_HEADERS(libmnl.h libmnl/libmnl.h, - [ - with_libmnl="yes" - break - ], [], -[#include -#include -#include -#include -#include -#include ]) - AC_CHECK_HEADERS(linux/gen_stats.h linux/pkt_sched.h, [], [], -[#include -#include -#include -#include ]) - - AC_COMPILE_IFELSE([AC_LANG_PROGRAM( -[[ -#include -#include -#include -#include -#include -#include -]], -[[ -int retval = TCA_STATS2; -return (retval); -]] - )], - [AC_DEFINE([HAVE_TCA_STATS2], [1], [True if the enum-member TCA_STATS2 exists])]) - - AC_COMPILE_IFELSE([AC_LANG_PROGRAM( -[[ -#include -#include -#include -#include -#include -#include -]], -[[ -int retval = TCA_STATS; -return (retval); -]] - )], - [AC_DEFINE([HAVE_TCA_STATS], 1, [True if the enum-member TCA_STATS exists])]) -fi -if test "x$with_libmnl" = "xyes" -then - AC_CHECK_MEMBERS([struct rtnl_link_stats64.tx_window_errors], - [AC_DEFINE(HAVE_RTNL_LINK_STATS64, 1, [Define if struct rtnl_link_stats64 exists and is usable.])], - [], - [ - #include - ]) -fi -if test "x$with_libmnl" = "xyes" -then - AC_CHECK_LIB(mnl, mnl_nlmsg_get_payload, - [with_libmnl="yes"], - [with_libmnl="no (symbol 'mnl_nlmsg_get_payload' not found)"], - [$with_libmnl_libs]) +if test "x$with_libmnl" = "xyes"; then + if $PKG_CONFIG --exists libmnl 2>/dev/null; then + with_libmnl_cflags="$with_libmnl_ldflags `$PKG_CONFIG --cflags libmnl`" + with_libmnl_libs="$with_libmnl_libs `$PKG_CONFIG --libs libmnl`" + fi + + AC_CHECK_HEADERS([libmnl.h libmnl/libmnl.h], + [ + with_libmnl="yes" + break + ], + [], + [[ + #include + #include + #include + #include + #include + #include ]] + ) + + AC_CHECK_HEADERS([linux/gen_stats.h linux/pkt_sched.h], + [], + [], + [[ + #include + #include + #include + #include + ]] + ) + + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM( + [[ + #include + #include + #include + #include + #include + #include + ]], + [[ + int retval = TCA_STATS2; + return (retval); + ]] + ) + ], + [AC_DEFINE([HAVE_TCA_STATS2], [1], [True if the enum-member TCA_STATS2 exists])] + ) + + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM( + [[ + #include + #include + #include + #include + #include + #include + ]], + [[ + int retval = TCA_STATS; + return (retval); + ]] + ) + ], + [AC_DEFINE([HAVE_TCA_STATS], 1, [True if the enum-member TCA_STATS exists])] + ) + + AC_CHECK_MEMBERS([struct rtnl_link_stats64.tx_window_errors], + [AC_DEFINE(HAVE_RTNL_LINK_STATS64, 1, [Define if struct rtnl_link_stats64 exists and is usable.])], + [], + [[#include ]] + ) + + AC_CHECK_LIB([mnl], [mnl_nlmsg_get_payload], + [with_libmnl="yes"], + [with_libmnl="no (symbol 'mnl_nlmsg_get_payload' not found)"], + [$with_libmnl_libs] + ) fi -if test "x$with_libmnl" = "xyes" -then - AC_DEFINE(HAVE_LIBMNL, 1, [Define if libmnl is present and usable.]) - BUILD_WITH_LIBMNL_CFLAGS="$with_libmnl_cflags" - BUILD_WITH_LIBMNL_LIBS="$with_libmnl_libs" - AC_SUBST(BUILD_WITH_LIBMNL_CFLAGS) - AC_SUBST(BUILD_WITH_LIBMNL_LIBS) + +if test "x$with_libmnl" = "xyes"; then + BUILD_WITH_LIBMNL_CFLAGS="$with_libmnl_cflags" + BUILD_WITH_LIBMNL_LIBS="$with_libmnl_libs" fi -AM_CONDITIONAL(BUILD_WITH_LIBMNL, test "x$with_libmnl" = "xyes") +AC_SUBST([BUILD_WITH_LIBMNL_CFLAGS]) +AC_SUBST([BUILD_WITH_LIBMNL_LIBS]) # }}} # --with-libnetapp {{{ AC_ARG_VAR([LIBNETAPP_CPPFLAGS], [C preprocessor flags required to build with libnetapp]) AC_ARG_VAR([LIBNETAPP_LDFLAGS], [Linker flags required to build with libnetapp]) AC_ARG_VAR([LIBNETAPP_LIBS], [Other libraries required to link against libnetapp]) -LIBNETAPP_CPPFLAGS="$LIBNETAPP_CPPFLAGS" -LIBNETAPP_LDFLAGS="$LIBNETAPP_LDFLAGS" -LIBNETAPP_LIBS="$LIBNETAPP_LIBS" -AC_ARG_WITH(libnetapp, [AS_HELP_STRING([--with-libnetapp@<:@=PREFIX@:>@], [Path to libnetapp.])], -[ - if test -d "$withval" - then - LIBNETAPP_CPPFLAGS="$LIBNETAPP_CPPFLAGS -I$withval/include" - LIBNETAPP_LDFLAGS="$LIBNETAPP_LDFLAGS -L$withval/lib" - with_libnetapp="yes" - else - with_libnetapp="$withval" - fi -], -[ - with_libnetapp="yes" -]) +AC_ARG_WITH([libnetapp], + [AS_HELP_STRING([--with-libnetapp@<:@=PREFIX@:>@], [Path to libnetapp.])], + [ + if test -d "$withval"; then + LIBNETAPP_CPPFLAGS="$LIBNETAPP_CPPFLAGS -I$withval/include" + LIBNETAPP_LDFLAGS="$LIBNETAPP_LDFLAGS -L$withval/lib" + with_libnetapp="yes" + else + with_libnetapp="$withval" + fi + ], + [with_libnetapp="yes"] +) SAVE_CPPFLAGS="$CPPFLAGS" SAVE_LDFLAGS="$LDFLAGS" CPPFLAGS="$CPPFLAGS $LIBNETAPP_CPPFLAGS" LDFLAGS="$LDFLAGS $LIBNETAPP_LDFLAGS" -if test "x$with_libnetapp" = "xyes" -then - if test "x$LIBNETAPP_CPPFLAGS" != "x" - then - AC_MSG_NOTICE([netapp CPPFLAGS: $LIBNETAPP_CPPFLAGS]) - fi - AC_CHECK_HEADERS(netapp_api.h, - [with_libnetapp="yes"], - [with_libnetapp="no (netapp_api.h not found)"]) +if test "x$with_libnetapp" = "xyes"; then + if test "x$LIBNETAPP_CPPFLAGS" != "x"; then + AC_MSG_NOTICE([netapp CPPFLAGS: $LIBNETAPP_CPPFLAGS]) + fi + AC_CHECK_HEADERS([netapp_api.h], + [with_libnetapp="yes"], + [with_libnetapp="no (netapp_api.h not found)"] + ) fi -if test "x$with_libnetapp" = "xyes" -then - if test "x$LIBNETAPP_LDFLAGS" != "x" - then - AC_MSG_NOTICE([netapp LDFLAGS: $LIBNETAPP_LDFLAGS]) - fi +if test "x$with_libnetapp" = "xyes"; then + if test "x$LIBNETAPP_LDFLAGS" != "x"; then + AC_MSG_NOTICE([netapp LDFLAGS: $LIBNETAPP_LDFLAGS]) + fi - if test "x$LIBNETAPP_LIBS" = "x" - then - LIBNETAPP_LIBS="$PTHREAD_LIBS -lxml -ladt -lssl -lm -lcrypto -lz" - fi - AC_MSG_NOTICE([netapp LIBS: $LIBNETAPP_LIBS]) + if test "x$LIBNETAPP_LIBS" = "x"; then + LIBNETAPP_LIBS="$PTHREAD_LIBS -lxml -ladt -lssl -lm -lcrypto -lz" + fi - AC_CHECK_LIB(netapp, na_server_invoke_elem, - [with_libnetapp="yes"], - [with_libnetapp="no (symbol na_server_invoke_elem not found)"], - [$LIBNETAPP_LIBS]) - LIBNETAPP_LIBS="-lnetapp $LIBNETAPP_LIBS" + AC_MSG_NOTICE([netapp LIBS: $LIBNETAPP_LIBS]) + + AC_CHECK_LIB([netapp], [na_server_invoke_elem], + [with_libnetapp="yes"], + [with_libnetapp="no (symbol na_server_invoke_elem not found)"], + [$LIBNETAPP_LIBS] + ) + + LIBNETAPP_LIBS="-lnetapp $LIBNETAPP_LIBS" fi CPPFLAGS="$SAVE_CPPFLAGS" LDFLAGS="$SAVE_LDFLAGS" -if test "x$with_libnetapp" = "xyes" -then - AC_DEFINE(HAVE_LIBNETAPP, 1, [Define to 1 if you have the netapp library (-lnetapp).]) -fi - -AC_SUBST(LIBNETAPP_CPPFLAGS) -AC_SUBST(LIBNETAPP_LDFLAGS) -AC_SUBST(LIBNETAPP_LIBS) -AM_CONDITIONAL(BUILD_WITH_LIBNETAPP, test "x$with_libnetapp" = "xyes") +AC_SUBST([LIBNETAPP_CPPFLAGS]) +AC_SUBST([LIBNETAPP_LDFLAGS]) +AC_SUBST([LIBNETAPP_LIBS]) # }}} # --with-libnetsnmp {{{ @@ -3626,7 +3697,10 @@ then SAVE_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $with_libnetsnmp_cppflags" - AC_CHECK_HEADERS(net-snmp/net-snmp-config.h, [], [with_libnetsnmp="no (net-snmp/net-snmp-config.h not found)"]) + AC_CHECK_HEADERS([net-snmp/net-snmp-config.h], + [with_libnetsnmp="yes"], + [with_libnetsnmp="no (net-snmp/net-snmp-config.h not found)"] + ) CPPFLAGS="$SAVE_CPPFLAGS" fi @@ -3653,552 +3727,496 @@ AC_SUBST(BUILD_WITH_LIBNETSNMP_LDFLAGS) AC_SUBST(BUILD_WITH_LIBNETSNMP_LIBS) # }}} -# --with-liboconfig {{{ -with_own_liboconfig="no" -liboconfig_LDFLAGS="$LDFLAGS" -liboconfig_CPPFLAGS="$CPPFLAGS" -AC_ARG_WITH(liboconfig, [AS_HELP_STRING([--with-liboconfig@<:@=PREFIX@:>@], [Path to liboconfig.])], -[ - if test "x$withval" != "xno" && test "x$withval" != "xyes" - then - if test -d "$withval/lib" - then - liboconfig_LDFLAGS="$LDFLAGS -L$withval/lib" - fi - if test -d "$withval/include" - then - liboconfig_CPPFLAGS="$CPPFLAGS -I$withval/include" - fi - fi - if test "x$withval" = "xno" - then - AC_MSG_ERROR("liboconfig is required") - fi -], -[ - with_liboconfig="yes" -]) - -save_LDFLAGS="$LDFLAGS" -save_CPPFLAGS="$CPPFLAGS" -LDFLAGS="$liboconfig_LDFLAGS" -CPPFLAGS="$liboconfig_CPPFLAGS" -AC_CHECK_LIB(oconfig, oconfig_parse_file, -[ - with_liboconfig="yes" - with_own_liboconfig="no" -], -[ - with_liboconfig="yes" - with_own_liboconfig="yes" - LDFLAGS="$save_LDFLAGS" - CPPFLAGS="$save_CPPFLAGS" -]) - -AM_CONDITIONAL(BUILD_WITH_OWN_LIBOCONFIG, test "x$with_own_liboconfig" = "xyes") -if test "x$with_own_liboconfig" = "xyes" -then - with_liboconfig="yes (shipped version)" -fi -# }}} - # --with-liboping {{{ -AC_ARG_WITH(liboping, [AS_HELP_STRING([--with-liboping@<:@=PREFIX@:>@], [Path to liboping.])], -[ - if test "x$withval" = "xyes" - then - with_liboping="yes" - else if test "x$withval" = "xno" - then - with_liboping="no" - else - with_liboping="yes" - LIBOPING_CPPFLAGS="$LIBOPING_CPPFLAGS -I$withval/include" - LIBOPING_LDFLAGS="$LIBOPING_LDFLAGS -L$withval/lib" - fi; fi -], -[with_liboping="yes"]) +AC_ARG_WITH([liboping], + [AS_HELP_STRING([--with-liboping@<:@=PREFIX@:>@], [Path to liboping.])], + [ + if test "x$withval" = "xyes"; then + with_liboping="yes" + else if test "x$withval" = "xno"; then + with_liboping="no" + else + with_liboping="yes" + LIBOPING_CPPFLAGS="-I$withval/include" + LIBOPING_LDFLAGS="-L$withval/lib" + fi; fi + ], + [with_liboping="yes"] +) SAVE_CPPFLAGS="$CPPFLAGS" SAVE_LDFLAGS="$LDFLAGS" - CPPFLAGS="$CPPFLAGS $LIBOPING_CPPFLAGS" LDFLAGS="$LDFLAGS $LIBOPING_LDFLAGS" -if test "x$with_liboping" = "xyes" -then - if test "x$LIBOPING_CPPFLAGS" != "x" - then - AC_MSG_NOTICE([liboping CPPFLAGS: $LIBOPING_CPPFLAGS]) - fi - AC_CHECK_HEADERS(oping.h, - [with_liboping="yes"], - [with_liboping="no (oping.h not found)"]) +if test "x$with_liboping" = "xyes"; then + AC_CHECK_HEADERS([oping.h], + [with_liboping="yes"], + [with_liboping="no (oping.h not found)"] + ) fi -if test "x$with_liboping" = "xyes" -then - if test "x$LIBOPING_LDFLAGS" != "x" - then - AC_MSG_NOTICE([liboping LDFLAGS: $LIBOPING_LDFLAGS]) - fi - AC_CHECK_LIB(oping, ping_construct, - [with_liboping="yes"], - [with_liboping="no (symbol 'ping_construct' not found)"]) + +if test "x$with_liboping" = "xyes"; then + AC_CHECK_LIB([oping], [ping_construct], + [with_liboping="yes"], + [with_liboping="no (symbol 'ping_construct' not found)"] + ) fi CPPFLAGS="$SAVE_CPPFLAGS" LDFLAGS="$SAVE_LDFLAGS" -if test "x$with_liboping" = "xyes" -then - BUILD_WITH_LIBOPING_CPPFLAGS="$LIBOPING_CPPFLAGS" - BUILD_WITH_LIBOPING_LDFLAGS="$LIBOPING_LDFLAGS" - AC_SUBST(BUILD_WITH_LIBOPING_CPPFLAGS) - AC_SUBST(BUILD_WITH_LIBOPING_LDFLAGS) +if test "x$with_liboping" = "xyes"; then + BUILD_WITH_LIBOPING_CPPFLAGS="$LIBOPING_CPPFLAGS" + BUILD_WITH_LIBOPING_LDFLAGS="$LIBOPING_LDFLAGS" fi -AM_CONDITIONAL(BUILD_WITH_LIBOPING, test "x$with_liboping" = "xyes") + +AC_SUBST([BUILD_WITH_LIBOPING_CPPFLAGS]) +AC_SUBST([BUILD_WITH_LIBOPING_LDFLAGS]) # }}} # --with-oracle {{{ -with_oracle_cppflags="" -with_oracle_libs="" -AC_ARG_WITH(oracle, [AS_HELP_STRING([--with-oracle@<:@=ORACLE_HOME@:>@], [Path to Oracle.])], -[ - if test "x$withval" = "xyes" - then - if test "x$ORACLE_HOME" = "x" - then - AC_MSG_WARN([Use of the Oracle library has been forced, but the environment variable ORACLE_HOME is not set.]) - fi - with_oracle="yes" - else if test "x$withval" = "xno" - then - with_oracle="no" - else - with_oracle="yes" - ORACLE_HOME="$withval" - fi; fi -], -[ - if test "x$ORACLE_HOME" = "x" - then - with_oracle="no (ORACLE_HOME is not set)" - else - with_oracle="yes" - fi -]) -if test "x$ORACLE_HOME" != "x" -then - with_oracle_cppflags="-I$ORACLE_HOME/rdbms/public" +AC_ARG_WITH([oracle], + [AS_HELP_STRING([--with-oracle@<:@=ORACLE_HOME@:>@], [Path to Oracle.])], + [ + if test "x$withval" = "xyes"; then + if test "x$ORACLE_HOME" = "x"; then + AC_MSG_WARN([Use of the Oracle library has been forced, but the environment variable ORACLE_HOME is not set.]) + fi + with_oracle="yes" + else if test "x$withval" = "xno"; then + with_oracle="no" + else + with_oracle="yes" + ORACLE_HOME="$withval" + fi; fi + ], + [ + if test "x$ORACLE_HOME" = "x"; then + with_oracle="no (ORACLE_HOME is not set)" + else + with_oracle="yes" + fi + ] +) - if test -e "$ORACLE_HOME/lib/ldflags" - then - with_oracle_libs=`cat "$ORACLE_HOME/lib/ldflags"` - fi - #with_oracle_libs="-L$ORACLE_HOME/lib $with_oracle_libs -lclntsh" - with_oracle_libs="-L$ORACLE_HOME/lib -lclntsh" +if test "x$ORACLE_HOME" != "x"; then + with_oracle_cppflags="-I$ORACLE_HOME/rdbms/public" + if test -e "$ORACLE_HOME/lib/ldflags"; then + with_oracle_libs=`cat "$ORACLE_HOME/lib/ldflags"` + fi + with_oracle_libs="-L$ORACLE_HOME/lib -lclntsh" fi -if test "x$with_oracle" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $with_oracle_cppflags" - AC_CHECK_HEADERS(oci.h, [with_oracle="yes"], [with_oracle="no (oci.h not found)"]) +if test "x$with_oracle" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_oracle_cppflags" + + AC_CHECK_HEADERS([oci.h], + [with_oracle="yes"], + [with_oracle="no (oci.h not found)"] + ) - CPPFLAGS="$SAVE_CPPFLAGS" + CPPFLAGS="$SAVE_CPPFLAGS" fi -if test "x$with_oracle" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - SAVE_LIBS="$LIBS" - CPPFLAGS="$CPPFLAGS $with_oracle_cppflags" - LIBS="$LIBS $with_oracle_libs" - AC_CHECK_FUNC(OCIEnvCreate, [with_oracle="yes"], [with_oracle="no (Symbol 'OCIEnvCreate' not found)"]) +if test "x$with_oracle" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + SAVE_LIBS="$LIBS" + CPPFLAGS="$CPPFLAGS $with_oracle_cppflags" + LIBS="$LIBS $with_oracle_libs" + + AC_CHECK_FUNC([OCIEnvCreate], + [with_oracle="yes"], + [with_oracle="no (Symbol 'OCIEnvCreate' not found)"] + ) - CPPFLAGS="$SAVE_CPPFLAGS" - LIBS="$SAVE_LIBS" + CPPFLAGS="$SAVE_CPPFLAGS" + LIBS="$SAVE_LIBS" fi -if test "x$with_oracle" = "xyes" -then - BUILD_WITH_ORACLE_CPPFLAGS="$with_oracle_cppflags" - BUILD_WITH_ORACLE_LIBS="$with_oracle_libs" - AC_SUBST(BUILD_WITH_ORACLE_CPPFLAGS) - AC_SUBST(BUILD_WITH_ORACLE_LIBS) + +if test "x$with_oracle" = "xyes"; then + BUILD_WITH_ORACLE_CPPFLAGS="$with_oracle_cppflags" + BUILD_WITH_ORACLE_LIBS="$with_oracle_libs" fi + +AC_SUBST([BUILD_WITH_ORACLE_CPPFLAGS]) +AC_SUBST([BUILD_WITH_ORACLE_LIBS]) # }}} # --with-libowcapi {{{ -with_libowcapi_cppflags="" -with_libowcapi_ldflags="" -AC_ARG_WITH(libowcapi, [AS_HELP_STRING([--with-libowcapi@<:@=PREFIX@:>@], [Path to libowcapi.])], -[ - if test "x$withval" != "xno" && test "x$withval" != "xyes" - then - with_libowcapi_cppflags="-I$withval/include" - with_libowcapi_ldflags="-L$withval/lib" - with_libowcapi="yes" - else - with_libowcapi="$withval" - fi -], -[ - with_libowcapi="yes" -]) -if test "x$with_libowcapi" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $with_libowcapi_cppflags" +AC_ARG_WITH([libowcapi], + [AS_HELP_STRING([--with-libowcapi@<:@=PREFIX@:>@], [Path to libowcapi.])], + [ + if test "x$withval" != "xno" && test "x$withval" != "xyes"; then + with_libowcapi_cppflags="-I$withval/include" + with_libowcapi_ldflags="-L$withval/lib" + with_libowcapi="yes" + else + with_libowcapi="$withval" + fi + ], + [with_libowcapi="yes"] +) + +if test "x$with_libowcapi" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_libowcapi_cppflags" - AC_CHECK_HEADERS(owcapi.h, [with_libowcapi="yes"], [with_libowcapi="no (owcapi.h not found)"]) + AC_CHECK_HEADERS([owcapi.h], + [with_libowcapi="yes"], + [with_libowcapi="no (owcapi.h not found)"] + ) - CPPFLAGS="$SAVE_CPPFLAGS" + CPPFLAGS="$SAVE_CPPFLAGS" fi -if test "x$with_libowcapi" = "xyes" -then - SAVE_LDFLAGS="$LDFLAGS" - SAVE_CPPFLAGS="$CPPFLAGS" - LDFLAGS="$LDFLAGS $with_libowcapi_ldflags" - CPPFLAGS="$with_libowcapi_cppflags" - AC_CHECK_LIB(owcapi, OW_get, [with_libowcapi="yes"], [with_libowcapi="no (libowcapi not found)"]) +if test "x$with_libowcapi" = "xyes"; then + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $with_libowcapi_ldflags" + + AC_CHECK_LIB([owcapi], [OW_get], + [with_libowcapi="yes"], + [with_libowcapi="no (libowcapi not found)"] + ) - LDFLAGS="$SAVE_LDFLAGS" - CPPFLAGS="$SAVE_CPPFLAGS" + LDFLAGS="$SAVE_LDFLAGS" fi -if test "x$with_libowcapi" = "xyes" -then - BUILD_WITH_LIBOWCAPI_CPPFLAGS="$with_libowcapi_cppflags" - BUILD_WITH_LIBOWCAPI_LDFLAGS="$with_libowcapi_ldflags" - BUILD_WITH_LIBOWCAPI_LIBS="-lowcapi" - AC_SUBST(BUILD_WITH_LIBOWCAPI_CPPFLAGS) - AC_SUBST(BUILD_WITH_LIBOWCAPI_LDFLAGS) - AC_SUBST(BUILD_WITH_LIBOWCAPI_LIBS) + +if test "x$with_libowcapi" = "xyes"; then + BUILD_WITH_LIBOWCAPI_CPPFLAGS="$with_libowcapi_cppflags" + BUILD_WITH_LIBOWCAPI_LDFLAGS="$with_libowcapi_ldflags" + BUILD_WITH_LIBOWCAPI_LIBS="-lowcapi" fi + +AC_SUBST([BUILD_WITH_LIBOWCAPI_CPPFLAGS]) +AC_SUBST([BUILD_WITH_LIBOWCAPI_LDFLAGS]) +AC_SUBST([BUILD_WITH_LIBOWCAPI_LIBS]) # }}} # --with-libpcap {{{ -AC_ARG_WITH(libpcap, [AS_HELP_STRING([--with-libpcap@<:@=PREFIX@:>@], [Path to libpcap.])], -[ - if test "x$withval" != "xno" && test "x$withval" != "xyes" - then - LDFLAGS="$LDFLAGS -L$withval/lib" - CPPFLAGS="$CPPFLAGS -I$withval/include" - with_libpcap="yes" - else - with_libpcap="$withval" - fi -], -[ - with_libpcap="yes" -]) -if test "x$with_libpcap" = "xyes" -then - AC_CHECK_LIB(pcap, pcap_open_live, - [ - AC_DEFINE(HAVE_LIBPCAP, 1, [Define to 1 if you have the pcap library (-lpcap).]) - ], [with_libpcap="no (libpcap not found)"]) +AC_ARG_WITH([libpcap], + [AS_HELP_STRING([--with-libpcap@<:@=PREFIX@:>@], [Path to libpcap.])], + [ + if test "x$withval" != "xno" && test "x$withval" != "xyes"; then + with_libpcap_cppflags="-I$withval/include" + with_libpcap_ldflags="$LDFLAGS -L$withval/lib" + with_libpcap="yes" + else + with_libpcap="$withval" + fi + ], + [with_libpcap="yes"] +) + +if test "x$with_libpcap" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_libpcap_cppflags" + + AC_CHECK_HEADERS([pcap.h], + [with_libpcap="yes"], + [with_libpcap="no (pcap.h not found)"] + ) + + CPPFLAGS="$SAVE_CPPFLAGS" fi -if test "x$with_libpcap" = "xyes" -then - AC_CHECK_HEADERS(pcap.h,, - [with_libpcap="no (pcap.h not found)"]) + +if test "x$with_libpcap" = "xyes"; then + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $with_libpcap_ldflags" + + AC_CHECK_LIB([pcap], [pcap_open_live], + [with_libpcap="yes"], + [with_libpcap="no (libpcap not found)"] + ) + + LDFLAGS="$SAVE_LDFLAGS" fi -if test "x$with_libpcap" = "xyes" -then - AC_CACHE_CHECK([whether libpcap has PCAP_ERROR_IFACE_NOT_UP], - [c_cv_libpcap_have_pcap_error_iface_not_up], - AC_COMPILE_IFELSE([AC_LANG_PROGRAM( -[[[ -#include -]]], -[[[ - int val = PCAP_ERROR_IFACE_NOT_UP; - return(val); -]]] - )], - [c_cv_libpcap_have_pcap_error_iface_not_up="yes"], - [c_cv_libpcap_have_pcap_error_iface_not_up="no"])) -fi -if test "x$c_cv_libpcap_have_pcap_error_iface_not_up" != "xyes" -then - with_libpcap="no (pcap.h misses PCAP_ERROR_IFACE_NOT_UP)" + +if test "x$with_libpcap" = "xyes"; then + AC_CACHE_CHECK([whether libpcap has PCAP_ERROR_IFACE_NOT_UP], + [c_cv_libpcap_have_pcap_error_iface_not_up], + [ + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM( + [[#include ]], + [[ + int val = PCAP_ERROR_IFACE_NOT_UP; + return(val); + ]] + ) + ], + [c_cv_libpcap_have_pcap_error_iface_not_up="yes"], + [c_cv_libpcap_have_pcap_error_iface_not_up="no"] + ) + ] + ) +fi + +if test "x$c_cv_libpcap_have_pcap_error_iface_not_up" != "xyes"; then + with_libpcap="no (pcap.h misses PCAP_ERROR_IFACE_NOT_UP)" +fi + +if test "x$with_libpcap" = "xyes"; then + BUILD_WITH_LIBPCAP_CPPFLAGS="$with_libpcap_cppflags" + BUILD_WITH_LIBPCAP_LDFLAGS="$with_libpcap_ldflags" + BUILD_WITH_LIBPCAP_LIBS="-lpcap" fi -AM_CONDITIONAL(BUILD_WITH_LIBPCAP, test "x$with_libpcap" = "xyes") + +AC_SUBST([BUILD_WITH_LIBPCAP_CPPFLAGS]) +AC_SUBST([BUILD_WITH_LIBPCAP_LDFLAGS]) +AC_SUBST([BUILD_WITH_LIBPCAP_LIBS]) # }}} # --with-libperl {{{ -perl_interpreter="perl" -AC_ARG_WITH(libperl, [AS_HELP_STRING([--with-libperl@<:@=PREFIX@:>@], [Path to libperl.])], -[ - if test -f "$withval" && test -x "$withval" - then - perl_interpreter="$withval" - with_libperl="yes" - else if test "x$withval" != "xno" && test "x$withval" != "xyes" - then - LDFLAGS="$LDFLAGS -L$withval/lib" - CPPFLAGS="$CPPFLAGS -I$withval/include" - perl_interpreter="$withval/bin/perl" - with_libperl="yes" - else - with_libperl="$withval" - fi; fi -], -[ - with_libperl="yes" -]) +AC_ARG_WITH([libperl], + [AS_HELP_STRING([--with-libperl@<:@=PREFIX@:>@], [Path to libperl.])], + [ + if test "x$withval" != "xno" && test "x$withval" != "xyes"; then + LDFLAGS="$LDFLAGS -L$withval/lib" + CPPFLAGS="$CPPFLAGS -I$withval/include" + with_libperl="yes" + else + with_libperl="$withval" + fi + ], + [with_libperl="yes"] +) -AC_MSG_CHECKING([for perl]) -perl_interpreter=`which "$perl_interpreter" 2> /dev/null` -if test -x "$perl_interpreter" -then - AC_MSG_RESULT([yes ($perl_interpreter)]) -else - perl_interpreter="" - AC_MSG_RESULT([no]) -fi +AC_ARG_VAR([PERL], [path to Perl interpreter]) +AC_PATH_PROG([PERL], [perl]) -AC_SUBST(PERL, "$perl_interpreter") +if test "x$PERL" = "x"; then + with_libperl="no (no Perl interpreter found)" +fi -if test "x$with_libperl" = "xyes" \ - && test -n "$perl_interpreter" -then +if test "x$with_libperl" = "xyes"; then SAVE_CFLAGS="$CFLAGS" SAVE_LIBS="$LIBS" -dnl ARCHFLAGS="" -> disable multi -arch on OSX (see Config_heavy.pl:fetch_string) - PERL_CFLAGS=`ARCHFLAGS="" $perl_interpreter -MExtUtils::Embed -e perl_inc` - PERL_LIBS=`ARCHFLAGS="" $perl_interpreter -MExtUtils::Embed -e ldopts` + dnl ARCHFLAGS="" -> disable multi -arch on OSX (see Config_heavy.pl:fetch_string) + PERL_CFLAGS=`ARCHFLAGS="" $PERL -MExtUtils::Embed -e perl_inc` + PERL_LIBS=`ARCHFLAGS="" $PERL -MExtUtils::Embed -e ldopts` CFLAGS="$CFLAGS $PERL_CFLAGS" LIBS="$LIBS $PERL_LIBS" AC_CACHE_CHECK([for libperl], [c_cv_have_libperl], - AC_LINK_IFELSE([AC_LANG_PROGRAM( -[[[ -#define PERL_NO_GET_CONTEXT -#include -#include -#include -]]], -[[[ - dTHX; - load_module (PERL_LOADMOD_NOIMPORT, - newSVpv ("Collectd::Plugin::FooBar", 24), - Nullsv); -]]] - )], - [c_cv_have_libperl="yes"], - [c_cv_have_libperl="no"] - ) + [ + AC_LINK_IFELSE( + [ + AC_LANG_PROGRAM( + [[ + #define PERL_NO_GET_CONTEXT + #include + #include + #include + ]], + [[ + dTHX; + load_module (PERL_LOADMOD_NOIMPORT, + newSVpv ("Collectd::Plugin::FooBar", 24), + Nullsv); + ]] + ) + ], + [c_cv_have_libperl="yes"], + [c_cv_have_libperl="no"] + ) + ] ) - if test "x$c_cv_have_libperl" = "xyes" - then - AC_DEFINE(HAVE_LIBPERL, 1, [Define if libperl is present and usable.]) - AC_SUBST(PERL_CFLAGS) - AC_SUBST(PERL_LIBS) - else - with_libperl="no" - fi - CFLAGS="$SAVE_CFLAGS" LIBS="$SAVE_LIBS" -else if test -z "$perl_interpreter"; then - with_libperl="no (no perl interpreter found)" - c_cv_have_libperl="no" -fi; fi -AM_CONDITIONAL(BUILD_WITH_LIBPERL, test "x$with_libperl" = "xyes") - -if test "x$with_libperl" = "xyes" -then - SAVE_CFLAGS="$CFLAGS" - SAVE_LIBS="$LIBS" - CFLAGS="$CFLAGS $PERL_CFLAGS" - LIBS="$LIBS $PERL_LIBS" - - AC_CACHE_CHECK([if perl supports ithreads], - [c_cv_have_perl_ithreads], - AC_LINK_IFELSE([AC_LANG_PROGRAM( -[[[ -#include -#include -#include - -#if !defined(USE_ITHREADS) -# error "Perl does not support ithreads!" -#endif /* !defined(USE_ITHREADS) */ -]]], -[[[ ]]] - )], - [c_cv_have_perl_ithreads="yes"], - [c_cv_have_perl_ithreads="no"] - ) - ) - - if test "x$c_cv_have_perl_ithreads" = "xyes" - then - AC_DEFINE(HAVE_PERL_ITHREADS, 1, [Define if Perl supports ithreads.]) - fi - CFLAGS="$SAVE_CFLAGS" - LIBS="$SAVE_LIBS" + if test "x$c_cv_have_libperl" = "xno"; then + with_libperl="no" + fi fi -if test "x$with_libperl" = "xyes" -then - SAVE_CFLAGS="$CFLAGS" - SAVE_LIBS="$LIBS" - # trigger an error if Perl_load_module*() uses __attribute__nonnull__(3) - # (see issues #41 and #42) - CFLAGS="$CFLAGS $PERL_CFLAGS -Wall -Werror" - LIBS="$LIBS $PERL_LIBS" - - AC_CACHE_CHECK([for broken Perl_load_module()], - [c_cv_have_broken_perl_load_module], - AC_LINK_IFELSE([AC_LANG_PROGRAM( -[[[ -#define PERL_NO_GET_CONTEXT -#include -#include -#include -]]], -[[[ - dTHX; - load_module (PERL_LOADMOD_NOIMPORT, - newSVpv ("Collectd::Plugin::FooBar", 24), - Nullsv); -]]] - )], - [c_cv_have_broken_perl_load_module="no"], - [c_cv_have_broken_perl_load_module="yes"] - ) - ) - - CFLAGS="$SAVE_CFLAGS" - LIBS="$SAVE_LIBS" -fi -AM_CONDITIONAL(HAVE_BROKEN_PERL_LOAD_MODULE, - test "x$c_cv_have_broken_perl_load_module" = "xyes") - -if test "x$with_libperl" = "xyes" -then - SAVE_CFLAGS="$CFLAGS" - SAVE_LIBS="$LIBS" - CFLAGS="$CFLAGS $PERL_CFLAGS" - LIBS="$LIBS $PERL_LIBS" - - AC_CHECK_MEMBER( - [struct mgvtbl.svt_local], - [have_struct_mgvtbl_svt_local="yes"], - [have_struct_mgvtbl_svt_local="no"], - [ -#include -#include -#include - ]) - - if test "x$have_struct_mgvtbl_svt_local" = "xyes" - then - AC_DEFINE(HAVE_PERL_STRUCT_MGVTBL_SVT_LOCAL, 1, - [Define if Perl's struct mgvtbl has member svt_local.]) - fi - - CFLAGS="$SAVE_CFLAGS" - LIBS="$SAVE_LIBS" -fi -# }}} +if test "x$with_libperl" = "xyes"; then + SAVE_CFLAGS="$CFLAGS" + SAVE_LIBS="$LIBS" + CFLAGS="$CFLAGS $PERL_CFLAGS" + LIBS="$LIBS $PERL_LIBS" -# --with-libpq {{{ + AC_CACHE_CHECK([if Perl supports ithreads], + [c_cv_have_perl_ithreads], + [ + AC_LINK_IFELSE( + [ + AC_LANG_PROGRAM( + [[ + #include + #include + #include + + #if !defined(USE_ITHREADS) + # error "Perl does not support ithreads!" + #endif /* !defined(USE_ITHREADS) */ + ]], + [] + ) + ], + [c_cv_have_perl_ithreads="yes"], + [c_cv_have_perl_ithreads="no"] + ) + ] + ) + + CFLAGS="$SAVE_CFLAGS" + LIBS="$SAVE_LIBS" +fi + +if test "x$with_libperl" = "xyes"; then + # trigger an error if Perl_load_module*() uses __attribute__nonnull__(3) + # (see issues #41 and #42) + SAVE_CFLAGS="$CFLAGS" + SAVE_LIBS="$LIBS" + CFLAGS="$CFLAGS $PERL_CFLAGS -Wall -Werror" + LIBS="$LIBS $PERL_LIBS" + + AC_CACHE_CHECK([for broken Perl_load_module()], + [c_cv_have_broken_perl_load_module], + [ + AC_LINK_IFELSE( + [ + AC_LANG_PROGRAM( + [[ + #define PERL_NO_GET_CONTEXT + #include + #include + #include + ]], + [[ + dTHX; + load_module (PERL_LOADMOD_NOIMPORT, + newSVpv ("Collectd::Plugin::FooBar", 24), + Nullsv); + ]] + ) + ], + [c_cv_have_broken_perl_load_module="no"], + [c_cv_have_broken_perl_load_module="yes"] + ) + ] + ) + + CFLAGS="$SAVE_CFLAGS" + LIBS="$SAVE_LIBS" +fi + +if test "x$c_cv_have_broken_perl_load_module" = "xyes"; then + PERL_CFLAGS="$PERL_CFLAGS -Wno-nonnull" +fi + +if test "x$with_libperl" = "xyes"; then + SAVE_CFLAGS="$CFLAGS" + SAVE_LIBS="$LIBS" + CFLAGS="$CFLAGS $PERL_CFLAGS" + LIBS="$LIBS $PERL_LIBS" + + AC_CHECK_MEMBER( + [struct mgvtbl.svt_local], + [have_struct_mgvtbl_svt_local="yes"], + [have_struct_mgvtbl_svt_local="no"], + [[ + #include + #include + #include + ]] + ) + + if test "x$have_struct_mgvtbl_svt_local" = "xyes"; then + AC_DEFINE([HAVE_PERL_STRUCT_MGVTBL_SVT_LOCAL], [1], [Define if Perls struct mgvtbl has member svt_local.]) + fi + + CFLAGS="$SAVE_CFLAGS" + LIBS="$SAVE_LIBS" +fi +AC_SUBST([PERL_CFLAGS]) +AC_SUBST([PERL_LIBS]) + +# }}} + +# --with-libpq {{{ with_pg_config="pg_config" -with_libpq_includedir="" -with_libpq_libdir="" -with_libpq_cppflags="" -with_libpq_ldflags="" -AC_ARG_WITH(libpq, [AS_HELP_STRING([--with-libpq@<:@=PREFIX@:>@], - [Path to libpq.])], -[ - if test "x$withval" = "xno" - then - with_libpq="no" - else if test "x$withval" = "xyes" - then - with_libpq="yes" - else - if test -f "$withval" && test -x "$withval"; - then - with_pg_config="$withval" - else if test -x "$withval/bin/pg_config" - then - with_pg_config="$withval/bin/pg_config" - fi; fi - with_libpq="yes" - fi; fi -], -[ - with_libpq="yes" -]) -if test "x$with_libpq" = "xyes" -then - with_libpq_includedir=`$with_pg_config --includedir 2> /dev/null` - pg_config_status=$? +AC_ARG_WITH([libpq], + [AS_HELP_STRING([--with-libpq@<:@=PREFIX@:>@], [Path to libpq.])], + [ + if test "x$withval" = "xno" || test "x$withval" = "xyes"; then + with_libpq="$withval" + else + if test -f "$withval" && test -x "$withval"; then + with_pg_config="$withval" + else if test -x "$withval/bin/pg_config"; then + with_pg_config="$withval/bin/pg_config" + fi; fi + with_libpq="yes" + fi + ], + [with_libpq="yes"] +) - if test $pg_config_status -eq 0 - then - if test -n "$with_libpq_includedir"; then - for dir in $with_libpq_includedir; do - with_libpq_cppflags="$with_libpq_cppflags -I$dir" - done - fi - else - AC_MSG_WARN([$with_pg_config returned with status $pg_config_status]) - fi +if test "x$with_libpq" = "xyes"; then + with_libpq_includedir=`$with_pg_config --includedir 2> /dev/null` + pg_config_status=$? - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $with_libpq_cppflags" + if test $pg_config_status -eq 0; then + if test -n "$with_libpq_includedir"; then + for dir in $with_libpq_includedir; do + with_libpq_cppflags="$with_libpq_cppflags -I$dir" + done + fi + else + AC_MSG_WARN([$with_pg_config returned with status $pg_config_status]) + fi - AC_CHECK_HEADERS(libpq-fe.h, [], - [with_libpq="no (libpq-fe.h not found)"], []) + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_libpq_cppflags" - CPPFLAGS="$SAVE_CPPFLAGS" + AC_CHECK_HEADERS([libpq-fe.h], + [with_libpq="yes"], + [with_libpq="no (libpq-fe.h not found)"] + ) + + CPPFLAGS="$SAVE_CPPFLAGS" fi -if test "x$with_libpq" = "xyes" -then - with_libpq_libdir=`$with_pg_config --libdir 2> /dev/null` - pg_config_status=$? - if test $pg_config_status -eq 0 - then - if test -n "$with_libpq_libdir"; then - for dir in $with_libpq_libdir; do - with_libpq_ldflags="$with_libpq_ldflags -L$dir" - done - fi - else - AC_MSG_WARN([$with_pg_config returned with status $pg_config_status]) - fi +if test "x$with_libpq" = "xyes"; then + with_libpq_libdir=`$with_pg_config --libdir 2> /dev/null` + pg_config_status=$? - SAVE_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $with_libpq_ldflags" + if test $pg_config_status -eq 0 + then + if test -n "$with_libpq_libdir"; then + for dir in $with_libpq_libdir; do + with_libpq_ldflags="$with_libpq_ldflags -L$dir" + done + fi + else + AC_MSG_WARN([$with_pg_config returned with status $pg_config_status]) + fi - AC_CHECK_LIB(pq, PQconnectdb, - [with_libpq="yes"], - [with_libpq="no (symbol 'PQconnectdb' not found)"]) + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $with_libpq_ldflags" - AC_CHECK_LIB(pq, PQserverVersion, - [with_libpq="yes"], - [with_libpq="no (symbol 'PQserverVersion' not found)"]) + AC_CHECK_LIB([pq], [PQserverVersion], + [with_libpq="yes"], + [with_libpq="no (symbol 'PQserverVersion' not found)"]) - LDFLAGS="$SAVE_LDFLAGS" + LDFLAGS="$SAVE_LDFLAGS" fi -if test "x$with_libpq" = "xyes" -then - BUILD_WITH_LIBPQ_CPPFLAGS="$with_libpq_cppflags" - BUILD_WITH_LIBPQ_LDFLAGS="$with_libpq_ldflags" - AC_SUBST(BUILD_WITH_LIBPQ_CPPFLAGS) - AC_SUBST(BUILD_WITH_LIBPQ_LDFLAGS) + +if test "x$with_libpq" = "xyes"; then + BUILD_WITH_LIBPQ_CPPFLAGS="$with_libpq_cppflags" + BUILD_WITH_LIBPQ_LDFLAGS="$with_libpq_ldflags" + BUILD_WITH_LIBPQ_LIBS="-lpq" fi -AM_CONDITIONAL(BUILD_WITH_LIBPQ, test "x$with_libpq" = "xyes") + +AC_SUBST([BUILD_WITH_LIBPQ_CPPFLAGS]) +AC_SUBST([BUILD_WITH_LIBPQ_LDFLAGS]) +AC_SUBST([BUILD_WITH_LIBPQ_LIBS]) # }}} # --with-libpqos {{{ @@ -4263,31 +4281,29 @@ fi # --with-libprotobuf {{{ with_libprotobuf_cppflags="" with_libprotobuf_ldflags="" -AC_ARG_WITH([libprotobuf], [AS_HELP_STRING([--with-libprotobuf@<:@=PREFIX@:>@], [Path to libprotobuf.])], +AC_ARG_WITH([libprotobuf], + [AS_HELP_STRING([--with-libprotobuf@<:@=PREFIX@:>@], [Path to libprotobuf.])], [ - if test "x$withval" != "xno" && test "x$withval" != "xyes" - then + if test "x$withval" != "xno" && test "x$withval" != "xyes"; then with_libprotobuf_cppflags="-I$withval/include" with_libprotobuf_ldflags="-L$withval/lib" with_libprotobuf="yes" fi - if test "x$withval" = "xno" - then + if test "x$withval" = "xno"; then with_libprotobuf="no (disabled on command line)" fi ], [withval="yes"] ) -if test "x$withval" = "xyes" -then -PKG_CHECK_MODULES([PROTOBUF], [protobuf], - [with_libprotobuf="yes"], - [with_libprotobuf="no (pkg-config could not find libprotobuf)"] -) + +if test "x$withval" = "xyes"; then + PKG_CHECK_MODULES([PROTOBUF], [protobuf], + [with_libprotobuf="yes"], + [with_libprotobuf="no (pkg-config could not find libprotobuf)"] + ) fi -if test "x$withval" != "xno" -then +if test "x$withval" != "xno"; then SAVE_LDFLAGS="$LDFLAGS" SAVE_LIBS="$LIBS" LDFLAGS="$with_libprotobuf_ldflags" @@ -4313,6 +4329,7 @@ then LDFLAGS="$SAVE_LDFLAGS" LIBS="$SAVE_LIBS" fi + BUILD_WITH_LIBPROTOBUF_CPPFLAGS="$with_libprotobuf_cppflags $PROTOBUF_CFLAGS" BUILD_WITH_LIBPROTOBUF_LDFLAGS="$with_libprotobuf_ldflags" BUILD_WITH_LIBPROTOBUF_LIBS="$PROTOBUF_LIBS" @@ -4321,34 +4338,46 @@ AC_SUBST([BUILD_WITH_LIBPROTOBUF_LDFLAGS]) AC_SUBST([BUILD_WITH_LIBPROTOBUF_LIBS]) # }}} +AC_ARG_VAR([PROTOC], [path to the protoc binary]) +AC_PATH_PROG([PROTOC], [protoc]) +have_protoc3="no" +if test "x$PROTOC" != "x"; then + AC_MSG_CHECKING([for protoc 3.0.0+]) + if $PROTOC --version | $EGREP libprotoc.3 >/dev/null; then + protoc3="yes (`$PROTOC --version`)" + have_protoc3="yes" + else + protoc3="no (`$PROTOC --version`)" + fi + AC_MSG_RESULT([$protoc3]) +fi +AM_CONDITIONAL([HAVE_PROTOC3], [test "x$have_protoc3" = "xyes"]) + # --with-libprotobuf-c {{{ -with_libprotobuf_c_cppflags="" -with_libprotobuf_c_ldflags="" -AC_ARG_WITH([libprotobuf-c], [AS_HELP_STRING([--with-libprotobuf-c@<:@=PREFIX@:>@], [Path to libprotobuf-c.])], +AC_ARG_WITH([libprotobuf-c], + [AS_HELP_STRING([--with-libprotobuf-c@<:@=PREFIX@:>@], [Path to libprotobuf-c.])], [ - if test "x$withval" != "xno" && test "x$withval" != "xyes" - then + if test "x$withval" != "xno" && test "x$withval" != "xyes"; then with_libprotobuf_c_cppflags="-I$withval/include" with_libprotobuf_c_ldflags="-L$withval/lib" with_libprotobuf_c="yes" fi - if test "x$withval" = "xno" - then + + if test "x$withval" = "xno"; then with_libprotobuf_c="no (disabled on command line)" fi ], [withval="yes"] ) -if test "x$withval" = "xyes" -then -PKG_CHECK_MODULES([PROTOBUF_C], [libprotobuf-c], - [with_libprotobuf_c="yes"], - [with_libprotobuf_c="no (pkg-config could not find libprotobuf-c)"] -) + +if test "x$withval" = "xyes"; then + PKG_CHECK_MODULES([PROTOBUF_C], [libprotobuf-c], + [with_libprotobuf_c="yes"], + [with_libprotobuf_c="no (pkg-config could not find libprotobuf-c)"] + ) fi -if test "x$withval" != "xno" -then +if test "x$withval" != "xno"; then SAVE_LDFLAGS="$LDFLAGS" SAVE_LIBS="$LIBS" LDFLAGS="$with_libprotobuf_c_ldflags" @@ -4357,10 +4386,10 @@ then [ SAVE_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$with_libprotobuf_c_cppflags $PROTOBUF_C_CFLAGS" - if test "x$PROTOBUF_C_LIBS" = "x" - then + if test "x$PROTOBUF_C_LIBS" = "x"; then PROTOBUF_C_LIBS="-lprotobuf-c" fi + AC_CHECK_HEADERS([protobuf-c/protobuf-c.h google/protobuf-c/protobuf-c.h], [ with_libprotobuf_c="yes" @@ -4368,6 +4397,7 @@ then ], [with_libprotobuf_c="no ( not found)"] ) + CPPFLAGS="$SAVE_CPPFLAGS" ], [with_libprotobuf_c="no (libprotobuf-c not found)"] @@ -4375,6 +4405,7 @@ then LDFLAGS="$SAVE_LDFLAGS" LIBS="$SAVE_LIBS" fi + BUILD_WITH_LIBPROTOBUF_C_CPPFLAGS="$with_libprotobuf_c_cppflags $PROTOBUF_C_CFLAGS" BUILD_WITH_LIBPROTOBUF_C_LDFLAGS="$with_libprotobuf_c_ldflags" BUILD_WITH_LIBPROTOBUF_C_LIBS="$PROTOBUF_C_LIBS" @@ -4383,18 +4414,26 @@ AC_SUBST([BUILD_WITH_LIBPROTOBUF_C_LDFLAGS]) AC_SUBST([BUILD_WITH_LIBPROTOBUF_C_LIBS]) # }}} +AC_ARG_VAR([PROTOC_C], [path to the protoc-c binary]) +AC_PATH_PROG([PROTOC_C], [protoc-c]) +if test "x$PROTOC_C" = "x" +then + have_protoc_c="no (protoc-c compiler not found)" +else + have_protoc_c="yes" +fi + # --with-libpython {{{ AC_ARG_VAR([LIBPYTHON_CPPFLAGS], [Preprocessor flags for libpython]) AC_ARG_VAR([LIBPYTHON_LDFLAGS], [Linker flags for libpython]) AC_ARG_VAR([LIBPYTHON_LIBS], [Libraries for libpython]) AC_ARG_WITH([libpython], - [AS_HELP_STRING([--with-libpython], - [if we should build with libpython @<:@default=yes@:>@]) - ], + [AS_HELP_STRING([--with-libpython], [if we should build with libpython @<:@default=yes@:>@])], [with_libpython="$withval"], [with_libpython="check"] ) + if test "$with_libpython" != "no"; then if test "$LIBPYTHON_CPPFLAGS" = "" && test "$LIBPYTHON_LDFLAGS" = ""; then AC_ARG_VAR([PYTHON_CONFIG], [path to python-config]) @@ -4432,6 +4471,7 @@ if test "$with_libpython" != "xno"; then CPPFLAGS="$LIBPYTHON_CPPFLAGS $CPPFLAGS" LDFLAGS="$LIBPYTHON_LDFLAGS $LDFLAGS" LIBS="$LIBPYTHON_LIBS $LIBS" + AC_CHECK_HEADERS([Python.h], [ AC_MSG_CHECKING([for libpython]) @@ -4446,6 +4486,7 @@ if test "$with_libpython" != "xno"; then ], [with_libpython="no"] ) + CPPFLAGS="$SAVE_CPPFLAGS" LDFLAGS="$SAVE_LDFLAGS" LIBS="$SAVE_LIBS" @@ -4453,272 +4494,272 @@ fi # }}} --with-libpython # --with-librabbitmq {{{ -with_librabbitmq_cppflags="" -with_librabbitmq_ldflags="" -AC_ARG_WITH(librabbitmq, [AS_HELP_STRING([--with-librabbitmq@<:@=PREFIX@:>@], [Path to librabbitmq.])], -[ - if test "x$withval" != "xno" && test "x$withval" != "xyes" - then - with_librabbitmq_cppflags="-I$withval/include" - with_librabbitmq_ldflags="-L$withval/lib" - with_librabbitmq="yes" - else - with_librabbitmq="$withval" - fi -], -[ - with_librabbitmq="yes" -]) -SAVE_CPPFLAGS="$CPPFLAGS" -SAVE_LDFLAGS="$LDFLAGS" -CPPFLAGS="$CPPFLAGS $with_librabbitmq_cppflags" -LDFLAGS="$LDFLAGS $with_librabbitmq_ldflags" -if test "x$with_librabbitmq" = "xyes" -then - AC_CHECK_HEADERS(amqp.h, [with_librabbitmq="yes"], [with_librabbitmq="no (amqp.h not found)"]) -fi -if test "x$with_librabbitmq" = "xyes" -then - # librabbitmq up to version 0.9.1 provides "library_errno", later - # versions use "library_error". The library does not provide a version - # macro :( Use "AC_CHECK_MEMBERS" (plural) for automatic defines. - AC_CHECK_MEMBERS([amqp_rpc_reply_t.library_errno],,, - [ -#if HAVE_STDLIB_H -# include -#endif -#if HAVE_STDIO_H -# include -#endif -#if HAVE_STDINT_H -# include -#endif -#if HAVE_INTTYPES_H -# include -#endif -#include - ]) -fi -if test "x$with_librabbitmq" = "xyes" -then - AC_CHECK_LIB(rabbitmq, amqp_basic_publish, [with_librabbitmq="yes"], [with_librabbitmq="no (Symbol 'amqp_basic_publish' not found)"]) -fi -if test "x$with_librabbitmq" = "xyes" -then - BUILD_WITH_LIBRABBITMQ_CPPFLAGS="$with_librabbitmq_cppflags" - BUILD_WITH_LIBRABBITMQ_LDFLAGS="$with_librabbitmq_ldflags" - BUILD_WITH_LIBRABBITMQ_LIBS="-lrabbitmq" - AC_SUBST(BUILD_WITH_LIBRABBITMQ_CPPFLAGS) - AC_SUBST(BUILD_WITH_LIBRABBITMQ_LDFLAGS) - AC_SUBST(BUILD_WITH_LIBRABBITMQ_LIBS) - AC_DEFINE(HAVE_LIBRABBITMQ, 1, [Define if librabbitmq is present and usable.]) -fi -CPPFLAGS="$SAVE_CPPFLAGS" -LDFLAGS="$SAVE_LDFLAGS" -AM_CONDITIONAL(BUILD_WITH_LIBRABBITMQ, test "x$with_librabbitmq" = "xyes") +AC_ARG_WITH([librabbitmq], + [AS_HELP_STRING([--with-librabbitmq@<:@=PREFIX@:>@], [Path to librabbitmq.])], + [ + if test "x$withval" != "xno" && test "x$withval" != "xyes"; then + with_librabbitmq_cppflags="-I$withval/include" + with_librabbitmq_ldflags="-L$withval/lib" + with_librabbitmq="yes" + else + with_librabbitmq="$withval" + fi + ], + [with_librabbitmq="yes"] +) -with_amqp_tcp_socket="no" -if test "x$with_librabbitmq" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - SAVE_LDFLAGS="$LDFLAGS" - SAVE_LIBS="$LIBS" - CPPFLAGS="$CPPFLAGS $with_librabbitmq_cppflags" - LDFLAGS="$LDFLAGS $with_librabbitmq_ldflags" - LIBS="-lrabbitmq" - - AC_CHECK_HEADERS(amqp_tcp_socket.h amqp_socket.h) - AC_CHECK_FUNC(amqp_tcp_socket_new, [with_amqp_tcp_socket="yes"], [with_amqp_tcp_socket="no"]) - if test "x$with_amqp_tcp_socket" = "xyes" - then - AC_DEFINE(HAVE_AMQP_TCP_SOCKET, 1, - [Define if librabbitmq provides the new TCP socket interface.]) - fi +if test "x$with_librabbitmq" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_librabbitmq_cppflags" - AC_CHECK_DECLS(amqp_socket_close, - [amqp_socket_close_decl="yes"], [amqp_socket_close_decl="no"], - [[ -#include -#ifdef HAVE_AMQP_TCP_SOCKET_H -# include -#endif -#ifdef HAVE_AMQP_SOCKET_H -# include -#endif - ]]) + AC_CHECK_HEADERS([amqp.h], + [with_librabbitmq="yes"], + [with_librabbitmq="no (amqp.h not found)"] + ) - CPPFLAGS="$SAVE_CPPFLAGS" - LDFLAGS="$SAVE_LDFLAGS" - LIBS="$SAVE_LIBS" + CPPFLAGS="$SAVE_CPPFLAGS" fi -# }}} -# --with-librdkafka {{{ -AC_ARG_WITH(librdkafka, [AS_HELP_STRING([--with-librdkafka@<:@=PREFIX@:>@], [Path to librdkafka.])], -[ - if test "x$withval" != "xno" && test "x$withval" != "xyes" - then - with_librdkafka_cppflags="-I$withval/include" - with_librdkafka_ldflags="-L$withval/lib" - with_librdkafka_rpath="$withval/lib" - with_librdkafka="yes" - else - with_librdkafka="$withval" - fi -], -[ - with_librdkafka="yes" -]) -SAVE_CPPFLAGS="$CPPFLAGS" -SAVE_LDFLAGS="$LDFLAGS" +if test "x$with_librabbitmq" = "xyes"; then + # librabbitmq up to version 0.9.1 provides "library_errno", later + # versions use "library_error". The library does not provide a version + # macro :(. -CPPFLAGS="$CPPFLAGS $with_librdkafka_cppflags" -LDFLAGS="$LDFLAGS $with_librdkafka_ldflags" + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_librabbitmq_cppflags" -if test "x$with_librdkafka" = "xyes" -then - AC_CHECK_HEADERS(librdkafka/rdkafka.h, [with_librdkafka="yes"], [with_librdkafka="no (librdkafka/rdkafka.h not found)"]) -fi + AC_CHECK_MEMBERS([amqp_rpc_reply_t.library_errno], + [], + [], + [[ + #include + #include + #include + #include + #include + ]] + ) + CPPFLAGS="$SAVE_CPPFLAGS" -if test "x$with_librdkafka" = "xyes" -then - AC_CHECK_LIB(rdkafka, rd_kafka_new, [with_librdkafka="yes"], [with_librdkafka="no (Symbol 'rd_kafka_new' not found)"]) - AC_CHECK_LIB(rdkafka, rd_kafka_conf_set_log_cb, [with_librdkafka_log_cb="yes"], [with_librdkafka_log_cb="no"]) - AC_CHECK_LIB(rdkafka, rd_kafka_set_logger, [with_librdkafka_logger="yes"], [with_librdkafka_logger="no"]) -fi -if test "x$with_librdkafka" = "xyes" -then - BUILD_WITH_LIBRDKAFKA_CPPFLAGS="$with_librdkafka_cppflags" - BUILD_WITH_LIBRDKAFKA_LDFLAGS="$with_librdkafka_ldflags" - if test "x$with_librdkafka_rpath" != "x" - then - BUILD_WITH_LIBRDKAFKA_LIBS="-Wl,-rpath,$with_librdkafka_rpath -lrdkafka" - else - BUILD_WITH_LIBRDKAFKA_LIBS="-lrdkafka" - fi - AC_SUBST(BUILD_WITH_LIBRDKAFKA_CPPFLAGS) - AC_SUBST(BUILD_WITH_LIBRDKAFKA_LDFLAGS) - AC_SUBST(BUILD_WITH_LIBRDKAFKA_LIBS) - AC_DEFINE(HAVE_LIBRDKAFKA, 1, [Define if librdkafka is present and usable.]) - if test "x$with_librdkafka_log_cb" = "xyes" - then - AC_DEFINE(HAVE_LIBRDKAFKA_LOG_CB, 1, [Define if librdkafka log facility is present and usable.]) - else if test "x$with_librdkafka_logger" = "xyes" - then - AC_DEFINE(HAVE_LIBRDKAFKA_LOGGER, 1, [Define if librdkafka log facility is present and usable.]) - fi; fi -fi -CPPFLAGS="$SAVE_CPPFLAGS" -LDFLAGS="$SAVE_LDFLAGS" -AM_CONDITIONAL(BUILD_WITH_LIBRDKAFKA, test "x$with_librdkafka" = "xyes") + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $with_librabbitmq_ldflags" -# }}} + AC_CHECK_LIB([rabbitmq], [amqp_basic_publish], + [with_librabbitmq="yes"], + [with_librabbitmq="no (Symbol 'amqp_basic_publish' not found)"] + ) -# --with-librouteros {{{ -AC_ARG_WITH(librouteros, [AS_HELP_STRING([--with-librouteros@<:@=PREFIX@:>@], [Path to librouteros.])], -[ - if test "x$withval" = "xyes" - then - with_librouteros="yes" - else if test "x$withval" = "xno" - then - with_librouteros="no" - else - with_librouteros="yes" - LIBROUTEROS_CPPFLAGS="$LIBROUTEROS_CPPFLAGS -I$withval/include" - LIBROUTEROS_LDFLAGS="$LIBROUTEROS_LDFLAGS -L$withval/lib" - fi; fi -], -[with_librouteros="yes"]) + LDFLAGS="$SAVE_LDFLAGS" +fi -SAVE_CPPFLAGS="$CPPFLAGS" -SAVE_LDFLAGS="$LDFLAGS" +if test "x$with_librabbitmq" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + SAVE_LDFLAGS="$LDFLAGS" + SAVE_LIBS="$LIBS" + CPPFLAGS="$CPPFLAGS $with_librabbitmq_cppflags" + LDFLAGS="$LDFLAGS $with_librabbitmq_ldflags" + LIBS="-lrabbitmq" -CPPFLAGS="$CPPFLAGS $LIBROUTEROS_CPPFLAGS" -LDFLAGS="$LDFLAGS $LIBROUTEROS_LDFLAGS" + AC_CHECK_HEADERS([amqp_tcp_socket.h amqp_socket.h]) + AC_CHECK_FUNC([amqp_tcp_socket_new], + [ + AC_DEFINE([HAVE_AMQP_TCP_SOCKET], [1], + [Define if librabbitmq provides the new TCP socket interface.]) + ] + ) -if test "x$with_librouteros" = "xyes" -then - if test "x$LIBROUTEROS_CPPFLAGS" != "x" - then - AC_MSG_NOTICE([librouteros CPPFLAGS: $LIBROUTEROS_CPPFLAGS]) - fi - AC_CHECK_HEADERS(routeros_api.h, - [with_librouteros="yes"], - [with_librouteros="no (routeros_api.h not found)"]) + AC_CHECK_DECLS([amqp_socket_close], + [], + [], + [[ + #include + #ifdef HAVE_AMQP_TCP_SOCKET_H + # include + #endif + #ifdef HAVE_AMQP_SOCKET_H + # include + #endif + ]] + ) + + CPPFLAGS="$SAVE_CPPFLAGS" + LDFLAGS="$SAVE_LDFLAGS" + LIBS="$SAVE_LIBS" fi -if test "x$with_librouteros" = "xyes" -then - if test "x$LIBROUTEROS_LDFLAGS" != "x" - then - AC_MSG_NOTICE([librouteros LDFLAGS: $LIBROUTEROS_LDFLAGS]) - fi - AC_CHECK_LIB(routeros, ros_interface, - [with_librouteros="yes"], - [with_librouteros="no (symbol 'ros_interface' not found)"]) + +if test "x$with_librabbitmq" = "xyes"; then + BUILD_WITH_LIBRABBITMQ_CPPFLAGS="$with_librabbitmq_cppflags" + BUILD_WITH_LIBRABBITMQ_LDFLAGS="$with_librabbitmq_ldflags" + BUILD_WITH_LIBRABBITMQ_LIBS="-lrabbitmq" fi -CPPFLAGS="$SAVE_CPPFLAGS" -LDFLAGS="$SAVE_LDFLAGS" +AC_SUBST(BUILD_WITH_LIBRABBITMQ_CPPFLAGS) +AC_SUBST(BUILD_WITH_LIBRABBITMQ_LDFLAGS) +AC_SUBST(BUILD_WITH_LIBRABBITMQ_LIBS) -if test "x$with_librouteros" = "xyes" -then - BUILD_WITH_LIBROUTEROS_CPPFLAGS="$LIBROUTEROS_CPPFLAGS" - BUILD_WITH_LIBROUTEROS_LDFLAGS="$LIBROUTEROS_LDFLAGS" - AC_SUBST(BUILD_WITH_LIBROUTEROS_CPPFLAGS) - AC_SUBST(BUILD_WITH_LIBROUTEROS_LDFLAGS) -fi -AM_CONDITIONAL(BUILD_WITH_LIBROUTEROS, test "x$with_librouteros" = "xyes") # }}} -# --with-librrd {{{ -librrd_cflags="" -librrd_ldflags="" -librrd_threadsafe="no" -librrd_rrdc_update="no" -AC_ARG_WITH(librrd, - [AS_HELP_STRING([--with-librrd@<:@=PREFIX@:>@], [Path to rrdtool.])], +# --with-librdkafka {{{ +AC_ARG_WITH([librdkafka], + [AS_HELP_STRING([--with-librdkafka@<:@=PREFIX@:>@], [Path to librdkafka.])], [ - if test "x$withval" != "xno" && test "x$withval" != "xyes" - then - librrd_cflags="-I$withval/include" - librrd_ldflags="-L$withval/lib" - with_librrd="yes" + if test "x$withval" != "xno" && test "x$withval" != "xyes"; then + with_librdkafka_cppflags="-I$withval/include" + with_librdkafka_ldflags="-L$withval/lib" + with_librdkafka_rpath="$withval/lib" + with_librdkafka="yes" else - with_librrd="$withval" + with_librdkafka="$withval" fi ], - [with_librrd="yes"] + [with_librdkafka="yes"] ) -if test "x$with_librrd" = "xyes" -then - SAVE_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $librrd_ldflags" - PKG_CHECK_MODULES([RRD], [librrd >= 1.6.0], - [ - AC_CHECK_LIB([rrd], [rrd_update_r], - [librrd_threadsafe="yes"], - [:] - ) - AC_CHECK_LIB([rrd], [rrdc_update], - [librrd_rrdc_update="yes"], - [:] - ) - ],[:] - ) - LDFLAGS="$SAVE_LDFLAGS" - +if test "x$with_librdkafka" = "xyes"; then SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $RRD_CFLAGS $librrd_cflags" + CPPFLAGS="$CPPFLAGS $with_librdkafka_cppflags" - AC_CHECK_HEADERS([rrd.h],, [with_librrd="no (rrd.h not found)"]) + AC_CHECK_HEADERS([librdkafka/rdkafka.h], + [with_librdkafka="yes"], + [with_librdkafka="no (librdkafka/rdkafka.h not found)"] + ) CPPFLAGS="$SAVE_CPPFLAGS" fi -if test "x$with_librrd" = "xyes" && test "x$librrd_threadsafe" = "xno" -then +if test "x$with_librdkafka" = "xyes"; then + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $with_librdkafka_ldflags" + + AC_CHECK_LIB([rdkafka], [rd_kafka_new], + [with_librdkafka="yes"], + [with_librdkafka="no (Symbol 'rd_kafka_new' not found)"]) + + AC_CHECK_LIB([rdkafka], [rd_kafka_conf_set_log_cb], + [with_librdkafka_log_cb="yes"], + [with_librdkafka_log_cb="no"]) + + AC_CHECK_LIB([rdkafka], [rd_kafka_set_logger], + [with_librdkafka_logger="yes"], + [with_librdkafka_logger="no"] + ) + + LDFLAGS="$SAVE_LDFLAGS" +fi + +if test "x$with_librdkafka" = "xyes"; then + BUILD_WITH_LIBRDKAFKA_CPPFLAGS="$with_librdkafka_cppflags" + BUILD_WITH_LIBRDKAFKA_LDFLAGS="$with_librdkafka_ldflags" + + if test "x$with_librdkafka_rpath" != "x"; then + BUILD_WITH_LIBRDKAFKA_LIBS="-Wl,-rpath,$with_librdkafka_rpath -lrdkafka" + else + BUILD_WITH_LIBRDKAFKA_LIBS="-lrdkafka" + fi + + if test "x$with_librdkafka_log_cb" = "xyes"; then + AC_DEFINE(HAVE_LIBRDKAFKA_LOG_CB, 1, [Define if librdkafka log facility is present and usable.]) + else if test "x$with_librdkafka_logger" = "xyes"; then + AC_DEFINE(HAVE_LIBRDKAFKA_LOGGER, 1, [Define if librdkafka log facility is present and usable.]) + fi; fi +fi + +AC_SUBST([BUILD_WITH_LIBRDKAFKA_CPPFLAGS]) +AC_SUBST([BUILD_WITH_LIBRDKAFKA_LDFLAGS]) +AC_SUBST([BUILD_WITH_LIBRDKAFKA_LIBS]) +# }}} + +# --with-librouteros {{{ +AC_ARG_WITH([librouteros], + [AS_HELP_STRING([--with-librouteros@<:@=PREFIX@:>@], [Path to librouteros.])], + [ + if test "x$withval" = "xyes" || test "x$withval" = "xno"; then + with_librouteros="$witval" + else + with_librouteros_cppflags="-I$withval/include" + with_librouteros_ldflags="-L$withval/lib" + with_librouteros="yes" + fi + ], + [with_librouteros="yes"] +) + +if test "x$with_librouteros" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_librouteros_cppflags" + + AC_CHECK_HEADERS([routeros_api.h], + [with_librouteros="yes"], + [with_librouteros="no (routeros_api.h not found)"] + ) + + CPPFLAGS="$SAVE_CPPFLAGS" +fi + +if test "x$with_librouteros" = "xyes"; then + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $with_librouteros_ldflags" + + AC_CHECK_LIB([routeros], [ros_interface], + [with_librouteros="yes"], + [with_librouteros="no (symbol 'ros_interface' not found)"] + ) + + LDFLAGS="$SAVE_LDFLAGS" +fi + +if test "x$with_librouteros" = "xyes"; then + BUILD_WITH_LIBROUTEROS_CPPFLAGS="$with_librouteros_cppflags" + BUILD_WITH_LIBROUTEROS_LDFLAGS="$with_librouteros_ldflags" +fi + +AC_SUBST([BUILD_WITH_LIBROUTEROS_CPPFLAGS]) +AC_SUBST([BUILD_WITH_LIBROUTEROS_LDFLAGS]) +# }}} + +# --with-librrd {{{ +librrd_threadsafe="no" +librrd_rrdc_update="no" +AC_ARG_WITH([librrd], + [AS_HELP_STRING([--with-librrd@<:@=PREFIX@:>@], [Path to rrdtool.])], + [ + if test "x$withval" != "xno" && test "x$withval" != "xyes"; then + librrd_cflags="-I$withval/include" + librrd_ldflags="-L$withval/lib" + with_librrd="yes" + else + with_librrd="$withval" + fi + ], + [with_librrd="yes"] +) + +if test "x$with_librrd" = "xyes"; then + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $librrd_ldflags" + PKG_CHECK_MODULES([RRD], [librrd >= 1.6.0], + [ + AC_CHECK_LIB([rrd], [rrd_update_r], + [librrd_threadsafe="yes"], + [:] + ) + AC_CHECK_LIB([rrd], [rrdc_update], + [librrd_rrdc_update="yes"], + [:] + ) + ],[:] + ) + LDFLAGS="$SAVE_LDFLAGS" + + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $RRD_CFLAGS $librrd_cflags" + + AC_CHECK_HEADERS([rrd.h],, [with_librrd="no (rrd.h not found)"]) + + CPPFLAGS="$SAVE_CPPFLAGS" +fi + +if test "x$with_librrd" = "xyes" && test "x$librrd_threadsafe" = "xno"; then SAVE_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $librrd_ldflags" @@ -4736,8 +4777,7 @@ then LDFLAGS="$SAVE_LDFLAGS" fi -if test "x$with_librrd" = "xyes" && test "x$librrd_threadsafe" = "xno" -then +if test "x$with_librrd" = "xyes" && test "x$librrd_threadsafe" = "xno"; then SAVE_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $librrd_ldflags" @@ -4754,82 +4794,78 @@ then LDFLAGS="$SAVE_LDFLAGS" fi -if test "x$with_librrd" = "xyes" -then +if test "x$with_librrd" = "xyes"; then BUILD_WITH_LIBRRD_CFLAGS="$RRD_CFLAGS $librrd_cflags" BUILD_WITH_LIBRRD_LDFLAGS="$librrd_ldflags" BUILD_WITH_LIBRRD_LIBS="$RRD_LIBS" - AC_SUBST(BUILD_WITH_LIBRRD_CFLAGS) - AC_SUBST(BUILD_WITH_LIBRRD_LDFLAGS) - AC_SUBST(BUILD_WITH_LIBRRD_LIBS) fi -if test "x$librrd_threadsafe" = "xyes" -then + +if test "x$librrd_threadsafe" = "xyes"; then AC_DEFINE([HAVE_THREADSAFE_LIBRRD], [1], [Define to 1 if the rrd library is thread-safe] ) fi + +AC_SUBST([BUILD_WITH_LIBRRD_CFLAGS]) +AC_SUBST([BUILD_WITH_LIBRRD_LDFLAGS]) +AC_SUBST([BUILD_WITH_LIBRRD_LIBS]) # }}} # --with-libsensors {{{ -with_sensors_cflags="" -with_sensors_ldflags="" -AC_ARG_WITH(libsensors, [AS_HELP_STRING([--with-libsensors@<:@=PREFIX@:>@], [Path to lm_sensors.])], -[ - if test "x$withval" = "xno" - then - with_libsensors="no" - else - with_libsensors="yes" - if test "x$withval" != "xyes" - then - with_sensors_cflags="-I$withval/include" - with_sensors_ldflags="-L$withval/lib" - with_libsensors="yes" - fi - fi -], -[ - if test "x$ac_system" = "xLinux" - then - with_libsensors="yes" - else - with_libsensors="no (Linux only library)" - fi -]) -if test "x$with_libsensors" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $with_sensors_cflags" +AC_ARG_WITH([libsensors], + [AS_HELP_STRING([--with-libsensors@<:@=PREFIX@:>@], [Path to lm_sensors.])], + [ + if test "x$withval" = "xno" || test "x$withval" = "xyes"; then + with_libsensors="$withval" + else + with_sensors_cppflags="-I$withval/include" + with_sensors_ldflags="-L$withval/lib" + with_libsensors="yes" + fi + ], + [ + if test "x$ac_system" = "xLinux"; then + with_libsensors="yes" + else + with_libsensors="no (Linux only library)" + fi + ] +) - AC_CHECK_HEADERS(sensors/sensors.h, [], [with_libsensors="no (sensors/sensors.h not found)"]) +if test "x$with_libsensors" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_sensors_cppflags" - CPPFLAGS="$SAVE_CPPFLAGS" + AC_CHECK_HEADERS([sensors/sensors.h], + [with_libsensors="yes"], + [with_libsensors="no (sensors/sensors.h not found)"] + ) + + CPPFLAGS="$SAVE_CPPFLAGS" fi -if test "x$with_libsensors" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - SAVE_LDFLAGS="$LDFLAGS" - CPPFLAGS="$CPPFLAGS $with_sensors_cflags" - LDFLAGS="$LDFLAGS $with_sensors_ldflags" - AC_CHECK_LIB(sensors, sensors_init, - [ - AC_DEFINE(HAVE_LIBSENSORS, 1, [Define to 1 if you have the sensors library (-lsensors).]) - ], - [with_libsensors="no (libsensors not found)"]) +if test "x$with_libsensors" = "xyes"; then + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $with_sensors_ldflags" - CPPFLAGS="$SAVE_CPPFLAGS" - LDFLAGS="$SAVE_LDFLAGS" + AC_CHECK_LIB([sensors], [sensors_init], + [with_libsensors="yes"], + [with_libsensors="no (libsensors not found)"] + ) + + LDFLAGS="$SAVE_LDFLAGS" fi -if test "x$with_libsensors" = "xyes" -then - BUILD_WITH_LIBSENSORS_CFLAGS="$with_sensors_cflags" - BUILD_WITH_LIBSENSORS_LDFLAGS="$with_sensors_ldflags" - AC_SUBST(BUILD_WITH_LIBSENSORS_CFLAGS) - AC_SUBST(BUILD_WITH_LIBSENSORS_LDFLAGS) + +if test "x$with_libsensors" = "xyes"; then + BUILD_WITH_LIBSENSORS_CPPFLAGS="$with_sensors_cppflags" + BUILD_WITH_LIBSENSORS_LDFLAGS="$with_sensors_ldflags" + BUILD_WITH_LIBSENSORS_LIBS="-lsensors" fi -AM_CONDITIONAL(BUILD_WITH_LM_SENSORS, test "x$with_libsensors" = "xyes") + +AC_SUBST([BUILD_WITH_LIBSENSORS_CPPFLAGS]) +AC_SUBST([BUILD_WITH_LIBSENSORS_LDFLAGS]) +AC_SUBST([BUILD_WITH_LIBSENSORS_LIBS]) + # }}} # libsigrok {{{ @@ -4842,35 +4878,29 @@ PKG_CHECK_MODULES([LIBSIGROK], [libsigrok < 0.4], # }}} # --with-libstatgrab {{{ -with_libstatgrab_cflags="" -with_libstatgrab_ldflags="" -AC_ARG_WITH(libstatgrab, [AS_HELP_STRING([--with-libstatgrab@<:@=PREFIX@:>@], [Path to libstatgrab.])], -[ - if test "x$withval" != "xno" \ - && test "x$withval" != "xyes" - then - with_libstatgrab_cflags="-I$withval/include" - with_libstatgrab_ldflags="-L$withval/lib -lstatgrab" - with_libstatgrab="yes" - with_libstatgrab_pkg_config="no" - else - with_libstatgrab="$withval" - with_libstatgrab_pkg_config="yes" - fi - ], -[ - with_libstatgrab="yes" - with_libstatgrab_pkg_config="yes" -]) +AC_ARG_WITH([libstatgrab], + [AS_HELP_STRING([--with-libstatgrab@<:@=PREFIX@:>@], [Path to libstatgrab.])], + [ + if test "x$withval" != "xno" && test "x$withval" != "xyes"; then + with_libstatgrab_cflags="-I$withval/include" + with_libstatgrab_ldflags="-L$withval/lib -lstatgrab" + with_libstatgrab="yes" + with_libstatgrab_pkg_config="no" + else + with_libstatgrab="$withval" + with_libstatgrab_pkg_config="yes" + fi + ], + [ + with_libstatgrab="yes" + with_libstatgrab_pkg_config="yes" + ]) -if test "x$with_libstatgrab" = "xyes" \ - && test "x$with_libstatgrab_pkg_config" = "xyes" -then +if test "x$with_libstatgrab" = "xyes" && test "x$with_libstatgrab_pkg_config" = "xyes"; then AC_MSG_CHECKING([pkg-config for libstatgrab]) temp_result="found" $PKG_CONFIG --exists libstatgrab 2>/dev/null - if test "$?" != "0" - then + if test "$?" != "0"; then with_libstatgrab_pkg_config="no" with_libstatgrab="no (pkg-config doesn't know libstatgrab)" temp_result="not found" @@ -4878,14 +4908,10 @@ then AC_MSG_RESULT([$temp_result]) fi -if test "x$with_libstatgrab" = "xyes" \ - && test "x$with_libstatgrab_pkg_config" = "xyes" \ - && test "x$with_libstatgrab_cflags" = "x" -then +if test "x$with_libstatgrab" = "xyes" && test "x$with_libstatgrab_pkg_config" = "xyes" && test "x$with_libstatgrab_cflags" = "x"; then AC_MSG_CHECKING([for libstatgrab CFLAGS]) temp_result="`$PKG_CONFIG --cflags libstatgrab`" - if test "$?" = "0" - then + if test "$?" = "0"; then with_libstatgrab_cflags="$temp_result" else with_libstatgrab="no ($PKG_CONFIG --cflags libstatgrab failed)" @@ -4894,10 +4920,7 @@ then AC_MSG_RESULT([$temp_result]) fi -if test "x$with_libstatgrab" = "xyes" \ - && test "x$with_libstatgrab_pkg_config" = "xyes" \ - && test "x$with_libstatgrab_ldflags" = "x" -then +if test "x$with_libstatgrab" = "xyes" && test "x$with_libstatgrab_pkg_config" = "xyes" && test "x$with_libstatgrab_ldflags" = "x"; then AC_MSG_CHECKING([for libstatgrab LDFLAGS]) temp_result="`$PKG_CONFIG --libs libstatgrab`" if test "$?" = "0" @@ -4910,36 +4933,31 @@ then AC_MSG_RESULT([$temp_result]) fi -if test "x$with_libstatgrab" = "xyes" -then +if test "x$with_libstatgrab" = "xyes"; then SAVE_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $with_libstatgrab_cflags" - AC_CHECK_HEADERS(statgrab.h, - [with_libstatgrab="yes"], - [with_libstatgrab="no (statgrab.h not found)"]) + AC_CHECK_HEADERS([statgrab.h], + [with_libstatgrab="yes"], + [with_libstatgrab="no (statgrab.h not found)"] + ) CPPFLAGS="$SAVE_CPPFLAGS" fi -if test "x$with_libstatgrab" = "xyes" -then - SAVE_CFLAGS="$CFLAGS" +if test "x$with_libstatgrab" = "xyes"; then SAVE_LDFLAGS="$LDFLAGS" - - CFLAGS="$CFLAGS $with_libstatgrab_cflags" LDFLAGS="$LDFLAGS $with_libstatgrab_ldflags" - AC_CHECK_LIB(statgrab, sg_init, - [with_libstatgrab="yes"], - [with_libstatgrab="no (symbol sg_init not found)"]) + AC_CHECK_LIB([statgrab], [sg_init], + [with_libstatgrab="yes"], + [with_libstatgrab="no (symbol sg_init not found)"] + ) - CFLAGS="$SAVE_CFLAGS" LDFLAGS="$SAVE_LDFLAGS" fi -if test "x$with_libstatgrab" = "xyes" -then +if test "x$with_libstatgrab" = "xyes"; then SAVE_CFLAGS="$CFLAGS" SAVE_LDFLAGS="$LDFLAGS" SAVE_LIBS="$LIBS" @@ -4949,19 +4967,24 @@ then LIBS="-lstatgrab $LIBS" AC_CACHE_CHECK([if libstatgrab >= 0.90], - [c_cv_have_libstatgrab_0_90], - AC_LINK_IFELSE([AC_LANG_PROGRAM( -[[[ -#include -#include -]]], -[[[ - if (sg_init()) return 0; -]]] - )], - [c_cv_have_libstatgrab_0_90="no"], - [c_cv_have_libstatgrab_0_90="yes"] + [c_cv_have_libstatgrab_0_90], + [ + AC_LINK_IFELSE( + [ + AC_LANG_PROGRAM( + [[ + #include + #include + ]], + [[ + if (sg_init()) return 0; + ]] ) + ], + [c_cv_have_libstatgrab_0_90="no"], + [c_cv_have_libstatgrab_0_90="yes"] + ) + ] ) CFLAGS="$SAVE_CFLAGS" @@ -4969,832 +4992,797 @@ then LIBS="$SAVE_LIBS" fi -AM_CONDITIONAL(BUILD_WITH_LIBSTATGRAB, test "x$with_libstatgrab" = "xyes") -if test "x$with_libstatgrab" = "xyes" -then - AC_DEFINE(HAVE_LIBSTATGRAB, 1, [Define to 1 if you have the 'statgrab' library (-lstatgrab)]) +AM_CONDITIONAL([BUILD_WITH_LIBSTATGRAB], [test "x$with_libstatgrab" = "xyes"]) + +if test "x$with_libstatgrab" = "xyes"; then + AC_DEFINE([HAVE_LIBSTATGRAB], [1], + [Define to 1 if you have the 'statgrab' library (-lstatgrab)] + ) + + if test "x$c_cv_have_libstatgrab_0_90" = "xyes"; then + AC_DEFINE([HAVE_LIBSTATGRAB_0_90], [1], + [Define to 1 if libstatgrab version >= 0.90] + ) + fi + BUILD_WITH_LIBSTATGRAB_CFLAGS="$with_libstatgrab_cflags" BUILD_WITH_LIBSTATGRAB_LDFLAGS="$with_libstatgrab_ldflags" - AC_SUBST(BUILD_WITH_LIBSTATGRAB_CFLAGS) - AC_SUBST(BUILD_WITH_LIBSTATGRAB_LDFLAGS) - if test "x$c_cv_have_libstatgrab_0_90" = "xyes" - then - AC_DEFINE(HAVE_LIBSTATGRAB_0_90, 1, [Define to 1 if libstatgrab version >= 0.90]) - fi + fi + +AC_SUBST([BUILD_WITH_LIBSTATGRAB_CFLAGS]) +AC_SUBST([BUILD_WITH_LIBSTATGRAB_LDFLAGS]) # }}} # --with-libtokyotyrant {{{ -with_libtokyotyrant_cppflags="" -with_libtokyotyrant_ldflags="" -with_libtokyotyrant_libs="" -AC_ARG_WITH(libtokyotyrant, [AS_HELP_STRING([--with-libtokyotyrant@<:@=PREFIX@:>@], [Path to libtokyotyrant.])], -[ - if test "x$withval" = "xno" - then - with_libtokyotyrant="no" - else if test "x$withval" = "xyes" - then - with_libtokyotyrant="yes" - else - with_libtokyotyrant_cppflags="-I$withval/include" - with_libtokyotyrant_ldflags="-L$withval/include" - with_libtokyotyrant_libs="-ltokyotyrant" - with_libtokyotyrant="yes" - fi; fi -], -[ - with_libtokyotyrant="yes" -]) +AC_ARG_WITH([libtokyotyrant], + [AS_HELP_STRING([--with-libtokyotyrant@<:@=PREFIX@:>@], [Path to libtokyotyrant.])], + [ + if test "x$withval" = "xno" || test "x$withval" = "xyes"; then + with_libtokyotyrant="$withval" + else + with_libtokyotyrant_cppflags="-I$withval/include" + with_libtokyotyrant_ldflags="-L$withval/include" + with_libtokyotyrant_libs="-ltokyotyrant" + with_libtokyotyrant="yes" + fi + ], + [with_libtokyotyrant="yes"] +) -if test "x$with_libtokyotyrant" = "xyes" -then - if $PKG_CONFIG --exists tokyotyrant - then +if test "x$with_libtokyotyrant" = "xyes"; then + if $PKG_CONFIG --exists tokyotyrant; then with_libtokyotyrant_cppflags="$with_libtokyotyrant_cppflags `$PKG_CONFIG --cflags tokyotyrant`" with_libtokyotyrant_ldflags="$with_libtokyotyrant_ldflags `$PKG_CONFIG --libs-only-L tokyotyrant`" with_libtokyotyrant_libs="$with_libtokyotyrant_libs `$PKG_CONFIG --libs-only-l tokyotyrant`" fi fi -SAVE_CPPFLAGS="$CPPFLAGS" -SAVE_LDFLAGS="$LDFLAGS" -CPPFLAGS="$CPPFLAGS $with_libtokyotyrant_cppflags" -LDFLAGS="$LDFLAGS $with_libtokyotyrant_ldflags" +if test "x$with_libtokyotyrant" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_libtokyotyrant_cppflags" -if test "x$with_libtokyotyrant" = "xyes" -then - AC_CHECK_HEADERS(tcrdb.h, - [ - AC_DEFINE(HAVE_TCRDB_H, 1, - [Define to 1 if you have the header file.]) - ], [with_libtokyotyrant="no (tcrdb.h not found)"]) -fi + AC_CHECK_HEADERS([tcrdb.h], + [with_libtokyotyrant="yes"], + [with_libtokyotyrant="no (tcrdb.h not found)"] + ) -if test "x$with_libtokyotyrant" = "xyes" -then - AC_CHECK_LIB(tokyotyrant, tcrdbrnum, - [ - AC_DEFINE(HAVE_LIBTOKYOTYRANT, 1, - [Define to 1 if you have the tokyotyrant library (-ltokyotyrant).]) - ], - [with_libtokyotyrant="no (symbol tcrdbrnum not found)"], - [$with_libtokyotyrant_libs]) + CPPFLAGS="$SAVE_CPPFLAGS" fi -CPPFLAGS="$SAVE_CPPFLAGS" -LDFLAGS="$SAVE_LDFLAGS" +if test "x$with_libtokyotyrant" = "xyes"; then + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $with_libtokyotyrant_ldflags" -if test "x$with_libtokyotyrant" = "xyes" -then + AC_CHECK_LIB([tokyotyrant], [tcrdbrnum], + [with_libtokyotyrant="yes"], + [with_libtokyotyrant="no (symbol tcrdbrnum not found)"], + [$with_libtokyotyrant_libs] + ) + + LDFLAGS="$SAVE_LDFLAGS" +fi + +if test "x$with_libtokyotyrant" = "xyes"; then BUILD_WITH_LIBTOKYOTYRANT_CPPFLAGS="$with_libtokyotyrant_cppflags" BUILD_WITH_LIBTOKYOTYRANT_LDFLAGS="$with_libtokyotyrant_ldflags" BUILD_WITH_LIBTOKYOTYRANT_LIBS="$with_libtokyotyrant_libs" - AC_SUBST(BUILD_WITH_LIBTOKYOTYRANT_CPPFLAGS) - AC_SUBST(BUILD_WITH_LIBTOKYOTYRANT_LDFLAGS) - AC_SUBST(BUILD_WITH_LIBTOKYOTYRANT_LIBS) fi -AM_CONDITIONAL(BUILD_WITH_LIBTOKYOTYRANT, test "x$with_libtokyotyrant" = "xyes") +AC_SUBST([BUILD_WITH_LIBTOKYOTYRANT_CPPFLAGS]) +AC_SUBST([BUILD_WITH_LIBTOKYOTYRANT_LDFLAGS]) +AC_SUBST([BUILD_WITH_LIBTOKYOTYRANT_LIBS]) # }}} # --with-libudev {{{ -with_libudev_cflags="" -with_libudev_ldflags="" -AC_ARG_WITH(libudev, [AS_HELP_STRING([--with-libudev@<:@=PREFIX@:>@], [Path to libudev.])], -[ - if test "x$withval" = "xno" - then - with_libudev="no" - else - with_libudev="yes" - if test "x$withval" != "xyes" - then - with_libudev_cflags="-I$withval/include" - with_libudev_ldflags="-L$withval/lib" - with_libudev="yes" - fi - fi -], -[ - if test "x$ac_system" = "xLinux" - then - with_libudev="yes" - else - with_libudev="no (Linux only library)" - fi -]) -if test "x$with_libudev" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $with_libudev_cflags" +AC_ARG_WITH([libudev], + [AS_HELP_STRING([--with-libudev@<:@=PREFIX@:>@], [Path to libudev.])], + [ + if test "x$withval" = "xno" || test "x$withval" = "xyes"; then + with_libudev="$withval" + else + with_libudev_cppflags="-I$withval/include" + with_libudev_ldflags="-L$withval/lib" + with_libudev="yes" + fi + ], + [ + if test "x$ac_system" = "xLinux"; then + with_libudev="yes" + else + with_libudev="no (Linux only library)" + fi + ] +) - AC_CHECK_HEADERS(libudev.h, [], [with_libudev="no (libudev.h not found)"]) +if test "x$with_libudev" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_libudev_cppflags" - CPPFLAGS="$SAVE_CPPFLAGS" + AC_CHECK_HEADERS([libudev.h], + [with_libudev="yes"], + [with_libudev="no (libudev.h not found)"] + ) + + CPPFLAGS="$SAVE_CPPFLAGS" fi -if test "x$with_libudev" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - SAVE_LDFLAGS="$LDFLAGS" - CPPFLAGS="$CPPFLAGS $with_libudev_cflags" - LDFLAGS="$LDFLAGS $with_libudev_ldflags" - AC_CHECK_LIB(udev, udev_new, - [ - AC_DEFINE(HAVE_LIBUDEV, 1, [Define to 1 if you have the udev library (-ludev).]) - ], - [with_libudev="no (libudev not found)"]) +if test "x$with_libudev" = "xyes"; then + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $with_libudev_ldflags" - CPPFLAGS="$SAVE_CPPFLAGS" - LDFLAGS="$SAVE_LDFLAGS" + AC_CHECK_LIB([udev], [udev_new], + [with_libudev="yes"], + [with_libudev="no (libudev not found)"] + ) + + LDFLAGS="$SAVE_LDFLAGS" fi -if test "x$with_libudev" = "xyes" -then - BUILD_WITH_LIBUDEV_CFLAGS="$with_libudev_cflags" - BUILD_WITH_LIBUDEV_LDFLAGS="$with_libudev_ldflags" - BUILD_WITH_LIBUDEV_LIBS="-ludev" - AC_SUBST(BUILD_WITH_LIBUDEV_CFLAGS) - AC_SUBST(BUILD_WITH_LIBUDEV_LDFLAGS) - AC_SUBST(BUILD_WITH_LIBUDEV_LIBS) -fi -AM_CONDITIONAL(BUILD_WITH_LIBUDEV, test "x$with_libudev" = "xyes") + +if test "x$with_libudev" = "xyes"; then + BUILD_WITH_LIBUDEV_CPPFLAGS="$with_libudev_cppflags" + BUILD_WITH_LIBUDEV_LDFLAGS="$with_libudev_ldflags" + BUILD_WITH_LIBUDEV_LIBS="-ludev" +fi + +AC_SUBST([BUILD_WITH_LIBUDEV_CPPFLAGS]) +AC_SUBST([BUILD_WITH_LIBUDEV_LDFLAGS]) +AC_SUBST([BUILD_WITH_LIBUDEV_LIBS]) + +AM_CONDITIONAL([BUILD_WITH_LIBUDEV], [test "x$with_libudev" = "xyes"]) # }}} # --with-libupsclient {{{ with_libupsclient_config="" -with_libupsclient_cflags="" -with_libupsclient_libs="" -AC_ARG_WITH(libupsclient, [AS_HELP_STRING([--with-libupsclient@<:@=PREFIX@:>@], [Path to the upsclient library.])], -[ - if test "x$withval" = "xno" - then - with_libupsclient="no" - else if test "x$withval" = "xyes" - then - with_libupsclient="use_pkgconfig" - else - if test -x "$withval" - then - with_libupsclient_config="$withval" - with_libupsclient="use_libupsclient_config" - else if test -x "$withval/bin/libupsclient-config" - then - with_libupsclient_config="$withval/bin/libupsclient-config" - with_libupsclient="use_libupsclient_config" - else - AC_MSG_NOTICE([Not checking for libupsclient: Manually configured]) - with_libupsclient_cflags="-I$withval/include" - with_libupsclient_libs="-L$withval/lib -lupsclient" - with_libupsclient="yes" - fi; fi - fi; fi -], -[with_libupsclient="use_pkgconfig"]) +AC_ARG_WITH([libupsclient], + [AS_HELP_STRING([--with-libupsclient@<:@=PREFIX@:>@], [Path to the upsclient library.])], + [ + if test "x$withval" = "xno"; then + with_libupsclient="no" + else if test "x$withval" = "xyes"; then + with_libupsclient="use_pkgconfig" + else + if test -x "$withval"; then + with_libupsclient_config="$withval" + with_libupsclient="use_libupsclient_config" + else if test -x "$withval/bin/libupsclient-config"; then + with_libupsclient_config="$withval/bin/libupsclient-config" + with_libupsclient="use_libupsclient_config" + else + AC_MSG_NOTICE([Not checking for libupsclient: Manually configured]) + with_libupsclient_cflags="-I$withval/include" + with_libupsclient_libs="-L$withval/lib -lupsclient" + with_libupsclient="yes" + fi; fi + fi; fi + ], + [with_libupsclient="use_pkgconfig"] +) # configure using libupsclient-config -if test "x$with_libupsclient" = "xuse_libupsclient_config" -then - AC_MSG_NOTICE([Checking for libupsclient using $with_libupsclient_config]) - with_libupsclient_cflags="`$with_libupsclient_config --cflags`" - if test $? -ne 0 - then - with_libupsclient="no ($with_libupsclient_config failed)" - fi - with_libupsclient_libs="`$with_libupsclient_config --libs`" - if test $? -ne 0 - then - with_libupsclient="no ($with_libupsclient_config failed)" - fi +if test "x$with_libupsclient" = "xuse_libupsclient_config"; then + with_libupsclient_cflags="`$with_libupsclient_config --cflags`" + if test $? -ne 0; then + with_libupsclient="no ($with_libupsclient_config failed)" + fi + with_libupsclient_libs="`$with_libupsclient_config --libs`" + if test $? -ne 0; then + with_libupsclient="no ($with_libupsclient_config failed)" + fi fi -if test "x$with_libupsclient" = "xuse_libupsclient_config" -then - with_libupsclient="yes" + +if test "x$with_libupsclient" = "xuse_libupsclient_config"; then + with_libupsclient="yes" fi # configure using pkg-config -if test "x$with_libupsclient" = "xuse_pkgconfig" -then - AC_MSG_NOTICE([Checking for libupsclient using $PKG_CONFIG]) - $PKG_CONFIG --exists 'libupsclient' 2>/dev/null - if test $? -ne 0 - then - with_libupsclient="no (pkg-config doesn't know libupsclient)" - fi +if test "x$with_libupsclient" = "xuse_pkgconfig"; then + AC_MSG_NOTICE([Checking for libupsclient using $PKG_CONFIG]) + $PKG_CONFIG --exists 'libupsclient' 2>/dev/null + if test $? -ne 0; then + with_libupsclient="no (pkg-config doesn't know libupsclient)" + fi fi -if test "x$with_libupsclient" = "xuse_pkgconfig" -then - with_libupsclient_cflags="`$PKG_CONFIG --cflags 'libupsclient'`" - if test $? -ne 0 - then - with_libupsclient="no ($PKG_CONFIG failed)" - fi - with_libupsclient_libs="`$PKG_CONFIG --libs 'libupsclient'`" - if test $? -ne 0 - then - with_libupsclient="no ($PKG_CONFIG failed)" - fi + +if test "x$with_libupsclient" = "xuse_pkgconfig"; then + with_libupsclient_cflags="`$PKG_CONFIG --cflags 'libupsclient'`" + if test $? -ne 0; then + with_libupsclient="no ($PKG_CONFIG failed)" + fi + + with_libupsclient_libs="`$PKG_CONFIG --libs 'libupsclient'`" + if test $? -ne 0; then + with_libupsclient="no ($PKG_CONFIG failed)" + fi fi -if test "x$with_libupsclient" = "xuse_pkgconfig" -then - with_libupsclient="yes" + +if test "x$with_libupsclient" = "xuse_pkgconfig"; then + with_libupsclient="yes" fi -# with_libupsclient_cflags and with_libupsclient_libs are set up now, let's do -# the actual checks. -if test "x$with_libupsclient" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $with_libupsclient_cflags" +if test "x$with_libupsclient" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_libupsclient_cflags" - AC_CHECK_HEADERS(upsclient.h, [], [with_libupsclient="no (upsclient.h not found)"]) + AC_CHECK_HEADERS([upsclient.h], + [with_libupsclient="yes"], + [with_libupsclient="no (upsclient.h not found)"] + ) - CPPFLAGS="$SAVE_CPPFLAGS" + CPPFLAGS="$SAVE_CPPFLAGS" fi -if test "x$with_libupsclient" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - SAVE_LDFLAGS="$LDFLAGS" - CPPFLAGS="$CPPFLAGS $with_libupsclient_cflags" - LDFLAGS="$LDFLAGS $with_libupsclient_libs" +if test "x$with_libupsclient" = "xyes"; then + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $with_libupsclient_libs" - AC_CHECK_LIB(upsclient, upscli_connect, - [with_libupsclient="yes"], - [with_libupsclient="no (symbol upscli_connect not found)"]) + AC_CHECK_LIB([upsclient], [upscli_connect], + [with_libupsclient="yes"], + [with_libupsclient="no (symbol upscli_connect not found)"] + ) - CPPFLAGS="$SAVE_CPPFLAGS" - LDFLAGS="$SAVE_LDFLAGS" + AC_CHECK_LIB([upsclient], [upscli_init], + [AC_DEFINE([WITH_UPSCLIENT_27], [1], [At least version 2-7])], + [] + ) + + LDFLAGS="$SAVE_LDFLAGS" fi -if test "x$with_libupsclient" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $with_libupsclient_cflags" - AC_CHECK_TYPES([UPSCONN_t, UPSCONN], [], [], -[#include -#include -#include ]) +if test "x$with_libupsclient" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_libupsclient_cflags" - CPPFLAGS="$SAVE_CPPFLAGS" + AC_CHECK_TYPES([UPSCONN_t, UPSCONN], + [], + [], + [[ + #include + #include + #include + ]] + ) + + CPPFLAGS="$SAVE_CPPFLAGS" fi -if test "x$with_libupsclient" = "xyes" -then - BUILD_WITH_LIBUPSCLIENT_CFLAGS="$with_libupsclient_cflags" - BUILD_WITH_LIBUPSCLIENT_LIBS="$with_libupsclient_libs" - AC_SUBST(BUILD_WITH_LIBUPSCLIENT_CFLAGS) - AC_SUBST(BUILD_WITH_LIBUPSCLIENT_LIBS) + +if test "x$with_libupsclient" = "xyes"; then + BUILD_WITH_LIBUPSCLIENT_CFLAGS="$with_libupsclient_cflags" + BUILD_WITH_LIBUPSCLIENT_LIBS="$with_libupsclient_libs" fi + +AC_SUBST([BUILD_WITH_LIBUPSCLIENT_CFLAGS]) +AC_SUBST([BUILD_WITH_LIBUPSCLIENT_LIBS]) # }}} # --with-libxenctrl {{{ -with_libxenctrl_cppflags="" -with_libxenctrl_ldflags="" -AC_ARG_WITH(libxenctrl, [AS_HELP_STRING([--with-libxenctrl@<:@=PREFIX@:>@], [Path to libxenctrl.])], -[ - if test "x$withval" != "xno" && test "x$withval" != "xyes" - then - with_libxenctrl_cppflags="-I$withval/include" - with_libxenctrl_ldflags="-L$withval/lib" - with_libxenctrl="yes" - else - with_libxenctrl="$withval" - fi -], -[ - with_libxenctrl="yes" -]) -if test "x$with_libxenctrl" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $with_libxenctrl_cppflags" +AC_ARG_WITH([libxenctrl], + [AS_HELP_STRING([--with-libxenctrl@<:@=PREFIX@:>@], [Path to libxenctrl.])], + [ + if test "x$withval" != "xno" && test "x$withval" != "xyes"; then + with_libxenctrl_cppflags="-I$withval/include" + with_libxenctrl_ldflags="-L$withval/lib" + with_libxenctrl="yes" + else + with_libxenctrl="$withval" + fi + ], + [with_libxenctrl="yes"] +) - AC_CHECK_HEADERS(xenctrl.h, [with_libxenctrl="yes"], [with_libxenctrl="no (xenctrl.h not found)"]) +if test "x$with_libxenctrl" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_libxenctrl_cppflags" - CPPFLAGS="$SAVE_CPPFLAGS" + AC_CHECK_HEADERS([xenctrl.h], + [with_libxenctrl="yes"], + [with_libxenctrl="no (xenctrl.h not found)"] + ) + + CPPFLAGS="$SAVE_CPPFLAGS" fi -if test "x$with_libxenctrl" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - SAVE_LDFLAGS="$LDFLAGS" - CPPFLAGS="$CPPFLAGS $with_libxenctrl_cppflags" - LDFLAGS="$LDFLAGS $with_libxenctrl_ldflags" - #Xen versions older than 3.4 has no xc_getcpuinfo() - AC_CHECK_LIB(xenctrl, xc_getcpuinfo, [with_libxenctrl="yes"], [with_libxenctrl="no (symbol 'xc_getcpuinfo' not found)"], []) +if test "x$with_libxenctrl" = "xyes"; then + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $with_libxenctrl_ldflags" + + #Xen versions older than 3.4 has no xc_getcpuinfo() + AC_CHECK_LIB([xenctrl], [xc_getcpuinfo], + [with_libxenctrl="yes"], + [with_libxenctrl="no (symbol 'xc_getcpuinfo' not found)"] + ) - CPPFLAGS="$SAVE_CPPFLAGS" - LDFLAGS="$SAVE_LDFLAGS" - LIBXENCTL_CPPFLAGS="$with_libxenctl_cppflags" - LIBXENCTL_LDFLAGS="$with_libxenctl_ldflags" - AC_SUBST(LIBXENCTL_CPPFLAGS) - AC_SUBST(LIBXENCTL_LDFLAGS) + LDFLAGS="$SAVE_LDFLAGS" fi + +LIBXENCTL_CPPFLAGS="$with_libxenctl_cppflags" +LIBXENCTL_LDFLAGS="$with_libxenctl_ldflags" +AC_SUBST([LIBXENCTL_CPPFLAGS]) +AC_SUBST([LIBXENCTL_LDFLAGS]) # }}} # --with-libxmms {{{ with_xmms_config="xmms-config" -with_xmms_cflags="" -with_xmms_libs="" -AC_ARG_WITH(libxmms, [AS_HELP_STRING([--with-libxmms@<:@=PREFIX@:>@], [Path to libxmms.])], -[ - if test "x$withval" != "xno" \ - && test "x$withval" != "xyes" - then - if test -f "$withval" && test -x "$withval"; - then - with_xmms_config="$withval" - else if test -x "$withval/bin/xmms-config" - then - with_xmms_config="$withval/bin/xmms-config" - fi; fi - with_libxmms="yes" - else if test "x$withval" = "xno" - then - with_libxmms="no" - else - with_libxmms="yes" - fi; fi -], -[ - with_libxmms="yes" -]) -if test "x$with_libxmms" = "xyes" -then - with_xmms_cflags=`$with_xmms_config --cflags 2>/dev/null` - xmms_config_status=$? +AC_ARG_WITH([libxmms], + [AS_HELP_STRING([--with-libxmms@<:@=PREFIX@:>@], [Path to libxmms.])], + [ + if test "x$withval" = "xno" || test "x$withval" = "xyes"; then + with_libxmms="$withval" + else + if test -f "$withval" && test -x "$withval"; then + with_xmms_config="$withval" + else if test -x "$withval/bin/xmms-config"; then + with_xmms_config="$withval/bin/xmms-config" + fi; fi + with_libxmms="yes" + fi + ], + [with_libxmms="yes"] +) - if test $xmms_config_status -ne 0 - then - with_libxmms="no" - fi +if test "x$with_libxmms" = "xyes"; then + with_xmms_cflags=`$with_xmms_config --cflags 2>/dev/null` + if test $? -ne 0; then + with_libxmms="no" + fi fi -if test "x$with_libxmms" = "xyes" -then - with_xmms_libs=`$with_xmms_config --libs 2>/dev/null` - xmms_config_status=$? - if test $xmms_config_status -ne 0 - then - with_libxmms="no" - fi +if test "x$with_libxmms" = "xyes"; then + with_xmms_libs=`$with_xmms_config --libs 2>/dev/null` + if test $? -ne 0; then + with_libxmms="no" + fi fi -if test "x$with_libxmms" = "xyes" -then - AC_CHECK_LIB(xmms, xmms_remote_get_info, - [ - BUILD_WITH_LIBXMMS_CFLAGS="$with_xmms_cflags" - BUILD_WITH_LIBXMMS_LIBS="$with_xmms_libs" - AC_SUBST(BUILD_WITH_LIBXMMS_CFLAGS) - AC_SUBST(BUILD_WITH_LIBXMMS_LIBS) - ], - [ - with_libxmms="no" - ], - [$with_xmms_libs]) -fi -with_libxmms_numeric=0 -if test "x$with_libxmms" = "xyes" -then - with_libxmms_numeric=1 + +if test "x$with_libxmms" = "xyes"; then + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$with_xmms_cflags" + + AC_CHECK_HEADER([xmmsctrl.h], + [with_libxmms="yes"], + [with_libxmms="no"], + ) + + CFLAGS="$SAVE_CFLAGS" +fi + +if test "x$with_libxmms" = "xyes"; then + SAVE_LIBS="$LIBS" + LIBS="$with_xmms_libs" + + AC_CHECK_LIB([xmms], [xmms_remote_get_info], + [with_libxmss="yes"], + [with_libxmms="no"], + [$with_xmms_libs] + + ) + + LIBS="$SAVE_LIBS" fi -AC_DEFINE_UNQUOTED(HAVE_LIBXMMS, [$with_libxmms_numeric], [Define to 1 if you have the 'xmms' library (-lxmms).]) -AM_CONDITIONAL(BUILD_WITH_LIBXMMS, test "x$with_libxmms" = "xyes") + +BUILD_WITH_LIBXMMS_CFLAGS="$with_xmms_cflags" +BUILD_WITH_LIBXMMS_LIBS="$with_xmms_libs" + +AC_SUBST([BUILD_WITH_LIBXMMS_CFLAGS]) +AC_SUBST([BUILD_WITH_LIBXMMS_LIBS]) # }}} # --with-libyajl {{{ -with_libyajl_cppflags="" -with_libyajl_ldflags="" -AC_ARG_WITH(libyajl, [AS_HELP_STRING([--with-libyajl@<:@=PREFIX@:>@], [Path to libyajl.])], -[ - if test "x$withval" != "xno" && test "x$withval" != "xyes" - then - with_libyajl_cppflags="-I$withval/include" - with_libyajl_ldflags="-L$withval/lib" - with_libyajl="yes" - else - with_libyajl="$withval" - fi -], -[ - with_libyajl="yes" -]) -if test "x$with_libyajl" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $with_libyajl_cppflags" +AC_ARG_WITH([libyajl], + [AS_HELP_STRING([--with-libyajl@<:@=PREFIX@:>@], [Path to libyajl.])], + [ + if test "x$withval" != "xno" && test "x$withval" != "xyes"; then + with_libyajl_cppflags="-I$withval/include" + with_libyajl_ldflags="-L$withval/lib" + with_libyajl="yes" + else + with_libyajl="$withval" + fi + ], + [with_libyajl="yes"] +) - AC_CHECK_HEADERS(yajl/yajl_parse.h, [with_libyajl="yes"], [with_libyajl="no (yajl/yajl_parse.h not found)"]) - AC_CHECK_HEADERS(yajl/yajl_version.h) +if test "x$with_libyajl" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_libyajl_cppflags" - CPPFLAGS="$SAVE_CPPFLAGS" + AC_CHECK_HEADERS([yajl/yajl_parse.h], + [with_libyajl="yes"], + [with_libyajl="no (yajl/yajl_parse.h not found)"] + ) + + AC_CHECK_HEADERS([yajl/yajl_tree.h], + [with_libyajl2="yes"], + [with_libyajl2="no (yajl/yajl_tree.h not found)"] + ) + + AC_CHECK_HEADERS([yajl/yajl_version.h]) + + CPPFLAGS="$SAVE_CPPFLAGS" fi -if test "x$with_libyajl" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - SAVE_LDFLAGS="$LDFLAGS" - CPPFLAGS="$CPPFLAGS $with_libyajl_cppflags" - LDFLAGS="$LDFLAGS $with_libyajl_ldflags" - AC_CHECK_LIB(yajl, yajl_alloc, [with_libyajl="yes"], [with_libyajl="no (Symbol 'yajl_alloc' not found)"]) +if test "x$with_libyajl" = "xyes"; then + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $with_libyajl_ldflags" - CPPFLAGS="$SAVE_CPPFLAGS" - LDFLAGS="$SAVE_LDFLAGS" + AC_CHECK_LIB([yajl], [yajl_alloc], + [with_libyajl="yes"], + [with_libyajl="no (Symbol 'yajl_alloc' not found)"] + ) + + AC_CHECK_LIB([yajl], [yajl_tree_parse], + [with_libyajl2="yes"], + [with_libyajl2="no (Symbol 'yajl_tree_parse' not found)"] + ) + + LDFLAGS="$SAVE_LDFLAGS" fi -if test "x$with_libyajl" = "xyes" -then - BUILD_WITH_LIBYAJL_CPPFLAGS="$with_libyajl_cppflags" - BUILD_WITH_LIBYAJL_LDFLAGS="$with_libyajl_ldflags" - BUILD_WITH_LIBYAJL_LIBS="-lyajl" - AC_SUBST(BUILD_WITH_LIBYAJL_CPPFLAGS) - AC_SUBST(BUILD_WITH_LIBYAJL_LDFLAGS) - AC_SUBST(BUILD_WITH_LIBYAJL_LIBS) - AC_DEFINE(HAVE_LIBYAJL, 1, [Define if libyajl is present and usable.]) -fi -AM_CONDITIONAL(BUILD_WITH_LIBYAJL, test "x$with_libyajl" = "xyes") + +if test "x$with_libyajl" = "xyes"; then + BUILD_WITH_LIBYAJL_CPPFLAGS="$with_libyajl_cppflags" + BUILD_WITH_LIBYAJL_LDFLAGS="$with_libyajl_ldflags" + BUILD_WITH_LIBYAJL_LIBS="-lyajl" + AC_DEFINE([HAVE_LIBYAJL], [1], [Define if libyajl is present and usable.]) +fi + +AC_SUBST([BUILD_WITH_LIBYAJL_CPPFLAGS]) +AC_SUBST([BUILD_WITH_LIBYAJL_LDFLAGS]) +AC_SUBST([BUILD_WITH_LIBYAJL_LIBS]) + +AM_CONDITIONAL([BUILD_WITH_LIBYAJL], [test "x$with_libyajl" = "xyes"]) # }}} # --with-mic {{{ -with_mic_cflags="-I/opt/intel/mic/sysmgmt/sdk/include" -with_mic_ldpath="-L/opt/intel/mic/sysmgmt/sdk/lib/Linux" -with_mic_libs="" -AC_ARG_WITH(mic,[AS_HELP_STRING([--with-mic@<:@=PREFIX@:>@], [Path to Intel MIC Access API.])], -[ - if test "x$withval" = "xno" - then - with_mic="no" - else if test "x$withval" = "xyes" - then - with_mic="yes" - else if test -d "$with_mic/lib" - then - AC_MSG_NOTICE([Not checking for Intel Mic: Manually configured]) - with_mic_cflags="-I$withval/include" - with_mic_ldpath="-L$withval/lib/Linux" - with_mic_libs="$PTHREAD_LIBS -lMicAccessSDK -lscif" - with_mic="yes" - fi; fi; fi -], -[with_mic="yes"]) -if test "x$with_mic" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $with_mic_cflags" - AC_CHECK_HEADERS(MicAccessApi.h,[],[with_mic="no (MicAccessApi not found)"]) - CPPFLAGS="$SAVE_CPPFLAGS" +with_mic_cppflags="-I/opt/intel/mic/sysmgmt/sdk/include" +with_mic_ldflags="-L/opt/intel/mic/sysmgmt/sdk/lib/Linux" +with_mic_libs="-lMicAccessSDK -scif" +AC_ARG_WITH([mic], + [AS_HELP_STRING([--with-mic@<:@=PREFIX@:>@], [Path to Intel MIC Access API.])], + [ + if test "x$withval" = "xno" || test "x$withval" = "xyes"; then + with_mic="$withval" + else if test -d "$with_mic/lib"; then + with_mic_cppflags="-I$withval/include" + with_mic_ldflags="-L$withval/lib/Linux" + with_mic="yes" + fi; fi + ], + [with_mic="yes"] +) + +if test "x$with_mic" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_mic_cppflags" + + AC_CHECK_HEADERS([MicAccessApi.h], + [with_mic="yes"], + [with_mic="no (MicAccessApi not found)"] + ) + + CPPFLAGS="$SAVE_CPPFLAGS" fi -if test "x$with_mic" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - SAVE_LDFLAGS="$LDFLAGS" - CPPFLAGS="$CPPFLAGS $with_mic_cflags" - LDFLAGS="$LDFLAGS $with_mic_ldpath" +if test "x$with_mic" = "xyes"; then + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $with_mic_ldflags" - AC_CHECK_LIB(MicAccessSDK, MicInitAPI, - [with_mic_ldpath="$with_mic_ldpath" - with_mic_libs="$PTHREAD_LIBS -lMicAccessSDK -lscif"], - [with_mic="no (symbol MicInitAPI not found)"],[$PTHREAD_LIBS -lscif]) + AC_CHECK_LIB([MicAccessSDK], [MicInitAPI], + [with_mic="yes"], + [with_mic="no (symbol MicInitAPI not found)"], + [$PTHREAD_LIBS -lscif] + ) - CPPFLAGS="$SAVE_CPPFLAGS" - LDFLAGS="$SAVE_LDFLAGS" + LDFLAGS="$SAVE_LDFLAGS" fi -if test "x$with_mic" = "xyes" -then - BUILD_WITH_MIC_CPPFLAGS="$with_mic_cflags" - BUILD_WITH_MIC_LIBPATH="$with_mic_ldpath" - BUILD_WITH_MIC_LDADD="$with_mic_libs" - AC_SUBST(BUILD_WITH_MIC_CPPFLAGS) - AC_SUBST(BUILD_WITH_MIC_LIBPATH) - AC_SUBST(BUILD_WITH_MIC_LDADD) +if test "x$with_mic" = "xyes"; then + BUILD_WITH_MIC_CPPFLAGS="$with_mic_cppflags" + BUILD_WITH_MIC_LDFLAGS="$with_mic_ldflags" + BUILD_WITH_MIC_LIBS="$with_mic_libs" fi +AC_SUBST([BUILD_WITH_MIC_CPPFLAGS]) +AC_SUBST([BUILD_WITH_MIC_LDFLAGS]) +AC_SUBST([BUILD_WITH_MIC_LIBS]) #}}} # --with-libvarnish {{{ -with_libvarnish_cppflags="" -with_libvarnish_cflags="" -with_libvarnish_libs="" -AC_ARG_WITH(libvarnish, [AS_HELP_STRING([--with-libvarnish@<:@=PREFIX@:>@], [Path to libvarnish.])], -[ - if test "x$withval" = "xno" - then - with_libvarnish="no" - else if test "x$withval" = "xyes" - then - with_libvarnish="use_pkgconfig" - else if test -d "$with_libvarnish/lib" - then - AC_MSG_NOTICE([Not checking for libvarnish: Manually configured]) - with_libvarnish_cflags="-I$withval/include" - with_libvarnish_libs="-L$withval/lib -lvarnishapi" - with_libvarnish="yes" - fi; fi; fi -], -[with_libvarnish="use_pkgconfig"]) +AC_ARG_WITH([libvarnish], + [AS_HELP_STRING([--with-libvarnish@<:@=PREFIX@:>@], [Path to libvarnish.])], + [ + if test "x$withval" = "xno"; then + with_libvarnish="no" + else if test "x$withval" = "xyes"; then + with_libvarnish="use_pkgconfig" + else if test -d "$with_libvarnish/lib"; then + with_libvarnish_cflags="-I$withval/include" + with_libvarnish_libs="-L$withval/lib -lvarnishapi" + with_libvarnish="yes" + fi; fi; fi + ], + [with_libvarnish="use_pkgconfig"] +) # configure using pkg-config -if test "x$with_libvarnish" = "xuse_pkgconfig" -then - AC_MSG_NOTICE([Checking for varnishapi using $PKG_CONFIG]) - $PKG_CONFIG --exists 'varnishapi' 2>/dev/null - if test $? -ne 0 - then - with_libvarnish="no (pkg-config doesn't know varnishapi)" - fi +if test "x$with_libvarnish" = "xuse_pkgconfig"; then + $PKG_CONFIG --exists 'varnishapi' 2>/dev/null + if test $? -ne 0; then + with_libvarnish="no (pkg-config doesn't know varnishapi)" + fi fi -if test "x$with_libvarnish" = "xuse_pkgconfig" -then - with_libvarnish_cflags="`$PKG_CONFIG --cflags 'varnishapi'`" - if test $? -ne 0 - then - with_libvarnish="no ($PKG_CONFIG failed)" - fi - with_libvarnish_libs="`$PKG_CONFIG --libs 'varnishapi'`" - if test $? -ne 0 - then - with_libvarnish="no ($PKG_CONFIG failed)" - fi + +if test "x$with_libvarnish" = "xuse_pkgconfig"; then + with_libvarnish_cflags="`$PKG_CONFIG --cflags 'varnishapi'`" + if test $? -ne 0; then + with_libvarnish="no ($PKG_CONFIG failed)" + fi + + with_libvarnish_libs="`$PKG_CONFIG --libs 'varnishapi'`" + if test $? -ne 0; then + with_libvarnish="no ($PKG_CONFIG failed)" + fi fi -if test "x$with_libvarnish" = "xuse_pkgconfig" -then - with_libvarnish="yes" +if test "x$with_libvarnish" = "xuse_pkgconfig"; then + with_libvarnish="yes" fi -# with_libvarnish_cflags and with_libvarnish_libs are set up now, let's do -# the actual checks. -if test "x$with_libvarnish" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - - CPPFLAGS="$CPPFLAGS $with_libvarnish_cflags" +if test "x$with_libvarnish" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_libvarnish_cflags" - AC_CHECK_HEADERS(vapi/vsc.h, - [AC_DEFINE([HAVE_VARNISH_V4], [1], [Varnish 4 API support])], - [AC_CHECK_HEADERS(vsc.h, - [AC_DEFINE([HAVE_VARNISH_V3], [1], [Varnish 3 API support])], - [AC_CHECK_HEADERS(varnishapi.h, - [AC_DEFINE([HAVE_VARNISH_V2], [1], [Varnish 2 API support])], - [with_libvarnish="no (found none of the varnish header files)"])])]) + AC_CHECK_HEADERS([vapi/vsc.h], + [AC_DEFINE([HAVE_VARNISH_V4], [1], [Varnish 4 API support])], + [ + AC_CHECK_HEADERS([vsc.h], + [AC_DEFINE([HAVE_VARNISH_V3], [1], [Varnish 3 API support]) ], + [ + AC_CHECK_HEADERS([varnishapi.h], + [AC_DEFINE([HAVE_VARNISH_V2], [1], [Varnish 2 API support])], + [with_libvarnish="no (found none of the varnish header files)"] + ) + ] + ) + ] + ) - CPPFLAGS="$SAVE_CPPFLAGS" + CPPFLAGS="$SAVE_CPPFLAGS" fi -if test "x$with_libvarnish" = "xyes" -then - BUILD_WITH_LIBVARNISH_CFLAGS="$with_libvarnish_cflags" - BUILD_WITH_LIBVARNISH_LIBS="$with_libvarnish_libs" - AC_SUBST(BUILD_WITH_LIBVARNISH_CFLAGS) - AC_SUBST(BUILD_WITH_LIBVARNISH_LIBS) + +if test "x$with_libvarnish" = "xyes"; then + BUILD_WITH_LIBVARNISH_CFLAGS="$with_libvarnish_cflags" + BUILD_WITH_LIBVARNISH_LIBS="$with_libvarnish_libs" fi + +AC_SUBST([BUILD_WITH_LIBVARNISH_CFLAGS]) +AC_SUBST([BUILD_WITH_LIBVARNISH_LIBS]) # }}} # pkg-config --exists 'libxml-2.0'; pkg-config --exists libvirt {{{ -with_libxml2="no (pkg-config isn't available)" -with_libxml2_cflags="" -with_libxml2_ldflags="" -with_libvirt="no (pkg-config isn't available)" -with_libvirt_cflags="" -with_libvirt_ldflags="" $PKG_CONFIG --exists 'libxml-2.0' 2>/dev/null -if test "$?" = "0" -then - with_libxml2="yes" +if test $? -eq 0; then + with_libxml2="yes" else - with_libxml2="no (pkg-config doesn't know libxml-2.0)" + with_libxml2="no (pkg-config doesn't know libxml-2.0)" fi $PKG_CONFIG --exists libvirt 2>/dev/null -if test "$?" = "0" -then - with_libvirt="yes" +if test $? = 0; then + with_libvirt="yes" else - with_libvirt="no (pkg-config doesn't know libvirt)" + with_libvirt="no (pkg-config doesn't know libvirt)" fi -if test "x$with_libxml2" = "xyes" -then - with_libxml2_cflags="`$PKG_CONFIG --cflags libxml-2.0`" - if test $? -ne 0 - then - with_libxml2="no" - fi - with_libxml2_ldflags="`$PKG_CONFIG --libs libxml-2.0`" - if test $? -ne 0 - then - with_libxml2="no" - fi + +if test "x$with_libxml2" = "xyes"; then + with_libxml2_cflags="`$PKG_CONFIG --cflags libxml-2.0`" + if test $? -ne 0; then + with_libxml2="no" + fi + + with_libxml2_ldflags="`$PKG_CONFIG --libs libxml-2.0`" + if test $? -ne 0; then + with_libxml2="no" + fi fi -if test "x$with_libxml2" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $with_libxml2_cflags" - AC_CHECK_HEADERS(libxml/parser.h, [], - [with_libxml2="no (libxml/parser.h not found)"]) +if test "x$with_libxml2" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_libxml2_cflags" - CPPFLAGS="$SAVE_CPPFLAGS" + AC_CHECK_HEADERS([libxml/parser.h], + [with_libxml2="yes"], + [with_libxml2="no (libxml/parser.h not found)"] + ) + + CPPFLAGS="$SAVE_CPPFLAGS" fi -if test "x$with_libxml2" = "xyes" -then - SAVE_CFLAGS="$CFLAGS" - SAVE_LDFLAGS="$LDFLAGS" - CFLAGS="$CFLAGS $with_libxml2_cflags" - LDFLAGS="$LDFLAGS $with_libxml2_ldflags" +if test "x$with_libxml2" = "xyes"; then + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $with_libxml2_ldflags" - AC_CHECK_LIB(xml2, xmlXPathEval, - [with_libxml2="yes"], - [with_libxml2="no (symbol xmlXPathEval not found)"]) + AC_CHECK_LIB([xml2], [xmlXPathEval], + [with_libxml2="yes"], + [with_libxml2="no (symbol xmlXPathEval not found)"] + ) - CFLAGS="$SAVE_CFLAGS" - LDFLAGS="$SAVE_LDFLAGS" + LDFLAGS="$SAVE_LDFLAGS" fi -dnl Add the right compiler flags and libraries. + if test "x$with_libxml2" = "xyes"; then - BUILD_WITH_LIBXML2_CFLAGS="$with_libxml2_cflags" - BUILD_WITH_LIBXML2_LIBS="$with_libxml2_ldflags" - AC_SUBST(BUILD_WITH_LIBXML2_CFLAGS) - AC_SUBST(BUILD_WITH_LIBXML2_LIBS) + BUILD_WITH_LIBXML2_CFLAGS="$with_libxml2_cflags" + BUILD_WITH_LIBXML2_LIBS="$with_libxml2_ldflags" fi -if test "x$with_libvirt" = "xyes" -then - with_libvirt_cflags="`$PKG_CONFIG --cflags libvirt`" - if test $? -ne 0 - then - with_libvirt="no" - fi - with_libvirt_ldflags="`$PKG_CONFIG --libs libvirt`" - if test $? -ne 0 - then - with_libvirt="no" - fi + +AC_SUBST([BUILD_WITH_LIBXML2_CFLAGS]) +AC_SUBST([BUILD_WITH_LIBXML2_LIBS]) + +if test "x$with_libvirt" = "xyes"; then + with_libvirt_cflags="`$PKG_CONFIG --cflags libvirt`" + if test $? -ne 0; then + with_libvirt="no" + fi + + with_libvirt_ldflags="`$PKG_CONFIG --libs libvirt`" + if test $? -ne 0; then + with_libvirt="no" + fi fi -if test "x$with_libvirt" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $with_libvirt_cflags" - AC_CHECK_HEADERS(libvirt/libvirt.h, [], - [with_libvirt="no (libvirt/libvirt.h not found)"]) +if test "x$with_libvirt" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_libvirt_cflags" - CPPFLAGS="$SAVE_CPPFLAGS" + AC_CHECK_HEADERS([libvirt/libvirt.h], + [with_libvirt="yes"], + [with_libvirt="no (libvirt/libvirt.h not found)"] + ) + + CPPFLAGS="$SAVE_CPPFLAGS" fi -if test "x$with_libvirt" = "xyes" -then - SAVE_CFLAGS="$CFLAGS" - SAVE_LDFLAGS="$LDFLAGS" - CFLAGS="$CFLAGS $with_libvirt_cflags" - LDFLAGS="$LDFLAGS $with_libvirt_ldflags" +if test "x$with_libvirt" = "xyes"; then + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $with_libvirt_ldflags" - AC_CHECK_LIB(virt, virDomainBlockStats, - [with_libvirt="yes"], - [with_libvirt="no (symbol virDomainBlockStats not found)"]) + AC_CHECK_LIB([virt], [virDomainBlockStats], + [with_libvirt="yes"], + [with_libvirt="no (symbol virDomainBlockStats not found)"] + ) - CFLAGS="$SAVE_CFLAGS" - LDFLAGS="$SAVE_LDFLAGS" + LDFLAGS="$SAVE_LDFLAGS" fi -dnl Add the right compiler flags and libraries. + if test "x$with_libvirt" = "xyes"; then - BUILD_WITH_LIBVIRT_CFLAGS="$with_libvirt_cflags" - BUILD_WITH_LIBVIRT_LIBS="$with_libvirt_ldflags" - AC_SUBST(BUILD_WITH_LIBVIRT_CFLAGS) - AC_SUBST(BUILD_WITH_LIBVIRT_LIBS) + BUILD_WITH_LIBVIRT_CFLAGS="$with_libvirt_cflags" + BUILD_WITH_LIBVIRT_LIBS="$with_libvirt_ldflags" fi + +AC_SUBST([BUILD_WITH_LIBVIRT_CFLAGS]) +AC_SUBST([BUILD_WITH_LIBVIRT_LIBS]) # }}} # $PKG_CONFIG --exists OpenIPMIpthread {{{ with_libopenipmipthread="yes" -with_libopenipmipthread_cflags="" -with_libopenipmipthread_libs="" - -if test "x$with_libopenipmipthread" = "xyes" -then - AC_MSG_CHECKING([for libOpenIPMIpthread]) - $PKG_CONFIG --exists OpenIPMIpthread 2>/dev/null - if test "$?" != "0" - then - with_libopenipmipthread="no (pkg-config doesn't know OpenIPMIpthread)" - fi - AC_MSG_RESULT([$with_libopenipmipthread]) -fi - -if test "x$with_libopenipmipthread" = "xyes" -then - AC_MSG_CHECKING([for libOpenIPMIpthread CFLAGS]) - temp_result="`$PKG_CONFIG --cflags OpenIPMIpthread`" - if test "$?" = "0" - then - with_libopenipmipthread_cflags="$temp_result" - else - with_libopenipmipthread="no ($PKG_CONFIG --cflags OpenIPMIpthread failed)" - temp_result="$PKG_CONFIG --cflags OpenIPMIpthread failed" - fi - AC_MSG_RESULT([$temp_result]) +AC_MSG_CHECKING([for libOpenIPMIpthread]) +$PKG_CONFIG --exists OpenIPMIpthread 2>/dev/null +if test $? -ne 0; then + with_libopenipmipthread="no (pkg-config doesn't know OpenIPMIpthread)" +fi +AC_MSG_RESULT([$with_libopenipmipthread]) + +if test "x$with_libopenipmipthread" = "xyes"; then + AC_MSG_CHECKING([for libOpenIPMIpthread CFLAGS]) + temp_result="`$PKG_CONFIG --cflags OpenIPMIpthread`" + if test $? -eq 0; then + with_libopenipmipthread_cflags="$temp_result" + else + with_libopenipmipthread="no ($PKG_CONFIG --cflags OpenIPMIpthread failed)" + temp_result="$PKG_CONFIG --cflags OpenIPMIpthread failed" + fi + AC_MSG_RESULT([$temp_result]) fi -if test "x$with_libopenipmipthread" = "xyes" -then - AC_MSG_CHECKING([for libOpenIPMIpthread LDFLAGS]) - temp_result="`$PKG_CONFIG --libs OpenIPMIpthread`" - if test "$?" = "0" - then - with_libopenipmipthread_ldflags="$temp_result" - else - with_libopenipmipthread="no ($PKG_CONFIG --libs OpenIPMIpthread failed)" - temp_result="$PKG_CONFIG --libs OpenIPMIpthread failed" - fi - AC_MSG_RESULT([$temp_result]) +if test "x$with_libopenipmipthread" = "xyes"; then + AC_MSG_CHECKING([for libOpenIPMIpthread LDFLAGS]) + temp_result="`$PKG_CONFIG --libs OpenIPMIpthread`" + if test $? -eq 0; then + with_libopenipmipthread_ldflags="$temp_result" + else + with_libopenipmipthread="no ($PKG_CONFIG --libs OpenIPMIpthread failed)" + temp_result="$PKG_CONFIG --libs OpenIPMIpthread failed" + fi + AC_MSG_RESULT([$temp_result]) fi -if test "x$with_libopenipmipthread" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $with_libopenipmipthread_cflags" - - AC_CHECK_HEADERS(OpenIPMI/ipmi_smi.h, - [with_libopenipmipthread="yes"], - [with_libopenipmipthread="no (OpenIPMI/ipmi_smi.h not found)"], -[#include -#include -#include -#include -]) +if test "x$with_libopenipmipthread" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_libopenipmipthread_cflags" + + AC_CHECK_HEADERS([OpenIPMI/ipmi_smi.h], + [with_libopenipmipthread="yes"], + [with_libopenipmipthread="no (OpenIPMI/ipmi_smi.h not found)"], + [[ + #include + #include + #include + #include + ]] + ) - CPPFLAGS="$SAVE_CPPFLAGS" + CPPFLAGS="$SAVE_CPPFLAGS" fi -if test "x$with_libopenipmipthread" = "xyes" -then - BUILD_WITH_OPENIPMI_CFLAGS="$with_libopenipmipthread_cflags" - BUILD_WITH_OPENIPMI_LIBS="$with_libopenipmipthread_ldflags" - AC_SUBST(BUILD_WITH_OPENIPMI_CFLAGS) - AC_SUBST(BUILD_WITH_OPENIPMI_LIBS) +if test "x$with_libopenipmipthread" = "xyes"; then + BUILD_WITH_OPENIPMI_CFLAGS="$with_libopenipmipthread_cflags" + BUILD_WITH_OPENIPMI_LIBS="$with_libopenipmipthread_ldflags" fi + +AC_SUBST([BUILD_WITH_OPENIPMI_CFLAGS]) +AC_SUBST([BUILD_WITH_OPENIPMI_LIBS]) # }}} # --with-libatasmart {{{ -with_libatasmart_cppflags="" -with_libatasmart_ldflags="" -AC_ARG_WITH(libatasmart, [AS_HELP_STRING([--with-libatasmart@<:@=PREFIX@:>@], [Path to libatasmart.])], -[ - if test "x$withval" != "xno" && test "x$withval" != "xyes" - then - with_libatasmart_cppflags="-I$withval/include" - with_libatasmart_ldflags="-L$withval/lib" - with_libatasmart="yes" - else - with_libatasmart="$withval" - fi -], -[ - if test "x$ac_system" = "xLinux" - then - with_libatasmart="yes" - else - with_libatasmart="no (Linux only library)" - fi -]) -if test "x$with_libatasmart" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $with_libatasmart_cppflags" +AC_ARG_WITH([libatasmart], + [AS_HELP_STRING([--with-libatasmart@<:@=PREFIX@:>@], [Path to libatasmart.])], + [ + if test "x$withval" != "xno" && test "x$withval" != "xyes"; then + with_libatasmart_cppflags="-I$withval/include" + with_libatasmart_ldflags="-L$withval/lib" + with_libatasmart="yes" + else + with_libatasmart="$withval" + fi + ], + [ + if test "x$ac_system" = "xLinux"; then + with_libatasmart="yes" + else + with_libatasmart="no (Linux only library)" + fi + ] +) + +if test "x$with_libatasmart" = "xyes"; then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_libatasmart_cppflags" - AC_CHECK_HEADERS(atasmart.h, [with_libatasmart="yes"], [with_libatasmart="no (atasmart.h not found)"]) + AC_CHECK_HEADERS([atasmart.h], + [with_libatasmart="yes"], + [with_libatasmart="no (atasmart.h not found)"]) - CPPFLAGS="$SAVE_CPPFLAGS" + CPPFLAGS="$SAVE_CPPFLAGS" fi -if test "x$with_libatasmart" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - SAVE_LDFLAGS="$LDFLAGS" - CPPFLAGS="$CPPFLAGS $with_libatasmart_cppflags" - LDFLAGS="$LDFLAGS $with_libatasmart_ldflags" - AC_CHECK_LIB(atasmart, sk_disk_open, [with_libatasmart="yes"], [with_libatasmart="no (Symbol 'sk_disk_open' not found)"]) +if test "x$with_libatasmart" = "xyes"; then + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $with_libatasmart_ldflags" - CPPFLAGS="$SAVE_CPPFLAGS" - LDFLAGS="$SAVE_LDFLAGS" + AC_CHECK_LIB([atasmart], [sk_disk_open], + [with_libatasmart="yes"], + [with_libatasmart="no (Symbol 'sk_disk_open' not found)"] + ) + + LDFLAGS="$SAVE_LDFLAGS" fi -if test "x$with_libatasmart" = "xyes" -then - BUILD_WITH_LIBATASMART_CPPFLAGS="$with_libatasmart_cppflags" - BUILD_WITH_LIBATASMART_LDFLAGS="$with_libatasmart_ldflags" - BUILD_WITH_LIBATASMART_LIBS="-latasmart" - AC_SUBST(BUILD_WITH_LIBATASMART_CPPFLAGS) - AC_SUBST(BUILD_WITH_LIBATASMART_LDFLAGS) - AC_SUBST(BUILD_WITH_LIBATASMART_LIBS) - AC_DEFINE(HAVE_LIBATASMART, 1, [Define if libatasmart is present and usable.]) -fi -AM_CONDITIONAL(BUILD_WITH_LIBATASMART, test "x$with_libatasmart" = "xyes") + +if test "x$with_libatasmart" = "xyes"; then + BUILD_WITH_LIBATASMART_CPPFLAGS="$with_libatasmart_cppflags" + BUILD_WITH_LIBATASMART_LDFLAGS="$with_libatasmart_ldflags" + BUILD_WITH_LIBATASMART_LIBS="-latasmart" +fi + +AC_SUBST([BUILD_WITH_LIBATASMART_CPPFLAGS]) +AC_SUBST([BUILD_WITH_LIBATASMART_LDFLAGS]) +AC_SUBST([BUILD_WITH_LIBATASMART_LIBS]) # }}} PKG_CHECK_MODULES([LIBNOTIFY], [libnotify], - [with_libnotify="yes"], - [with_libnotify="no (pkg-config doesn't know libnotify)"] + [with_libnotify="yes"], + [with_libnotify="no (pkg-config doesn't know libnotify)"] ) PKG_CHECK_MODULES([LIBRIEMANN_CLIENT], [riemann-client >= 1.6.0], [with_libriemann_client="yes"], - [with_libriemann_client="no (pkg-config doesn't know libriemann-client)"]) + [with_libriemann_client="no (pkg-config doesn't know libriemann-client)"] +) # Check for enabled/disabled features # @@ -5802,61 +5790,59 @@ PKG_CHECK_MODULES([LIBRIEMANN_CLIENT], [riemann-client >= 1.6.0], # AC_COLLECTD(name, enable/disable, info-text, feature/module) # ------------------------------------------------------------ dnl -m4_define([my_toupper], [m4_translit([$1], m4_defn([m4_cr_letters]), m4_defn([m4_cr_LETTERS]))]) +m4_define([my_toupper],[m4_translit([$1], m4_defn([m4_cr_letters]), m4_defn([m4_cr_LETTERS]))]) dnl AC_DEFUN( - [AC_COLLECTD], - [ - m4_if([$1], [], [AC_FATAL([AC_COLLECTD([$1], [$2], [$3], [$4]): 1st argument must not be empty])])dnl - m4_if( - [$2], - [enable], - [dnl - m4_define([EnDis],[disabled])dnl - m4_define([YesNo],[no])dnl - ],dnl - [m4_if( - [$2], - [disable], - [dnl - m4_define([EnDis],[enabled])dnl - m4_define([YesNo],[yes])dnl - ], - [dnl - AC_FATAL([AC_COLLECTD([$1], [$2], [$3], [$4]): 2nd argument must be either enable or disable])dnl - ]dnl - )]dnl - )dnl - m4_if([$3], [feature], [], - [m4_if( - [$3], [module], [], - [dnl - AC_FATAL([AC_COLLECTD([$1], [$2], [$3], [$4]): 3rd argument must be either feature or disable])dnl - ]dnl - )]dnl - )dnl - AC_ARG_ENABLE( - [$1], - AS_HELP_STRING([--$2-$1], [$2 $4 (EnDis by def)]), - [], - enable_$1='[YesNo]'dnl - )# AC_ARG_ENABLE -if test "x$enable_$1" = "xno" -then - collectd_$1=0 -else - if test "x$enable_$1" = "xyes" - then - collectd_$1=1 - else - AC_MSG_NOTICE([please specify either --enable-$1 or --disable-$1; enabling $1.]) - collectd_$1=1 - enable_$1='yes' - fi -fi - AC_DEFINE_UNQUOTED([COLLECT_]my_toupper([$1]), [$collectd_$1], [wether or not to enable $3 $4]) - AM_CONDITIONAL([BUILD_]my_toupper([$3])[_]my_toupper([$1]), [test "x$enable_$1" = "xyes"])dnl - ]dnl + [AC_COLLECTD], + [ + m4_if([$1], [], [AC_FATAL([AC_COLLECTD([$1], [$2], [$3], [$4]): 1st argument must not be empty])])dnl + m4_if( + [$2], + [enable], + [dnl + m4_define([EnDis],[disabled])dnl + m4_define([YesNo],[no])dnl + ],dnl + [m4_if( + [$2], + [disable], + [dnl + m4_define([EnDis],[enabled])dnl + m4_define([YesNo],[yes])dnl + ], + [dnl + AC_FATAL([AC_COLLECTD([$1], [$2], [$3], [$4]): 2nd argument must be either enable or disable])dnl + ]dnl + )]dnl + )dnl + m4_if([$3], [feature], [], + [m4_if( + [$3], [module], [], + [dnl + AC_FATAL([AC_COLLECTD([$1], [$2], [$3], [$4]): 3rd argument must be either feature or disable])dnl + ]dnl + )]dnl + )dnl + AC_ARG_ENABLE( + [$1], + AS_HELP_STRING([--$2-$1], [$2 $4 (EnDis by def)]), + [], + enable_$1='[YesNo]'dnl + )# AC_ARG_ENABLE + if test "x$enable_$1" = "xno"; then + collectd_$1=0 + else + if test "x$enable_$1" = "xyes"; then + collectd_$1=1 + else + AC_MSG_NOTICE([please specify either --enable-$1 or --disable-$1; enabling $1.]) + collectd_$1=1 + enable_$1='yes' + fi + fi + AC_DEFINE_UNQUOTED([COLLECT_]my_toupper([$1]), [$collectd_$1], [whether or not to enable $3 $4]) + AM_CONDITIONAL([BUILD_]my_toupper([$3])[_]my_toupper([$1]), [test "x$enable_$1" = "xyes"])dnl + ]dnl )# AC_COLLECTD(name, enable/disable, info-text, feature/module) # AC_PLUGIN(name, default, info) @@ -5867,47 +5853,42 @@ AC_DEFUN( [ enable_plugin="no" force="no" - AC_ARG_ENABLE([$1], AS_HELP_STRING([--enable-$1],[$3]), - [ - if test "x$enableval" = "xyes" - then - enable_plugin="yes" - else if test "x$enableval" = "xforce" - then - enable_plugin="yes" - force="yes" - else - enable_plugin="no (disabled on command line)" - fi; fi - ], - [ - if test "x$enable_all_plugins" = "xauto" - then - if test "x$2" = "xyes" - then - enable_plugin="yes" - else - enable_plugin="$2" - fi - else - enable_plugin="$enable_all_plugins" - fi - ]) - if test "x$enable_plugin" = "xyes" - then - if test "x$2" = "xyes" || test "x$force" = "xyes" - then - AC_DEFINE([HAVE_PLUGIN_]my_toupper([$1]), 1, [Define to 1 if the $1 plugin is enabled.]) - if test "x$2" != "xyes" - then - dependency_warning="yes" - fi - else # User passed "yes" but dependency checking yielded "no" => Dependency problem. - dependency_error="yes" - enable_plugin="$2 (dependency error)" - fi + AC_ARG_ENABLE([$1], + [AS_HELP_STRING([--enable-$1],[$3])], + [ + if test "x$enableval" = "xyes"; then + enable_plugin="yes" + else if test "x$enableval" = "xforce"; then + enable_plugin="yes" + force="yes" + else + enable_plugin="no (disabled on command line)" + fi; fi + ], + [ + if test "x$enable_all_plugins" = "xauto"; then + if test "x$2" = "xyes"; then + enable_plugin="yes" + else + enable_plugin="$2" + fi + else + enable_plugin="$enable_all_plugins" + fi + ] + ) + if test "x$enable_plugin" = "xyes"; then + if test "x$2" = "xyes" || test "x$force" = "xyes"; then + AC_DEFINE([HAVE_PLUGIN_]my_toupper([$1]), 1, [Define to 1 if the $1 plugin is enabled.]) + if test "x$2" != "xyes"; then + dependency_warning="yes" + fi + else # User passed "yes" but dependency checking yielded "no" => Dependency problem. + dependency_error="yes" + enable_plugin="$2 (dependency error)" + fi fi - AM_CONDITIONAL([BUILD_PLUGIN_]my_toupper([$1]), test "x$enable_plugin" = "xyes") + AM_CONDITIONAL([BUILD_PLUGIN_]my_toupper([$1]), [test "x$enable_plugin" = "xyes"]) enable_$1="$enable_plugin" ] )# AC_PLUGIN(name, default, info) @@ -5939,6 +5920,7 @@ plugin_curl_xml="no" plugin_df="no" plugin_disk="no" plugin_drbd="no" +plugin_dpdkevents="no" plugin_dpdkstat="no" plugin_entropy="no" plugin_ethstat="no" @@ -5949,15 +5931,19 @@ plugin_grpc="no" plugin_hugepages="no" plugin_intel_rdt="no" plugin_interface="no" +plugin_ipc="no" plugin_ipmi="no" plugin_ipvs="no" plugin_irq="no" plugin_load="no" plugin_log_logstash="no" +plugin_mcelog="no" plugin_memory="no" plugin_multimeter="no" plugin_nfs="no" plugin_numa="no" +plugin_ovs_events="no" +plugin_ovs_stats="no" plugin_perl="no" plugin_pinba="no" plugin_processes="no" @@ -5984,374 +5970,310 @@ plugin_zone="no" plugin_zookeeper="no" # Linux -if test "x$ac_system" = "xLinux" -then - plugin_battery="yes" - plugin_cgroups="yes" - plugin_conntrack="yes" - plugin_contextswitch="yes" - plugin_cpu="yes" - plugin_cpufreq="yes" - plugin_disk="yes" - plugin_drbd="yes" - plugin_entropy="yes" - plugin_fhcount="yes" - plugin_fscache="yes" - plugin_hugepages="yes" - plugin_interface="yes" - plugin_ipc="yes" - plugin_irq="yes" - plugin_load="yes" - plugin_lvm="yes" - plugin_memory="yes" - plugin_nfs="yes" - plugin_numa="yes" - plugin_processes="yes" - plugin_protocols="yes" - plugin_serial="yes" - plugin_swap="yes" - plugin_tcpconns="yes" - plugin_thermal="yes" - plugin_uptime="yes" - plugin_vmem="yes" - plugin_vserver="yes" - plugin_wireless="yes" - plugin_zfs_arc="yes" - - if test "x$have_linux_ip_vs_h" = "xyes" || test "x$have_net_ip_vs_h" = "xyes" || test "x$have_ip_vs_h" = "xyes" - then - plugin_ipvs="yes" - fi - if test "x$c_cv_have_usable_asm_msrindex_h" = "xyes" && test "x$have_cpuid_h" = "xyes" - then - plugin_turbostat="yes" - fi - - if test "x$c_cv_have_clock_boottime_monotonic" = "xyes" - then - plugin_cpusleep="yes" - fi +if test "x$ac_system" = "xLinux"; then + plugin_battery="yes" + plugin_cgroups="yes" + plugin_conntrack="yes" + plugin_contextswitch="yes" + plugin_cpu="yes" + plugin_cpufreq="yes" + plugin_disk="yes" + plugin_drbd="yes" + plugin_entropy="yes" + plugin_fhcount="yes" + plugin_fscache="yes" + plugin_hugepages="yes" + plugin_interface="yes" + plugin_ipc="yes" + plugin_irq="yes" + plugin_load="yes" + plugin_lvm="yes" + plugin_mcelog="yes" + plugin_memory="yes" + plugin_nfs="yes" + plugin_numa="yes" + plugin_processes="yes" + plugin_protocols="yes" + plugin_serial="yes" + plugin_swap="yes" + plugin_tcpconns="yes" + plugin_thermal="yes" + plugin_uptime="yes" + plugin_vmem="yes" + plugin_vserver="yes" + plugin_wireless="yes" + plugin_zfs_arc="yes" + + if test "x$have_linux_ip_vs_h" = "xyes" || test "x$have_net_ip_vs_h" = "xyes" || test "x$have_ip_vs_h" = "xyes"; then + plugin_ipvs="yes" + fi + + if test "x$c_cv_have_usable_asm_msrindex_h" = "xyes" && test "x$have_cpuid_h" = "xyes"; then + plugin_turbostat="yes" + fi + + if test "x$c_cv_have_clock_boottime_monotonic" = "xyes"; then + plugin_cpusleep="yes" + fi + + if test "x$with_libyajl" = "xyes" && test "x$with_libyajl2" = "xyes"; then + plugin_ovs_events="yes" + plugin_ovs_stats="yes" + fi fi -if test "x$ac_system" = "xOpenBSD" -then - plugin_tcpconns="yes" +if test "x$ac_system" = "xOpenBSD"; then + plugin_tcpconns="yes" fi -if test "x$ac_system" = "xNetBSD" -then - plugin_disk="yes" - plugin_entropy="yes" - plugin_irq="yes" - plugin_processes="yes" +if test "x$ac_system" = "xNetBSD"; then + plugin_disk="yes" + plugin_entropy="yes" + plugin_irq="yes" + plugin_processes="yes" fi # Mac OS X devices -if test "x$with_libiokit" = "xyes" -then - plugin_battery="yes" - plugin_disk="yes" +if test "x$with_libiokit" = "xyes"; then + plugin_battery="yes" + plugin_disk="yes" fi # AIX -if test "x$ac_system" = "xAIX" -then - plugin_ipc="yes" - plugin_tcpconns="yes" +if test "x$ac_system" = "xAIX"; then + plugin_ipc="yes" + plugin_tcpconns="yes" fi # FreeBSD -if test "x$ac_system" = "xFreeBSD" -then - plugin_disk="yes" - plugin_zfs_arc="yes" +if test "x$ac_system" = "xFreeBSD"; then + plugin_disk="yes" + plugin_zfs_arc="yes" fi -if test "x$with_perfstat" = "xyes" -then - plugin_contextswitch="yes" - plugin_cpu="yes" - plugin_disk="yes" - plugin_interface="yes" - plugin_load="yes" - plugin_memory="yes" - plugin_swap="yes" - plugin_uptime="yes" +if test "x$with_perfstat" = "xyes"; then + plugin_contextswitch="yes" + plugin_cpu="yes" + plugin_disk="yes" + plugin_interface="yes" + plugin_load="yes" + plugin_memory="yes" + plugin_swap="yes" + plugin_uptime="yes" fi -if test "x$with_procinfo" = "xyes" -then - plugin_processes="yes" +if test "x$with_procinfo" = "xyes"; then + plugin_processes="yes" fi # Solaris -if test "x$with_kstat" = "xyes" -then - plugin_nfs="yes" - plugin_processes="yes" - plugin_uptime="yes" - plugin_zfs_arc="yes" - plugin_zone="yes" -fi - -if test "x$with_devinfo$with_kstat" = "xyesyes" -then - plugin_cpu="yes" - plugin_disk="yes" - plugin_interface="yes" - plugin_memory="yes" - plugin_tape="yes" +if test "x$with_kstat" = "xyes"; then + plugin_nfs="yes" + plugin_processes="yes" + plugin_uptime="yes" + plugin_zfs_arc="yes" + plugin_zone="yes" fi -# libi2c-dev -if test "x$ac_system" = "xLinux" -then -AC_CHECK_DECL(i2c_smbus_read_i2c_block_data, - [with_libi2c="yes"], - [with_libi2c="no (symbol i2c_smbus_read_i2c_block_data not found - have you installed libi2c-dev ?)"], - [[#include - #include ]]) -else - with_libi2c="no (Linux only)" +if test "x$with_devinfo" = "xyes" && test "x$with_kstat" = "xyes"; then + plugin_cpu="yes" + plugin_disk="yes" + plugin_interface="yes" + plugin_memory="yes" + plugin_tape="yes" fi -if test "x$with_libi2c" = "xyes" -then - plugin_barometer="yes" +if test "x$with_libi2c" = "xyes"; then + plugin_barometer="yes" fi # libstatgrab -if test "x$with_libstatgrab" = "xyes" -then - plugin_cpu="yes" - plugin_disk="yes" - plugin_interface="yes" - plugin_load="yes" - plugin_memory="yes" - plugin_swap="yes" - plugin_users="yes" +if test "x$with_libstatgrab" = "xyes"; then + plugin_cpu="yes" + plugin_disk="yes" + plugin_interface="yes" + plugin_load="yes" + plugin_memory="yes" + plugin_swap="yes" + plugin_users="yes" +fi + +if test "x$with_libcurl" = "xyes" && test "x$with_libxml2" = "xyes"; then + plugin_ascent="yes" + if test "x$have_strptime" = "xyes"; then + plugin_bind="yes" + fi fi -if test "x$with_libcurl" = "xyes" && test "x$with_libxml2" = "xyes" -then - plugin_ascent="yes" - if test "x$have_strptime" = "xyes" - then - plugin_bind="yes" - fi +if test "x$with_libopenipmipthread" = "xyes"; then + plugin_ipmi="yes" fi -if test "x$with_libopenipmipthread" = "xyes" -then - plugin_ipmi="yes" +if test "x$with_libcurl" = "xyes" && test "x$with_libyajl" = "xyes"; then + plugin_curl_json="yes" fi -if test "x$with_libcurl" = "xyes" && test "x$with_libyajl" = "xyes" -then - plugin_curl_json="yes" +if test "x$with_libcurl" = "xyes" && test "x$with_libxml2" = "xyes"; then + plugin_curl_xml="yes" fi -if test "x$with_libcurl" = "xyes" && test "x$with_libxml2" = "xyes" -then - plugin_curl_xml="yes" +if test "x$with_libyajl" = "xyes"; then + plugin_ceph="yes" fi -if test "x$with_libyajl" = "xyes" -then - plugin_ceph="yes" +if test "x$have_processor_info" = "xyes"; then + plugin_cpu="yes" fi -if test "x$have_processor_info" = "xyes" -then - plugin_cpu="yes" -fi -if test "x$have_sysctl" = "xyes" -then - plugin_cpu="yes" - plugin_memory="yes" - plugin_uptime="yes" - if test "x$ac_system" = "xDarwin" - then - plugin_swap="yes" - fi +if test "x$have_sysctl" = "xyes"; then + plugin_cpu="yes" + plugin_memory="yes" + plugin_uptime="yes" + if test "x$ac_system" = "xDarwin"; then + plugin_swap="yes" + fi fi -if test "x$have_sysctlbyname" = "xyes" -then - plugin_contextswitch="yes" - plugin_cpu="yes" - plugin_memory="yes" - plugin_tcpconns="yes" + +if test "x$have_sysctlbyname" = "xyes"; then + plugin_contextswitch="yes" + plugin_cpu="yes" + plugin_memory="yes" + plugin_tcpconns="yes" fi -# Df plugin: Check if we know how to determine mount points first. -#if test "x$have_listmntent" = "xyes"; then -# plugin_df="yes" -#fi -if test "x$have_getvfsstat" = "xyes" || test "x$have_getfsstat" = "xyes" -then - plugin_df="yes" +if test "x$have_getvfsstat" = "xyes" || test "x$have_getfsstat" = "xyes"; then + plugin_df="yes" fi -if test "x$c_cv_have_two_getmntent" = "xyes" || test "x$have_getmntent" = "xgen" || test "x$have_getmntent" = "xsun" -then - plugin_df="yes" + +if test "x$c_cv_have_two_getmntent" = "xyes" || test "x$have_getmntent" = "xgen" || test "x$have_getmntent" = "xsun"; then + plugin_df="yes" fi -#if test "x$have_getmntent" = "xseq" -#then -# plugin_df="yes" -#fi -if test "x$c_cv_have_one_getmntent" = "xyes" -then - plugin_df="yes" + +if test "x$c_cv_have_one_getmntent" = "xyes"; then + plugin_df="yes" fi -if test "x$c_cv_have_getmntent_r" = "xyes" -then - plugin_df="yes" +if test "x$c_cv_have_getmntent_r" = "xyes"; then + plugin_df="yes" fi -# Df plugin: Check if we have either `statfs' or `statvfs' second. -if test "x$plugin_df" = "xyes" -then - plugin_df="no" - if test "x$have_statfs" = "xyes" - then - plugin_df="yes" - fi - if test "x$have_statvfs" = "xyes" - then - plugin_df="yes" - fi +if test "x$plugin_df" = "xyes"; then + plugin_df="no" + if test "x$have_statfs" = "xyes"; then + plugin_df="yes" + fi + + if test "x$have_statvfs" = "xyes"; then + plugin_df="yes" + fi fi -if test "x$have_linux_sockios_h$have_linux_ethtool_h" = "xyesyes" -then - plugin_ethstat="yes" +if test "x$have_linux_sockios_h" = "xyes" && test "x$have_linux_ethtool_h" = "xyes"; then + plugin_ethstat="yes" fi -if test "x$with_libgrpcpp" = "xyes" && test "x$with_libprotobuf" = "xyes" && test "x$have_protoc3" = "xyes" && test "x$GRPC_CPP_PLUGIN" != "x" -then - plugin_grpc="yes" +if test "x$with_libgps" = "xyes"; then + plugin_gps="yes" fi -if test "x$have_getifaddrs" = "xyes" -then - plugin_interface="yes" +if test "x$with_libgrpcpp" = "xyes" && test "x$with_libprotobuf" = "xyes" && test "x$have_protoc3" = "xyes" && test "x$GRPC_CPP_PLUGIN" != "x"; then + plugin_grpc="yes" fi -if test "x$with_libgps" = "xyes" -then - plugin_gps="yes" +if test "x$have_getifaddrs" = "xyes"; then + plugin_interface="yes" fi -if test "x$have_getloadavg" = "xyes" -then - plugin_load="yes" +if test "x$have_getloadavg" = "xyes"; then + plugin_load="yes" fi -if test "x$with_libyajl" = "xyes" -then - plugin_log_logstash="yes" +if test "x$with_libyajl" = "xyes"; then + plugin_log_logstash="yes" fi -if test "x$c_cv_have_libperl$c_cv_have_perl_ithreads" = "xyesyes" -then - plugin_perl="yes" +if test "x$with_libperl" = "xyes" && test "x$c_cv_have_perl_ithreads" = "xyes"; then + plugin_perl="yes" fi -if test "x$have_protoc_c" = "xyes" && test "x$with_libprotobuf_c" = "xyes" -then - plugin_pinba="yes" - if test "x$with_libmicrohttpd" = "xyes" - then - plugin_write_prometheus="yes" - fi +if test "x$have_protoc_c" = "xyes" && test "x$with_libprotobuf_c" = "xyes"; then + plugin_pinba="yes" + if test "x$with_libmicrohttpd" = "xyes"; then + plugin_write_prometheus="yes" + fi fi # Mac OS X memory interface -if test "x$have_host_statistics" = "xyes" -then - plugin_memory="yes" +if test "x$have_host_statistics" = "xyes"; then + plugin_memory="yes" fi -if test "x$have_termios_h" = "xyes" -then - if test "x$ac_system" != "xAIX" - then - plugin_multimeter="yes" - fi - plugin_ted="yes" +if test "x$have_termios_h" = "xyes"; then + if test "x$ac_system" != "xAIX"; then + plugin_multimeter="yes" + fi + plugin_ted="yes" fi -if test "x$have_thread_info" = "xyes" -then - plugin_processes="yes" +if test "x$have_thread_info" = "xyes"; then + plugin_processes="yes" fi -if test "x$with_kvm_getprocs" = "xyes" && test "x$have_struct_kinfo_proc_freebsd" = "xyes" -then - plugin_processes="yes" +if test "x$with_kvm_getprocs" = "xyes" && test "x$have_struct_kinfo_proc_freebsd" = "xyes"; then + plugin_processes="yes" fi -if test "x$with_kvm_getprocs" = "xyes" && test "x$have_struct_kinfo_proc_openbsd" = "xyes" -then - plugin_processes="yes" +if test "x$with_kvm_getprocs" = "xyes" && test "x$have_struct_kinfo_proc_openbsd" = "xyes"; then + plugin_processes="yes" fi -if test "x$with_libpython" != "xno" -then - plugin_python="yes" +if test "x$with_libpython" != "xno"; then + plugin_python="yes" fi -if test "x$with_libatasmart" = "xyes" && test "x$with_libudev" = "xyes" -then - plugin_smart="yes" +if test "x$with_libatasmart" = "xyes" && test "x$with_libudev" = "xyes"; then + plugin_smart="yes" fi -if test "x$with_kvm_getswapinfo" = "xyes" -then - plugin_swap="yes" +if test "x$with_kvm_getswapinfo" = "xyes"; then + plugin_swap="yes" fi -if test "x$have_swapctl" = "xyes" && test "x$c_cv_have_swapctl_two_args" = "xyes" -then - plugin_swap="yes" +if test "x$have_swapctl" = "xyes" && test "x$c_cv_have_swapctl_two_args" = "xyes"; then + plugin_swap="yes" fi -if test "x$have_swapctl" = "xyes" && test "x$c_cv_have_swapctl_three_args" = "xyes" -then - plugin_swap="yes" +if test "x$have_swapctl" = "xyes" && test "x$c_cv_have_swapctl_three_args" = "xyes"; then + plugin_swap="yes" fi -if test "x$with_kvm_openfiles$with_kvm_nlist" = "xyesyes" -then - plugin_tcpconns="yes" +if test "x$with_kvm_openfiles = "xyes" && $with_kvm_nlist" = "xyes"; then + plugin_tcpconns="yes" fi -if test "x$have_getutent" = "xyes" -then - plugin_users="yes" +if test "x$have_getutent" = "xyes"; then + plugin_users="yes" fi -if test "x$have_getutxent" = "xyes" -then - plugin_users="yes" + +if test "x$have_getutxent" = "xyes"; then + plugin_users="yes" fi -if test "x$with_libxml2" = "xyes" && test "x$with_libvirt" = "xyes" -then - plugin_virt="yes" +if test "x$with_libxml2" = "xyes" && test "x$with_libvirt" = "xyes"; then + plugin_virt="yes" fi -if test "x$with_libxenctrl" = "xyes" -then +if test "x$with_libxenctrl" = "xyes"; then plugin_xencpu="yes" fi if test "x$with_libdpdk" = "xyes" then + plugin_dpdkevents="$dpdk_keepalive" plugin_dpdkstat="yes" fi @@ -6359,19 +6281,18 @@ m4_divert_once([HELP_ENABLE], [ collectd plugins:]) AC_ARG_ENABLE([all-plugins], - AS_HELP_STRING([--enable-all-plugins],[enable all plugins (auto by def)]), - [ - if test "x$enableval" = "xyes" - then - enable_all_plugins="yes" - else if test "x$enableval" = "xauto" - then - enable_all_plugins="auto" - else - enable_all_plugins="no" - fi; fi - ], - [enable_all_plugins="auto"]) + [AS_HELP_STRING([--enable-all-plugins], [enable all plugins @<:@default=yes@:>@])], + [ + if test "x$enableval" = "xyes"; then + enable_all_plugins="yes" + else if test "x$enableval" = "xauto"; then + enable_all_plugins="auto" + else + enable_all_plugins="no" + fi; fi + ], + [enable_all_plugins="auto"] +) m4_divert_once([HELP_ENABLE], []) @@ -6401,7 +6322,8 @@ AC_PLUGIN([dbi], [$with_libdbi], [General database st AC_PLUGIN([df], [$plugin_df], [Filesystem usage statistics]) AC_PLUGIN([disk], [$plugin_disk], [Disk usage statistics]) AC_PLUGIN([dns], [$with_libpcap], [DNS traffic analysis]) -AC_PLUGIN([dpdkstat], [$plugin_dpdkstat], [Stats & Status from DPDK]) +AC_PLUGIN([dpdkevents], [$plugin_dpdkevents], [Events from DPDK]) +AC_PLUGIN([dpdkstat], [$plugin_dpdkstat], [Stats from DPDK]) AC_PLUGIN([drbd], [$plugin_drbd], [DRBD statistics]) AC_PLUGIN([email], [yes], [EMail statistics]) AC_PLUGIN([entropy], [$plugin_entropy], [Entropy statistics]) @@ -6436,6 +6358,7 @@ AC_PLUGIN([match_regex], [yes], [The regex match]) AC_PLUGIN([match_timediff], [yes], [The timediff match]) AC_PLUGIN([match_value], [yes], [The value match]) AC_PLUGIN([mbmon], [yes], [Query mbmond]) +AC_PLUGIN([mcelog], [$plugin_mcelog], [Machine Check Exceptions notifications]) AC_PLUGIN([md], [$have_linux_raid_md_u_h], [md (Linux software RAID) devices]) AC_PLUGIN([memcachec], [$with_libmemcached], [memcachec statistics]) AC_PLUGIN([memcached], [yes], [memcached statistics]) @@ -6461,6 +6384,8 @@ AC_PLUGIN([onewire], [$with_libowcapi], [OneWire sensor stat AC_PLUGIN([openldap], [$with_libldap], [OpenLDAP statistics]) AC_PLUGIN([openvpn], [yes], [OpenVPN client statistics]) AC_PLUGIN([oracle], [$with_oracle], [Oracle plugin]) +AC_PLUGIN([ovs_events], [$plugin_ovs_events], [OVS events plugin]) +AC_PLUGIN([ovs_stats], [$plugin_ovs_stats], [OVS statistics plugin]) AC_PLUGIN([perl], [$plugin_perl], [Embed a Perl interpreter]) AC_PLUGIN([pf], [$have_net_pfvar_h], [BSD packet filter (PF) statistics]) # FIXME: Check for libevent, too. @@ -6532,45 +6457,41 @@ LOAD_PLUGIN_LOG_LOGSTASH="" AC_MSG_CHECKING([which default log plugin to load]) default_log_plugin="none" -if test "x$enable_syslog" = "xyes" -then - default_log_plugin="syslog" +if test "x$enable_syslog" = "xyes"; then + default_log_plugin="syslog" else - LOAD_PLUGIN_SYSLOG="##" + LOAD_PLUGIN_SYSLOG="##" fi -if test "x$enable_logfile" = "xyes" -then - if test "x$default_log_plugin" = "xnone" - then - default_log_plugin="logfile" - else - LOAD_PLUGIN_LOGFILE="#" - fi +if test "x$enable_logfile" = "xyes"; then + if test "x$default_log_plugin" = "xnone"; then + default_log_plugin="logfile" + else + LOAD_PLUGIN_LOGFILE="#" + fi else - LOAD_PLUGIN_LOGFILE="##" + LOAD_PLUGIN_LOGFILE="##" fi -if test "x$enable_log_logstash" = "xyes" -then +if test "x$enable_log_logstash" = "xyes"; then LOAD_PLUGIN_LOG_LOGSTASH="#" else LOAD_PLUGIN_LOG_LOGSTASH="##" fi - AC_MSG_RESULT([$default_log_plugin]) -AC_SUBST(LOAD_PLUGIN_SYSLOG) -AC_SUBST(LOAD_PLUGIN_LOGFILE) -AC_SUBST(LOAD_PLUGIN_LOG_LOGSTASH) +AC_SUBST([LOAD_PLUGIN_SYSLOG]) +AC_SUBST([LOAD_PLUGIN_LOGFILE]) +AC_SUBST([LOAD_PLUGIN_LOG_LOGSTASH]) -DEFAULT_LOG_LEVEL="info" if test "x$enable_debug" = "xyes" then - DEFAULT_LOG_LEVEL="debug" + DEFAULT_LOG_LEVEL="debug" +else + DEFAULT_LOG_LEVEL="info" fi -AC_SUBST(DEFAULT_LOG_LEVEL) +AC_SUBST([DEFAULT_LOG_LEVEL]) # Load only one of rrdtool, network, csv in the default config. LOAD_PLUGIN_RRDTOOL="" @@ -6579,73 +6500,65 @@ LOAD_PLUGIN_CSV="" AC_MSG_CHECKING([which default write plugin to load]) default_write_plugin="none" -if test "x$enable_rrdtool" = "xyes" -then - default_write_plugin="rrdtool" +if test "x$enable_rrdtool" = "xyes"; then + default_write_plugin="rrdtool" else - LOAD_PLUGIN_RRDTOOL="##" + LOAD_PLUGIN_RRDTOOL="##" fi -if test "x$enable_network" = "xyes" -then - if test "x$default_write_plugin" = "xnone" - then - default_write_plugin="network" - else - LOAD_PLUGIN_NETWORK="#" - fi +if test "x$enable_network" = "xyes"; then + if test "x$default_write_plugin" = "xnone"; then + default_write_plugin="network" + else + LOAD_PLUGIN_NETWORK="#" + fi else - LOAD_PLUGIN_NETWORK="##" + LOAD_PLUGIN_NETWORK="##" fi -if test "x$enable_csv" = "xyes" -then - if test "x$default_write_plugin" = "xnone" - then - default_write_plugin="csv" - else - LOAD_PLUGIN_CSV="#" - fi +if test "x$enable_csv" = "xyes"; then + if test "x$default_write_plugin" = "xnone"; then + default_write_plugin="csv" + else + LOAD_PLUGIN_CSV="#" + fi else - LOAD_PLUGIN_CSV="##" + LOAD_PLUGIN_CSV="##" fi AC_MSG_RESULT([$default_write_plugin]) -AC_SUBST(LOAD_PLUGIN_RRDTOOL) -AC_SUBST(LOAD_PLUGIN_NETWORK) -AC_SUBST(LOAD_PLUGIN_CSV) +AC_SUBST([LOAD_PLUGIN_RRDTOOL]) +AC_SUBST([LOAD_PLUGIN_NETWORK]) +AC_SUBST([LOAD_PLUGIN_CSV]) dnl ip_vs.h -if test "x$ac_system" = "xLinux" \ - && test "x$have_linux_ip_vs_h$have_net_ip_vs_h$have_ip_vs_h" = "xnonono" -then - enable_ipvs="$enable_ipvs (ip_vs.h not found)" +if test "x$ac_system" = "xLinux" && test "x$have_linux_ip_vs_h" = "xno" && "x$have_net_ip_vs_h" = "xno" && "x$have_ip_vs_h" = "xno"; then + enable_ipvs="$enable_ipvs (ip_vs.h not found)" fi -if test "x$ip_vs_h_needs_kernel_cflags" = "xyes" -then - enable_ipvs="$enable_ipvs (needs $KERNEL_CFLAGS)" +if test "x$ip_vs_h_needs_kernel_cflags" = "xyes"; then + enable_ipvs="$enable_ipvs (needs $KERNEL_CFLAGS)" fi dnl Perl bindings PERL_BINDINGS_OPTIONS="PREFIX=${prefix}" AC_ARG_WITH(perl-bindings, [AS_HELP_STRING([--with-perl-bindings@<:@=OPTIONS@:>@], [Options passed to "perl Makefile.PL".])], [ - if test "x$withval" != "xno" && test "x$withval" != "xyes" - then - PERL_BINDINGS_OPTIONS="$withval" - with_perl_bindings="yes" - else - with_perl_bindings="$withval" - fi + if test "x$withval" != "xno" && test "x$withval" != "xyes" + then + PERL_BINDINGS_OPTIONS="$withval" + with_perl_bindings="yes" + else + with_perl_bindings="$withval" + fi ], [ - if test -n "$perl_interpreter" - then - with_perl_bindings="yes" - else - with_perl_bindings="no (no perl interpreter found)" - fi + if test "x$PERL" != "x" + then + with_perl_bindings="yes" + else + with_perl_bindings="no (no perl interpreter found)" + fi ]) if test "x$with_perl_bindings" = "xyes" @@ -6661,12 +6574,13 @@ fi if test "x$with_perl_bindings" = "xyes" then - PERL_BINDINGS="perl" + PERL_BINDINGS="perl" else - PERL_BINDINGS="" + PERL_BINDINGS="" fi -AC_SUBST(PERL_BINDINGS) -AC_SUBST(PERL_BINDINGS_OPTIONS) + +AC_SUBST([PERL_BINDINGS]) +AC_SUBST([PERL_BINDINGS_OPTIONS]) dnl libcollectdclient LCC_VERSION_MAJOR=`echo $PACKAGE_VERSION | cut -d'.' -f1` @@ -6677,49 +6591,48 @@ LCC_VERSION_EXTRA=`echo $PACKAGE_VERSION | cut -d'.' -f4-` LCC_VERSION_STRING="$LCC_VERSION_MAJOR.$LCC_VERSION_MINOR.$LCC_VERSION_PATCH" -AC_SUBST(LCC_VERSION_MAJOR) -AC_SUBST(LCC_VERSION_MINOR) -AC_SUBST(LCC_VERSION_PATCH) -AC_SUBST(LCC_VERSION_EXTRA) -AC_SUBST(LCC_VERSION_STRING) +AC_SUBST([LCC_VERSION_MAJOR]) +AC_SUBST([LCC_VERSION_MINOR]) +AC_SUBST([LCC_VERSION_PATCH]) +AC_SUBST([LCC_VERSION_EXTRA]) +AC_SUBST([LCC_VERSION_STRING]) -AC_CONFIG_FILES(src/libcollectdclient/collectd/lcc_features.h) +AC_CONFIG_FILES([src/libcollectdclient/collectd/lcc_features.h]) AM_CFLAGS="-Wall" AM_CXXFLAGS="-Wall" -if test "x$enable_werror" != "xno" -then - AM_CFLAGS="$AM_CFLAGS -Werror" - AM_CXXFLAGS="$AM_CXXFLAGS -Werror" +if test "x$enable_werror" != "xno"; then + AM_CFLAGS="$AM_CFLAGS -Werror" + AM_CXXFLAGS="$AM_CXXFLAGS -Werror" fi + AC_SUBST([AM_CFLAGS]) AC_SUBST([AM_CXXFLAGS]) -AC_CONFIG_FILES([Makefile proto/Makefile src/Makefile src/daemon/Makefile src/collectd.conf src/libcollectdclient/Makefile src/libcollectdclient/libcollectdclient.pc src/liboconfig/Makefile bindings/Makefile bindings/java/Makefile]) +AC_CONFIG_FILES([ \ + Makefile \ + src/collectd.conf \ + src/libcollectdclient/libcollectdclient.pc \ +]) + AC_OUTPUT -if test "x$with_librrd" = "xyes" \ - && test "x$librrd_threadsafe" != "xyes" -then - with_librrd="yes (warning: librrd is not thread-safe)" +if test "x$with_librrd" = "xyes" && test "x$librrd_threadsafe" != "xyes"; then + with_librrd="yes (warning: librrd is not thread-safe)" fi -if test "x$with_libperl" = "xyes" -then - with_libperl="yes (version `$perl_interpreter -MConfig -e 'print $Config{version};'`)" +if test "x$with_libperl" = "xyes"; then + with_libperl="yes (version `$PERL -MConfig -e 'print $Config{version};'`)" else - enable_perl="no (needs libperl)" + enable_perl="no (needs libperl)" fi -if test "x$enable_perl" = "xno" && test "x$c_cv_have_perl_ithreads" = "xno" -then - enable_perl="no (libperl doesn't support ithreads)" +if test "x$enable_perl" = "xno" && test "x$c_cv_have_perl_ithreads" = "xno"; then + enable_perl="no (libperl doesn't support ithreads)" fi -if test "x$with_perl_bindings" = "xyes" \ - && test "x$PERL_BINDINGS_OPTIONS" != "x" -then - with_perl_bindings="yes ($PERL_BINDINGS_OPTIONS)" +if test "x$with_perl_bindings" = "xyes" && test "x$PERL_BINDINGS_OPTIONS" != "x"; then + with_perl_bindings="yes ($PERL_BINDINGS_OPTIONS)" fi AC_MSG_RESULT() @@ -6750,7 +6663,6 @@ AC_MSG_RESULT([ libganglia . . . . . $with_libganglia]) AC_MSG_RESULT([ libgcrypt . . . . . . $with_libgcrypt]) AC_MSG_RESULT([ libgps . . . . . . . $with_libgps]) AC_MSG_RESULT([ libgrpc++ . . . . . . $with_libgrpcpp]) -AC_MSG_RESULT([ libhal . . . . . . . $with_libhal]) AC_MSG_RESULT([ libhiredis . . . . . $with_libhiredis]) AC_MSG_RESULT([ libi2c-dev . . . . . $with_libi2c]) AC_MSG_RESULT([ libiokit . . . . . . $with_libiokit]) @@ -6771,7 +6683,6 @@ AC_MSG_RESULT([ libmysql . . . . . . $with_libmysql]) AC_MSG_RESULT([ libnetapp . . . . . . $with_libnetapp]) AC_MSG_RESULT([ libnetsnmp . . . . . $with_libnetsnmp]) AC_MSG_RESULT([ libnotify . . . . . . $with_libnotify]) -AC_MSG_RESULT([ liboconfig . . . . . $with_liboconfig]) AC_MSG_RESULT([ libopenipmi . . . . . $with_libopenipmipthread]) AC_MSG_RESULT([ liboping . . . . . . $with_liboping]) AC_MSG_RESULT([ libowcapi . . . . . . $with_libowcapi]) @@ -6838,6 +6749,7 @@ AC_MSG_RESULT([ dbi . . . . . . . . . $enable_dbi]) AC_MSG_RESULT([ df . . . . . . . . . $enable_df]) AC_MSG_RESULT([ disk . . . . . . . . $enable_disk]) AC_MSG_RESULT([ dns . . . . . . . . . $enable_dns]) +AC_MSG_RESULT([ dpdkevents. . . . . . $enable_dpdkevents]) AC_MSG_RESULT([ dpdkstat . . . . . . $enable_dpdkstat]) AC_MSG_RESULT([ drbd . . . . . . . . $enable_drbd]) AC_MSG_RESULT([ email . . . . . . . . $enable_email]) @@ -6852,7 +6764,7 @@ AC_MSG_RESULT([ gps . . . . . . . . . $enable_gps]) AC_MSG_RESULT([ grpc . . . . . . . . $enable_grpc]) AC_MSG_RESULT([ hddtemp . . . . . . . $enable_hddtemp]) AC_MSG_RESULT([ hugepages . . . . . . $enable_hugepages]) -AC_MSG_RESULT([ intel_rdt. . . . . . $enable_intel_rdt]) +AC_MSG_RESULT([ intel_rdt . . . . . . $enable_intel_rdt]) AC_MSG_RESULT([ interface . . . . . . $enable_interface]) AC_MSG_RESULT([ ipc . . . . . . . . . $enable_ipc]) AC_MSG_RESULT([ ipmi . . . . . . . . $enable_ipmi]) @@ -6873,6 +6785,7 @@ AC_MSG_RESULT([ match_regex . . . . . $enable_match_regex]) AC_MSG_RESULT([ match_timediff . . . $enable_match_timediff]) AC_MSG_RESULT([ match_value . . . . . $enable_match_value]) AC_MSG_RESULT([ mbmon . . . . . . . . $enable_mbmon]) +AC_MSG_RESULT([ mcelog . . . . . . . $enable_mcelog]) AC_MSG_RESULT([ md . . . . . . . . . $enable_md]) AC_MSG_RESULT([ memcachec . . . . . . $enable_memcachec]) AC_MSG_RESULT([ memcached . . . . . . $enable_memcached]) @@ -6898,6 +6811,8 @@ AC_MSG_RESULT([ onewire . . . . . . . $enable_onewire]) AC_MSG_RESULT([ openldap . . . . . . $enable_openldap]) AC_MSG_RESULT([ openvpn . . . . . . . $enable_openvpn]) AC_MSG_RESULT([ oracle . . . . . . . $enable_oracle]) +AC_MSG_RESULT([ ovs_events . . . . . $enable_ovs_events]) +AC_MSG_RESULT([ ovs_stats . . . . . . $enable_ovs_stats]) AC_MSG_RESULT([ perl . . . . . . . . $enable_perl]) AC_MSG_RESULT([ pf . . . . . . . . . $enable_pf]) AC_MSG_RESULT([ pinba . . . . . . . . $enable_pinba]) @@ -6962,11 +6877,11 @@ AC_MSG_RESULT([ zookeeper . . . . . . $enable_zookeeper]) AC_MSG_RESULT() if test "x$dependency_error" = "xyes"; then - AC_MSG_ERROR("Some plugins are missing dependencies - see the summary above for details") + AC_MSG_ERROR("Some plugins are missing dependencies - see the summary above for details") fi if test "x$dependency_warning" = "xyes"; then - AC_MSG_WARN("Some plugins seem to have missing dependencies but have been enabled forcibly - see the summary above for details") + AC_MSG_WARN("Some plugins seem to have missing dependencies but have been enabled forcibly - see the summary above for details") fi -# vim: set fdm=marker : +# vim: set fdm=marker sw=2 sts=2 ts=2 et : diff --git a/contrib/README b/contrib/README index 5f401f09..6e2ea19e 100644 --- a/contrib/README +++ b/contrib/README @@ -49,6 +49,21 @@ should look something like this: datadir: "/var/lib/collectd/rrd/" libdir: "/usr/lib/collectd/" +docker/ +------- +Sample docker setup using an LD_PRELOAD wrapper to redirect system calls +accessing /proc and /sys to prefixed bind-mounts inside the container. + +Drop your collectd configuration snippets in the +contrib/docker/collectd.conf.d/ directory, and build an image including them: + $ docker build -t my_collectd ./contrib/docker/ + +Then run it with the required bind-mounts: + $ docker run -it --rm \ + -v /proc:/rootfs/proc:ro -v /sys:/rootfs/sys:ro \ + --name collectd my_collectd + $ docker exec -it collectd collectdctl listval + exec-munin.px ------------- Script to be used with the exec-plugin (see collectd-exec(5) for details) diff --git a/contrib/docker/50docker-apt-conf b/contrib/docker/50docker-apt-conf new file mode 100644 index 00000000..3f898b3b --- /dev/null +++ b/contrib/docker/50docker-apt-conf @@ -0,0 +1,4 @@ +APT::Install-Recommends "0"; +APT::Install-Suggests "0"; +APT::Get::Assume-Yes "1"; +APT::Get::AutomaticRemove "1"; diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile new file mode 100644 index 00000000..a691f2e6 --- /dev/null +++ b/contrib/docker/Dockerfile @@ -0,0 +1,24 @@ +FROM debian:stable + +ENV DEBIAN_FRONTEND noninteractive +COPY 50docker-apt-conf /etc/apt/apt.conf.d/ + +COPY rootfs_prefix/ /usr/src/rootfs_prefix/ + +RUN apt-get update \ + && apt-get upgrade \ + && apt-get install \ + collectd-core \ + collectd-utils \ + build-essential \ + && make -C /usr/src/rootfs_prefix/ \ + && apt-get --purge remove build-essential \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +COPY collectd.conf /etc/collectd/collectd.conf +COPY collectd.conf.d /etc/collectd/collectd.conf.d + +ENV LD_PRELOAD /usr/src/rootfs_prefix/rootfs_prefix.so + +CMD [ "/usr/sbin/collectd", "-f"] diff --git a/contrib/docker/collectd.conf b/contrib/docker/collectd.conf new file mode 100644 index 00000000..bbcd0791 --- /dev/null +++ b/contrib/docker/collectd.conf @@ -0,0 +1,16 @@ +LoadPlugin logfile + + LogLevel "info" + File STDOUT + Timestamp true + PrintSeverity true + + +LoadPlugin unixsock + + SocketGroup "nogroup" + + + + Filter "*.conf" + diff --git a/contrib/docker/collectd.conf.d/sample.conf b/contrib/docker/collectd.conf.d/sample.conf new file mode 100644 index 00000000..cbd7ce15 --- /dev/null +++ b/contrib/docker/collectd.conf.d/sample.conf @@ -0,0 +1,4 @@ +LoadPlugin cpu +LoadPlugin memory +LoadPlugin disk +LoadPlugin df diff --git a/contrib/docker/rootfs_prefix/.gitignore b/contrib/docker/rootfs_prefix/.gitignore new file mode 100644 index 00000000..c95ccf81 --- /dev/null +++ b/contrib/docker/rootfs_prefix/.gitignore @@ -0,0 +1 @@ +rootprefix.so diff --git a/contrib/docker/rootfs_prefix/Makefile b/contrib/docker/rootfs_prefix/Makefile new file mode 100644 index 00000000..f26bebd0 --- /dev/null +++ b/contrib/docker/rootfs_prefix/Makefile @@ -0,0 +1,2 @@ +rootfs_prefix.so: rootfs_prefix.c + $(CC) -Wall -Werror -fPIC -shared -o rootfs_prefix.so rootfs_prefix.c -ldl diff --git a/contrib/docker/rootfs_prefix/rootfs_prefix.c b/contrib/docker/rootfs_prefix/rootfs_prefix.c new file mode 100644 index 00000000..2b831518 --- /dev/null +++ b/contrib/docker/rootfs_prefix/rootfs_prefix.c @@ -0,0 +1,58 @@ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include + +#define PREFIX "/rootfs" +#define BUFSIZE 256 + +const char *add_prefix(const char *orig, char *prefixed) { + if ((strncmp(orig, "/proc", strlen("/proc")) != 0) && + (strncmp(orig, "/sys", strlen("/sys")) != 0)) + return orig; + + int status = snprintf(prefixed, BUFSIZE, "%s%s", PREFIX, orig); + if (status < 1) { + error(status, errno, "adding '%s' prefix to file path failed: '%s' -> '%s'", + PREFIX, orig, prefixed); + return orig; + } else if ((unsigned int)status >= BUFSIZE) { + error(status, ENAMETOOLONG, + "'%s' got truncated when adding '%s' prefix: '%s'", orig, PREFIX, + prefixed); + return orig; + } else { + return (const char *)prefixed; + } +} + +FILE *fopen(const char *path, const char *mode) { + char filename[BUFSIZE] = "\0"; + + FILE *(*original_fopen)(const char *, const char *); + original_fopen = dlsym(RTLD_NEXT, "fopen"); + + return (*original_fopen)(add_prefix(path, filename), mode); +} + +DIR *opendir(const char *name) { + char filename[BUFSIZE] = "\0"; + + DIR *(*original_opendir)(const char *); + original_opendir = dlsym(RTLD_NEXT, "opendir"); + + return (*original_opendir)(add_prefix(name, filename)); +} + +int *open(const char *pathname, int flags) { + char filename[BUFSIZE] = "\0"; + + int *(*original_open)(const char *, int); + original_open = dlsym(RTLD_NEXT, "open"); + + return (*original_open)(add_prefix(pathname, filename), flags); +} diff --git a/contrib/redhat/collectd.spec b/contrib/redhat/collectd.spec index 1cf2e31c..bceaaf8e 100644 --- a/contrib/redhat/collectd.spec +++ b/contrib/redhat/collectd.spec @@ -88,6 +88,7 @@ %define with_lvm 0%{!?_without_lvm:1} %define with_madwifi 0%{!?_without_madwifi:1} %define with_mbmon 0%{!?_without_mbmon:1} +%define with_mcelog 0%{!?_without_mcelog:1} %define with_md 0%{!?_without_md:1} %define with_memcachec 0%{!?_without_memcachec:1} %define with_memcached 0%{!?_without_memcached:1} @@ -109,6 +110,8 @@ %define with_olsrd 0%{!?_without_olsrd:1} %define with_openldap 0%{!?_without_openldap:1} %define with_openvpn 0%{!?_without_openvpn:1} +%define with_ovs_events 0%{!?_without_ovs_events:1} +%define with_ovs_stats 0%{!?_without_ovs_stats:1} %define with_perl 0%{!?_without_perl:1} %define with_pinba 0%{!?_without_pinba:1} %define with_ping 0%{!?_without_ping:1} @@ -166,10 +169,12 @@ %define with_aquaero 0%{!?_without_aquaero:0} # plugin barometer disabled, requires a libi2c %define with_barometer 0%{!?_without_barometer:0} -# plugin grpc disabled, requires protobuf-compiler >= 3.0 -%define with_grpc 0%{!?_without_grpc:0} +# plugin dpdkevents disabled, requires libdpdk +%define with_dpdkevents 0%{!?_without_dpdkevents:0} # plugin dpdkstat disabled, requires libdpdk %define with_dpdkstat 0%{!?_without_dpdkstat:0} +# plugin grpc disabled, requires protobuf-compiler >= 3.0 +%define with_grpc 0%{!?_without_grpc:0} # plugin lpar disabled, requires AIX %define with_lpar 0%{!?_without_lpar:0} # plugin intel_rdt disabled, requires intel-cmt-cat @@ -227,6 +232,8 @@ %define with_cpusleep 0 %define with_gps 0 %define with_mqtt 0 +%define with_ovs_events 0 +%define with_ovs_stats 0 %define with_redis 0 %define with_rrdcached 0 %define with_write_redis 0 @@ -237,13 +244,13 @@ Summary: Statistics collection and monitoring daemon Name: collectd Version: 5.7.1 -Release: 3%{?dist} +Release: 6%{?dist} URL: https://collectd.org Source: https://collectd.org/files/%{name}-%{version}.tar.bz2 License: GPLv2 Group: System Environment/Daemons BuildRoot: %{_tmppath}/%{name}-%{version}-root -BuildRequires: libgcrypt-devel, kernel-headers, libtool-ltdl-devel, libcap-devel, which +BuildRequires: libgcrypt-devel, kernel-headers, libcap-devel, which Vendor: collectd development team %if 0%{?fedora} || 0%{?rhel} >= 7 @@ -540,6 +547,16 @@ This plugin collects size of “Logical Volumes” (LV) and “Volume Groups” of Linux' “Logical Volume Manager” (LVM). %endif +%if %{with_mcelog} +%package mcelog +Summary: Mcelog plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +%description mcelog +This plugin monitors machine check exceptions reported by mcelog and generates +appropriate notifications when machine check exceptions are detected. +%endif + %if %{with_memcachec} %package memcachec Summary: Memcachec plugin for collectd @@ -655,6 +672,29 @@ BuildRequires: openldap-devel This plugin reads monitoring information from OpenLDAP's cn=Monitor subtree. %endif +%if %{with_ovs_events} +%package ovs_events +Summary: Open vSwitch events plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +BuildRequires: yajl-devel +%description ovs_events +This plugin monitors the link status of Open vSwitch (OVS) connected +interfaces, dispatches the values to collectd and sends notifications +whenever a link state change occurs in the OVS database. +%endif + +%if %{with_ovs_stats} +%package ovs_stats +Summary: Open vSwitch statistics plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +BuildRequires: yajl-devel +%description ovs_stats +This plugin collects statictics of OVS connected bridges and +interfaces. +%endif + %if %{with_perl} %package perl Summary: Perl plugin for collectd @@ -1101,6 +1141,12 @@ Collectd utilities %define _with_drbd --disable-drbd %endif +%if %{with_dpdkevents} +%define _with_dpdkevents --enable-dpdkevents +%else +%define _with_dpdkevents --disable-dpdkevents +%endif + %if %{with_dpdkstat} %define _with_dpdkstat --enable-dpdkstat %else @@ -1281,6 +1327,12 @@ Collectd utilities %define _with_mbmon --disable-mbmon %endif +%if %{with_mcelog} +%define _with_mcelog --enable-mcelog +%else +%define _with_mbmon --disable-mcelog +%endif + %if %{with_md} %define _with_md --enable-md %else @@ -1431,6 +1483,18 @@ Collectd utilities %define _with_oracle --disable-oracle %endif +%if %{with_ovs_events} +%define _with_ovs_events --enable-ovs_events +%else +%define _with_ovs_events --disable-ovs_events +%endif + +%if %{with_ovs_stats} +%define _with_ovs_stats --enable-ovs_stats +%else +%define _with_ovs_stats --disable-ovs_stats +%endif + %if %{with_perl} %define _with_perl --enable-perl --with-perl-bindings="INSTALLDIRS=vendor" %else @@ -1769,7 +1833,6 @@ Collectd utilities %configure CFLAGS="%{optflags} -DLT_LAZY_OR_NOW=\"RTLD_LAZY|RTLD_GLOBAL\"" \ %{?_python_config} \ --disable-static \ - --without-included-ltdl \ --enable-all-plugins=yes \ --enable-match_empty_counter \ --enable-match_hashed \ @@ -1808,6 +1871,7 @@ Collectd utilities %{?_with_disk} \ %{?_with_dns} \ %{?_with_drbd} \ + %{?_with_dpdkevents} \ %{?_with_dpdkstat} \ %{?_with_email} \ %{?_with_entropy} \ @@ -1837,6 +1901,7 @@ Collectd utilities %{?_with_lvm} \ %{?_with_madwifi} \ %{?_with_mbmon} \ + %{?_with_mcelog} \ %{?_with_md} \ %{?_with_memcachec} \ %{?_with_memcached} \ @@ -1862,6 +1927,8 @@ Collectd utilities %{?_with_openldap} \ %{?_with_openvpn} \ %{?_with_oracle} \ + %{?_with_ovs_events} \ + %{?_with_ovs_stats} \ %{?_with_perl} \ %{?_with_pf} \ %{?_with_pinba} \ @@ -2088,9 +2155,6 @@ fi %if %{with_drbd} %{_libdir}/%{name}/drbd.so %endif -%if %{with_dpdkstat} -%{_libdir}/%{name}/dpdkstat.so -%endif %if %{with_ethstat} %{_libdir}/%{name}/ethstat.so %endif @@ -2136,6 +2200,9 @@ fi %if %{with_mbmon} %{_libdir}/%{name}/mbmon.so %endif +%if %{with_mcelog} +%{_libdir}/%{name}/mcelog.so +%endif %if %{with_md} %{_libdir}/%{name}/md.so %endif @@ -2346,6 +2413,16 @@ fi %{_libdir}/%{name}/dbi.so %endif +%if %{with_dpdkevents} +%files dpdkevents +%{_libdir}/%{name}/dpdkevents.so +%endif + +%if %{with_dpdkstat} +%files dpdkstat +%{_libdir}/%{name}/dpdkstat.so +%endif + %if %{with_email} %files email %{_libdir}/%{name}/email.so @@ -2470,6 +2547,16 @@ fi %{_libdir}/%{name}/openldap.so %endif +%if %{with_ovs_events} +%files ovs_events +%{_libdir}/%{name}/ovs_events.so +%endif + +%if %{with_ovs_stats} +%files ovs_stats +%{_libdir}/%{name}/ovs_stats.so +%endif + %if %{with_perl} %files perl %{perl_vendorlib}/Collectd.pm @@ -2589,9 +2676,18 @@ fi %doc contrib/ %changelog -* Sun Mar 05 2017 Ruben Kerkhof - 5.7.1-2 +* Sun Mar 05 2017 Ruben Kerkhof - 5.7.1-6 +- Move recently added plugins to subpackages + +* Sun Mar 05 2017 Ruben Kerkhof - 5.7.1-5 +- Add new ovs_stats plugin + +* Sun Mar 05 2017 Ruben Kerkhof - 5.7.1-4 - Don't enable XFS support on RHEL6, it is missing for i386 +* Sun Mar 05 2017 Ruben Kerkhof - 5.7.1-3 +- Add dpdkevents plugin, disabled by default + * Wed Feb 22 2017 Ruben Kerkhof - 5.7.1-2 - Enable XFS support in df plugin - Fix bogus date in changelog @@ -2599,6 +2695,12 @@ fi * Sun Jan 01 2017 Marc Fournier - 5.7.1-1 - New upstream version +* Sat Dec 31 2016 Ruben Kerkhof - 5.7.0-4 +- Add new ovs_events plugin + +* Sat Dec 31 2016 Ruben Kerkhof - 5.7.0-3 +- Add new mcelog plugin + * Tue Nov 29 2016 Ruben Kerkhof - 5.7.0-2 - Disable redis plugin on RHEL 6, hiredis has been retired from EPEL6 diff --git a/contrib/systemd.collectd.service b/contrib/systemd.collectd.service index 7bc15d7c..4e2f6ae4 100644 --- a/contrib/systemd.collectd.service +++ b/contrib/systemd.collectd.service @@ -18,6 +18,7 @@ ProtectHome=true # ceph CAP_DAC_OVERRIDE # dns CAP_NET_RAW # exec CAP_SETUID CAP_SETGID +# intel_rdt CAP_SYS_RAWIO # iptables CAP_NET_ADMIN # ping CAP_NET_RAW # smart CAP_SYS_RAWIO diff --git a/docs/BUILD.dpdkstat.md b/docs/BUILD.dpdkstat.md index 8991a615..96f1eb95 100644 --- a/docs/BUILD.dpdkstat.md +++ b/docs/BUILD.dpdkstat.md @@ -148,34 +148,6 @@ instruction set manually: * Run `ldconfig` to update the shared library cache. -### Static library - -To build static DPDK library for use with collectd: - - * To configure DPDK to build the combined static library `libdpdk.a` ensure - that `CONFIG_RTE_BUILD_SHARED_LIB` is set to “n” in `config/common_base` in - your DPDK as follows: - - # - # Compile to share library - # - CONFIG_RTE_BUILD_SHARED_LIB=n - - * Prepare the configuration for the appropriate target as specified at: - http://dpdk.org/doc/guides/linux_gsg/build_dpdk.html. - - For example: - - make config T=x86_64-native-linuxapp-gcc - - * Build the target using `-fPIC`: - - make EXTRA_CFLAGS=-fPIC -j - - * Install DPDK to `/usr`: - - sudo make install prefix=/usr - ## Build collectd with DPDK **Note:** DPDK 16.04 is the minimum version and currently supported version of @@ -199,33 +171,32 @@ implications. See also: http://dpdk.org/doc/guides/prog_guide/multi_proc_support.html * Generate the build script as specified below. (i.e. run `build.sh`). - * Configure collectd with the DPDK shared library: - - ./configure --with-libdpdk=/usr + * Configure collectd with the DPDK shared library. If DPDK is installed in + custom installation path you can specify headers include path using + LIBDPDK_CPPFLAGS variable and libraries path with LIBDPDK_LDFLAGS. + Example: -### Build with the static DPDK library + ./configure -To configure collectd with the DPDK static library: + or for custom DPKD installation: - * Run *configure* with the following CFLAGS: + ./configure LIBDPDK_CPPFLAGS="-I/home/joe/include/dpdk" LIBDPDK_LDFLAGS="-L/home/joe/usr/lib" - ./configure --with-libdpdk=/usr CFLAGS=" -lpthread -Wl,--whole-archive -Wl,-ldpdk -Wl,-lm -Wl,-lrt -Wl,-lpcap -Wl,-ldl -Wl,--no-whole-archive" - - * Make sure that dpdk and dpdkstat are enabled in the *configure* output. + * Make sure that libdpdk and dpdkstat are enabled in the *configure* output. Expected output: Libraries: ... libdpdk . . . . . . . . yes - + Modules: ... dpdkstat . . . . . . .yes * Build collectd: - make -j && make -j install. + make -j && make -j install **Note:** As mentioned above, if you are building on Ubuntu 14.04 with GCC <= 4.8.X, you need to use: @@ -237,6 +208,12 @@ To configure collectd with the DPDK static library: * The same PCI device configuration should be passed to the primary process as the secondary process uses the same port indexes as the primary. * A blacklist / whitelist of NICs isn't supported yet. + * Plugin initialization time depends on read interval. It requires 5 read + cycles to set up internal buffers and states. During that time no statistics + are submitted. + * If number of DPDK ports is increased while plugin is running, internal + buffers are resized. That requires 3 read cycles and no port statistics + are submitted in that time. ## License diff --git a/docs/README.virt.md b/docs/README.virt.md new file mode 100644 index 00000000..a80e9eac --- /dev/null +++ b/docs/README.virt.md @@ -0,0 +1,240 @@ +Inside the virt plugin +====================== + +Originally written: 20161111 + +Last updated: 20161124 + +This document will explain the new domain tag support introduced +in the virt plugin, and will provide one important use case for this feature. +In the reminder of this document, we consider + +* libvirt <= 2.0.0 +* QEMU <= 2.6.0 + + +Domain tags and domains partitioning across virt reader instances +----------------------------------------------------------------- + +The virt plugin gained the `Instances` option. It allows to start +more than one reader instance, so the the libvirt domains could be queried +by more than one reader thread. +The default value for `Instances` is `1`. +With default settings, the plugin will behave in a fully transparent, +backward compatible way. +It is recommended to set this value to one multiple of the +daemon `ReadThreads` value. + +Each reader instance will query only a subset of the libvirt domain. +The subset is identified as follows: + +1. Each virt reader instance is named `virt-$NUM`, where `NUM` is + the progressive order of instances. If you configure `Instances 3` + you will have `virt-0`, `virt-1`, `virt-2`. Please note: the `virt-0` + instance is special, and will always be available. +2. Each virt reader instance will iterate over all the libvirt active domains, + and will look for one `tag` attribute (see below) in the domain metadata section. +3. Each virt reader instance will take care *only* of the libvirt domains whose + tag matches with its own +4. The special `virt-0` instance will take care of all the libvirt domains with + no tags, or with tags which are not in the set \[virt-0 ... virt-$NUM\] + +Collectd will just use the domain tags, but never enforces or requires them. +It is up to an external entity, like a software management system, +to attach and manage the tags to the domain. + +Please note that unless you have such tag-aware management sofware, +it most likely make no sense to enable more than one reader instance on your +setup. + + +Libvirt tag metadata format +---------------------------- + +This is the snipped to be added to libvirt domains: + + + $TAG + + +it must be included in the section. + +Check the `src/virt_test.c` file for really minimal example of libvirt domains. + + +Examples +-------- + +### Example one: 10 libvirt domains named "domain-A" ... "domain-J", virt plugin with instances=5, using 5 different tags + + + libvirt domain name - tag - read instance - reason + domain-A virt-0 0 tag match + domain-B virt-1 1 tag match + domain-C virt-2 2 tag match + domain-D virt-3 3 tag match + domain-E virt-4 4 tag match + domain-F virt-0 0 tag match + domain-G virt-1 1 tag match + domain-H virt-2 2 tag match + domain-I virt-3 3 tag match + domain-J virt-4 4 tag match + + + Because the domain where properly tagged, all the read instances have even load. Please note that the the virt plugin + knows nothing, and should know nothing, about *how* the libvirt domain are tagged. This is entirely up to the + management system. + + +Example two: 10 libvirt domains named "domain-A" ... "domain-J", virt plugin with instances=3, using 5 different tags + + + libvirt domain name - tag - read instance - reason + domain-A virt-0 0 tag match + domain-B virt-1 1 tag match + domain-C virt-2 2 tag match + domain-D virt-3 0 adopted by instance #0 + domain-E virt-4 0 adopted by instance #0 + domain-F virt-0 0 rag match + domain-G virt-1 1 tag match + domain-H virt-2 2 tag match + domain-I virt-3 0 adopted by instance #0 + domain-J virt-4 0 adopted by instance #0 + + + In this case we have uneven load, but no domain is ignored. + + +### Example three: 10 libvirt domains named "domain-A" ... "domain-J", virt plugin with instances=5, using 3 different tags + + + libvirt domain name - tag - read instance - reason + domain-A virt-0 0 tag match + domain-B virt-1 1 tag match + domain-C virt-2 2 tag match + domain-D virt-0 0 tag match + domain-E virt-1 1 tag match + domain-F virt-2 2 tag match + domain-G virt-0 0 tag match + domain-H virt-1 1 tag match + domain-I virt-2 2 tag match + domain-J virt-0 0 tag match + + + Once again we have uneven load and two idle read instances, but besides that no domain is left unmonitored + + +### Example four: 10 libvirt domains named "domain-A" ... "domain-J", virt plugin with instances=5, partial tagging + + + libvirt domain name - tag - read instance - reason + domain-A virt-0 0 tag match + domain-B virt-1 1 tag match + domain-C virt-2 2 tag match + domain-D virt-0 0 tag match + domain-E 0 adopted by instance #0 + domain-F 0 adopted by instance #0 + domain-G 0 adopted by instance #0 + domain-H 0 adopted by instance #0 + domain-I 0 adopted by instance #0 + domain-J 0 adopted by instance #0 + + +The lack of tags causes uneven load, but no domain are unmonitored. + + +Possible extensions - custom tag format +--------------------------------------- + +The aformentioned approach relies on fixed tag format, `virt-$N`. The algorithm works fine with any tag, which +is just one string, compared for equality. However, using custom strings for tags creates the need for a mapping +between tags and the read instances. +This mapping needs to be updated as long as domain are created or destroyed, and the virt plugin needs to be +notified of the changes. + +This adds a significant amount of complexity, with little gain with respect to the fixed schema adopted initially. +For this reason, the introdution of dynamic, custom mapping was not implemented. + + +Dealing with datacenters: libvirt, qemu, shared storage +------------------------------------------------------- + +When used in a datacenter, QEMU is most often configured to use shared storage. This is +the default configuration of datacenter management solutions like [oVirt](http://www.ovirt.org). +The actual shared storage could be implemented on top of NFS for small installations, or most likely +ISCSI or Fiber Channel. The key takeaway is that the storage is accessed over the network, +not using e.g. the SATA or PCI bus of any given host, so any network issue could cause +one or more storage operations to delay, or to be lost entirely. + +In that case, the userspace process that requested the operation can end up in the D state, +and become unresponsive, and unkillable. + + +Dealing with unresponsive domains +--------------------------------- + +All the above considered, one robust management or monitoring application must deal with the fact that +the libvirt API can block for a long time, or forever. This is not an issue or a bug of one specific +API, but it is rather a byproduct of how libvirt and QEMU interact. + +Whenever we query more than one VM, we should take care to avoid that one blocked VM prevent other, +well behaving VMs to be queried. We don't want one rogue VM to disrupt well-behaving VMs. +Unfortunately, any way we enumerate VMs, either implicitely, using the libvirt bulk stats API, +or explicitely, listing all libvirt domains and query each one in turn, we may unpredictably encounter +one unresponsive VM. + +There are many possible approaches to deal with this issue. The virt plugin supports +a simple but effective approach partitioning the domains, as follows. + +1. The virt plugin always register one or more `read` callbacks. The `zero` read callback is guaranteed to + be always present, so it performs special duties (more details later) + Each callback will be named 'virt-$N', where `N` ranges from 0 (zero) to M-1, where M is the number of instances configured. + `M` equals to `5` by default, because this is the same default number of threads in the libvirt worker pool. +2. Each of the read callbacks queries libvirt for the list of all the active domains, and retrieves the libvirt domain metadata. + Both of those operations are safe wrt domain blocked in I/O (they affect only the libvirtd daemon). +3. Each of the read callbacks extracts the `tag` from the domain metadata using a well-known format (see below). + Each of the read callbacks discards any domain which has no tag, or whose tag doesn't match with the read callback tag. +3.a. The read callback tag equals to the read callback name, thus `virt-$N`. Remember that `virt-0` is guaranteed to be + always present. +3.b. Since the `virt-0` reader is always present, it will take care of domains with no tag, or with unrecognized tag. + One unrecognized tag is any tag which has not the scheme `virt-$N`. +4. Each read callback only samples the subset of domains with matching tag. The `virt-0` reader will possibly do more, + but worst case the load will be unbalanced, no domain will be left unsampled. + +To make this approach work, some entity must attach the tags to the libvirt domains, in such a way that all +the domains which run on a given host and insist on the same network-based storage share the same tag. +This minimizes the disruption, because when using the shared storage, if one domain becomes unresponsive because +of unavailable storage, the most likely thing to happen is that others domain using the same storage will soon become +unavailable; should the box run other libvirt domains using other network-based storage, they could be monitored +safely. + +In case of [oVirt](http://www.ovirt.org), the aforementioned tagging is performed by the host agent. + +Please note that this approach is ineffective if the host completely lose network access to the storage network. +In this case, however, no recovery is possible and no damage limitation is possible. + +Lastly, please note that if the virt plugin is configured with instances=1, it behaves exactly like before. + + +Addendum: high level overview: libvirt client, libvirt daemon, qemu +-------------------------------------------------------------------- + +Let's review how the client application (collectd + virt plugin), the libvirtd daemon and the +QEMU processes interact with each other. + +The libvirt daemon talks to QEMU using the JSON QMP protcol over one unix domain socket. +The details of the protocol are not important now, but the key part is that the protocol +is a simple request/response, meaning that libvirtd must serialize all the interactions +with the QEMU monitor, and must protects its endpoint with a lock. +No out of order request/responses are possible (e.g. no pipelining or async replies). +This means that if for any reason one QMP request could not be completed, any other caller +trying to access the QEMU monitor will block until the blocked caller returns. + +To retrieve some key informations, most notably about the block device state or the balloon +device state, the libvirtd daemon *must* use the QMP protocol. + +The QEMU core, including the handling of the QMP protocol, is single-threaded. +All the above combined make it possible for a client to block forever waiting for one QMP +request, if QEMU itself is blocked. The most likely cause of block is I/O, and this is especially +true considering how QEMU is used in a datacenter. + diff --git a/m4/.gitignore b/m4/.gitignore new file mode 100644 index 00000000..f935021a --- /dev/null +++ b/m4/.gitignore @@ -0,0 +1 @@ +!.gitignore diff --git a/proto/Makefile.am b/proto/Makefile.am deleted file mode 100644 index 62d3bed5..00000000 --- a/proto/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -EXTRA_DIST = collectd.proto types.proto prometheus.proto diff --git a/src/Makefile.am b/src/Makefile.am deleted file mode 100644 index 11bc17d9..00000000 --- a/src/Makefile.am +++ /dev/null @@ -1,1521 +0,0 @@ -SUBDIRS = libcollectdclient -if BUILD_WITH_OWN_LIBOCONFIG -SUBDIRS += liboconfig -endif -SUBDIRS += daemon - -PLUGIN_LDFLAGS = -module -avoid-version -export-symbols-regex '\' - -AM_CPPFLAGS = -I$(srcdir)/daemon -AM_CPPFLAGS += -DPREFIX='"${prefix}"' -AM_CPPFLAGS += -DCONFIGFILE='"${sysconfdir}/${PACKAGE_NAME}.conf"' -AM_CPPFLAGS += -DLOCALSTATEDIR='"${localstatedir}"' -AM_CPPFLAGS += -DPKGLOCALSTATEDIR='"${localstatedir}/lib/${PACKAGE_NAME}"' -if BUILD_FEATURE_DAEMON -AM_CPPFLAGS += -DPIDFILE='"${localstatedir}/run/${PACKAGE_NAME}.pid"' -endif -AM_CPPFLAGS += -DPLUGINDIR='"${pkglibdir}"' -AM_CPPFLAGS += -DPKGDATADIR='"${pkgdatadir}"' - -LOG_COMPILER = env VALGRIND="@VALGRIND@" $(abs_top_srcdir)/testwrapper.sh - -V_PROTOC = $(v_protoc_@AM_V@) -v_protoc_ = $(v_protoc_@AM_DEFAULT_V@) -v_protoc_0 = @echo " PROTOC " $@; - -noinst_LTLIBRARIES = -check_PROGRAMS = -TESTS = - -noinst_LTLIBRARIES += libformat_graphite.la -libformat_graphite_la_SOURCES = utils_format_graphite.c utils_format_graphite.h -libformat_graphite_la_CPPFLAGS = $(AM_CPPFLAGS) -libformat_graphite_la_LDFLAGS = $(AM_LDFLAGS) -check_PROGRAMS += test_format_graphite -TESTS += test_format_graphite -test_format_graphite_SOURCES = utils_format_graphite_test.c testing.h -test_format_graphite_LDADD = libformat_graphite.la daemon/libmetadata.la daemon/libplugin_mock.la -lm - -noinst_LTLIBRARIES += libformat_json.la -libformat_json_la_SOURCES = utils_format_json.c utils_format_json.h -libformat_json_la_CPPFLAGS = $(AM_CPPFLAGS) -libformat_json_la_LDFLAGS = $(AM_LDFLAGS) -libformat_json_la_LIBADD = -if BUILD_WITH_LIBYAJL -libformat_json_la_CPPFLAGS += $(BUILD_WITH_LIBYAJL_CPPFLAGS) -libformat_json_la_LDFLAGS += $(BUILD_WITH_LIBYAJL_LDFLAGS) -libformat_json_la_LIBADD += $(BUILD_WITH_LIBYAJL_LIBS) -check_PROGRAMS += test_format_json -TESTS += test_format_json -test_format_json_SOURCES = utils_format_json_test.c testing.h -test_format_json_LDADD = libformat_json.la daemon/libmetadata.la daemon/libplugin_mock.la -lm -endif - -noinst_LTLIBRARIES += liblatency.la -liblatency_la_SOURCES = utils_latency.c utils_latency.h utils_latency_config.c utils_latency_config.h -liblatency_la_LIBADD = daemon/libcommon.la -lm -check_PROGRAMS += test_utils_latency -TESTS += test_utils_latency -test_utils_latency_SOURCES = utils_latency_test.c testing.h -test_utils_latency_LDADD = liblatency.la daemon/libplugin_mock.la -lm - -noinst_LTLIBRARIES += libcmds.la -libcmds_la_SOURCES = utils_cmds.c utils_cmds.h \ - utils_cmd_flush.c utils_cmd_flush.h \ - utils_cmd_getthreshold.c utils_cmd_getthreshold.h \ - utils_cmd_getval.c utils_cmd_getval.h \ - utils_cmd_listval.c utils_cmd_listval.h \ - utils_cmd_putnotif.c utils_cmd_putnotif.h \ - utils_cmd_putval.c utils_cmd_putval.h \ - utils_parse_option.c utils_parse_option.h -libcmds_la_LIBADD = daemon/libcommon.la daemon/libmetadata.la -lm -check_PROGRAMS += test_utils_cmds -TESTS += test_utils_cmds -test_utils_cmds_SOURCES = utils_cmds_test.c testing.h -test_utils_cmds_LDADD = libcmds.la \ - daemon/libplugin_mock.la - -noinst_LTLIBRARIES += liblookup.la -liblookup_la_SOURCES = utils_vl_lookup.c utils_vl_lookup.h -liblookup_la_LIBADD = daemon/libavltree.la -check_PROGRAMS += test_utils_vl_lookup -TESTS += test_utils_vl_lookup -test_utils_vl_lookup_SOURCES = utils_vl_lookup_test.c testing.h -test_utils_vl_lookup_LDADD = liblookup.la daemon/libplugin_mock.la -if BUILD_WITH_LIBKSTAT -test_utils_vl_lookup_LDADD += -lkstat -endif - -noinst_LTLIBRARIES += libmount.la -libmount_la_SOURCES = utils_mount.c utils_mount.h -check_PROGRAMS += test_utils_mount -TESTS += test_utils_mount -test_utils_mount_SOURCES = utils_mount_test.c testing.h -test_utils_mount_LDADD = libmount.la daemon/libplugin_mock.la -if BUILD_WITH_LIBKSTAT -test_utils_mount_LDADD += -lkstat -endif - -sbin_PROGRAMS = collectdmon -bin_PROGRAMS = collectd-nagios collectdctl collectd-tg - -collectdmon_SOURCES = collectdmon.c - -collectd_nagios_SOURCES = collectd-nagios.c -collectd_nagios_CPPFLAGS = $(AM_CPPFLAGS) \ - -I$(top_srcdir)/src/libcollectdclient/collectd \ - -I$(top_builddir)/src/libcollectdclient/collectd -collectd_nagios_LDADD = libcollectdclient/libcollectdclient.la -if BUILD_WITH_LIBSOCKET -collectd_nagios_LDADD += -lsocket -endif -if BUILD_AIX -collectd_nagios_LDADD += -lm -endif - - -collectdctl_SOURCES = collectdctl.c -collectdctl_CPPFLAGS = $(AM_CPPFLAGS) \ - -I$(top_srcdir)/src/libcollectdclient/collectd \ - -I$(top_builddir)/src/libcollectdclient/collectd -collectdctl_LDADD = libcollectdclient/libcollectdclient.la -if BUILD_WITH_LIBSOCKET -collectdctl_LDADD += -lsocket -endif -if BUILD_AIX -collectdctl_LDADD += -lm -endif - - -collectd_tg_SOURCES = collectd-tg.c -collectd_tg_CPPFLAGS = $(AM_CPPFLAGS) \ - -I$(top_srcdir)/src/libcollectdclient/collectd \ - -I$(top_builddir)/src/libcollectdclient/collectd -collectd_tg_LDADD = \ - $(PTHREAD_LIBS) \ - daemon/libheap.la \ - libcollectdclient/libcollectdclient.la -if BUILD_WITH_LIBSOCKET -collectd_tg_LDADD += -lsocket -endif -if BUILD_WITH_LIBRT -collectd_tg_LDADD += -lrt -endif -if BUILD_AIX -collectd_tg_LDADD += -lm -endif - - -pkglib_LTLIBRARIES = - -BUILT_SOURCES = -CLEANFILES = - -if HAVE_PROTOC3 -if HAVE_GRPC_CPP -BUILT_SOURCES += collectd.grpc.pb.cc collectd.pb.cc types.pb.cc -CLEANFILES += collectd.grpc.pb.cc collectd.pb.cc types.pb.cc \ - collectd.grpc.pb.h collectd.pb.h types.pb.h - -collectd.grpc.pb.cc: $(top_srcdir)/proto/collectd.proto $(top_srcdir)/proto/types.proto - $(V_PROTOC)@PROTOC@ -I$(top_srcdir)/proto \ - --grpc_out=$(builddir) --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN) $< - -collectd.pb.cc: $(top_srcdir)/proto/collectd.proto $(top_srcdir)/proto/types.proto - $(V_PROTOC)@PROTOC@ -I$(top_srcdir)/proto --cpp_out=$(builddir) $< - -types.pb.cc: $(top_srcdir)/proto/types.proto - $(V_PROTOC)@PROTOC@ -I$(top_srcdir)/proto --cpp_out=$(builddir) $< -endif -endif - -if BUILD_PLUGIN_AGGREGATION -pkglib_LTLIBRARIES += aggregation.la -aggregation_la_SOURCES = aggregation.c \ - utils_vl_lookup.c utils_vl_lookup.h -aggregation_la_LDFLAGS = $(PLUGIN_LDFLAGS) -aggregation_la_LIBADD = -lm -endif - -if BUILD_PLUGIN_AMQP -pkglib_LTLIBRARIES += amqp.la -amqp_la_SOURCES = amqp.c -amqp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRABBITMQ_LDFLAGS) -amqp_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBRABBITMQ_CPPFLAGS) -amqp_la_LIBADD = $(BUILD_WITH_LIBRABBITMQ_LIBS) \ - libcmds.la libformat_graphite.la libformat_json.la -endif - -if BUILD_PLUGIN_APACHE -pkglib_LTLIBRARIES += apache.la -apache_la_SOURCES = apache.c -apache_la_LDFLAGS = $(PLUGIN_LDFLAGS) -apache_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS) -apache_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) -endif - - -if BUILD_PLUGIN_APCUPS -pkglib_LTLIBRARIES += apcups.la -apcups_la_SOURCES = apcups.c -apcups_la_LDFLAGS = $(PLUGIN_LDFLAGS) -apcups_la_LIBADD = -if BUILD_WITH_LIBSOCKET -apcups_la_LIBADD += -lsocket -endif -endif - -if BUILD_PLUGIN_APPLE_SENSORS -pkglib_LTLIBRARIES += apple_sensors.la -apple_sensors_la_SOURCES = apple_sensors.c -apple_sensors_la_LDFLAGS = $(PLUGIN_LDFLAGS) -framework IOKit -endif - -if BUILD_PLUGIN_AQUAERO -pkglib_LTLIBRARIES += aquaero.la -aquaero_la_SOURCES = aquaero.c -aquaero_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBAQUAERO5_CFLAGS) -aquaero_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBAQUAERO5_LDFLAGS) -aquaero_la_LIBADD = -laquaero5 -endif - -if BUILD_PLUGIN_ASCENT -pkglib_LTLIBRARIES += ascent.la -ascent_la_SOURCES = ascent.c -ascent_la_LDFLAGS = $(PLUGIN_LDFLAGS) -ascent_la_CFLAGS = $(AM_CFLAGS) \ - $(BUILD_WITH_LIBCURL_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS) -ascent_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBXML2_LIBS) -endif - -if BUILD_PLUGIN_BAROMETER -pkglib_LTLIBRARIES += barometer.la -barometer_la_SOURCES = barometer.c -barometer_la_LDFLAGS = $(PLUGIN_LDFLAGS) -barometer_la_LIBADD = -lm -endif - -if BUILD_PLUGIN_BATTERY -pkglib_LTLIBRARIES += battery.la -battery_la_SOURCES = battery.c battery_statefs.c -battery_la_LDFLAGS = $(PLUGIN_LDFLAGS) -if BUILD_WITH_LIBIOKIT -battery_la_LDFLAGS += -framework IOKit -endif -endif - -if BUILD_PLUGIN_BIND -pkglib_LTLIBRARIES += bind.la -bind_la_SOURCES = bind.c -bind_la_LDFLAGS = $(PLUGIN_LDFLAGS) -bind_la_CFLAGS = $(AM_CFLAGS) \ - $(BUILD_WITH_LIBCURL_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS) -bind_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBXML2_LIBS) -endif - -if BUILD_PLUGIN_CEPH -pkglib_LTLIBRARIES += ceph.la -ceph_la_SOURCES = ceph.c -ceph_la_CFLAGS = $(AM_CFLAGS) -ceph_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS) -ceph_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS) -ceph_la_LIBADD = $(BUILD_WITH_LIBYAJL_LIBS) -endif - -if BUILD_PLUGIN_CGROUPS -pkglib_LTLIBRARIES += cgroups.la -cgroups_la_SOURCES = cgroups.c -cgroups_la_LDFLAGS = $(PLUGIN_LDFLAGS) -cgroups_la_LIBADD = libmount.la -endif - -if BUILD_PLUGIN_CHRONY -pkglib_LTLIBRARIES += chrony.la -chrony_la_SOURCES = chrony.c -chrony_la_LDFLAGS = $(PLUGIN_LDFLAGS) -chrony_la_LIBADD = -lm -endif - -if BUILD_PLUGIN_CONNTRACK -pkglib_LTLIBRARIES += conntrack.la -conntrack_la_SOURCES = conntrack.c -conntrack_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_CONTEXTSWITCH -pkglib_LTLIBRARIES += contextswitch.la -contextswitch_la_SOURCES = contextswitch.c -contextswitch_la_LDFLAGS = $(PLUGIN_LDFLAGS) -contextswitch_la_LIBADD = -if BUILD_WITH_PERFSTAT -contextswitch_la_LIBADD += -lperfstat -endif -endif - -if BUILD_PLUGIN_CPU -pkglib_LTLIBRARIES += cpu.la -cpu_la_SOURCES = cpu.c -cpu_la_CFLAGS = $(AM_CFLAGS) -cpu_la_LDFLAGS = $(PLUGIN_LDFLAGS) -cpu_la_LIBADD = -if BUILD_WITH_LIBKSTAT -cpu_la_LIBADD += -lkstat -endif -if BUILD_WITH_LIBDEVINFO -cpu_la_LIBADD += -ldevinfo -endif -if BUILD_WITH_LIBSTATGRAB -cpu_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) -cpu_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) -endif -if BUILD_WITH_PERFSTAT -cpu_la_LIBADD += -lperfstat -endif -endif - -if BUILD_PLUGIN_CPUFREQ -pkglib_LTLIBRARIES += cpufreq.la -cpufreq_la_SOURCES = cpufreq.c -cpufreq_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_CPUSLEEP -pkglib_LTLIBRARIES += cpusleep.la -cpusleep_la_SOURCES = cpusleep.c -cpusleep_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_CSV -pkglib_LTLIBRARIES += csv.la -csv_la_SOURCES = csv.c -csv_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_CURL -pkglib_LTLIBRARIES += curl.la -curl_la_SOURCES = curl.c \ - utils_curl_stats.c utils_curl_stats.h \ - utils_match.c utils_match.h -curl_la_LDFLAGS = $(PLUGIN_LDFLAGS) -curl_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS) -curl_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) liblatency.la -endif - -if BUILD_PLUGIN_CURL_JSON -pkglib_LTLIBRARIES += curl_json.la -curl_json_la_SOURCES = curl_json.c \ - utils_curl_stats.c utils_curl_stats.h -curl_json_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS) -curl_json_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS) -curl_json_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS) -curl_json_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBYAJL_LIBS) -endif - -if BUILD_PLUGIN_CURL_XML -pkglib_LTLIBRARIES += curl_xml.la -curl_xml_la_SOURCES = curl_xml.c \ - utils_curl_stats.c utils_curl_stats.h -curl_xml_la_LDFLAGS = $(PLUGIN_LDFLAGS) -curl_xml_la_CFLAGS = $(AM_CFLAGS) \ - $(BUILD_WITH_LIBCURL_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS) -curl_xml_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBXML2_LIBS) -endif - -if BUILD_PLUGIN_DBI -pkglib_LTLIBRARIES += dbi.la -dbi_la_SOURCES = dbi.c \ - utils_db_query.c utils_db_query.h -dbi_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBDBI_CPPFLAGS) -dbi_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBDBI_LDFLAGS) -dbi_la_LIBADD = $(BUILD_WITH_LIBDBI_LIBS) -endif - -if BUILD_PLUGIN_DF -pkglib_LTLIBRARIES += df.la -df_la_SOURCES = df.c -df_la_LDFLAGS = $(PLUGIN_LDFLAGS) -df_la_LIBADD = libmount.la -endif - -if BUILD_PLUGIN_DISK -pkglib_LTLIBRARIES += disk.la -disk_la_SOURCES = disk.c -disk_la_CFLAGS = $(AM_CFLAGS) -disk_la_LDFLAGS = $(PLUGIN_LDFLAGS) -disk_la_LIBADD = -if BUILD_WITH_LIBKSTAT -disk_la_LIBADD += -lkstat -endif -if BUILD_WITH_LIBDEVINFO -disk_la_LIBADD += -ldevinfo -endif -if BUILD_WITH_LIBIOKIT -disk_la_LDFLAGS += -framework IOKit -endif -if BUILD_WITH_LIBSTATGRAB -disk_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) -disk_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) -endif -if BUILD_WITH_LIBUDEV -disk_la_CFLAGS += $(BUILD_WITH_LIBUDEV_CFLAGS) -disk_la_LDFLAGS += $(BUILD_WITH_LIBUDEV_LDFLAGS) -disk_la_LIBADD += $(BUILD_WITH_LIBUDEV_LIBS) -endif -if BUILD_FREEBSD -disk_la_LIBADD += -ldevstat -lgeom -endif -if BUILD_WITH_PERFSTAT -disk_la_LIBADD += -lperfstat -endif -endif - -if BUILD_PLUGIN_DNS -pkglib_LTLIBRARIES += dns.la -dns_la_SOURCES = dns.c utils_dns.c utils_dns.h -dns_la_LDFLAGS = $(PLUGIN_LDFLAGS) -dns_la_LIBADD = -lpcap -endif - -if BUILD_PLUGIN_DPDKSTAT -pkglib_LTLIBRARIES += dpdkstat.la -dpdkstat_la_SOURCES = dpdkstat.c -dpdkstat_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBDPDK_CPPFLAGS) -dpdkstat_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBDPDK_LDFLAGS) -dpdkstat_la_LIBADD = -ldpdk -endif - -if BUILD_PLUGIN_DRBD -pkglib_LTLIBRARIES += drbd.la -drbd_la_SOURCES = drbd.c -drbd_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_EMAIL -pkglib_LTLIBRARIES += email.la -email_la_SOURCES = email.c -email_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_ENTROPY -pkglib_LTLIBRARIES += entropy.la -entropy_la_SOURCES = entropy.c -entropy_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_EXEC -pkglib_LTLIBRARIES += exec.la -exec_la_SOURCES = exec.c -exec_la_LDFLAGS = $(PLUGIN_LDFLAGS) -exec_la_LIBADD = libcmds.la -endif - -if BUILD_PLUGIN_ETHSTAT -pkglib_LTLIBRARIES += ethstat.la -ethstat_la_SOURCES = ethstat.c -ethstat_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_FHCOUNT -pkglib_LTLIBRARIES += fhcount.la -fhcount_la_SOURCES = fhcount.c -fhcount_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_FILECOUNT -pkglib_LTLIBRARIES += filecount.la -filecount_la_SOURCES = filecount.c -filecount_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_GMOND -pkglib_LTLIBRARIES += gmond.la -gmond_la_SOURCES = gmond.c -gmond_la_CPPFLAGS = $(AM_CPPFLAGS) $(GANGLIA_CPPFLAGS) -gmond_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(GANGLIA_LDFLAGS) -gmond_la_LIBADD = $(GANGLIA_LIBS) -endif - -if BUILD_PLUGIN_GPS -pkglib_LTLIBRARIES += gps.la -gps_la_SOURCES = gps.c -gps_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBGPS_CFLAGS) -gps_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBGPS_LDFLAGS) -gps_la_LIBADD = -lpthread $(BUILD_WITH_LIBGPS_LIBS) -endif - -if BUILD_PLUGIN_GRPC -pkglib_LTLIBRARIES += grpc.la -grpc_la_SOURCES = grpc.cc -nodist_grpc_la_SOURCES = collectd.grpc.pb.cc collectd.pb.cc types.pb.cc -grpc_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBGRPCPP_CPPFLAGS) $(BUILD_WITH_LIBPROTOBUF_CPPFLAGS) -grpc_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBGRPCPP_LDFLAGS) $(BUILD_WITH_LIBPROTOBUF_LDFLAGS) -grpc_la_LIBADD = $(BUILD_WITH_LIBGRPCPP_LIBS) $(BUILD_WITH_LIBPROTOBUF_LIBS) -endif - -if BUILD_PLUGIN_HDDTEMP -pkglib_LTLIBRARIES += hddtemp.la -hddtemp_la_SOURCES = hddtemp.c -hddtemp_la_LDFLAGS = $(PLUGIN_LDFLAGS) -hddtemp_la_LIBADD = -if BUILD_WITH_LIBSOCKET -hddtemp_la_LIBADD += -lsocket -endif -endif - -if BUILD_PLUGIN_HUGEPAGES -pkglib_LTLIBRARIES += hugepages.la -hugepages_la_SOURCES = hugepages.c -hugepages_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_INTERFACE -pkglib_LTLIBRARIES += interface.la -interface_la_SOURCES = interface.c -interface_la_CFLAGS = $(AM_CFLAGS) -interface_la_LDFLAGS = $(PLUGIN_LDFLAGS) -interface_la_LIBADD = -if BUILD_WITH_LIBSTATGRAB -interface_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) -interface_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) -else -if BUILD_WITH_LIBKSTAT -interface_la_LIBADD += -lkstat -endif -if BUILD_WITH_LIBDEVINFO -interface_la_LIBADD += -ldevinfo -endif # BUILD_WITH_LIBDEVINFO -endif # !BUILD_WITH_LIBSTATGRAB -if BUILD_WITH_PERFSTAT -interface_la_LIBADD += -lperfstat -endif -endif # BUILD_PLUGIN_INTERFACE - -if BUILD_PLUGIN_IPC -pkglib_LTLIBRARIES += ipc.la -ipc_la_SOURCES = ipc.c -ipc_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_IPTABLES -pkglib_LTLIBRARIES += iptables.la -iptables_la_SOURCES = iptables.c -iptables_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBIPTC_CPPFLAGS) -iptables_la_LDFLAGS = $(PLUGIN_LDFLAGS) -iptables_la_LIBADD = $(BUILD_WITH_LIBIPTC_LDFLAGS) -endif - -if BUILD_PLUGIN_IPMI -pkglib_LTLIBRARIES += ipmi.la -ipmi_la_SOURCES = ipmi.c -ipmi_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_OPENIPMI_CFLAGS) -ipmi_la_LDFLAGS = $(PLUGIN_LDFLAGS) -ipmi_la_LIBADD = $(BUILD_WITH_OPENIPMI_LIBS) -endif - -if BUILD_PLUGIN_IPVS -pkglib_LTLIBRARIES += ipvs.la -ipvs_la_SOURCES = ipvs.c -ipvs_la_CFLAGS = $(AM_CFLAGS) -if IP_VS_H_NEEDS_KERNEL_CFLAGS -ipvs_la_CFLAGS += $(KERNEL_CFLAGS) -endif -ipvs_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_IRQ -pkglib_LTLIBRARIES += irq.la -irq_la_SOURCES = irq.c -irq_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_JAVA -pkglib_LTLIBRARIES += java.la -java_la_SOURCES = java.c -java_la_CPPFLAGS = $(AM_CPPFLAGS) $(JAVA_CPPFLAGS) -java_la_CFLAGS = $(AM_CFLAGS) $(JAVA_CFLAGS) -java_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(JAVA_LDFLAGS) -java_la_LIBADD = $(JAVA_LIBS) -endif - -if BUILD_PLUGIN_LOAD -pkglib_LTLIBRARIES += load.la -load_la_SOURCES = load.c -load_la_CFLAGS = $(AM_CFLAGS) -load_la_LDFLAGS = $(PLUGIN_LDFLAGS) -load_la_LIBADD = -if BUILD_WITH_LIBSTATGRAB -load_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) -load_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) -endif # BUILD_WITH_LIBSTATGRAB -if BUILD_WITH_PERFSTAT -load_la_LIBADD += -lperfstat -endif -endif # BUILD_PLUGIN_LOAD - -if BUILD_PLUGIN_LOGFILE -pkglib_LTLIBRARIES += logfile.la -logfile_la_SOURCES = logfile.c -logfile_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_LOG_LOGSTASH -pkglib_LTLIBRARIES += log_logstash.la -log_logstash_la_SOURCES = log_logstash.c -log_logstash_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS) -log_logstash_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS) -log_logstash_la_LIBADD = $(BUILD_WITH_LIBYAJL_LIBS) -endif - -if BUILD_PLUGIN_LPAR -pkglib_LTLIBRARIES += lpar.la -lpar_la_SOURCES = lpar.c -lpar_la_LDFLAGS = $(PLUGIN_LDFLAGS) -lpar_la_LIBADD = -lperfstat -endif - -if BUILD_PLUGIN_LUA -pkglib_LTLIBRARIES += lua.la -lua_la_SOURCES = lua.c \ - utils_lua.c utils_lua.h -lua_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBLUA_CFLAGS) -lua_la_LDFLAGS = $(PLUGIN_LDFLAGS) -lua_la_LIBADD = $(BUILD_WITH_LIBLUA_LIBS) -endif - -if BUILD_PLUGIN_LVM -pkglib_LTLIBRARIES += lvm.la -lvm_la_SOURCES = lvm.c -lvm_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBLVM2APP_CPPFLAGS) -lvm_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBLVM2APP_LDFLAGS) -lvm_la_LIBADD = $(BUILD_WITH_LIBLVM2APP_LIBS) -endif - -if BUILD_PLUGIN_MADWIFI -pkglib_LTLIBRARIES += madwifi.la -madwifi_la_SOURCES = madwifi.c madwifi.h -madwifi_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_MATCH_EMPTY_COUNTER -pkglib_LTLIBRARIES += match_empty_counter.la -match_empty_counter_la_SOURCES = match_empty_counter.c -match_empty_counter_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_MATCH_HASHED -pkglib_LTLIBRARIES += match_hashed.la -match_hashed_la_SOURCES = match_hashed.c -match_hashed_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_MATCH_REGEX -pkglib_LTLIBRARIES += match_regex.la -match_regex_la_SOURCES = match_regex.c -match_regex_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_MATCH_TIMEDIFF -pkglib_LTLIBRARIES += match_timediff.la -match_timediff_la_SOURCES = match_timediff.c -match_timediff_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_MATCH_VALUE -pkglib_LTLIBRARIES += match_value.la -match_value_la_SOURCES = match_value.c -match_value_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_MBMON -pkglib_LTLIBRARIES += mbmon.la -mbmon_la_SOURCES = mbmon.c -mbmon_la_LDFLAGS = $(PLUGIN_LDFLAGS) -mbmon_la_LIBADD = -if BUILD_WITH_LIBSOCKET -mbmon_la_LIBADD += -lsocket -endif -endif - -if BUILD_PLUGIN_MD -pkglib_LTLIBRARIES += md.la -md_la_SOURCES = md.c -md_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_MEMCACHEC -pkglib_LTLIBRARIES += memcachec.la -memcachec_la_SOURCES = memcachec.c \ - utils_match.c utils_match.h -memcachec_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBMEMCACHED_LDFLAGS) -memcachec_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBMEMCACHED_CPPFLAGS) -memcachec_la_LIBADD = $(BUILD_WITH_LIBMEMCACHED_LIBS) liblatency.la -endif - -if BUILD_PLUGIN_MEMCACHED -pkglib_LTLIBRARIES += memcached.la -memcached_la_SOURCES = memcached.c -memcached_la_LDFLAGS = $(PLUGIN_LDFLAGS) -memcached_la_LIBADD = -if BUILD_WITH_LIBSOCKET -memcached_la_LIBADD += -lsocket -endif -endif - -if BUILD_PLUGIN_MEMORY -pkglib_LTLIBRARIES += memory.la -memory_la_SOURCES = memory.c -memory_la_CFLAGS = $(AM_CFLAGS) -memory_la_LDFLAGS = $(PLUGIN_LDFLAGS) -memory_la_LIBADD = -if BUILD_WITH_LIBKSTAT -memory_la_LIBADD += -lkstat -endif -if BUILD_WITH_LIBDEVINFO -memory_la_LIBADD += -ldevinfo -endif -if BUILD_WITH_LIBSTATGRAB -memory_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) -memory_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) -endif -if BUILD_WITH_PERFSTAT -memory_la_LIBADD += -lperfstat -endif -endif - -if BUILD_PLUGIN_MIC -pkglib_LTLIBRARIES += mic.la -mic_la_SOURCES = mic.c -mic_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_MIC_LIBPATH) -mic_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_MIC_CPPFLAGS) -mic_la_LIBADD = $(BUILD_WITH_MIC_LDADD) -endif - -if BUILD_PLUGIN_MODBUS -pkglib_LTLIBRARIES += modbus.la -modbus_la_SOURCES = modbus.c -modbus_la_LDFLAGS = $(PLUGIN_LDFLAGS) -modbus_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBMODBUS_CFLAGS) -modbus_la_LIBADD = $(BUILD_WITH_LIBMODBUS_LIBS) -endif - -if BUILD_PLUGIN_MQTT -pkglib_LTLIBRARIES += mqtt.la -mqtt_la_SOURCES = mqtt.c -mqtt_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBMOSQUITTO_CPPFLAGS) -mqtt_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBMOSQUITTO_LDFLAGS) -mqtt_la_LIBADD = $(BUILD_WITH_LIBMOSQUITTO_LIBS) -endif - -if BUILD_PLUGIN_MULTIMETER -pkglib_LTLIBRARIES += multimeter.la -multimeter_la_SOURCES = multimeter.c -multimeter_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_MYSQL -pkglib_LTLIBRARIES += mysql.la -mysql_la_SOURCES = mysql.c -mysql_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBMYSQL_CFLAGS) -mysql_la_LDFLAGS = $(PLUGIN_LDFLAGS) -mysql_la_LIBADD = $(BUILD_WITH_LIBMYSQL_LIBS) -endif - -if BUILD_PLUGIN_NETAPP -pkglib_LTLIBRARIES += netapp.la -netapp_la_SOURCES = netapp.c -netapp_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBNETAPP_CPPFLAGS) -netapp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBNETAPP_LDFLAGS) -netapp_la_LIBADD = $(LIBNETAPP_LIBS) -endif - -if BUILD_PLUGIN_NETLINK -pkglib_LTLIBRARIES += netlink.la -netlink_la_SOURCES = netlink.c -netlink_la_LDFLAGS = $(PLUGIN_LDFLAGS) -netlink_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBMNL_CFLAGS) -netlink_la_LIBADD = $(BUILD_WITH_LIBMNL_LIBS) -endif - -if BUILD_PLUGIN_NETWORK -pkglib_LTLIBRARIES += network.la -network_la_SOURCES = network.c network.h \ - utils_fbhash.c utils_fbhash.h -network_la_CPPFLAGS = $(AM_CPPFLAGS) -network_la_LDFLAGS = $(PLUGIN_LDFLAGS) -network_la_LIBADD = -if BUILD_WITH_LIBSOCKET -network_la_LIBADD += -lsocket -endif -if BUILD_WITH_LIBGCRYPT -network_la_CPPFLAGS += $(GCRYPT_CPPFLAGS) -network_la_LDFLAGS += $(GCRYPT_LDFLAGS) -network_la_LIBADD += $(GCRYPT_LIBS) -endif -endif - -if BUILD_PLUGIN_NFS -pkglib_LTLIBRARIES += nfs.la -nfs_la_SOURCES = nfs.c -nfs_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_FSCACHE -pkglib_LTLIBRARIES += fscache.la -fscache_la_SOURCES = fscache.c -fscache_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_NGINX -pkglib_LTLIBRARIES += nginx.la -nginx_la_SOURCES = nginx.c -nginx_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS) -nginx_la_LDFLAGS = $(PLUGIN_LDFLAGS) -nginx_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) -endif - -if BUILD_PLUGIN_NOTIFY_DESKTOP -pkglib_LTLIBRARIES += notify_desktop.la -notify_desktop_la_SOURCES = notify_desktop.c -notify_desktop_la_CFLAGS = $(AM_CFLAGS) $(LIBNOTIFY_CFLAGS) -notify_desktop_la_LDFLAGS = $(PLUGIN_LDFLAGS) -notify_desktop_la_LIBADD = $(LIBNOTIFY_LIBS) -endif - -if BUILD_PLUGIN_NOTIFY_EMAIL -pkglib_LTLIBRARIES += notify_email.la -notify_email_la_SOURCES = notify_email.c -notify_email_la_LDFLAGS = $(PLUGIN_LDFLAGS) -notify_email_la_LIBADD = -lesmtp -endif - -if BUILD_PLUGIN_NOTIFY_NAGIOS -pkglib_LTLIBRARIES += notify_nagios.la -notify_nagios_la_SOURCES = notify_nagios.c -notify_nagios_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_NTPD -pkglib_LTLIBRARIES += ntpd.la -ntpd_la_SOURCES = ntpd.c -ntpd_la_LDFLAGS = $(PLUGIN_LDFLAGS) -ntpd_la_LIBADD = -if BUILD_WITH_LIBSOCKET -ntpd_la_LIBADD += -lsocket -endif -endif - -if BUILD_PLUGIN_NUMA -pkglib_LTLIBRARIES += numa.la -numa_la_SOURCES = numa.c -numa_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_NUT -pkglib_LTLIBRARIES += nut.la -nut_la_SOURCES = nut.c -nut_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBUPSCLIENT_CFLAGS) -nut_la_LDFLAGS = $(PLUGIN_LDFLAGS) -nut_la_LIBADD = $(BUILD_WITH_LIBUPSCLIENT_LIBS) -endif - -if BUILD_PLUGIN_OLSRD -pkglib_LTLIBRARIES += olsrd.la -olsrd_la_SOURCES = olsrd.c -olsrd_la_LDFLAGS = $(PLUGIN_LDFLAGS) -olsrd_la_LIBADD = -if BUILD_WITH_LIBSOCKET -olsrd_la_LIBADD += -lsocket -endif -endif - -if BUILD_PLUGIN_ONEWIRE -pkglib_LTLIBRARIES += onewire.la -onewire_la_SOURCES = onewire.c -onewire_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBOWCAPI_CPPFLAGS) -onewire_la_LIBADD = $(BUILD_WITH_LIBOWCAPI_LIBS) -onewire_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBOWCAPI_LDFLAGS) -endif - -if BUILD_PLUGIN_OPENLDAP -pkglib_LTLIBRARIES += openldap.la -openldap_la_SOURCES = openldap.c -openldap_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBLDAP_CPPFLAGS) -openldap_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBLDAP_LDFLAGS) -openldap_la_LIBADD = -lldap -endif - -if BUILD_PLUGIN_OPENVPN -pkglib_LTLIBRARIES += openvpn.la -openvpn_la_SOURCES = openvpn.c -openvpn_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_ORACLE -pkglib_LTLIBRARIES += oracle.la -oracle_la_SOURCES = oracle.c \ - utils_db_query.c utils_db_query.h -oracle_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_ORACLE_CPPFLAGS) -oracle_la_LIBADD = $(BUILD_WITH_ORACLE_LIBS) -oracle_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_PERL -pkglib_LTLIBRARIES += perl.la -perl_la_SOURCES = perl.c -# Despite C99 providing the "bool" type thru stdbool.h, Perl defines its own -# version of that type if HAS_BOOL is not defined... *sigh* -perl_la_CPPFLAGS = $(AM_CPPFLAGS) -DHAS_BOOL=1 -# Despite off_t being 64 bit wide on 64 bit platforms, Perl insist on using -# off64_t which is only exposed when _LARGEFILE64_SOURCE is defined... *sigh* -# On older platforms we also need _REENTRANT. _GNU_SOURCE sets both of these. -perl_la_CPPFLAGS += -D_GNU_SOURCE -perl_la_CFLAGS = $(AM_CFLAGS) \ - $(PERL_CFLAGS) \ - -DXS_VERSION=\"$(VERSION)\" -DVERSION=\"$(VERSION)\" -# Work-around for issues #41 and #42 - Perl 5.10 incorrectly introduced -# __attribute__nonnull__(3) for Perl_load_module(). -if HAVE_BROKEN_PERL_LOAD_MODULE -perl_la_CFLAGS += -Wno-nonnull -endif -perl_la_LDFLAGS = $(PLUGIN_LDFLAGS) \ - $(PERL_LDFLAGS) -perl_la_LIBADD = $(PERL_LIBS) -endif - -if BUILD_PLUGIN_PF -pkglib_LTLIBRARIES += pf.la -pf_la_SOURCES = pf.c -pf_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_PINBA -pkglib_LTLIBRARIES += pinba.la -pinba_la_SOURCES = pinba.c -nodist_pinba_la_SOURCES = pinba.pb-c.c pinba.pb-c.h -pinba_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBPROTOBUF_C_CPPFLAGS) -pinba_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBPROTOBUF_C_LDFLAGS) -pinba_la_LIBADD = $(BUILD_WITH_LIBPROTOBUF_C_LIBS) -endif - -if BUILD_PLUGIN_PING -pkglib_LTLIBRARIES += ping.la -ping_la_SOURCES = ping.c -ping_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBOPING_CPPFLAGS) -ping_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBOPING_LDFLAGS) -ping_la_LIBADD = -loping -lm -endif - -if BUILD_PLUGIN_POSTGRESQL -pkglib_LTLIBRARIES += postgresql.la -postgresql_la_SOURCES = postgresql.c \ - utils_db_query.c utils_db_query.h -postgresql_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBPQ_CPPFLAGS) -postgresql_la_LDFLAGS = $(PLUGIN_LDFLAGS) \ - $(BUILD_WITH_LIBPQ_LDFLAGS) -postgresql_la_LIBADD = -lpq -endif - -if BUILD_PLUGIN_POWERDNS -pkglib_LTLIBRARIES += powerdns.la -powerdns_la_SOURCES = powerdns.c -powerdns_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_PYTHON -pkglib_LTLIBRARIES += python.la -python_la_SOURCES = python.c pyconfig.c pyvalues.c cpython.h -python_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBPYTHON_CPPFLAGS) -if COMPILER_IS_GCC -python_la_CPPFLAGS += -fno-strict-aliasing -Wno-strict-aliasing -endif -python_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBPYTHON_LDFLAGS) -endif - -if BUILD_PLUGIN_PROCESSES -pkglib_LTLIBRARIES += processes.la -processes_la_SOURCES = processes.c -processes_la_LDFLAGS = $(PLUGIN_LDFLAGS) -processes_la_LIBADD = -if BUILD_WITH_LIBKVM_GETPROCS -processes_la_LIBADD += -lkvm -endif -endif - -if BUILD_PLUGIN_PROTOCOLS -pkglib_LTLIBRARIES += protocols.la -protocols_la_SOURCES = protocols.c -protocols_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_INTEL_RDT -pkglib_LTLIBRARIES += intel_rdt.la -intel_rdt_la_SOURCES = intel_rdt.c -intel_rdt_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBPQOS_LDFLAGS) -intel_rdt_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBPQOS_CPPFLAGS) -intel_rdt_la_LIBADD = $(BUILD_WITH_LIBPQOS_LIBS) -endif - -if BUILD_PLUGIN_REDIS -pkglib_LTLIBRARIES += redis.la -redis_la_SOURCES = redis.c -redis_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBHIREDIS_LDFLAGS) -redis_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBHIREDIS_CPPFLAGS) -redis_la_LIBADD = -lhiredis -endif - -if BUILD_PLUGIN_ROUTEROS -pkglib_LTLIBRARIES += routeros.la -routeros_la_SOURCES = routeros.c -routeros_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBROUTEROS_CPPFLAGS) -routeros_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBROUTEROS_LDFLAGS) -routeros_la_LIBADD = -lrouteros -endif - -if BUILD_PLUGIN_RRDCACHED -pkglib_LTLIBRARIES += rrdcached.la -rrdcached_la_SOURCES = rrdcached.c utils_rrdcreate.c utils_rrdcreate.h -rrdcached_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRRD_LDFLAGS) -rrdcached_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBRRD_CFLAGS) -rrdcached_la_LIBADD = $(BUILD_WITH_LIBRRD_LIBS) -endif - -if BUILD_PLUGIN_RRDTOOL -pkglib_LTLIBRARIES += rrdtool.la -rrdtool_la_SOURCES = rrdtool.c utils_rrdcreate.c utils_rrdcreate.h -rrdtool_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRRD_LDFLAGS) -rrdtool_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBRRD_CFLAGS) -rrdtool_la_LIBADD = $(BUILD_WITH_LIBRRD_LIBS) -endif - -if BUILD_PLUGIN_SENSORS -pkglib_LTLIBRARIES += sensors.la -sensors_la_SOURCES = sensors.c -sensors_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBSENSORS_CFLAGS) -sensors_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBSENSORS_LDFLAGS) -sensors_la_LIBADD = -lsensors -endif - -if BUILD_PLUGIN_SERIAL -pkglib_LTLIBRARIES += serial.la -serial_la_SOURCES = serial.c -serial_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_SIGROK -pkglib_LTLIBRARIES += sigrok.la -sigrok_la_SOURCES = sigrok.c -sigrok_la_CFLAGS = $(AM_CFLAGS) $(LIBSIGROK_CFLAGS) -sigrok_la_LDFLAGS = $(PLUGIN_LDFLAGS) -sigrok_la_LIBADD = $(LIBSIGROK_LIBS) -endif - -if BUILD_PLUGIN_SMART -if BUILD_WITH_LIBUDEV -pkglib_LTLIBRARIES += smart.la -smart_la_SOURCES = smart.c -smart_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBATASMART_CPPFLAGS) $(BUILD_WITH_LIBUDEV_CFLAGS) -smart_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBATASMART_LDFLAGS) $(BUILD_WITH_LIBUDEV_LDFLAGS) -smart_la_LIBADD = $(BUILD_WITH_LIBATASMART_LIBS) $(BUILD_WITH_LIBUDEV_LIBS) -endif -endif - -if BUILD_PLUGIN_SNMP -pkglib_LTLIBRARIES += snmp.la -snmp_la_SOURCES = snmp.c -snmp_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBNETSNMP_CPPFLAGS) -snmp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBNETSNMP_LDFLAGS) -snmp_la_LIBADD = $(BUILD_WITH_LIBNETSNMP_LIBS) -endif - -if BUILD_PLUGIN_STATSD -pkglib_LTLIBRARIES += statsd.la -statsd_la_SOURCES = statsd.c -statsd_la_LDFLAGS = $(PLUGIN_LDFLAGS) -statsd_la_LIBADD = liblatency.la -endif - -if BUILD_PLUGIN_SWAP -pkglib_LTLIBRARIES += swap.la -swap_la_SOURCES = swap.c -swap_la_CFLAGS = $(AM_CFLAGS) -swap_la_LDFLAGS = $(PLUGIN_LDFLAGS) -swap_la_LIBADD = -if BUILD_WITH_LIBKSTAT -swap_la_LIBADD += -lkstat -endif -if BUILD_WITH_LIBDEVINFO -swap_la_LIBADD += -ldevinfo -endif -if BUILD_WITH_LIBKVM_GETSWAPINFO -swap_la_LIBADD += -lkvm -endif -if BUILD_WITH_LIBSTATGRAB -swap_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) -swap_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) -endif -if BUILD_WITH_PERFSTAT -swap_la_LIBADD += -lperfstat -endif - -endif - -if BUILD_PLUGIN_SYSLOG -pkglib_LTLIBRARIES += syslog.la -syslog_la_SOURCES = syslog.c -syslog_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_TABLE -pkglib_LTLIBRARIES += table.la -table_la_SOURCES = table.c -table_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_TAIL -pkglib_LTLIBRARIES += tail.la -tail_la_SOURCES = tail.c \ - utils_match.c utils_match.h \ - utils_tail.c utils_tail.h \ - utils_tail_match.c utils_tail_match.h -tail_la_LDFLAGS = $(PLUGIN_LDFLAGS) -tail_la_LIBADD = liblatency.la -endif - -if BUILD_PLUGIN_TAIL_CSV -pkglib_LTLIBRARIES += tail_csv.la -tail_csv_la_SOURCES = tail_csv.c \ - utils_tail.c utils_tail.h -tail_csv_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_TAPE -pkglib_LTLIBRARIES += tape.la -tape_la_SOURCES = tape.c -tape_la_LDFLAGS = $(PLUGIN_LDFLAGS) -tape_la_LIBADD = -lkstat -ldevinfo -endif - -if BUILD_PLUGIN_TARGET_NOTIFICATION -pkglib_LTLIBRARIES += target_notification.la -target_notification_la_SOURCES = target_notification.c -target_notification_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_TARGET_REPLACE -pkglib_LTLIBRARIES += target_replace.la -target_replace_la_SOURCES = target_replace.c -target_replace_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_TARGET_SCALE -pkglib_LTLIBRARIES += target_scale.la -target_scale_la_SOURCES = target_scale.c -target_scale_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_TARGET_SET -pkglib_LTLIBRARIES += target_set.la -target_set_la_SOURCES = target_set.c -target_set_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_TARGET_V5UPGRADE -pkglib_LTLIBRARIES += target_v5upgrade.la -target_v5upgrade_la_SOURCES = target_v5upgrade.c -target_v5upgrade_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_TCPCONNS -pkglib_LTLIBRARIES += tcpconns.la -tcpconns_la_SOURCES = tcpconns.c -tcpconns_la_LDFLAGS = $(PLUGIN_LDFLAGS) -tcpconns_la_LIBADD = -if BUILD_WITH_LIBKVM_NLIST -tcpconns_la_LIBADD += -lkvm -endif -endif - -if BUILD_PLUGIN_TEAMSPEAK2 -pkglib_LTLIBRARIES += teamspeak2.la -teamspeak2_la_SOURCES = teamspeak2.c -teamspeak2_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_TED -pkglib_LTLIBRARIES += ted.la -ted_la_SOURCES = ted.c -ted_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_THERMAL -pkglib_LTLIBRARIES += thermal.la -thermal_la_SOURCES = thermal.c -thermal_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_THRESHOLD -pkglib_LTLIBRARIES += threshold.la -threshold_la_SOURCES = threshold.c -threshold_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_TOKYOTYRANT -pkglib_LTLIBRARIES += tokyotyrant.la -tokyotyrant_la_SOURCES = tokyotyrant.c -tokyotyrant_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBTOKYOTYRANT_CPPFLAGS) -tokyotyrant_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBTOKYOTYRANT_LDFLAGS) -tokyotyrant_la_LIBADD = $(BUILD_WITH_LIBTOKYOTYRANT_LIBS) -if BUILD_WITH_LIBSOCKET -tokyotyrant_la_LIBADD += -lsocket -endif -endif - -if BUILD_PLUGIN_TURBOSTAT -pkglib_LTLIBRARIES += turbostat.la -turbostat_la_SOURCES = turbostat.c -turbostat_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_UNIXSOCK -pkglib_LTLIBRARIES += unixsock.la -unixsock_la_SOURCES = unixsock.c -unixsock_la_LDFLAGS = $(PLUGIN_LDFLAGS) -unixsock_la_LIBADD = libcmds.la -endif - -if BUILD_PLUGIN_UPTIME -pkglib_LTLIBRARIES += uptime.la -uptime_la_SOURCES = uptime.c -uptime_la_CFLAGS = $(AM_CFLAGS) -uptime_la_LDFLAGS = $(PLUGIN_LDFLAGS) -uptime_la_LIBADD = -if BUILD_WITH_LIBKSTAT -uptime_la_LIBADD += -lkstat -endif -if BUILD_WITH_PERFSTAT -uptime_la_LIBADD += -lperfstat -endif -endif - -if BUILD_PLUGIN_USERS -pkglib_LTLIBRARIES += users.la -users_la_SOURCES = users.c -users_la_CFLAGS = $(AM_CFLAGS) -users_la_LDFLAGS = $(PLUGIN_LDFLAGS) -users_la_LIBADD = -if BUILD_WITH_LIBSTATGRAB -users_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) -users_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) -endif -endif - -if BUILD_PLUGIN_UUID -pkglib_LTLIBRARIES += uuid.la -uuid_la_SOURCES = uuid.c -uuid_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBHAL_CFLAGS) -uuid_la_LIBADD = $(BUILD_WITH_LIBHAL_LIBS) -uuid_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_VARNISH -pkglib_LTLIBRARIES += varnish.la -varnish_la_SOURCES = varnish.c -varnish_la_LDFLAGS = $(PLUGIN_LDFLAGS) -varnish_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBVARNISH_CFLAGS) -varnish_la_LIBADD = $(BUILD_WITH_LIBVARNISH_LIBS) -endif - -if BUILD_PLUGIN_VIRT -pkglib_LTLIBRARIES += virt.la -virt_la_SOURCES = virt.c -virt_la_CFLAGS = $(AM_CFLAGS) \ - $(BUILD_WITH_LIBVIRT_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS) -virt_la_LIBADD = $(BUILD_WITH_LIBVIRT_LIBS) $(BUILD_WITH_LIBXML2_LIBS) -virt_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_VMEM -pkglib_LTLIBRARIES += vmem.la -vmem_la_SOURCES = vmem.c -vmem_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_VSERVER -pkglib_LTLIBRARIES += vserver.la -vserver_la_SOURCES = vserver.c -vserver_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_WIRELESS -pkglib_LTLIBRARIES += wireless.la -wireless_la_SOURCES = wireless.c -wireless_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_WRITE_GRAPHITE -pkglib_LTLIBRARIES += write_graphite.la -write_graphite_la_SOURCES = write_graphite.c -write_graphite_la_LDFLAGS = $(PLUGIN_LDFLAGS) -write_graphite_la_LIBADD = libformat_graphite.la -endif - -if BUILD_PLUGIN_WRITE_HTTP -pkglib_LTLIBRARIES += write_http.la -write_http_la_SOURCES = write_http.c \ - utils_format_kairosdb.c utils_format_kairosdb.h -write_http_la_LDFLAGS = $(PLUGIN_LDFLAGS) -write_http_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS) -write_http_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) libformat_json.la -endif - -if BUILD_PLUGIN_WRITE_KAFKA -pkglib_LTLIBRARIES += write_kafka.la -write_kafka_la_SOURCES = write_kafka.c \ - utils_crc32.c utils_crc32.h -write_kafka_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBRDKAFKA_CPPFLAGS) -write_kafka_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRDKAFKA_LDFLAGS) -write_kafka_la_LIBADD = $(BUILD_WITH_LIBRDKAFKA_LIBS) \ - libcmds.la libformat_graphite.la libformat_json.la -endif - -if BUILD_PLUGIN_WRITE_LOG -pkglib_LTLIBRARIES += write_log.la -write_log_la_SOURCES = write_log.c -write_log_la_LDFLAGS = $(PLUGIN_LDFLAGS) -write_log_la_LIBADD = libformat_graphite.la libformat_json.la -endif - -if BUILD_PLUGIN_WRITE_MONGODB -pkglib_LTLIBRARIES += write_mongodb.la -write_mongodb_la_SOURCES = write_mongodb.c -write_mongodb_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBMONGOC_CPPFLAGS) -write_mongodb_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBMONGOC_LDFLAGS) -write_mongodb_la_LIBADD = -lmongoc -endif - -if BUILD_PLUGIN_WRITE_PROMETHEUS -pkglib_LTLIBRARIES += write_prometheus.la -write_prometheus_la_SOURCES = write_prometheus.c -nodist_write_prometheus_la_SOURCES = prometheus.pb-c.c prometheus.pb-c.h -write_prometheus_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBPROTOBUF_C_CPPFLAGS) $(BUILD_WITH_LIBMICROHTTPD_CPPFLAGS) -write_prometheus_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBPROTOBUF_C_LDFLAGS) $(BUILD_WITH_LIBMICROHTTPD_LDFLAGS) -write_prometheus_la_LIBADD = $(BUILD_WITH_LIBPROTOBUF_C_LIBS) $(BUILD_WITH_LIBMICROHTTPD_LIBS) -endif - -if BUILD_PLUGIN_WRITE_REDIS -pkglib_LTLIBRARIES += write_redis.la -write_redis_la_SOURCES = write_redis.c -write_redis_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBHIREDIS_LDFLAGS) -write_redis_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBHIREDIS_CPPFLAGS) -write_redis_la_LIBADD = -lhiredis -endif - -if BUILD_PLUGIN_WRITE_RIEMANN -pkglib_LTLIBRARIES += write_riemann.la -write_riemann_la_SOURCES = write_riemann.c write_riemann_threshold.c write_riemann_threshold.h -write_riemann_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBRIEMANN_CLIENT_LIBS) -write_riemann_la_CFLAGS = $(AM_CFLAGS) $(LIBRIEMANN_CLIENT_CFLAGS) -endif - -if BUILD_PLUGIN_WRITE_SENSU -pkglib_LTLIBRARIES += write_sensu.la -write_sensu_la_SOURCES = write_sensu.c -write_sensu_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_WRITE_TSDB -pkglib_LTLIBRARIES += write_tsdb.la -write_tsdb_la_SOURCES = write_tsdb.c -write_tsdb_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -if BUILD_PLUGIN_XENCPU -pkglib_LTLIBRARIES += xencpu.la -xencpu_la_SOURCES = xencpu.c -xencpu_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBXENCTL_CPPFLAGS) -xencpu_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBXENCTL_LDFLAGS) -xencpu_la_LIBADD = -lxenctrl -endif - -if BUILD_PLUGIN_XMMS -pkglib_LTLIBRARIES += xmms.la -xmms_la_SOURCES = xmms.c -xmms_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBXMMS_CFLAGS) -xmms_la_LDFLAGS = $(PLUGIN_LDFLAGS) -xmms_la_LIBADD = $(BUILD_WITH_LIBXMMS_LIBS) -endif - -if BUILD_PLUGIN_ZFS_ARC -pkglib_LTLIBRARIES += zfs_arc.la -zfs_arc_la_SOURCES = zfs_arc.c -zfs_arc_la_LDFLAGS = $(PLUGIN_LDFLAGS) -if BUILD_FREEBSD -zfs_arc_la_LIBADD = -lm -endif -if BUILD_SOLARIS -zfs_arc_la_LIBADD = -lkstat -endif -endif - -if BUILD_PLUGIN_ZOOKEEPER -pkglib_LTLIBRARIES += zookeeper.la -zookeeper_la_SOURCES = zookeeper.c -zookeeper_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -BUILT_SOURCES += $(dist_man_MANS) - -if BUILD_PLUGIN_ZONE -pkglib_LTLIBRARIES += zone.la -zone_la_SOURCES = zone.c -zone_la_LDFLAGS = $(PLUGIN_LDFLAGS) -endif - -dist_man_MANS = collectd.1 \ - collectd.conf.5 \ - collectd-email.5 \ - collectd-exec.5 \ - collectdctl.1 \ - collectd-java.5 \ - collectd-lua.5 \ - collectdmon.1 \ - collectd-nagios.1 \ - collectd-perl.5 \ - collectd-python.5 \ - collectd-snmp.5 \ - collectd-tg.1 \ - collectd-threshold.5 \ - collectd-unixsock.5 \ - types.db.5 - -EXTRA_DIST = collectd.conf.pod \ - collectd-email.pod \ - collectd-exec.pod \ - collectdctl.pod \ - collectd-java.pod \ - collectd-lua.pod \ - collectdmon.pod \ - collectd-nagios.pod \ - collectd-perl.pod \ - collectd-python.pod \ - collectd.pod \ - collectd-snmp.pod \ - collectd-tg.pod \ - collectd-threshold.pod \ - collectd-unixsock.pod \ - postgresql_default.conf \ - types.db \ - types.db.pod \ - valgrind.FreeBSD.suppress - -AM_V_POD2MAN_C = $(am__v_POD2MAN_C_@AM_V@) -am__v_POD2MAN_C_ = $(am__v_POD2MAN_C_@AM_DEFAULT_V@) -am__v_POD2MAN_C_0 = @echo " POD2MAN " $@; -am__v_POD2MAN_C_1 = - -.pod.1: - $(AM_V_POD2MAN_C)pod2man --release=$(VERSION) --center=$(PACKAGE) $< \ - >.pod2man.tmp.$$$$ 2>/dev/null && mv -f .pod2man.tmp.$$$$ $@ || true - @if grep '\' $@ >/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 '\' $@ >/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 diff --git a/src/aggregation.c b/src/aggregation.c index 4e20d0cf..8d501f63 100644 --- a/src/aggregation.c +++ b/src/aggregation.c @@ -752,5 +752,3 @@ void module_register(void) { plugin_register_read("aggregation", agg_read); plugin_register_write("aggregation", agg_write, /* user_data = */ NULL); } - -/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ diff --git a/src/amqp.c b/src/amqp.c index cd07023f..4870107c 100644 --- a/src/amqp.c +++ b/src/amqp.c @@ -1022,5 +1022,3 @@ void module_register(void) { plugin_register_complex_config("amqp", camqp_config); plugin_register_shutdown("amqp", camqp_shutdown); } /* void module_register */ - -/* vim: set sw=4 sts=4 et fdm=marker : */ diff --git a/src/apache.c b/src/apache.c index eaef61b1..547d7456 100644 --- a/src/apache.c +++ b/src/apache.c @@ -573,5 +573,3 @@ void module_register(void) { plugin_register_complex_config("apache", config); plugin_register_init("apache", apache_init); } /* void module_register */ - -/* vim: set sw=8 noet fdm=marker : */ diff --git a/src/apple_sensors.c b/src/apple_sensors.c index 2f8cccd8..902b5f96 100644 --- a/src/apple_sensors.c +++ b/src/apple_sensors.c @@ -29,10 +29,6 @@ #include "common.h" #include "plugin.h" -#if HAVE_CTYPE_H -#include -#endif - #if HAVE_MACH_MACH_TYPES_H #include #endif diff --git a/src/aquaero.c b/src/aquaero.c index 4a78f685..22278e03 100644 --- a/src/aquaero.c +++ b/src/aquaero.c @@ -161,5 +161,3 @@ void module_register(void) { plugin_register_read("aquaero", aquaero_read); plugin_register_shutdown("aquaero", aquaero_shutdown); } /* void module_register */ - -/* vim: set sw=8 sts=8 noet : */ diff --git a/src/ascent.c b/src/ascent.c index 840fe8b8..5f0d85e7 100644 --- a/src/ascent.c +++ b/src/ascent.c @@ -571,5 +571,3 @@ void module_register(void) { plugin_register_init("ascent", ascent_init); plugin_register_read("ascent", ascent_read); } /* void module_register */ - -/* vim: set sw=2 sts=2 ts=8 et fdm=marker : */ diff --git a/src/battery_statefs.c b/src/battery_statefs.c index 4b9baf42..4f6a8c15 100644 --- a/src/battery_statefs.c +++ b/src/battery_statefs.c @@ -87,9 +87,9 @@ int battery_read_statefs(void) { } struct { - char *path; - char *type; - char *type_instance; + const char *path; + const char *type; + const char *type_instance; gauge_t factor; } metrics[] = { {STATEFS_ROOT "Current", "current", NULL, 1e-6}, // from uA to A diff --git a/src/bind.c b/src/bind.c index 9bb662fc..38761775 100644 --- a/src/bind.c +++ b/src/bind.c @@ -1613,5 +1613,3 @@ void module_register(void) { plugin_register_read("bind", bind_read); plugin_register_shutdown("bind", bind_shutdown); } /* void module_register */ - -/* vim: set sw=2 sts=2 ts=8 et fdm=marker : */ diff --git a/src/ceph.c b/src/ceph.c index 4e435b3e..2331e33d 100644 --- a/src/ceph.c +++ b/src/ceph.c @@ -1446,4 +1446,3 @@ void module_register(void) { plugin_register_read("ceph", ceph_read); plugin_register_shutdown("ceph", ceph_shutdown); } -/* vim: set sw=4 sts=4 et : */ diff --git a/src/ceph_test.c b/src/ceph_test.c index 3da4098c..2f65b509 100644 --- a/src/ceph_test.c +++ b/src/ceph_test.c @@ -187,5 +187,3 @@ int main(void) { END_TEST; } - -/* vim: set sw=2 sts=2 et : */ diff --git a/src/collectd-tg.c b/src/collectd-tg.c index 7ded64dd..3bde3259 100644 --- a/src/collectd-tg.c +++ b/src/collectd-tg.c @@ -423,5 +423,3 @@ int main(int argc, char **argv) /* {{{ */ lcc_network_destroy(net); exit(EXIT_SUCCESS); } /* }}} int main */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/collectd.conf.in b/src/collectd.conf.in index e5b96435..e2d6aafa 100644 --- a/src/collectd.conf.in +++ b/src/collectd.conf.in @@ -114,6 +114,7 @@ #@BUILD_PLUGIN_DF_TRUE@LoadPlugin df #@BUILD_PLUGIN_DISK_TRUE@LoadPlugin disk #@BUILD_PLUGIN_DNS_TRUE@LoadPlugin dns +#@BUILD_PLUGIN_DPDKEVENTS_TRUE@LoadPlugin dpdkevents #@BUILD_PLUGIN_DPDKSTAT_TRUE@LoadPlugin dpdkstat #@BUILD_PLUGIN_DRBD_TRUE@LoadPlugin drbd #@BUILD_PLUGIN_EMAIL_TRUE@LoadPlugin email @@ -142,6 +143,7 @@ #@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 @@ -167,6 +169,8 @@ #@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_OVS_STATS_TRUE@LoadPlugin ovs_stats #@BUILD_PLUGIN_PERL_TRUE@LoadPlugin perl #@BUILD_PLUGIN_PINBA_TRUE@LoadPlugin pinba #@BUILD_PLUGIN_PING_TRUE@LoadPlugin ping @@ -523,14 +527,39 @@ # SelectNumericQueryTypes true # +# +# +# Coremask "0x1" +# MemoryChannels "4" +# ProcessType "secondary" +# FilePrefix "rte" +# +# +# SendEventsOnUpdate true +# EnabledPortMask 0xffff +# PortName "interface1" +# PortName "interface2" +# SendNotification false +# +# +# SendEventsOnUpdate true +# LCoreMask "0xf" +# KeepAliveShmName "/dpdk_keepalive_shm_name" +# SendNotification false +# +# + # -# Interval 1 -# Coremask "0xf" -# ProcessType "secondary" -# FilePrefix "rte" -# EnabledPortMask 0xffff -# PortName "interface1" -# PortName "interface2" +# +# Coremask "0x2" +# MemoryChannels "4" +# ProcessType "secondary" +# FilePrefix "rte" +# +# SharedMemObj "dpdk_collectd_stats_0" +# EnabledPortMask 0xffff +# PortName "interface1" +# PortName "interface2" # # @@ -690,6 +719,11 @@ # Port "411" # +# +# McelogClientSocket "/var/run/mcelog-client" +# McelogLogfile "/var/log/mcelog" +# + # # Device "/dev/md0" # IgnoreSelected false @@ -933,6 +967,9 @@ # # UPS "upsname@hostname:port" +# ForceSSL true +# VerifyPeer true +# CAPath "/path/to/folder" # # @@ -985,6 +1022,22 @@ # # +# +# Port "6640" +# Address "127.0.0.1" +# Socket "/var/run/openvswitch/db.sock" +# Interfaces "br0" "veth0" +# SendNotification true +# DispatchValues false +# + +# +# Port "6640" +# Address "127.0.0.1" +# Socket "/var/run/openvswitch/db.sock" +# Bridges "br0" "br_ext" +# + # # IncludeDir "/my/include/path" # BaseName "Collectd::Plugins" @@ -1085,7 +1138,18 @@ # # +# CollectFileDescriptor true +# CollectContextSwitch true # Process "name" +# ProcessMatch "name" "regex" +# +# CollectFileDescriptor false +# CollectContextSwitch false +# +# +# CollectFileDescriptor false +# CollectContextSwitch true +# # # @@ -1441,6 +1505,8 @@ # HostnameFormat name # InterfaceFormat name # PluginInstanceFormat name +# Instances 1 +# ExtraStats "cpu_util disk disk_err domain_state fs_info job_stats_background pcpu perf vcpupin" # # @@ -1480,6 +1546,7 @@ # Header "X-Custom-Header: custom_value" # SSLVersion "TLSv1" # Format "Command" +# Attribute "key" "value" # only available for KAIROSDB format # Metrics true # Notifications false # StoreRates false diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index 11cfaebd..6a7a9176 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -2383,6 +2383,128 @@ Enabled by default, collects unknown (and thus presented as numeric only) query =back +=head2 Plugin C + +The I collects events from DPDK such as link status of +network ports and Keep Alive status of DPDK logical cores. +In order to get Keep Alive events following requirements must be met: +- DPDK >= 16.07 +- support for Keep Alive implemented in DPDK application. More details can +be found here: http://dpdk.org/doc/guides/sample_app_ug/keep_alive.html + +B + + + + Coremask "0x1" + MemoryChannels "4" + ProcessType "secondary" + FilePrefix "rte" + + + SendEventsOnUpdate true + EnabledPortMask 0xffff + PortName "interface1" + PortName "interface2" + SendNotification false + + + SendEventsOnUpdate true + LCoreMask "0xf" + KeepAliveShmName "/dpdk_keepalive_shm_name" + SendNotification false + + + +B + + +=head3 The EAL block + +=over 5 + +=item B I + +=item B I + +Number of memory channels per processor socket. + +=item B I + +The type of DPDK process instance. + +=item B I + +The prefix text used for hugepage filenames. The filename will be set to +/var/run/._config where prefix is what is passed in by the user. + +=back + +=head3 The Event block + +The B block defines configuration for specific event. It accepts a +single argument which specifies the name of the event. + +=head4 Link Status event + +=over 5 + +=item B I + +If set to true link status value will be dispatched only when it is +different from previously read value. This is an optional argument - default +value is true. + +=item B I + +A hexidecimal bit mask of the DPDK ports which should be enabled. A mask +of 0x0 means that all ports will be disabled. A bitmask of all F's means +that all ports will be enabled. This is an optional argument - by default +all ports are enabled. + +=item B I + +A string containing an optional name for the enabled DPDK ports. Each PortName +option should contain only one port name; specify as many PortName options as +desired. Default naming convention will be used if PortName is blank. If there +are less PortName options than there are enabled ports, the default naming +convention will be used for the additional ports. + +=item B I + +If set to true, link status notifications are sent, instead of link status +being collected as a statistic. This is an optional argument - default +value is false. + +=back + +=head4 Keep Alive event + +=over 5 + +=item B I + +If set to true keep alive value will be dispatched only when it is +different from previously read value. This is an optional argument - default +value is true. + +=item B I + +An hexadecimal bit mask of the logical cores to monitor keep alive state. + +=item B I + +Shared memory name identifier that is used by secondary process to monitor +the keep alive cores state. + +=item B I + +If set to true, keep alive notifications are sent, instead of keep alive +information being collected as a statistic. This is an optional +argument - default value is false. + +=back + =head2 Plugin C The I collects information about DPDK interfaces using the @@ -2391,18 +2513,24 @@ extended NIC stats API in DPDK. B - Coremask "0x4" - MemoryChannels "4" - ProcessType "secondary" - FilePrefix "rte" - EnabledPortMask 0xffff - PortName "interface1" - PortName "interface2" + + Coremask "0x4" + MemoryChannels "4" + ProcessType "secondary" + FilePrefix "rte" + SocketMemory "1024" + + SharedMemObj "dpdk_collectd_stats_0" + EnabledPortMask 0xffff + PortName "interface1" + PortName "interface2" B -=over 4 +=head3 The EAL block + +=over 5 =item B I @@ -2425,7 +2553,16 @@ The prefix text used for hugepage filenames. The filename will be set to =item B I A string containing amount of Memory to allocate from hugepages on specific -sockets in MB +sockets in MB. This is an optional value. + +=back + +=over 3 + +=item B I +A string containing the name of the shared memory object that should be used to +share stats from the DPDK secondary process to the collectd dpdkstat plugin. +Defaults to dpdk_collectd_stats if no other value is configured. =item B I @@ -2949,6 +3086,10 @@ allows to monitor instructions per clock (IPC). Monitor events are hardware dependant. Monitoring capabilities are detected on plugin initialization and only supported events are monitored. +B I plugin is using model-specific registers (MSRs), which +require an additional capability to be enabled if collectd is run as a service. +Please refer to I file for more details. + B @@ -3322,6 +3463,28 @@ TCP-Port to connect to. Defaults to B<411>. =back +=head2 Plugin C + +The C 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 I +Connect to the mcelog client socket using the UNIX domain socket at I. +Defaults to B<"/var/run/mcelog-client">. + +=item B I + +The mcelog file to parse. Defaults to B<"/var/log/mcelog">. + +=back + =head2 Plugin C The C collects information from Linux Software-RAID devices (md). @@ -5086,6 +5249,35 @@ making it through. Add a UPS to collect data from. The format is identical to the one accepted by L. +=item B B|B + +Stops connections from falling back to unsecured if an SSL connection +cannot be established. Defaults to false if undeclared. + +=item B I|I + +If set to true, requires a CAPath be provided. Will use the CAPath to find +certificates to use as Trusted Certificates to validate a upsd server certificate. +If validation of the upsd server certificate fails, the connection will not be +established. If ForceSSL is undeclared or set to false, setting VerifyPeer to true +will override and set ForceSSL to true. + +=item B I/path/to/certs/folder + +If VerifyPeer is set to true, this is required. Otherwise this is ignored. +The folder pointed at must contain certificate(s) named according to their hash. +Ex: XXXXXXXX.Y where X is the hash value of a cert and Y is 0. If name collisions +occur because two different certs have the same hash value, Y can be incremented +in order to avoid conflict. To create a symbolic link to a certificate the following +command can be used from within the directory where the cert resides: + +C + +Alternatively, the package openssl-perl provides a command C that will +generate links like the one described above for ALL certs in a given folder. +Example usage: +C + =back =head2 Plugin C @@ -5431,6 +5623,123 @@ refer to them from. =back +=head2 Plugin C + +The I plugin monitors the link status of I (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 + + + Port 6640 + Address "127.0.0.1" + Socket "/var/run/openvswitch/db.sock" + Interfaces "br0" "veth0" + SendNotification true + DispatchValues false + + +The plugin provides the following configuration options: + +=over 4 + +=item B
I + +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 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 I + +TCP-port to connect to. Either a service name or a port number may be given. +Defaults to B<6640>. + +=item B I + +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 for more details. If this +option is set, B
and B options are ignored. + +=item B [I ...] + +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 I + +If set to true, OVS link notifications (interface status and OVS DB connection +terminate) are sent to collectd. Default value is true. + +=item B I + +Dispatch the OVS DB interface link status value with configured plugin interval. +Defaults to false. Please note, if B and B +options are false, no OVS information will be provided by the plugin. + +=back + +B 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 option of the OVS B 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 + +The I plugin collects statistics of OVS connected interfaces. +This plugin uses OVSDB management protocol (RFC7047) monitor mechanism to get +statistics from OVSDB + +B + + + Port 6640 + Address "127.0.0.1" + Socket "/var/run/openvswitch/db.sock" + Bridges "br0" "br_ext" + + +The plugin provides the following configuration options: + +=over 4 + +=item B
I + +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 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 I + +TCP-port to connect to. Either a service name or a port number may be given. +Defaults to B<6640>. + +=item B I + +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 for more details. If this +option is set, B
and B options are ignored. + +=item B [I ...] + +List of OVS bridge names to be monitored by this plugin. If this option is +omitted or is empty then all OVS bridges will be monitored. + +Default: empty (monitor all bridges) + +=back + =head2 Plugin C This plugin embeds a Perl-interpreter into collectd and provides an interface @@ -6219,9 +6528,15 @@ C/var/run/collectd-powerdns>. =item B I Select more detailed statistics of processes matching this name. The statistics -collected for these selected processes are size of the resident segment size -(RSS), user- and system-time used, number of processes and number of threads, -io data (where available) and minor and major pagefaults. +collected for these selected processes are: + - size of the resident segment size (RSS) + - user- and system-time used + - number of processes + - number of threads + - number of open files (under Linux) + - io data (where available) + - context switches (under Linux) + - minor and major pagefaults. Some platforms have a limit on the length of process names. I must stay below this limit. @@ -7831,11 +8146,11 @@ Collect statistics about worker threads. False by default. =head2 Plugin C -This plugin allows CPU, disk and network load to be collected for virtualized -guests on the machine. This means that these metrics can be collected for guest -systems without installing any software on them - I only runs on the -host system. The statistics are collected through libvirt -(L). +This plugin allows CPU, disk, network load and other metrics to be collected for +virtualized guests on the machine. The statistics are collected through libvirt +API (L). Majority of metrics can be gathered without +installing any additional software on guests, especially I, which runs +only on the host system. Only I is required. @@ -7973,6 +8288,61 @@ You can also specify combinations of the B and B fields. For example B means to concatenate the guest name and UUID (with a literal colon character between, thus I<"foo:1234-1234-1234-1234">). +=item B B + +How many read instances you want to use for this plugin. The default is one, +and the sensible setting is a multiple of the B value. +If you are not sure, just use the default setting. + +=item B B + +Report additional extra statistics. The default is no extra statistics, preserving +the previous behaviour of the plugin. If unsure, leave the default. If enabled, +allows the plugin to reported more detailed statistics about the behaviour of +Virtual Machines. The argument is a space-separated list of selectors. + +Currently supported selectors are: + +=over 4 + +=item B: report CPU utilization per domain in percentage. + +=item B: report extra statistics like number of flush operations and total +service time for read, write and flush operations. Requires libvirt API version +I<0.9.5> or later. + +=item B: report disk errors if any occured. Requires libvirt API version +I<0.9.10> or later. + +=item B: report domain state and reason in human-readable format as +a notification. If libvirt API version I<0.9.2> or later is available, domain +reason will be included in notification. + +=item B: report file system information as a notification. Requires +libvirt API version I<1.2.11> or later. Can be collected only if I +is installed and configured inside VM. Make sure that installed I +version supports retrieving file system information. + +=item B: report statistics about progress of a background +job on a domain. Only one type of job statistics can be collected at the same time. +Requires libvirt API version I<1.2.9> or later. + +=item B: report statistics about a recently completed job on +a domain. Only one type of job statistics can be collected at the same time. +Requires libvirt API version I<1.2.9> or later. + +=item B: report the physical user/system cpu time consumed by the hypervisor, per-vm. +Requires libvirt API version I<0.9.11> or later. + +=item B: report performance monitoring events. To collect performance +metrics they must be enabled for domain and supported by the platform. Requires +libvirt API version I<1.3.3> or later. +B: I metrics can't be collected if I plugin is enabled. + +=item B: report pinning of domain VCPUs to host physical CPUs. + +=back + =back =head2 Plugin C @@ -8143,6 +8513,8 @@ packets. Synopsis: + ResolveInterval 60 + ResolveJitter 60 Host "tsd-1.my.domain" Port "4242" @@ -8151,7 +8523,36 @@ Synopsis: The configuration consists of one or more EBEIE -blocks. Inside the B blocks, the following options are recognized: +blocks and global directives. + +Global directives are: + +=over 4 + +=item B I + +=item B I + +When I 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 seconds. +Defaults to the I of the I, e.g. 10Eseconds. + +You can also define a jitter, a random interval to wait in addition to +I. This prevents all your collectd servers to resolve the +hostname at the same time when the connection fails. +Defaults to the I of the I, e.g. 10Eseconds. + +B 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 + I seconds. + +=back + +Inside the B blocks, the following options are recognized: =over 4 @@ -8368,6 +8769,15 @@ create output in the I (JSON). When set to KAIROSDB Defaults to B. +=item B I I + +Only available for KAIROSDB output format. + +Consider the two given strings to be the key and value of an additional tag for +each metric being sent out. + +You can add multiple B. + =item B B|B Controls whether I are POSTed to this location. Defaults to B. diff --git a/src/collectdctl.c b/src/collectdctl.c index 30d1cdc0..248baadf 100644 --- a/src/collectdctl.c +++ b/src/collectdctl.c @@ -585,5 +585,3 @@ int main(int argc, char **argv) { return (status); return (0); } /* main */ - -/* vim: set sw=2 ts=2 tw=78 expandtab : */ diff --git a/src/collectdmon.c b/src/collectdmon.c index 9040f8d9..4a7d1a6b 100644 --- a/src/collectdmon.c +++ b/src/collectdmon.c @@ -386,5 +386,3 @@ int main(int argc, char **argv) { free(collectd_argv); return 0; } /* main */ - -/* vim: set sw=4 ts=4 tw=78 noexpandtab : */ diff --git a/src/cpu.c b/src/cpu.c index 9091fef9..c0bdd56f 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -862,5 +862,3 @@ void module_register(void) { plugin_register_config("cpu", cpu_config, config_keys, config_keys_num); plugin_register_read("cpu", cpu_read); } /* void module_register */ - -/* vim: set sw=8 sts=8 noet fdm=marker : */ diff --git a/src/curl.c b/src/curl.c index c6f0b607..4906d927 100644 --- a/src/curl.c +++ b/src/curl.c @@ -679,5 +679,3 @@ void module_register(void) { plugin_register_read("curl", cc_read); plugin_register_shutdown("curl", cc_shutdown); } /* void module_register */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/curl_json.c b/src/curl_json.c index e6c0b513..4d8677ac 100644 --- a/src/curl_json.c +++ b/src/curl_json.c @@ -940,5 +940,3 @@ void module_register(void) { plugin_register_complex_config("curl_json", cj_config); plugin_register_init("curl_json", cj_init); } /* void module_register */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/curl_xml.c b/src/curl_xml.c index 4e4c6f99..1c282277 100644 --- a/src/curl_xml.c +++ b/src/curl_xml.c @@ -1026,5 +1026,3 @@ void module_register(void) { plugin_register_complex_config("curl_xml", cx_config); plugin_register_init("curl_xml", cx_init); } /* void module_register */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am deleted file mode 100644 index 52079438..00000000 --- a/src/daemon/Makefile.am +++ /dev/null @@ -1,111 +0,0 @@ -AM_CPPFLAGS = -I$(top_srcdir)/src -AM_CPPFLAGS += -DPREFIX='"${prefix}"' -AM_CPPFLAGS += -DCONFIGFILE='"${sysconfdir}/${PACKAGE_NAME}.conf"' -AM_CPPFLAGS += -DLOCALSTATEDIR='"${localstatedir}"' -AM_CPPFLAGS += -DPKGLOCALSTATEDIR='"${localstatedir}/lib/${PACKAGE_NAME}"' -if BUILD_FEATURE_DAEMON -AM_CPPFLAGS += -DPIDFILE='"${localstatedir}/run/${PACKAGE_NAME}.pid"' -endif -AM_CPPFLAGS += -DPLUGINDIR='"${pkglibdir}"' -AM_CPPFLAGS += -DPKGDATADIR='"${pkgdatadir}"' - -# Link to these libraries.. -COMMON_LIBS = $(PTHREAD_LIBS) -if BUILD_WITH_CAPABILITY -COMMON_LIBS += -lcap -endif -if BUILD_WITH_LIBRT -COMMON_LIBS += -lrt -endif -if BUILD_WITH_LIBPOSIX4 -COMMON_LIBS += -lposix4 -endif -if BUILD_WITH_LIBSOCKET -COMMON_LIBS += -lsocket -endif -if BUILD_WITH_LIBRESOLV -COMMON_LIBS += -lresolv -endif -if BUILD_WITH_LIBKSTAT -COMMON_LIBS += -lkstat -endif -if BUILD_WITH_LIBDEVINFO -COMMON_LIBS += -ldevinfo -endif - -sbin_PROGRAMS = collectd - -noinst_LTLIBRARIES = libavltree.la libcommon.la libheap.la libmetadata.la libplugin_mock.la - -libavltree_la_SOURCES = utils_avltree.c utils_avltree.h - -libcommon_la_SOURCES = common.c common.h -libcommon_la_LIBADD = $(COMMON_LIBS) - -libheap_la_SOURCES = utils_heap.c utils_heap.h - -libmetadata_la_SOURCES = meta_data.c meta_data.h - -libplugin_mock_la_SOURCES = plugin_mock.c utils_cache_mock.c \ - utils_time.c utils_time.h -libplugin_mock_la_CPPFLAGS = $(AM_CPPFLAGS) -DMOCK_TIME -libplugin_mock_la_LIBADD = $(COMMON_LIBS) libcommon.la - -collectd_SOURCES = collectd.c collectd.h \ - configfile.c configfile.h \ - filter_chain.c filter_chain.h \ - meta_data.c meta_data.h \ - plugin.c plugin.h \ - utils_cache.c utils_cache.h \ - utils_complain.c utils_complain.h \ - utils_ignorelist.c utils_ignorelist.h \ - utils_llist.c utils_llist.h \ - utils_random.c utils_random.h \ - utils_subst.c utils_subst.h \ - utils_time.c utils_time.h \ - types_list.c types_list.h \ - utils_threshold.c utils_threshold.h - - -collectd_CPPFLAGS = $(AM_CPPFLAGS) $(LTDLINCL) -collectd_CFLAGS = $(AM_CFLAGS) -collectd_LDFLAGS = -export-dynamic -collectd_LDADD = libavltree.la libcommon.la libheap.la -lm $(COMMON_LIBS) -collectd_DEPENDENCIES = libavltree.la libcommon.la libheap.la libmetadata.la - -# The daemon needs to call sg_init, so we need to link it against libstatgrab, -# too. -octo -if BUILD_WITH_LIBSTATGRAB -collectd_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) -collectd_LDADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) -endif - -if BUILD_WITH_OWN_LIBOCONFIG -collectd_LDADD += $(LIBLTDL) $(top_builddir)/src/liboconfig/liboconfig.la -collectd_DEPENDENCIES += $(top_builddir)/src/liboconfig/liboconfig.la -else -collectd_LDADD += -loconfig -endif - -LOG_COMPILER = env VALGRIND="@VALGRIND@" $(abs_top_srcdir)/testwrapper.sh - -check_PROGRAMS = test_common test_meta_data test_utils_avltree test_utils_heap test_utils_time test_utils_subst -TESTS = test_common test_meta_data test_utils_avltree test_utils_heap test_utils_time test_utils_subst - -test_common_SOURCES = common_test.c ../testing.h -test_common_LDADD = libplugin_mock.la - -test_meta_data_SOURCES = meta_data_test.c ../testing.h -test_meta_data_LDADD = libmetadata.la libplugin_mock.la - -test_utils_avltree_SOURCES = utils_avltree_test.c ../testing.h -test_utils_avltree_LDADD = libavltree.la $(COMMON_LIBS) - -test_utils_heap_SOURCES = utils_heap_test.c ../testing.h -test_utils_heap_LDADD = libheap.la $(COMMON_LIBS) - -test_utils_time_SOURCES = utils_time_test.c ../testing.h - -test_utils_subst_SOURCES = utils_subst_test.c ../testing.h \ - utils_subst.c utils_subst.h -test_utils_subst_LDADD = libplugin_mock.la diff --git a/src/daemon/collectd.h b/src/daemon/collectd.h index 4ec002de..38ffd0f6 100644 --- a/src/daemon/collectd.h +++ b/src/daemon/collectd.h @@ -31,36 +31,27 @@ #include "config.h" #endif +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include #if HAVE_SYS_TYPES_H #include #endif #if HAVE_SYS_STAT_H #include #endif -#if STDC_HEADERS -#include -#include -#else -#if HAVE_STDLIB_H -#include -#endif -#endif -#if HAVE_STRING_H -#if !STDC_HEADERS && HAVE_MEMORY_H -#include -#endif -#include -#endif #if HAVE_STRINGS_H #include #endif -#if HAVE_INTTYPES_H -#include -#endif -#if HAVE_STDINT_H -#include -#endif #if HAVE_UNISTD_H #include #endif @@ -73,18 +64,9 @@ #ifndef WIFEXITED #define WIFEXITED(stat_val) (((stat_val)&255) == 0) #endif -#if HAVE_SIGNAL_H -#include -#endif #if HAVE_FCNTL_H #include #endif -#if HAVE_ERRNO_H -#include -#endif -#if HAVE_LIMITS_H -#include -#endif #if TIME_WITH_SYS_TIME #include #include @@ -99,18 +81,6 @@ #include #endif -#if HAVE_ASSERT_H -#include -#else -#define assert(...) /* nop */ -#endif - -#if !defined(HAVE__BOOL) || !HAVE__BOOL -typedef int _Bool; -#undef HAVE__BOOL -#define HAVE__BOOL 1 -#endif - #if NAN_STATIC_DEFAULT #include /* #endif NAN_STATIC_DEFAULT*/ @@ -212,12 +182,6 @@ typedef int _Bool; #endif #endif -#if HAVE_STDARG_H -#include -#endif -#if HAVE_CTYPE_H -#include -#endif #if HAVE_SYS_PARAM_H #include #endif diff --git a/src/daemon/common.c b/src/daemon/common.c index ec5c7aba..a167122c 100644 --- a/src/daemon/common.c +++ b/src/daemon/common.c @@ -37,10 +37,6 @@ #include "plugin.h" #include "utils_cache.h" -#ifdef HAVE_MATH_H -#include -#endif - /* for getaddrinfo */ #include #include @@ -154,7 +150,7 @@ char *sstrdup(const char *s) { ERROR("sstrdup: Out of memory."); exit(3); } - memcpy(r, s, sizeof(char) * sz); + memcpy(r, s, sz); return (r); } /* char *sstrdup */ diff --git a/src/daemon/common_test.c b/src/daemon/common_test.c index 0c96945f..f18d9fda 100644 --- a/src/daemon/common_test.c +++ b/src/daemon/common_test.c @@ -392,5 +392,3 @@ int main(void) { END_TEST; } - -/* vim: set sw=2 sts=2 et : */ diff --git a/src/daemon/configfile.c b/src/daemon/configfile.c index 3934e1f9..654cc49b 100644 --- a/src/daemon/configfile.c +++ b/src/daemon/configfile.c @@ -245,7 +245,7 @@ static int dispatch_value_plugindir(oconfig_item_t *ci) { static int dispatch_loadplugin(oconfig_item_t *ci) { const char *name; - unsigned int flags = 0; + _Bool global = 0; plugin_ctx_t ctx = {0}; plugin_ctx_t old_ctx; int ret_val; @@ -270,7 +270,7 @@ static int dispatch_loadplugin(oconfig_item_t *ci) { oconfig_item_t *child = ci->children + i; if (strcasecmp("Globals", child->key) == 0) - cf_util_get_flag(child, &flags, PLUGIN_FLAGS_GLOBAL); + cf_util_get_boolean(child, &global); else if (strcasecmp("Interval", child->key) == 0) cf_util_get_cdtime(child, &ctx.interval); else if (strcasecmp("FlushInterval", child->key) == 0) @@ -285,7 +285,7 @@ static int dispatch_loadplugin(oconfig_item_t *ci) { } old_ctx = plugin_set_ctx(ctx); - ret_val = plugin_load(name, (uint32_t)flags); + ret_val = plugin_load(name, global); /* reset to the "global" context */ plugin_set_ctx(old_ctx); diff --git a/src/daemon/filter_chain.c b/src/daemon/filter_chain.c index 9c4a89c1..f21ea32b 100644 --- a/src/daemon/filter_chain.c +++ b/src/daemon/filter_chain.c @@ -942,5 +942,3 @@ int fc_configure(const oconfig_item_t *ci) /* {{{ */ return (-1); } /* }}} int fc_configure */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/daemon/filter_chain.h b/src/daemon/filter_chain.h index 36ccbae9..5cc06fc5 100644 --- a/src/daemon/filter_chain.h +++ b/src/daemon/filter_chain.h @@ -101,4 +101,3 @@ int fc_default_action(const data_set_t *ds, value_list_t *vl); int fc_configure(const oconfig_item_t *ci); #endif /* FILTER_CHAIN_H */ -/* vim: set sw=2 sts=2 et : */ diff --git a/src/daemon/meta_data.c b/src/daemon/meta_data.c index 583d8196..3ac53706 100644 --- a/src/daemon/meta_data.c +++ b/src/daemon/meta_data.c @@ -690,7 +690,7 @@ int meta_data_get_boolean(meta_data_t *md, /* {{{ */ int meta_data_as_string(meta_data_t *md, /* {{{ */ const char *key, char **value) { meta_entry_t *e; - char *actual; + const char *actual; char buffer[MD_MAX_NONSTRING_CHARS]; /* For non-string types. */ char *temp; int type; @@ -746,5 +746,3 @@ int meta_data_as_string(meta_data_t *md, /* {{{ */ return (0); } /* }}} int meta_data_as_string */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/daemon/meta_data.h b/src/daemon/meta_data.h index 3ef33604..50fdb8d6 100644 --- a/src/daemon/meta_data.h +++ b/src/daemon/meta_data.h @@ -69,4 +69,3 @@ int meta_data_get_boolean(meta_data_t *md, const char *key, _Bool *value); int meta_data_as_string(meta_data_t *md, const char *key, char **value); #endif /* META_DATA_H */ -/* vim: set sw=2 sts=2 et : */ diff --git a/src/daemon/meta_data_test.c b/src/daemon/meta_data_test.c index 803c7454..bcd457d4 100644 --- a/src/daemon/meta_data_test.c +++ b/src/daemon/meta_data_test.c @@ -114,5 +114,3 @@ int main(void) { END_TEST; } - -/* vim: set sw=2 sts=2 et : */ diff --git a/src/daemon/plugin.c b/src/daemon/plugin.c index 0f067374..b37e9b32 100644 --- a/src/daemon/plugin.c +++ b/src/daemon/plugin.c @@ -46,7 +46,7 @@ #include /* for pthread_set_name_np(3) */ #endif -#include +#include /* * Private structures @@ -388,40 +388,25 @@ static int plugin_unregister(llist_t *list, const char *name) /* {{{ */ * object, but it will bitch about a shared object not having a * ``module_register'' symbol.. */ -static int plugin_load_file(char *file, uint32_t flags) { - lt_dlhandle dlh; +static int plugin_load_file(const char *file, _Bool global) { void (*reg_handle)(void); - lt_dlinit(); - lt_dlerror(); /* clear errors */ + int flags = RTLD_NOW; + if (global) + flags |= RTLD_GLOBAL; -#if LIBTOOL_VERSION == 2 - if (flags & PLUGIN_FLAGS_GLOBAL) { - lt_dladvise advise; - lt_dladvise_init(&advise); - lt_dladvise_global(&advise); - dlh = lt_dlopenadvise(file, advise); - lt_dladvise_destroy(&advise); - } else { - dlh = lt_dlopen(file); - } -#else /* if LIBTOOL_VERSION == 1 */ - if (flags & PLUGIN_FLAGS_GLOBAL) - WARNING("plugin_load_file: The global flag is not supported, " - "libtool 2 is required for this."); - dlh = lt_dlopen(file); -#endif + void *dlh = dlopen(file, flags); if (dlh == NULL) { char errbuf[1024] = ""; ssnprintf(errbuf, sizeof(errbuf), - "lt_dlopen (\"%s\") failed: %s. " + "dlopen (\"%s\") failed: %s. " "The most common cause for this problem is " "missing dependencies. Use ldd(1) to check " "the dependencies of the plugin " "/ shared object.", - file, lt_dlerror()); + file, dlerror()); ERROR("%s", errbuf); /* Make sure this is printed to STDERR in any case, but also @@ -432,10 +417,11 @@ static int plugin_load_file(char *file, uint32_t flags) { return (1); } - if ((reg_handle = (void (*)(void))lt_dlsym(dlh, "module_register")) == NULL) { + reg_handle = (void (*)(void))dlsym(dlh, "module_register"); + if (reg_handle == NULL) { WARNING("Couldn't find symbol \"module_register\" in \"%s\": %s\n", file, - lt_dlerror()); - lt_dlclose(dlh); + dlerror()); + dlclose(dlh); return (-1); } @@ -972,7 +958,7 @@ static void plugin_free_loaded(void) { } #define BUFSIZE 512 -int plugin_load(char const *plugin_name, uint32_t flags) { +int plugin_load(char const *plugin_name, _Bool global) { DIR *dh; const char *dir; char filename[BUFSIZE] = ""; @@ -1006,7 +992,7 @@ int plugin_load(char const *plugin_name, uint32_t flags) { */ if ((strcasecmp("perl", plugin_name) == 0) || (strcasecmp("python", plugin_name) == 0)) - flags |= PLUGIN_FLAGS_GLOBAL; + global = 1; /* `cpu' should not match `cpufreq'. To solve this we add `.so' to the * type when matching the filename */ @@ -1044,7 +1030,7 @@ int plugin_load(char const *plugin_name, uint32_t flags) { continue; } - status = plugin_load_file(filename, flags); + status = plugin_load_file(filename, global); if (status == 0) { /* success */ plugin_mark_loaded(plugin_name); @@ -2590,5 +2576,3 @@ int plugin_thread_create(pthread_t *thread, const pthread_attr_t *attr, return 0; } /* int plugin_thread_create */ - -/* vim: set sw=8 ts=8 noet fdm=marker : */ diff --git a/src/daemon/plugin.h b/src/daemon/plugin.h index f6448a58..4f877e0e 100644 --- a/src/daemon/plugin.h +++ b/src/daemon/plugin.h @@ -36,8 +36,6 @@ #include -#define PLUGIN_FLAGS_GLOBAL 0x0001 - #ifndef DATA_MAX_NAME_LEN #define DATA_MAX_NAME_LEN 128 #endif @@ -226,7 +224,7 @@ void plugin_set_dir(const char *dir); * * ARGUMENTS * `name' Name of the plugin to load. - * `flags' Hints on how to handle this plugin. + * `global' Make this plugins symbols available for other shared libraries. * * RETURN VALUE * Returns zero upon success, a value greater than zero if no plugin was found @@ -236,7 +234,7 @@ void plugin_set_dir(const char *dir); * Re-loading an already loaded module is detected and zero is returned in * this case. */ -int plugin_load(const char *name, uint32_t flags); +int plugin_load(const char *name, _Bool global); int plugin_init_all(void); void plugin_read_all(void); diff --git a/src/daemon/plugin_mock.c b/src/daemon/plugin_mock.c index ddfc7890..9e7ba39e 100644 --- a/src/daemon/plugin_mock.c +++ b/src/daemon/plugin_mock.c @@ -32,6 +32,12 @@ kstat_ctl_t *kc = NULL; char hostname_g[] = "example.com"; +int plugin_register_config(const char *name, + int (*callback)(const char *key, const char *val), + const char **keys, int keys_num) { + return ENOTSUP; +} + int plugin_register_complex_config(const char *type, int (*callback)(oconfig_item_t *)) { return ENOTSUP; @@ -45,6 +51,13 @@ int plugin_register_read(const char *name, int (*callback)(void)) { return ENOTSUP; } +int plugin_register_complex_read(const char *group, const char *name, + int (*callback)(user_data_t *), + cdtime_t interval, + user_data_t const *user_data) { + return ENOTSUP; +} + int plugin_register_shutdown(const char *name, int (*callback)(void)) { return ENOTSUP; } @@ -76,5 +89,3 @@ void plugin_log(int level, char const *format, ...) { } cdtime_t plugin_get_interval(void) { return TIME_T_TO_CDTIME_T(10); } - -/* vim: set sw=2 sts=2 et : */ diff --git a/src/daemon/types_list.c b/src/daemon/types_list.c index b1a7203c..b0531571 100644 --- a/src/daemon/types_list.c +++ b/src/daemon/types_list.c @@ -191,7 +191,3 @@ int read_types_list(const char *file) { return (0); } /* int read_types_list */ - -/* - * vim: shiftwidth=2:softtabstop=2:tabstop=8 - */ diff --git a/src/daemon/utils_avltree_test.c b/src/daemon/utils_avltree_test.c index 0a84f6f9..345f97bf 100644 --- a/src/daemon/utils_avltree_test.c +++ b/src/daemon/utils_avltree_test.c @@ -135,5 +135,3 @@ int main(void) { END_TEST; } - -/* vim: set sw=2 sts=2 et : */ diff --git a/src/daemon/utils_cache.c b/src/daemon/utils_cache.c index fe0e083e..0caf22c5 100644 --- a/src/daemon/utils_cache.c +++ b/src/daemon/utils_cache.c @@ -938,5 +938,3 @@ int uc_meta_data_exists(const value_list_t *vl, const char *key, _Bool *value) UC_WRAP(meta_data_get_boolean) #undef UC_WRAP - - /* vim: set sw=2 ts=8 sts=2 tw=78 : */ diff --git a/src/daemon/utils_cache.h b/src/daemon/utils_cache.h index 2f408734..24c58ff7 100644 --- a/src/daemon/utils_cache.h +++ b/src/daemon/utils_cache.h @@ -133,5 +133,4 @@ int uc_meta_data_get_double(const value_list_t *vl, const char *key, int uc_meta_data_get_boolean(const value_list_t *vl, const char *key, _Bool *value); -/* vim: set shiftwidth=2 softtabstop=2 tabstop=8 : */ #endif /* !UTILS_CACHE_H */ diff --git a/src/daemon/utils_complain.c b/src/daemon/utils_complain.c index fb452431..d2162ba7 100644 --- a/src/daemon/utils_complain.c +++ b/src/daemon/utils_complain.c @@ -97,5 +97,3 @@ void c_do_release(int level, c_complain_t *c, const char *format, ...) { plugin_log(level, "%s", message); } /* c_release */ - -/* vim: set sw=4 ts=4 tw=78 noexpandtab : */ diff --git a/src/daemon/utils_complain.h b/src/daemon/utils_complain.h index fbeea90f..46d3a198 100644 --- a/src/daemon/utils_complain.h +++ b/src/daemon/utils_complain.h @@ -113,5 +113,3 @@ c_do_release(int level, c_complain_t *c, const char *format, ...); } while (0) #endif /* UTILS_COMPLAIN_H */ - -/* vim: set sw=4 ts=4 tw=78 noexpandtab : */ diff --git a/src/daemon/utils_heap.c b/src/daemon/utils_heap.c index 8dd501da..3bae48ee 100644 --- a/src/daemon/utils_heap.c +++ b/src/daemon/utils_heap.c @@ -203,5 +203,3 @@ void *c_heap_get_root(c_heap_t *h) { return (ret); } /* void *c_heap_get_root */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/daemon/utils_heap.h b/src/daemon/utils_heap.h index 2f77cc45..d2d70cdc 100644 --- a/src/daemon/utils_heap.h +++ b/src/daemon/utils_heap.h @@ -97,4 +97,3 @@ int c_heap_insert(c_heap_t *h, void *ptr); void *c_heap_get_root(c_heap_t *h); #endif /* UTILS_HEAP_H */ -/* vim: set sw=2 sts=2 et : */ diff --git a/src/daemon/utils_heap_test.c b/src/daemon/utils_heap_test.c index 8443b605..dec84f94 100644 --- a/src/daemon/utils_heap_test.c +++ b/src/daemon/utils_heap_test.c @@ -76,5 +76,3 @@ int main(void) { END_TEST; } - -/* vim: set sw=2 sts=2 et : */ diff --git a/src/daemon/utils_ignorelist.c b/src/daemon/utils_ignorelist.c deleted file mode 100644 index 9cf6aa1e..00000000 --- a/src/daemon/utils_ignorelist.c +++ /dev/null @@ -1,309 +0,0 @@ -/** - * collectd - src/utils_ignorelist.c - * Copyright (C) 2006 Lubos Stanek - * Copyright (C) 2008 Florian Forster - * - * This program is free software; you can redistribute it and/ - * or modify it under the terms of the GNU General Public Li- - * cence as published by the Free Software Foundation; either - * version 2 of the Licence, or any later version. - * - * This program is distributed in the hope that it will be use- - * ful, but WITHOUT ANY WARRANTY; without even the implied war- - * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public Licence for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Authors: - * Lubos Stanek - * Florian Forster - **/ -/** - * ignorelist handles plugin's list of configured collectable - * entries with global ignore action - **/ -/** - * Usage: - * - * Define plugin's global pointer variable of type ignorelist_t: - * ignorelist_t *myconfig_ignore; - * If you know the state of the global ignore (IgnoreSelected), - * allocate the variable with: - * myconfig_ignore = ignorelist_create (YourKnownIgnore); - * If you do not know the state of the global ignore, - * initialize the global variable and set the ignore flag later: - * myconfig_ignore = ignorelist_init (); - * Append single entries in your cf_register'ed callback function: - * ignorelist_add (myconfig_ignore, newentry); - * When you hit the IgnoreSelected config option, - * offer it to the list: - * ignorelist_ignore (myconfig_ignore, instantly_got_value_of_ignore); - * That is all for the ignorelist initialization. - * Later during read and write (plugin's registered functions) get - * the information whether this entry would be collected or not: - * if (ignorelist_match (myconfig_ignore, thisentry)) - * return; - **/ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include "common.h" -#include "plugin.h" -#include "utils_ignorelist.h" - -/* - * private prototypes - */ -struct ignorelist_item_s { -#if HAVE_REGEX_H - regex_t *rmatch; /* regular expression entry identification */ -#endif - char *smatch; /* string entry identification */ - struct ignorelist_item_s *next; -}; -typedef struct ignorelist_item_s ignorelist_item_t; - -struct ignorelist_s { - int ignore; /* ignore entries */ - ignorelist_item_t *head; /* pointer to the first entry */ -}; - -/* *** *** *** ********************************************* *** *** *** */ -/* *** *** *** *** *** *** private functions *** *** *** *** *** *** */ -/* *** *** *** ********************************************* *** *** *** */ - -static inline void ignorelist_append(ignorelist_t *il, - ignorelist_item_t *item) { - assert((il != NULL) && (item != NULL)); - - item->next = il->head; - il->head = item; -} - -#if HAVE_REGEX_H -static int ignorelist_append_regex(ignorelist_t *il, const char *re_str) { - regex_t *re; - ignorelist_item_t *entry; - int status; - - re = calloc(1, sizeof(*re)); - if (re == NULL) { - ERROR("ignorelist_append_regex: calloc failed."); - return (ENOMEM); - } - - status = regcomp(re, re_str, REG_EXTENDED); - if (status != 0) { - char errbuf[1024]; - (void)regerror(status, re, errbuf, sizeof(errbuf)); - ERROR("utils_ignorelist: regcomp failed: %s", errbuf); - ERROR("ignorelist_append_regex: Compiling regular expression \"%s\" " - "failed: %s", - re_str, errbuf); - sfree(re); - return (status); - } - - entry = calloc(1, sizeof(*entry)); - if (entry == NULL) { - ERROR("ignorelist_append_regex: calloc failed."); - regfree(re); - sfree(re); - return (ENOMEM); - } - entry->rmatch = re; - - ignorelist_append(il, entry); - return (0); -} /* int ignorelist_append_regex */ -#endif - -static int ignorelist_append_string(ignorelist_t *il, const char *entry) { - ignorelist_item_t *new; - - /* create new entry */ - if ((new = calloc(1, sizeof(*new))) == NULL) { - ERROR("cannot allocate new entry"); - return (1); - } - new->smatch = sstrdup(entry); - - /* append new entry */ - ignorelist_append(il, new); - - return (0); -} /* int ignorelist_append_string(ignorelist_t *il, const char *entry) */ - -#if HAVE_REGEX_H -/* - * check list for entry regex match - * return 1 if found - */ -static int ignorelist_match_regex(ignorelist_item_t *item, const char *entry) { - assert((item != NULL) && (item->rmatch != NULL) && (entry != NULL) && - (strlen(entry) > 0)); - - /* match regex */ - if (regexec(item->rmatch, entry, 0, NULL, 0) == 0) - return (1); - - return (0); -} /* int ignorelist_match_regex (ignorelist_item_t *item, const char *entry) */ -#endif - -/* - * check list for entry string match - * return 1 if found - */ -static int ignorelist_match_string(ignorelist_item_t *item, const char *entry) { - assert((item != NULL) && (item->smatch != NULL) && (entry != NULL) && - (strlen(entry) > 0)); - - if (strcmp(entry, item->smatch) == 0) - return (1); - - return (0); -} /* int ignorelist_match_string (ignorelist_item_t *item, const char *entry) */ - -/* *** *** *** ******************************************** *** *** *** */ -/* *** *** *** *** *** *** public functions *** *** *** *** *** *** */ -/* *** *** *** ******************************************** *** *** *** */ - -/* - * create the ignorelist_t with known ignore state - * return pointer to ignorelist_t - */ -ignorelist_t *ignorelist_create(int invert) { - ignorelist_t *il; - - il = calloc(1, sizeof(*il)); - if (il == NULL) - return NULL; - - /* - * ->ignore == 0 => collect - * ->ignore == 1 => ignore - */ - il->ignore = invert ? 0 : 1; - - return (il); -} /* ignorelist_t *ignorelist_create (int ignore) */ - -/* - * free memory used by ignorelist_t - */ -void ignorelist_free(ignorelist_t *il) { - ignorelist_item_t *this; - ignorelist_item_t *next; - - if (il == NULL) - return; - - for (this = il->head; this != NULL; this = next) { - next = this->next; -#if HAVE_REGEX_H - if (this->rmatch != NULL) { - regfree(this->rmatch); - sfree(this->rmatch); - this->rmatch = NULL; - } -#endif - if (this->smatch != NULL) { - sfree(this->smatch); - this->smatch = NULL; - } - sfree(this); - } - - sfree(il); -} /* void ignorelist_destroy (ignorelist_t *il) */ - -/* - * set ignore state of the ignorelist_t - */ -void ignorelist_set_invert(ignorelist_t *il, int invert) { - if (il == NULL) { - DEBUG("ignore call with ignorelist_t == NULL"); - return; - } - - il->ignore = invert ? 0 : 1; -} /* void ignorelist_set_invert (ignorelist_t *il, int ignore) */ - -/* - * append entry into ignorelist_t - * return 0 for success - */ -int ignorelist_add(ignorelist_t *il, const char *entry) { - size_t len; - - if (il == NULL) { - DEBUG("add called with ignorelist_t == NULL"); - return (1); - } - - len = strlen(entry); - - /* append nothing */ - if (len == 0) { - DEBUG("not appending: empty entry"); - return (1); - } - -#if HAVE_REGEX_H - /* regex string is enclosed in "/.../" */ - if ((len > 2) && (entry[0] == '/') && entry[len - 1] == '/') { - char *copy; - int status; - - /* skip leading slash */ - copy = strdup(entry + 1); - if (copy == NULL) - return ENOMEM; - - /* trim trailing slash */ - copy[strlen(copy) - 1] = 0; - - status = ignorelist_append_regex(il, copy); - sfree(copy); - return status; - } -#endif - - return ignorelist_append_string(il, entry); -} /* int ignorelist_add (ignorelist_t *il, const char *entry) */ - -/* - * check list for entry - * return 1 for ignored entry - */ -int ignorelist_match(ignorelist_t *il, const char *entry) { - /* if no entries, collect all */ - if ((il == NULL) || (il->head == NULL)) - return (0); - - if ((entry == NULL) || (strlen(entry) == 0)) - return (0); - - /* traverse list and check entries */ - for (ignorelist_item_t *traverse = il->head; traverse != NULL; - traverse = traverse->next) { -#if HAVE_REGEX_H - if (traverse->rmatch != NULL) { - if (ignorelist_match_regex(traverse, entry)) - return (il->ignore); - } else -#endif - { - if (ignorelist_match_string(traverse, entry)) - return (il->ignore); - } - } /* for traverse */ - - return (1 - il->ignore); -} /* int ignorelist_match (ignorelist_t *il, const char *entry) */ diff --git a/src/daemon/utils_ignorelist.h b/src/daemon/utils_ignorelist.h deleted file mode 100644 index a7fa86d5..00000000 --- a/src/daemon/utils_ignorelist.h +++ /dev/null @@ -1,69 +0,0 @@ -/** - * collectd - src/utils_ignorelist.h - * Copyright (C) 2006 Lubos Stanek - * - * This program is free software; you can redistribute it and/ - * or modify it under the terms of the GNU General Public Li- - * cence as published by the Free Software Foundation; either - * version 2 of the Licence, or any later version. - * - * This program is distributed in the hope that it will be use- - * ful, but WITHOUT ANY WARRANTY; without even the implied war- - * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public Licence for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Authors: - * Lubos Stanek - **/ -/** - * ignorelist handles plugin's list of configured collectable - * entries with global ignore action - **/ - -#ifndef UTILS_IGNORELIST_H -#define UTILS_IGNORELIST_H 1 - -#include "collectd.h" - -#if HAVE_REGEX_H -#include -#endif - -/* public prototypes */ - -struct ignorelist_s; -typedef struct ignorelist_s ignorelist_t; - -/* - * create the ignorelist_t with known ignore state - * return pointer to ignorelist_t - */ -ignorelist_t *ignorelist_create(int invert); - -/* - * free memory used by ignorelist_t - */ -void ignorelist_free(ignorelist_t *il); - -/* - * set ignore state of the ignorelist_t - */ -void ignorelist_set_invert(ignorelist_t *il, int invert); - -/* - * append entry to ignorelist_t - * returns zero on success, non-zero upon failure. - */ -int ignorelist_add(ignorelist_t *il, const char *entry); - -/* - * check list for entry - * return 1 for ignored entry - */ -int ignorelist_match(ignorelist_t *il, const char *entry); - -#endif /* UTILS_IGNORELIST_H */ diff --git a/src/daemon/utils_random.c b/src/daemon/utils_random.c index d490986d..77b500fb 100644 --- a/src/daemon/utils_random.c +++ b/src/daemon/utils_random.c @@ -50,7 +50,7 @@ static void cdrand_seed(void) { have_seed = 1; } -double cdrand_d() { +double cdrand_d(void) { double r; pthread_mutex_lock(&lock); @@ -61,7 +61,7 @@ double cdrand_d() { return (r); } -uint32_t cdrand_u() { +uint32_t cdrand_u(void) { long r; pthread_mutex_lock(&lock); diff --git a/src/daemon/utils_random.h b/src/daemon/utils_random.h index e25ae9b6..75bdc12e 100644 --- a/src/daemon/utils_random.h +++ b/src/daemon/utils_random.h @@ -29,7 +29,7 @@ * * This function is thread- and reentrant-safe. */ -double cdrand_d(); +double cdrand_d(void); /** * cdrand_u returns a random uint32_t value uniformly distributed in the range @@ -37,7 +37,7 @@ double cdrand_d(); * * This function is thread- and reentrant-safe. */ -uint32_t cdrand_u(); +uint32_t cdrand_u(void); /** * Returns a random long between min and max, inclusively. diff --git a/src/daemon/utils_subst.c b/src/daemon/utils_subst.c index 7056c5f0..52353432 100644 --- a/src/daemon/utils_subst.c +++ b/src/daemon/utils_subst.c @@ -159,5 +159,3 @@ char *subst_string(char *buf, size_t buflen, const char *string, return (buf); } /* char *subst_string */ - -/* vim: set sw=4 ts=4 tw=78 noexpandtab : */ diff --git a/src/daemon/utils_subst.h b/src/daemon/utils_subst.h index 025f8d4e..a10b2589 100644 --- a/src/daemon/utils_subst.h +++ b/src/daemon/utils_subst.h @@ -100,5 +100,3 @@ char *subst_string(char *buf, size_t buflen, const char *string, const char *needle, const char *replacement); #endif /* UTILS_SUBST_H */ - -/* vim: set sw=4 ts=4 tw=78 noexpandtab : */ diff --git a/src/daemon/utils_subst_test.c b/src/daemon/utils_subst_test.c index e335b501..00ea0eae 100644 --- a/src/daemon/utils_subst_test.c +++ b/src/daemon/utils_subst_test.c @@ -132,5 +132,3 @@ int main(void) { END_TEST; } - -/* vim: set sw=2 sts=2 et : */ diff --git a/src/daemon/utils_threshold.h b/src/daemon/utils_threshold.h index 585ad12a..cefc6e2c 100644 --- a/src/daemon/utils_threshold.h +++ b/src/daemon/utils_threshold.h @@ -61,5 +61,3 @@ threshold_t *threshold_search(const value_list_t *vl); int ut_search_threshold(const value_list_t *vl, threshold_t *ret_threshold); #endif /* UTILS_THRESHOLD_H */ - -/* vim: set sw=2 sts=2 ts=8 : */ diff --git a/src/daemon/utils_time.c b/src/daemon/utils_time.c index 9ba2b5a1..815d9697 100644 --- a/src/daemon/utils_time.c +++ b/src/daemon/utils_time.c @@ -240,5 +240,3 @@ int rfc3339nano_local(char *buffer, size_t buffer_size, cdtime_t t) /* {{{ */ return format_rfc3339_local(buffer, buffer_size, t, 1); } /* }}} int rfc3339nano */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/daemon/utils_time.h b/src/daemon/utils_time.h index db510afe..60a6ea95 100644 --- a/src/daemon/utils_time.h +++ b/src/daemon/utils_time.h @@ -130,4 +130,3 @@ int rfc3339_local(char *buffer, size_t buffer_size, cdtime_t t); int rfc3339nano_local(char *buffer, size_t buffer_size, cdtime_t t); #endif /* UTILS_TIME_H */ -/* vim: set sw=2 sts=2 et : */ diff --git a/src/daemon/utils_time_test.c b/src/daemon/utils_time_test.c index c1c60a20..c0179cc0 100644 --- a/src/daemon/utils_time_test.c +++ b/src/daemon/utils_time_test.c @@ -167,5 +167,3 @@ int main(void) { END_TEST; } - -/* vim: set sw=2 sts=2 et : */ diff --git a/src/dbi.c b/src/dbi.c index 7cab1d54..2b374e9f 100644 --- a/src/dbi.c +++ b/src/dbi.c @@ -780,7 +780,3 @@ void module_register(void) /* {{{ */ plugin_register_init("dbi", cdbi_init); plugin_register_shutdown("dbi", cdbi_shutdown); } /* }}} void module_register */ - -/* - * vim: shiftwidth=2 softtabstop=2 et fdm=marker - */ diff --git a/src/disk.c b/src/disk.c index e01e1506..58a1c189 100644 --- a/src/disk.c +++ b/src/disk.c @@ -139,7 +139,7 @@ static int pnumdisk; #error "No applicable input method." #endif -#if HAVE_LIBUDEV +#if HAVE_UDEV_H #include static char *conf_udev_name_attr = NULL; @@ -173,7 +173,7 @@ static int disk_config(const char *key, const char *value) { "on Mach / Mac OS X and will be ignored."); #endif } else if (strcasecmp("UdevNameAttr", key) == 0) { -#if HAVE_LIBUDEV +#if HAVE_UDEV_H if (conf_udev_name_attr != NULL) { free(conf_udev_name_attr); conf_udev_name_attr = NULL; @@ -209,7 +209,7 @@ static int disk_init(void) { /* #endif HAVE_IOKIT_IOKITLIB_H */ #elif KERNEL_LINUX -#if HAVE_LIBUDEV +#if HAVE_UDEV_H if (conf_udev_name_attr != NULL) { handle_udev = udev_new(); if (handle_udev == NULL) { @@ -217,7 +217,7 @@ static int disk_init(void) { return (-1); } } -#endif /* HAVE_LIBUDEV */ +#endif /* HAVE_UDEV_H */ /* #endif KERNEL_LINUX */ #elif KERNEL_FREEBSD @@ -260,10 +260,10 @@ static int disk_init(void) { static int disk_shutdown(void) { #if KERNEL_LINUX -#if HAVE_LIBUDEV +#if HAVE_UDEV_H if (handle_udev != NULL) udev_unref(handle_udev); -#endif /* HAVE_LIBUDEV */ +#endif /* HAVE_UDEV_H */ #endif /* KERNEL_LINUX */ return (0); } /* int disk_shutdown */ @@ -325,7 +325,7 @@ static counter_t disk_calc_time_incr(counter_t delta_time, } #endif -#if HAVE_LIBUDEV +#if HAVE_UDEV_H /** * Attempt to provide an rename disk instance from an assigned udev attribute. * @@ -842,7 +842,7 @@ static int disk_read(void) { output_name = disk_name; -#if HAVE_LIBUDEV +#if HAVE_UDEV_H char *alt_name = NULL; if (conf_udev_name_attr != NULL) { alt_name = @@ -853,7 +853,7 @@ static int disk_read(void) { #endif if (ignorelist_match(ignorelist, output_name) != 0) { -#if HAVE_LIBUDEV +#if HAVE_UDEV_H /* release udev-based alternate name, if allocated */ sfree(alt_name); #endif @@ -879,7 +879,7 @@ static int disk_read(void) { submit_io_time(output_name, io_time, weighted_time); } /* if (is_disk) */ -#if HAVE_LIBUDEV +#if HAVE_UDEV_H /* release udev-based alternate name, if allocated */ sfree(alt_name); #endif diff --git a/src/dpdkevents.c b/src/dpdkevents.c new file mode 100644 index 00000000..6be6bc04 --- /dev/null +++ b/src/dpdkevents.c @@ -0,0 +1,584 @@ +/* + * collectd - src/dpdkevents.c + * MIT License + * + * Copyright(c) 2017 Intel Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Maryam Tahhan + * Harry van Haaren + * Serhiy Pshyk + * Kim-Marie Jones + * Krzysztof Matczak + */ + +#include "collectd.h" + +#include "common.h" +#include "plugin.h" + +#include "semaphore.h" +#include "sys/mman.h" +#include "utils_dpdk.h" +#include "utils_time.h" + +#include +#include +#include +#include + +#define DPDK_EVENTS_PLUGIN "dpdkevents" +#define DPDK_EVENTS_NAME "dpdk_collectd_events" +#define ETH_LINK_NA 0xFF + +#define INT64_BIT_SIZE 64 +#define KEEPALIVE_PLUGIN_INSTANCE "keepalive" +#define RTE_KEEPALIVE_SHM_NAME "/dpdk_keepalive_shm_name" + +typedef struct dpdk_keepalive_shm_s { + sem_t core_died; + enum rte_keepalive_state core_state[RTE_KEEPALIVE_MAXCORES]; + uint64_t core_last_seen_times[RTE_KEEPALIVE_MAXCORES]; +} dpdk_keepalive_shm_t; + +typedef struct dpdk_ka_monitor_s { + cdtime_t read_time; + int lcore_state; +} dpdk_ka_monitor_t; + +typedef struct dpdk_link_status_config_s { + int enabled; + int send_updated; + uint32_t enabled_port_mask; + char port_name[RTE_MAX_ETHPORTS][DATA_MAX_NAME_LEN]; + int notify; +} dpdk_link_status_config_t; + +typedef struct dpdk_keep_alive_config_s { + int enabled; + int send_updated; + uint128_t lcore_mask; + dpdk_keepalive_shm_t *shm; + char shm_name[DATA_MAX_NAME_LEN]; + int notify; +} dpdk_keep_alive_config_t; + +typedef struct dpdk_events_config_s { + cdtime_t interval; + dpdk_link_status_config_t link_status; + dpdk_keep_alive_config_t keep_alive; +} dpdk_events_config_t; + +typedef struct dpdk_link_info_s { + cdtime_t read_time; + int status_updated; + int link_status; +} dpdk_link_info_t; + +typedef struct dpdk_events_ctx_s { + dpdk_events_config_t config; + uint32_t nb_ports; + dpdk_link_info_t link_info[RTE_MAX_ETHPORTS]; + dpdk_ka_monitor_t core_info[RTE_KEEPALIVE_MAXCORES]; +} dpdk_events_ctx_t; + +#define DPDK_EVENTS_CTX_GET(a) ((dpdk_events_ctx_t *)dpdk_helper_priv_get(a)) + +#define DPDK_EVENTS_TRACE() \ + DEBUG("%s:%s:%d pid=%u", DPDK_EVENTS_PLUGIN, __FUNCTION__, __LINE__, getpid()) + +static dpdk_helper_ctx_t *g_hc; + +static int dpdk_event_keep_alive_shm_create(void) { + dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(g_hc); + char *shm_name; + + if (strlen(ec->config.keep_alive.shm_name)) { + shm_name = ec->config.keep_alive.shm_name; + } else { + shm_name = RTE_KEEPALIVE_SHM_NAME; + WARNING(DPDK_EVENTS_PLUGIN ": Keep alive shared memory identifier is not " + "specified, using default one: %s", + shm_name); + } + + char errbuf[ERR_BUF_SIZE]; + int fd = shm_open(shm_name, O_RDWR, 0); + if (fd < 0) { + ERROR(DPDK_EVENTS_PLUGIN ": Failed to open %s as SHM:%s. Is DPDK KA " + "primary application running?", + shm_name, sstrerror(errno, errbuf, sizeof(errbuf))); + return errno; + } else { + ec->config.keep_alive.shm = + (dpdk_keepalive_shm_t *)mmap(0, sizeof(*(ec->config.keep_alive.shm)), + PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + close(fd); + if (ec->config.keep_alive.shm == MAP_FAILED) { + ERROR(DPDK_EVENTS_PLUGIN ": Failed to mmap KA SHM:%s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return errno; + } + } + + return 0; +} + +static void dpdk_events_default_config(void) { + dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(g_hc); + + ec->config.interval = plugin_get_interval(); + + /* Link Status */ + ec->config.link_status.enabled = 0; + ec->config.link_status.enabled_port_mask = ~0; + ec->config.link_status.send_updated = 1; + ec->config.link_status.notify = 0; + + for (int i = 0; i < RTE_MAX_ETHPORTS; i++) { + ec->config.link_status.port_name[i][0] = 0; + } + + /* Keep Alive */ + ec->config.keep_alive.enabled = 0; + ec->config.keep_alive.send_updated = 1; + ec->config.keep_alive.notify = 0; + memset(&ec->config.keep_alive.lcore_mask, 0, + sizeof(ec->config.keep_alive.lcore_mask)); + memset(&ec->config.keep_alive.shm_name, 0, + sizeof(ec->config.keep_alive.shm_name)); +} + +static int dpdk_events_preinit(void) { + DPDK_EVENTS_TRACE(); + + if (g_hc != NULL) { + /* already initialized if config callback was called before init callback */ + DEBUG("dpdk_events_preinit: helper already initialized."); + return 0; + } + + int ret = + dpdk_helper_init(DPDK_EVENTS_NAME, sizeof(dpdk_events_ctx_t), &g_hc); + if (ret != 0) { + ERROR(DPDK_EVENTS_PLUGIN ": failed to initialize %s helper(error: %s)", + DPDK_EVENTS_NAME, strerror(ret)); + return ret; + } + + dpdk_events_default_config(); + + dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(g_hc); + for (int i = 0; i < RTE_MAX_ETHPORTS; i++) { + ec->link_info[i].link_status = ETH_LINK_NA; + } + + for (int i = 0; i < RTE_KEEPALIVE_MAXCORES; i++) { + ec->core_info[i].lcore_state = ETH_LINK_NA; + } + + return ret; +} + +static int dpdk_events_link_status_config(dpdk_events_ctx_t *ec, + oconfig_item_t *ci) { + ec->config.link_status.enabled = 1; + + DEBUG(DPDK_EVENTS_PLUGIN ": Subscribed for Link Status Events."); + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("EnabledPortMask", child->key) == 0) { + ec->config.link_status.enabled_port_mask = + (uint32_t)child->values[0].value.number; + DEBUG(DPDK_EVENTS_PLUGIN ": LinkStatus:Enabled Port Mask 0x%X", + ec->config.link_status.enabled_port_mask); + } else if (strcasecmp("SendEventsOnUpdate", child->key) == 0) { + ec->config.link_status.send_updated = child->values[0].value.boolean; + DEBUG(DPDK_EVENTS_PLUGIN ": LinkStatus:SendEventsOnUpdate %d", + (int)child->values[0].value.boolean); + } else if (strcasecmp("SendNotification", child->key) == 0) { + ec->config.link_status.notify = child->values[0].value.boolean; + DEBUG(DPDK_EVENTS_PLUGIN ": LinkStatus:SendNotification %d", + (int)child->values[0].value.boolean); + } + } + + int port_num = 0; + + /* parse port names after EnabledPortMask was parsed */ + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + if (strcasecmp("PortName", child->key) == 0) { + while (!(ec->config.link_status.enabled_port_mask & (1 << port_num))) + port_num++; + ssnprintf(ec->config.link_status.port_name[port_num], DATA_MAX_NAME_LEN, + "%s", child->values[0].value.string); + DEBUG(DPDK_EVENTS_PLUGIN ": LinkStatus:Port %d Name: %s", port_num, + ec->config.link_status.port_name[port_num]); + port_num++; + } + } + + return 0; +} + +static int dpdk_events_keep_alive_config(dpdk_events_ctx_t *ec, + oconfig_item_t *ci) { + ec->config.keep_alive.enabled = 1; + DEBUG(DPDK_EVENTS_PLUGIN ": Subscribed for Keep Alive Events."); + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("SendEventsOnUpdate", child->key) == 0) { + ec->config.keep_alive.send_updated = child->values[0].value.boolean; + DEBUG(DPDK_EVENTS_PLUGIN ": KeepAlive:SendEventsOnUpdate %d", + (int)child->values[0].value.boolean); + } else if (strcasecmp("LCoreMask", child->key) == 0) { + char lcore_mask[DATA_MAX_NAME_LEN]; + ssnprintf(lcore_mask, sizeof(lcore_mask), "%s", + child->values[0].value.string); + ec->config.keep_alive.lcore_mask = + str_to_uint128(lcore_mask, strlen(lcore_mask)); + DEBUG(DPDK_EVENTS_PLUGIN ": KeepAlive:LCoreMask 0x%" PRIX64 "%" PRIX64 "", + ec->config.keep_alive.lcore_mask.high, + ec->config.keep_alive.lcore_mask.low); + } else if (strcasecmp("KeepAliveShmName", child->key) == 0) { + ssnprintf(ec->config.keep_alive.shm_name, + sizeof(ec->config.keep_alive.shm_name), "%s", + child->values[0].value.string); + DEBUG(DPDK_EVENTS_PLUGIN ": KeepAlive:KeepAliveShmName %s", + ec->config.keep_alive.shm_name); + } else if (strcasecmp("SendNotification", child->key) == 0) { + ec->config.keep_alive.notify = child->values[0].value.boolean; + DEBUG(DPDK_EVENTS_PLUGIN ": KeepAlive:SendNotification %d", + (int)child->values[0].value.boolean); + } + } + + return 0; +} + +static int dpdk_events_config(oconfig_item_t *ci) { + DPDK_EVENTS_TRACE(); + + int ret = dpdk_events_preinit(); + if (ret) + return ret; + + dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(g_hc); + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + if (strcasecmp("EAL", child->key) == 0) { + dpdk_helper_eal_config_parse(g_hc, child); + } else if (strcasecmp("Event", child->key) == 0) { + if (strcasecmp(child->values[0].value.string, "link_status") == 0) { + dpdk_events_link_status_config(ec, child); + } else if (strcasecmp(child->values[0].value.string, "keep_alive") == 0) { + dpdk_events_keep_alive_config(ec, child); + } else { + ERROR(DPDK_EVENTS_PLUGIN ": The selected event \"%s\" is unknown.", + child->values[0].value.string); + } + } + } + + if (!ec->config.keep_alive.enabled && !ec->config.link_status.enabled) { + ERROR(DPDK_EVENTS_PLUGIN ": At least one type of events should be " + "configured for collecting. Plugin misconfigured"); + return -1; + } + + return ret; +} + +static int dpdk_helper_link_status_get(dpdk_helper_ctx_t *phc) { + dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(phc); + + /* get Link Status values from DPDK */ + uint8_t nb_ports = rte_eth_dev_count(); + if (nb_ports == 0) { + DPDK_CHILD_LOG("dpdkevent-helper: No DPDK ports available. " + "Check bound devices to DPDK driver.\n"); + return -ENODEV; + } + ec->nb_ports = nb_ports > RTE_MAX_ETHPORTS ? RTE_MAX_ETHPORTS : nb_ports; + + for (int i = 0; i < ec->nb_ports; i++) { + if (ec->config.link_status.enabled_port_mask & (1 << i)) { + struct rte_eth_link link; + ec->link_info[i].read_time = cdtime(); + rte_eth_link_get_nowait(i, &link); + if ((link.link_status == ETH_LINK_NA) || + (link.link_status != ec->link_info[i].link_status)) { + ec->link_info[i].link_status = link.link_status; + ec->link_info[i].status_updated = 1; + DPDK_CHILD_LOG(" === PORT %d Link Status: %s\n", i, + link.link_status ? "UP" : "DOWN"); + } + } + } + + return 0; +} + +/* this function is called from helper context */ +int dpdk_helper_command_handler(dpdk_helper_ctx_t *phc, enum DPDK_CMD cmd) { + if (phc == NULL) { + DPDK_CHILD_LOG(DPDK_EVENTS_PLUGIN ": Invalid argument(phc)\n"); + return -EINVAL; + } + + if (cmd != DPDK_CMD_GET_EVENTS) { + DPDK_CHILD_LOG(DPDK_EVENTS_PLUGIN ": Unknown command (cmd=%d)\n", cmd); + return -EINVAL; + } + + dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(phc); + int ret = 0; + if (ec->config.link_status.enabled) + ret = dpdk_helper_link_status_get(phc); + + return ret; +} + +static void dpdk_events_notification_dispatch(int severity, + const char *plugin_instance, + cdtime_t time, const char *msg) { + notification_t n = { + .severity = severity, .time = time, .plugin = DPDK_EVENTS_PLUGIN}; + sstrncpy(n.host, hostname_g, sizeof(n.host)); + sstrncpy(n.plugin_instance, plugin_instance, sizeof(n.plugin_instance)); + sstrncpy(n.message, msg, sizeof(n.message)); + plugin_dispatch_notification(&n); +} + +static void dpdk_events_gauge_submit(const char *plugin_instance, + const char *type_instance, gauge_t value, + cdtime_t time) { + value_list_t vl = {.values = &(value_t){.gauge = value}, + .values_len = 1, + .time = time, + .plugin = DPDK_EVENTS_PLUGIN, + .type = "gauge", + .meta = NULL}; + sstrncpy(vl.host, hostname_g, sizeof(vl.host)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); + plugin_dispatch_values(&vl); +} + +static int dpdk_events_link_status_dispatch(dpdk_helper_ctx_t *phc) { + dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(phc); + DEBUG(DPDK_EVENTS_PLUGIN ": %s:%d ports=%u", __FUNCTION__, __LINE__, + ec->nb_ports); + + /* dispatch Link Status values to collectd */ + for (int i = 0; i < ec->nb_ports; i++) { + if (ec->config.link_status.enabled_port_mask & (1 << i)) { + if (!ec->config.link_status.send_updated || + ec->link_info[i].status_updated) { + + DEBUG(DPDK_EVENTS_PLUGIN ": Dispatch PORT %d Link Status: %s", i, + ec->link_info[i].link_status ? "UP" : "DOWN"); + + char dev_name[DATA_MAX_NAME_LEN]; + if (ec->config.link_status.port_name[i][0] != 0) { + ssnprintf(dev_name, sizeof(dev_name), "%s", + ec->config.link_status.port_name[i]); + } else { + ssnprintf(dev_name, sizeof(dev_name), "port.%d", i); + } + + if (ec->config.link_status.notify) { + int sev = ec->link_info[i].link_status ? NOTIF_OKAY : NOTIF_WARNING; + char msg[DATA_MAX_NAME_LEN]; + ssnprintf(msg, sizeof(msg), "Link Status: %s", + ec->link_info[i].link_status ? "UP" : "DOWN"); + dpdk_events_notification_dispatch(sev, dev_name, + ec->link_info[i].read_time, msg); + } else { + dpdk_events_gauge_submit(dev_name, "link_status", + (gauge_t)ec->link_info[i].link_status, + ec->link_info[i].read_time); + } + ec->link_info[i].status_updated = 0; + } + } + } + + return 0; +} + +static void dpdk_events_keep_alive_dispatch(dpdk_helper_ctx_t *phc) { + dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(phc); + + /* dispatch Keep Alive values to collectd */ + for (int i = 0; i < RTE_KEEPALIVE_MAXCORES; i++) { + if (i < INT64_BIT_SIZE) { + if (!(ec->config.keep_alive.lcore_mask.low & ((uint64_t)1 << i))) + continue; + } else if (i >= INT64_BIT_SIZE && i < INT64_BIT_SIZE * 2) { + if (!(ec->config.keep_alive.lcore_mask.high & + ((uint64_t)1 << (i - INT64_BIT_SIZE)))) + continue; + } else { + WARNING(DPDK_EVENTS_PLUGIN + ": %s:%d Core id %u is out of 0 to %u range, skipping", + __FUNCTION__, __LINE__, i, INT64_BIT_SIZE * 2); + continue; + } + + char core_name[DATA_MAX_NAME_LEN]; + ssnprintf(core_name, sizeof(core_name), "lcore%u", i); + + if (!ec->config.keep_alive.send_updated || + (ec->core_info[i].lcore_state != + ec->config.keep_alive.shm->core_state[i])) { + ec->core_info[i].lcore_state = ec->config.keep_alive.shm->core_state[i]; + ec->core_info[i].read_time = cdtime(); + + if (ec->config.keep_alive.notify) { + char msg[DATA_MAX_NAME_LEN]; + int sev; + + switch (ec->config.keep_alive.shm->core_state[i]) { + case RTE_KA_STATE_ALIVE: + sev = NOTIF_OKAY; + ssnprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: ALIVE", i); + break; + case RTE_KA_STATE_MISSING: + ssnprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: MISSING", i); + sev = NOTIF_WARNING; + break; + case RTE_KA_STATE_DEAD: + ssnprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: DEAD", i); + sev = NOTIF_FAILURE; + break; + case RTE_KA_STATE_UNUSED: + ssnprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: UNUSED", i); + sev = NOTIF_OKAY; + break; + case RTE_KA_STATE_GONE: + ssnprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: GONE", i); + sev = NOTIF_FAILURE; + break; + case RTE_KA_STATE_DOZING: + ssnprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: DOZING", i); + sev = NOTIF_OKAY; + break; + case RTE_KA_STATE_SLEEP: + ssnprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: SLEEP", i); + sev = NOTIF_OKAY; + break; + default: + ssnprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: UNKNOWN", i); + sev = NOTIF_FAILURE; + } + + dpdk_events_notification_dispatch(sev, KEEPALIVE_PLUGIN_INSTANCE, + ec->core_info[i].read_time, msg); + } else { + dpdk_events_gauge_submit(KEEPALIVE_PLUGIN_INSTANCE, core_name, + ec->config.keep_alive.shm->core_state[i], + ec->core_info[i].read_time); + } + } + } +} + +static int dpdk_events_read(user_data_t *ud) { + DPDK_EVENTS_TRACE(); + + if (g_hc == NULL) { + ERROR(DPDK_EVENTS_PLUGIN ": plugin not initialized."); + return -1; + } + + dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(g_hc); + + if (ec->config.link_status.enabled) { + int cmd_res = 0; + int ret = dpdk_helper_command(g_hc, DPDK_CMD_GET_EVENTS, &cmd_res, + ec->config.interval); + if (cmd_res == 0 && ret == 0) { + dpdk_events_link_status_dispatch(g_hc); + } + } + + if (ec->config.keep_alive.enabled) { + dpdk_events_keep_alive_dispatch(g_hc); + } + + return 0; +} + +static int dpdk_events_init(void) { + DPDK_EVENTS_TRACE(); + + int ret = dpdk_events_preinit(); + if (ret) + return ret; + + dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(g_hc); + + if (ec->config.keep_alive.enabled) { + ret = dpdk_event_keep_alive_shm_create(); + if (ret) { + ERROR(DPDK_EVENTS_PLUGIN ": %s : error %d in ka_shm_create()", + __FUNCTION__, ret); + return ret; + } + } + return 0; +} + +static int dpdk_events_shutdown(void) { + DPDK_EVENTS_TRACE(); + int ret; + + dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(g_hc); + if (ec->config.keep_alive.enabled) { + ret = munmap(ec->config.keep_alive.shm, sizeof(dpdk_keepalive_shm_t)); + if (ret) { + ERROR(DPDK_EVENTS_PLUGIN ": munmap KA monitor returned %d", ret); + return ret; + } + } + + ret = dpdk_helper_shutdown(g_hc); + g_hc = NULL; + if (ret) + ERROR(DPDK_EVENTS_PLUGIN ": failed to cleanup %s helper", DPDK_EVENTS_NAME); + + return ret; +} + +void module_register(void) { + plugin_register_init(DPDK_EVENTS_PLUGIN, dpdk_events_init); + plugin_register_complex_config(DPDK_EVENTS_PLUGIN, dpdk_events_config); + plugin_register_complex_read(NULL, DPDK_EVENTS_PLUGIN, dpdk_events_read, 0, + NULL); + plugin_register_shutdown(DPDK_EVENTS_PLUGIN, dpdk_events_shutdown); +} diff --git a/src/dpdkstat.c b/src/dpdkstat.c index 6d0aabf7..cfe993cb 100644 --- a/src/dpdkstat.c +++ b/src/dpdkstat.c @@ -1,4 +1,4 @@ -/*- +/* * collectd - src/dpdkstat.c * MIT License * @@ -26,47 +26,30 @@ * Maryam Tahhan * Harry van Haaren * Taras Chornyi + * Serhiy Pshyk + * Krzysztof Matczak */ #include "collectd.h" -#include "common.h" /* auxiliary functions */ -#include "plugin.h" /* plugin_register_*, plugin_dispatch_values */ -#include "utils_time.h" - -#include -#include -#include -#include -#include +#include "common.h" +#include "utils_dpdk.h" -#include -#include -#include #include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DPDK_DEFAULT_RTE_CONFIG "/var/run/.rte_config" -#define DPDK_MAX_ARGC 8 -#define DPDKSTAT_MAX_BUFFER_SIZE (4096 * 4) -#define DPDK_SHM_NAME "dpdk_collectd_stats_shm" -#define ERR_BUF_SIZE 1024 -#define REINIT_SHM 1 -#define RESET 1 -#define NO_RESET 0 + +#define DPDK_STATS_PLUGIN "dpdkstat" +#define DPDK_STATS_NAME "dpdk_collectd_stats" + +#define DPDK_STATS_TRACE() \ + DEBUG("%s:%s:%d pid=%u", DPDK_STATS_PLUGIN, __FUNCTION__, __LINE__, getpid()) + +struct dpdk_stats_config_s { + cdtime_t interval; + uint32_t enabled_port_mask; + char port_name[RTE_MAX_ETHPORTS][DATA_MAX_NAME_LEN]; +}; +typedef struct dpdk_stats_config_s dpdk_stats_config_t; #define RTE_VERSION_16_07 RTE_VERSION_NUM(16, 7, 0, 16) @@ -88,740 +71,436 @@ ctx->xstats = (struct rte_eth_xstat *)&ctx->raw_data[0]; \ ctx->xnames = \ (struct rte_eth_xstat_name *)&ctx \ - ->raw_data[ctx->num_xstats * sizeof(struct rte_eth_xstat)]; \ + ->raw_data[ctx->stats_count * sizeof(struct rte_eth_xstat)]; \ } while (0) #endif -enum DPDK_HELPER_ACTION { - DPDK_HELPER_ACTION_COUNT_STATS, - DPDK_HELPER_ACTION_SEND_STATS, -}; - -enum DPDK_HELPER_STATUS { - DPDK_HELPER_NOT_INITIALIZED = 0, - DPDK_HELPER_WAITING_ON_PRIMARY, - DPDK_HELPER_INITIALIZING_EAL, - DPDK_HELPER_ALIVE_SENDING_STATS, - DPDK_HELPER_GRACEFUL_QUIT, -}; - -struct dpdk_config_s { - /* General DPDK params */ - char coremask[DATA_MAX_NAME_LEN]; - char memory_channels[DATA_MAX_NAME_LEN]; - char socket_memory[DATA_MAX_NAME_LEN]; - char process_type[DATA_MAX_NAME_LEN]; - char file_prefix[DATA_MAX_NAME_LEN]; - cdtime_t interval; - uint32_t eal_initialized; - uint32_t enabled_port_mask; - char port_name[RTE_MAX_ETHPORTS][DATA_MAX_NAME_LEN]; - uint32_t eal_argc; - /* Helper info */ - int collectd_reinit_shm; - pid_t helper_pid; - sem_t sema_helper_get_stats; - sem_t sema_stats_in_shm; - int helper_pipes[2]; - enum DPDK_HELPER_STATUS helper_status; - enum DPDK_HELPER_ACTION helper_action; - /* xstats info */ - uint32_t num_ports; - uint32_t num_xstats; +struct dpdk_stats_ctx_s { + dpdk_stats_config_t config; + uint32_t stats_count; + uint32_t ports_count; cdtime_t port_read_time[RTE_MAX_ETHPORTS]; - uint32_t num_stats_in_port[RTE_MAX_ETHPORTS]; - struct rte_eth_link link_status[RTE_MAX_ETHPORTS]; + uint32_t port_stats_count[RTE_MAX_ETHPORTS]; #if RTE_VERSION < RTE_VERSION_16_07 struct rte_eth_xstats *xstats; #else struct rte_eth_xstat *xstats; struct rte_eth_xstat_name *xnames; #endif - char *raw_data; - /* rte_eth_xstats from here on until the end of the SHM */ + char raw_data[]; }; -typedef struct dpdk_config_s dpdk_config_t; - -static int g_configured; -static dpdk_config_t *g_configuration; - -static void dpdk_config_init_default(void); -static int dpdk_config(oconfig_item_t *ci); -static int dpdk_helper_init_eal(void); -static int dpdk_helper_run(void); -static int dpdk_helper_spawn(enum DPDK_HELPER_ACTION action); -static int dpdk_init(void); -static int dpdk_read(user_data_t *ud); -static int dpdk_shm_cleanup(void); -static int dpdk_shm_init(size_t size); - -/* Write the default configuration to the g_configuration instances */ -static void dpdk_config_init_default(void) { - g_configuration->interval = plugin_get_interval(); - if (g_configuration->interval == cf_get_default_interval()) - WARNING("dpdkstat: No time interval was configured, default value %" PRIu64 - " ms is set", - CDTIME_T_TO_MS(g_configuration->interval)); - /* Default is all ports enabled */ - g_configuration->enabled_port_mask = ~0; - g_configuration->eal_argc = DPDK_MAX_ARGC; - g_configuration->eal_initialized = 0; - ssnprintf(g_configuration->coremask, DATA_MAX_NAME_LEN, "%s", "0xf"); - ssnprintf(g_configuration->memory_channels, DATA_MAX_NAME_LEN, "%s", "1"); - ssnprintf(g_configuration->process_type, DATA_MAX_NAME_LEN, "%s", - "secondary"); - ssnprintf(g_configuration->file_prefix, DATA_MAX_NAME_LEN, "%s", - DPDK_DEFAULT_RTE_CONFIG); - - for (int i = 0; i < RTE_MAX_ETHPORTS; i++) - g_configuration->port_name[i][0] = 0; +typedef struct dpdk_stats_ctx_s dpdk_stats_ctx_t; + +#define DPDK_STATS_CTX_GET(a) ((dpdk_stats_ctx_t *)dpdk_helper_priv_get(a)) + +dpdk_helper_ctx_t *g_hc = NULL; +static char g_shm_name[DATA_MAX_NAME_LEN] = DPDK_STATS_NAME; +static int dpdk_stats_reinit_helper(); +static void dpdk_stats_default_config(void) { + dpdk_stats_ctx_t *ec = DPDK_STATS_CTX_GET(g_hc); + + ec->config.interval = plugin_get_interval(); + for (int i = 0; i < RTE_MAX_ETHPORTS; i++) { + ec->config.port_name[i][0] = 0; + } + /* Enable all ports by default */ + ec->config.enabled_port_mask = ~0; } -static int dpdk_config(oconfig_item_t *ci) { - int port_counter = 0; - /* Allocate g_configuration and - * initialize a POSIX SHared Memory (SHM) object. - */ - int err = dpdk_shm_init(sizeof(dpdk_config_t)); - if (err) { +static int dpdk_stats_preinit(void) { + DPDK_STATS_TRACE(); + + if (g_hc != NULL) { + /* already initialized if config callback was called before init callback */ + DEBUG("dpdk_stats_preinit: helper already initialized"); + return 0; + } + + int ret = dpdk_helper_init(g_shm_name, sizeof(dpdk_stats_ctx_t), &g_hc); + if (ret != 0) { char errbuf[ERR_BUF_SIZE]; - ERROR("dpdkstat: error in shm_init, %s", - sstrerror(errno, errbuf, sizeof(errbuf))); - return -1; + ERROR("%s: failed to initialize %s helper(error: %s)", DPDK_STATS_PLUGIN, + g_shm_name, sstrerror(errno, errbuf, sizeof(errbuf))); + return ret; } - /* Set defaults for config, overwritten by loop if config item exists */ - dpdk_config_init_default(); + dpdk_stats_default_config(); + return ret; +} + +static int dpdk_stats_config(oconfig_item_t *ci) { + DPDK_STATS_TRACE(); + + int ret = dpdk_stats_preinit(); + if (ret) + return ret; + + dpdk_stats_ctx_t *ctx = DPDK_STATS_CTX_GET(g_hc); for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp("Coremask", child->key) == 0) { - cf_util_get_string_buffer(child, g_configuration->coremask, - sizeof(g_configuration->coremask)); - DEBUG("dpdkstat:COREMASK %s ", g_configuration->coremask); - } else if (strcasecmp("MemoryChannels", child->key) == 0) { - cf_util_get_string_buffer(child, g_configuration->memory_channels, - sizeof(g_configuration->memory_channels)); - DEBUG("dpdkstat:Memory Channels %s ", g_configuration->memory_channels); - } else if (strcasecmp("SocketMemory", child->key) == 0) { - cf_util_get_string_buffer(child, g_configuration->socket_memory, - sizeof(g_configuration->memory_channels)); - DEBUG("dpdkstat: socket mem %s ", g_configuration->socket_memory); - } else if (strcasecmp("ProcessType", child->key) == 0) { - cf_util_get_string_buffer(child, g_configuration->process_type, - sizeof(g_configuration->process_type)); - DEBUG("dpdkstat: proc type %s ", g_configuration->process_type); - } else if ((strcasecmp("FilePrefix", child->key) == 0) && - (child->values[0].type == OCONFIG_TYPE_STRING)) { - ssnprintf(g_configuration->file_prefix, DATA_MAX_NAME_LEN, - "/var/run/.%s_config", child->values[0].value.string); - DEBUG("dpdkstat: file prefix %s ", g_configuration->file_prefix); - } else if ((strcasecmp("EnabledPortMask", child->key) == 0) && - (child->values[0].type == OCONFIG_TYPE_NUMBER)) { - g_configuration->enabled_port_mask = - (uint32_t)child->values[0].value.number; - DEBUG("dpdkstat: Enabled Port Mask %u", - g_configuration->enabled_port_mask); - } else if (strcasecmp("PortName", child->key) == 0) { - cf_util_get_string_buffer( - child, g_configuration->port_name[port_counter], - sizeof(g_configuration->port_name[port_counter])); - DEBUG("dpdkstat: Port %d Name: %s ", port_counter, - g_configuration->port_name[port_counter]); - port_counter++; - } else { - WARNING("dpdkstat: The config option \"%s\" is unknown.", child->key); + if ((strcasecmp("EnabledPortMask", child->key) == 0) && + (child->values[0].type == OCONFIG_TYPE_NUMBER)) { + ctx->config.enabled_port_mask = child->values[0].value.number; + DEBUG("%s: Enabled Port Mask 0x%X", DPDK_STATS_PLUGIN, + ctx->config.enabled_port_mask); + } else if (strcasecmp("SharedMemObj", child->key) == 0) { + cf_util_get_string_buffer(child, g_shm_name, sizeof(g_shm_name)); + DEBUG("%s: Shared memory object %s", DPDK_STATS_PLUGIN, g_shm_name); + dpdk_stats_reinit_helper(); + } else if (strcasecmp("EAL", child->key) == 0) { + ret = dpdk_helper_eal_config_parse(g_hc, child); + if (ret) + return ret; } - } /* End for (int i = 0; i < ci->children_num; i++)*/ - g_configured = 1; /* Bypass configuration in dpdk_shm_init(). */ + } - return 0; -} + int port_num = 0; -/* - * Allocate g_configuration and initialize SHared Memory (SHM) - * for config and helper process - */ -static int dpdk_shm_init(size_t size) { - /* - * Check if SHM is already configured: when config items are provided, the - * config function initializes SHM. If there is no config, then init() will - * just return. - */ - if (g_configuration) - return 0; + /* parse port names after EnabledPortMask was parsed */ + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; - char errbuf[ERR_BUF_SIZE]; + if (strcasecmp("PortName", child->key) == 0) { - /* Create and open a new object, or open an existing object. */ - int fd = shm_open(DPDK_SHM_NAME, O_CREAT | O_TRUNC | O_RDWR, 0666); - if (fd < 0) { - WARNING("dpdkstat:Failed to open %s as SHM:%s", DPDK_SHM_NAME, - sstrerror(errno, errbuf, sizeof(errbuf))); - goto fail; - } - /* Set the size of the shared memory object. */ - int ret = ftruncate(fd, size); - if (ret != 0) { - WARNING("dpdkstat:Failed to resize SHM:%s", - sstrerror(errno, errbuf, sizeof(errbuf))); - goto fail_close; - } - /* Map the shared memory object into this process' virtual address space. */ - g_configuration = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (g_configuration == MAP_FAILED) { - WARNING("dpdkstat:Failed to mmap SHM:%s", - sstrerror(errno, errbuf, sizeof(errbuf))); - goto fail_close; - } - /* - * Close the file descriptor, the shared memory object still exists - * and can only be removed by calling shm_unlink(). - */ - close(fd); - - /* Initialize g_configuration. */ - memset(g_configuration, 0, size); - - /* Initialize the semaphores for SHM use */ - int err = sem_init(&g_configuration->sema_helper_get_stats, 1, 0); - if (err) { - ERROR("dpdkstat semaphore init failed: %s", - sstrerror(errno, errbuf, sizeof(errbuf))); - goto fail; - } - err = sem_init(&g_configuration->sema_stats_in_shm, 1, 0); - if (err) { - ERROR("dpdkstat semaphore init failed: %s", - sstrerror(errno, errbuf, sizeof(errbuf))); - goto fail; - } + while (!(ctx->config.enabled_port_mask & (1 << port_num))) + port_num++; - g_configuration->xstats = NULL; + cf_util_get_string_buffer(child, ctx->config.port_name[port_num], + sizeof(ctx->config.port_name[port_num])); + DEBUG("%s: Port %d Name: %s", DPDK_STATS_PLUGIN, port_num, + ctx->config.port_name[port_num]); - return 0; + port_num++; + } + } -fail_close: - close(fd); -fail: - /* Reset to zero, as it was set to MAP_FAILED aka: (void *)-1. Avoid - * an issue if collectd attempts to run this plugin failure. - */ - g_configuration = 0; - return -1; + return ret; } -static int dpdk_re_init_shm() { - dpdk_config_t temp_config; - memcpy(&temp_config, g_configuration, sizeof(dpdk_config_t)); - DEBUG("dpdkstat: %s: ports %" PRIu32 ", xstats %" PRIu32, __func__, - temp_config.num_ports, temp_config.num_xstats); - - size_t shm_xstats_size = - sizeof(dpdk_config_t) + - (DPDK_STATS_CTX_GET_XSTAT_SIZE * g_configuration->num_xstats); - DEBUG("=== SHM new size for %" PRIu32 " xstats", g_configuration->num_xstats); - - int err = dpdk_shm_cleanup(); - if (err) { - ERROR("dpdkstat: Error in shm_cleanup in %s", __func__); - return err; - } - err = dpdk_shm_init(shm_xstats_size); - if (err) { - WARNING("dpdkstat: Error in shm_init in %s", __func__); - return err; - } - /* If the XML config() function has been run, don't re-initialize defaults */ - if (!g_configured) - dpdk_config_init_default(); - - memcpy(g_configuration, &temp_config, sizeof(dpdk_config_t)); - g_configuration->collectd_reinit_shm = 0; - g_configuration->raw_data = (char *)(g_configuration + 1); - DPDK_STATS_CTX_INIT(g_configuration); - return 0; -} +static int dpdk_helper_stats_get(dpdk_helper_ctx_t *phc) { + int len = 0; + int ret = 0; + int stats = 0; + dpdk_stats_ctx_t *ctx = DPDK_STATS_CTX_GET(phc); -static int dpdk_init(void) { - int err = dpdk_shm_init(sizeof(dpdk_config_t)); - if (err) { - ERROR("dpdkstat: %s : error %d in shm_init()", __func__, err); - return err; - } + /* get stats from DPDK */ + for (uint8_t i = 0; i < ctx->ports_count; i++) { + if (!(ctx->config.enabled_port_mask & (1 << i))) + continue; - /* If the XML config() function has been run, dont re-initialize defaults */ - if (!g_configured) { - dpdk_config_init_default(); + ctx->port_read_time[i] = cdtime(); + /* Store available stats array length for port */ + len = ctx->port_stats_count[i]; + + ret = rte_eth_xstats_get(i, &ctx->xstats[stats], len); + if (ret < 0 || ret > len) { + DPDK_CHILD_LOG(DPDK_STATS_PLUGIN + ": Error reading stats (port=%d; len=%d, ret=%d)\n", + i, len, ret); + ctx->port_stats_count[i] = 0; + return -1; + } +#if RTE_VERSION >= RTE_VERSION_16_07 + ret = rte_eth_xstats_get_names(i, &ctx->xnames[stats], len); + if (ret < 0 || ret > len) { + DPDK_CHILD_LOG(DPDK_STATS_PLUGIN + ": Error reading stat names (port=%d; len=%d ret=%d)\n", + i, len, ret); + ctx->port_stats_count[i] = 0; + return -1; + } +#endif + ctx->port_stats_count[i] = ret; + stats += ctx->port_stats_count[i]; } + assert(stats <= ctx->stats_count); return 0; } -static int dpdk_helper_stop(int reset) { - g_configuration->helper_status = DPDK_HELPER_GRACEFUL_QUIT; - if (reset) { - g_configuration->eal_initialized = 0; - g_configuration->num_ports = 0; - g_configuration->xstats = NULL; - g_configuration->num_xstats = 0; - for (int i = 0; i < RTE_MAX_ETHPORTS; i++) - g_configuration->num_stats_in_port[i] = 0; - } - close(g_configuration->helper_pipes[1]); - int err = kill(g_configuration->helper_pid, SIGKILL); - if (err) { - char errbuf[ERR_BUF_SIZE]; - WARNING("dpdkstat: error sending kill to helper: %s", - sstrerror(errno, errbuf, sizeof(errbuf))); - } +static int dpdk_helper_stats_count_get(dpdk_helper_ctx_t *phc) { + uint8_t ports = dpdk_helper_eth_dev_count(); + if (ports == 0) + return -ENODEV; - return 0; -} + dpdk_stats_ctx_t *ctx = DPDK_STATS_CTX_GET(phc); + ctx->ports_count = ports; -static int dpdk_helper_spawn(enum DPDK_HELPER_ACTION action) { - char errbuf[ERR_BUF_SIZE]; - g_configuration->eal_initialized = 0; - g_configuration->helper_action = action; - /* - * Create a pipe for helper stdout back to collectd. This is necessary for - * logging EAL failures, as rte_eal_init() calls rte_panic(). - */ - if (pipe(g_configuration->helper_pipes) != 0) { - DEBUG("dpdkstat: Could not create helper pipe: %s", - sstrerror(errno, errbuf, sizeof(errbuf))); - return -1; + int len = 0; + int stats_count = 0; + for (int i = 0; i < ports; i++) { + if (!(ctx->config.enabled_port_mask & (1 << i))) + continue; +#if RTE_VERSION >= RTE_VERSION_16_07 + len = rte_eth_xstats_get_names(i, NULL, 0); +#else + len = rte_eth_xstats_get(i, NULL, 0); +#endif + if (len < 0) { + DPDK_CHILD_LOG("%s: Cannot get stats count\n", DPDK_STATS_PLUGIN); + return -1; + } + ctx->port_stats_count[i] = len; + stats_count += len; } - int pipe0_flags = fcntl(g_configuration->helper_pipes[0], F_GETFL, 0); - int pipe1_flags = fcntl(g_configuration->helper_pipes[1], F_GETFL, 0); - if (pipe0_flags == -1 || pipe1_flags == -1) { - WARNING("dpdkstat: Failed setting up pipe flags: %s", - sstrerror(errno, errbuf, sizeof(errbuf))); - } - int pipe0_err = fcntl(g_configuration->helper_pipes[0], F_SETFL, - pipe1_flags | O_NONBLOCK); - int pipe1_err = fcntl(g_configuration->helper_pipes[1], F_SETFL, - pipe0_flags | O_NONBLOCK); - if (pipe0_err == -1 || pipe1_err == -1) { - WARNING("dpdkstat: Failed setting up pipes: %s", - sstrerror(errno, errbuf, sizeof(errbuf))); - } + DPDK_CHILD_LOG("%s:%s:%d stats_count=%d\n", DPDK_STATS_PLUGIN, __FUNCTION__, + __LINE__, stats_count); - pid_t pid = fork(); - if (pid > 0) { - close(g_configuration->helper_pipes[1]); - g_configuration->helper_pid = pid; - DEBUG("dpdkstat: helper pid %li", (long)g_configuration->helper_pid); - /* Kick helper once its alive to have it start processing */ - sem_post(&g_configuration->sema_helper_get_stats); - } else if (pid == 0) { - /* Replace stdout with a pipe to collectd. */ - close(g_configuration->helper_pipes[0]); - close(STDOUT_FILENO); - dup2(g_configuration->helper_pipes[1], STDOUT_FILENO); - dpdk_helper_run(); - exit(0); - } else { - ERROR("dpdkstat: Failed to fork helper process: %s", - sstrerror(errno, errbuf, sizeof(errbuf))); - return -1; - } - return 0; + return stats_count; } -/* - * Initialize the DPDK EAL, if this returns, EAL is successfully initialized. - * On failure, the EAL prints an error message, and the helper process exits. - */ -static int dpdk_helper_init_eal(void) { - g_configuration->helper_status = DPDK_HELPER_INITIALIZING_EAL; - char *argp[(g_configuration->eal_argc) + 1]; - int i = 0; - - argp[i++] = "collectd-dpdk"; - if (strcasecmp(g_configuration->coremask, "") != 0) { - argp[i++] = "-c"; - argp[i++] = g_configuration->coremask; - } - if (strcasecmp(g_configuration->memory_channels, "") != 0) { - argp[i++] = "-n"; - argp[i++] = g_configuration->memory_channels; - } - if (strcasecmp(g_configuration->socket_memory, "") != 0) { - argp[i++] = "--socket-mem"; - argp[i++] = g_configuration->socket_memory; +static int dpdk_stats_get_size(dpdk_helper_ctx_t *phc) { + return (dpdk_helper_data_size_get(phc) - sizeof(dpdk_stats_ctx_t)); +} + +int dpdk_helper_command_handler(dpdk_helper_ctx_t *phc, enum DPDK_CMD cmd) { + /* this function is called from helper context */ + + if (phc == NULL) { + DPDK_CHILD_LOG("%s: Invalid argument(phc)\n", DPDK_STATS_PLUGIN); + return -EINVAL; } - if (strcasecmp(g_configuration->file_prefix, "") != 0 && - strcasecmp(g_configuration->file_prefix, DPDK_DEFAULT_RTE_CONFIG) != 0) { - argp[i++] = "--file-prefix"; - argp[i++] = g_configuration->file_prefix; + + if (cmd != DPDK_CMD_GET_STATS) { + DPDK_CHILD_LOG("%s: Unknown command (cmd=%d)\n", DPDK_STATS_PLUGIN, cmd); + return -EINVAL; } - if (strcasecmp(g_configuration->process_type, "") != 0) { - argp[i++] = "--proc-type"; - argp[i++] = g_configuration->process_type; + + int stats_count = dpdk_helper_stats_count_get(phc); + if (stats_count < 0) { + return stats_count; } - g_configuration->eal_argc = i; - g_configuration->eal_initialized = 1; - int ret = rte_eal_init(g_configuration->eal_argc, argp); - if (ret < 0) { - g_configuration->eal_initialized = 0; - return ret; + DPDK_STATS_CTX_GET(phc)->stats_count = stats_count; + int stats_size = stats_count * DPDK_STATS_CTX_GET_XSTAT_SIZE; + + if (dpdk_stats_get_size(phc) < stats_size) { + DPDK_CHILD_LOG( + DPDK_STATS_PLUGIN + ":%s:%d not enough space for stats (available=%d, needed=%d)\n", + __FUNCTION__, __LINE__, (int)dpdk_stats_get_size(phc), stats_size); + return -ENOBUFS; } - return 0; + + return dpdk_helper_stats_get(phc); } -static int dpdk_helper_run(void) { - char errbuf[ERR_BUF_SIZE]; - pid_t ppid = getppid(); - g_configuration->helper_status = DPDK_HELPER_WAITING_ON_PRIMARY; - - while (1) { - /* sem_timedwait() to avoid blocking forever */ - cdtime_t now = cdtime(); - cdtime_t safety_period = MS_TO_CDTIME_T(1500); - int ret = - sem_timedwait(&g_configuration->sema_helper_get_stats, - &CDTIME_T_TO_TIMESPEC(now + safety_period + - g_configuration->interval * 2)); - - if (ret == -1 && errno == ETIMEDOUT) { - ERROR("dpdkstat-helper: sem timedwait()" - " timeout, did collectd terminate?"); - dpdk_helper_stop(RESET); - } - /* Parent PID change means collectd died so quit the helper process. */ - if (ppid != getppid()) { - WARNING("dpdkstat-helper: parent PID changed, quitting."); - dpdk_helper_stop(RESET); +static void dpdk_stats_resolve_cnt_type(char *cnt_type, size_t cnt_type_len, + const char *cnt_name) { + char *type_end; + type_end = strrchr(cnt_name, '_'); + + if ((type_end != NULL) && (strncmp(cnt_name, "rx_", strlen("rx_")) == 0)) { + if (strstr(type_end, "bytes") != NULL) { + sstrncpy(cnt_type, "if_rx_octets", cnt_type_len); + } else if (strstr(type_end, "error") != NULL) { + sstrncpy(cnt_type, "if_rx_errors", cnt_type_len); + } else if (strstr(type_end, "dropped") != NULL) { + sstrncpy(cnt_type, "if_rx_dropped", cnt_type_len); + } else if (strstr(type_end, "packets") != NULL) { + sstrncpy(cnt_type, "if_rx_packets", cnt_type_len); + } else if (strstr(type_end, "_placement") != NULL) { + sstrncpy(cnt_type, "if_rx_errors", cnt_type_len); + } else if (strstr(type_end, "_buff") != NULL) { + sstrncpy(cnt_type, "if_rx_errors", cnt_type_len); + } else { + /* Does not fit obvious type: use a more generic one */ + sstrncpy(cnt_type, "derive", cnt_type_len); } - /* Checking for DPDK primary process. */ - if (!rte_eal_primary_proc_alive(g_configuration->file_prefix)) { - if (g_configuration->eal_initialized) { - WARNING("dpdkstat-helper: no primary alive but EAL initialized:" - " quitting."); - dpdk_helper_stop(RESET); - } - g_configuration->helper_status = DPDK_HELPER_WAITING_ON_PRIMARY; - /* Back to start of while() - waiting for primary process */ - continue; + } else if ((type_end != NULL) && + (strncmp(cnt_name, "tx_", strlen("tx_"))) == 0) { + if (strstr(type_end, "bytes") != NULL) { + sstrncpy(cnt_type, "if_tx_octets", cnt_type_len); + } else if (strstr(type_end, "error") != NULL) { + sstrncpy(cnt_type, "if_tx_errors", cnt_type_len); + } else if (strstr(type_end, "dropped") != NULL) { + sstrncpy(cnt_type, "if_tx_dropped", cnt_type_len); + } else if (strstr(type_end, "packets") != NULL) { + sstrncpy(cnt_type, "if_tx_packets", cnt_type_len); + } else { + /* Does not fit obvious type: use a more generic one */ + sstrncpy(cnt_type, "derive", cnt_type_len); } - - if (!g_configuration->eal_initialized) { - /* Initialize EAL. */ - int ret = dpdk_helper_init_eal(); - if (ret != 0) { - WARNING("ERROR INITIALIZING EAL"); - dpdk_helper_stop(RESET); - } + } else if ((type_end != NULL) && + (strncmp(cnt_name, "flow_", strlen("flow_"))) == 0) { + + if (strstr(type_end, "_filters") != NULL) { + sstrncpy(cnt_type, "operations", cnt_type_len); + } else if (strstr(type_end, "error") != NULL) + sstrncpy(cnt_type, "errors", cnt_type_len); + + } else if ((type_end != NULL) && + (strncmp(cnt_name, "mac_", strlen("mac_"))) == 0) { + if (strstr(type_end, "error") != NULL) { + sstrncpy(cnt_type, "errors", cnt_type_len); } + } else { + /* Does not fit obvious type, or strrchr error: + * use a more generic type */ + sstrncpy(cnt_type, "derive", cnt_type_len); + } +} - g_configuration->helper_status = DPDK_HELPER_ALIVE_SENDING_STATS; +static void dpdk_stats_counter_submit(const char *plugin_instance, + const char *cnt_name, derive_t value, + cdtime_t port_read_time) { + value_list_t vl = VALUE_LIST_INIT; + vl.values = &(value_t){.derive = value}; + vl.values_len = 1; + vl.time = port_read_time; + sstrncpy(vl.host, hostname_g, sizeof(vl.host)); + sstrncpy(vl.plugin, DPDK_STATS_PLUGIN, sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + dpdk_stats_resolve_cnt_type(vl.type, sizeof(vl.type), cnt_name); + sstrncpy(vl.type_instance, cnt_name, sizeof(vl.type_instance)); + plugin_dispatch_values(&vl); +} - uint8_t nb_ports = rte_eth_dev_count(); - if (nb_ports == 0) { - DEBUG("dpdkstat-helper: No DPDK ports available. " - "Check bound devices to DPDK driver."); - dpdk_helper_stop(RESET); - } +static int dpdk_stats_counters_dispatch(dpdk_helper_ctx_t *phc) { + dpdk_stats_ctx_t *ctx = DPDK_STATS_CTX_GET(phc); - if (nb_ports > RTE_MAX_ETHPORTS) - nb_ports = RTE_MAX_ETHPORTS; + /* dispatch stats values to collectd */ - int len = 0, enabled_port_count = 0, num_xstats = 0; - for (uint8_t i = 0; i < nb_ports; i++) { - if (!(g_configuration->enabled_port_mask & (1 << i))) - continue; + DEBUG("%s:%s:%d ports=%u", DPDK_STATS_PLUGIN, __FUNCTION__, __LINE__, + ctx->ports_count); - if (g_configuration->helper_action == DPDK_HELPER_ACTION_COUNT_STATS) { -#if RTE_VERSION >= RTE_VERSION_16_07 - len = rte_eth_xstats_get_names(i, NULL, 0); -#else - len = rte_eth_xstats_get(i, NULL, 0); -#endif - if (len < 0) { - ERROR("dpdkstat-helper: Cannot get xstats count on port %" PRIu8, i); - break; - } - num_xstats += len; - g_configuration->num_stats_in_port[enabled_port_count] = len; - enabled_port_count++; - continue; - } else { - len = g_configuration->num_stats_in_port[enabled_port_count]; - g_configuration->port_read_time[enabled_port_count] = cdtime(); - ret = rte_eth_xstats_get( - i, g_configuration->xstats + num_xstats, - g_configuration->num_stats_in_port[enabled_port_count]); - if (ret < 0 || ret != len) { - DEBUG("dpdkstat-helper: Error reading xstats on port %" PRIu8 - " len = %d", - i, len); - break; - } -#if RTE_VERSION >= RTE_VERSION_16_07 - ret = rte_eth_xstats_get_names(i, g_configuration->xnames + num_xstats, - len); - if (ret < 0 || ret != len) { - ERROR("dpdkstat-helper: Error reading xstat names (port=%d; len=%d)", - i, len); - break; - } -#endif - num_xstats += g_configuration->num_stats_in_port[enabled_port_count]; - enabled_port_count++; - } - } /* for (nb_ports) */ - - if (g_configuration->helper_action == DPDK_HELPER_ACTION_COUNT_STATS) { - g_configuration->num_ports = enabled_port_count; - g_configuration->num_xstats = num_xstats; - DEBUG("dpdkstat-helper ports: %" PRIu32 ", num stats: %" PRIu32, - g_configuration->num_ports, g_configuration->num_xstats); - /* Exit, allowing collectd to re-init SHM to the right size */ - g_configuration->collectd_reinit_shm = REINIT_SHM; - dpdk_helper_stop(NO_RESET); + int stats_count = 0; + + for (int i = 0; i < ctx->ports_count; i++) { + if (!(ctx->config.enabled_port_mask & (1 << i))) + continue; + + char dev_name[64]; + if (ctx->config.port_name[i][0] != 0) { + ssnprintf(dev_name, sizeof(dev_name), "%s", ctx->config.port_name[i]); + } else { + ssnprintf(dev_name, sizeof(dev_name), "port.%d", i); } - /* Now kick collectd send thread to send the stats */ - int err = sem_post(&g_configuration->sema_stats_in_shm); - if (err) { - WARNING("dpdkstat: error posting semaphore to helper %s", - sstrerror(errno, errbuf, sizeof(errbuf))); - dpdk_helper_stop(RESET); + + DEBUG(" === Dispatch stats for port %d (name=%s; stats_count=%d)", i, + dev_name, ctx->port_stats_count[i]); + + for (int j = 0; j < ctx->port_stats_count[i]; j++) { + const char *cnt_name = DPDK_STATS_XSTAT_GET_NAME(ctx, stats_count); + if (cnt_name == NULL) + WARNING("dpdkstat: Invalid counter name"); + else + dpdk_stats_counter_submit( + dev_name, cnt_name, + (derive_t)DPDK_STATS_XSTAT_GET_VALUE(ctx, stats_count), + ctx->port_read_time[i]); + stats_count++; + + assert(stats_count <= ctx->stats_count); } - } /* while(1) */ + } return 0; } -static void dpdk_submit_xstats(const char *dev_name, int count, - uint32_t counters, cdtime_t port_read_time) { - for (uint32_t j = 0; j < counters; j++) { - value_list_t vl = VALUE_LIST_INIT; - char *counter_name; - char *type_end; - - vl.values = &(value_t){.derive = (derive_t)DPDK_STATS_XSTAT_GET_VALUE( - g_configuration, count + j)}; - vl.values_len = 1; /* Submit stats one at a time */ - vl.time = port_read_time; - sstrncpy(vl.plugin, "dpdkstat", sizeof(vl.plugin)); - sstrncpy(vl.plugin_instance, dev_name, sizeof(vl.plugin_instance)); - counter_name = DPDK_STATS_XSTAT_GET_NAME(g_configuration, count + j); - if (counter_name == NULL) { - WARNING("dpdkstat: Failed to get counter name."); - return; - } +static int dpdk_stats_reinit_helper() { + DPDK_STATS_TRACE(); - type_end = strrchr(counter_name, '_'); - - if ((type_end != NULL) && - (strncmp(counter_name, "rx_", strlen("rx_")) == 0)) { - if (strstr(type_end, "bytes") != NULL) { - sstrncpy(vl.type, "if_rx_octets", sizeof(vl.type)); - } else if (strstr(type_end, "error") != NULL) { - sstrncpy(vl.type, "if_rx_errors", sizeof(vl.type)); - } else if (strstr(type_end, "dropped") != NULL) { - sstrncpy(vl.type, "if_rx_dropped", sizeof(vl.type)); - } else if (strstr(type_end, "packets") != NULL) { - sstrncpy(vl.type, "if_rx_packets", sizeof(vl.type)); - } else if (strstr(type_end, "_placement") != NULL) { - sstrncpy(vl.type, "if_rx_errors", sizeof(vl.type)); - } else if (strstr(type_end, "_buff") != NULL) { - sstrncpy(vl.type, "if_rx_errors", sizeof(vl.type)); - } else { - /* Does not fit obvious type: use a more generic one */ - sstrncpy(vl.type, "derive", sizeof(vl.type)); - } - - } else if ((type_end != NULL) && - (strncmp(counter_name, "tx_", strlen("tx_"))) == 0) { - if (strstr(type_end, "bytes") != NULL) { - sstrncpy(vl.type, "if_tx_octets", sizeof(vl.type)); - } else if (strstr(type_end, "error") != NULL) { - sstrncpy(vl.type, "if_tx_errors", sizeof(vl.type)); - } else if (strstr(type_end, "dropped") != NULL) { - sstrncpy(vl.type, "if_tx_dropped", sizeof(vl.type)); - } else if (strstr(type_end, "packets") != NULL) { - sstrncpy(vl.type, "if_tx_packets", sizeof(vl.type)); - } else { - /* Does not fit obvious type: use a more generic one */ - sstrncpy(vl.type, "derive", sizeof(vl.type)); - } - } else if ((type_end != NULL) && - (strncmp(counter_name, "flow_", strlen("flow_"))) == 0) { - - if (strstr(type_end, "_filters") != NULL) { - sstrncpy(vl.type, "operations", sizeof(vl.type)); - } else if (strstr(type_end, "error") != NULL) - sstrncpy(vl.type, "errors", sizeof(vl.type)); - - } else if ((type_end != NULL) && - (strncmp(counter_name, "mac_", strlen("mac_"))) == 0) { - if (strstr(type_end, "error") != NULL) { - sstrncpy(vl.type, "errors", sizeof(vl.type)); - } - } else { - /* Does not fit obvious type, or strrchr error: - * use a more generic type */ - sstrncpy(vl.type, "derive", sizeof(vl.type)); - } + dpdk_stats_ctx_t *ctx = DPDK_STATS_CTX_GET(g_hc); - sstrncpy(vl.type_instance, counter_name, sizeof(vl.type_instance)); - plugin_dispatch_values(&vl); - } -} + size_t data_size = sizeof(dpdk_stats_ctx_t) + + (ctx->stats_count * DPDK_STATS_CTX_GET_XSTAT_SIZE); -static int dpdk_read(user_data_t *ud) { - int ret = 0; + DEBUG("%s:%d helper reinit (new_size=%zu)", __FUNCTION__, __LINE__, + data_size); - /* - * Check if SHM flag is set to be re-initialized. AKA DPDK ports have been - * counted, so re-init SHM to be large enough to fit all the statistics. - */ - if (g_configuration->collectd_reinit_shm) { - DEBUG("dpdkstat: read() now reinit SHM then launching send-thread"); - dpdk_re_init_shm(); - } + dpdk_stats_ctx_t tmp_ctx; + dpdk_eal_config_t tmp_eal; - /* - * Check if DPDK proc is alive, and has already counted port / stats. This - * must be done in dpdk_read(), because the DPDK primary process may not be - * alive at dpdk_init() time. - */ - if (g_configuration->helper_status == DPDK_HELPER_NOT_INITIALIZED || - g_configuration->helper_status == DPDK_HELPER_GRACEFUL_QUIT) { - int action = DPDK_HELPER_ACTION_SEND_STATS; - if (g_configuration->num_xstats == 0) - action = DPDK_HELPER_ACTION_COUNT_STATS; - /* Spawn the helper thread to count stats or to read stats. */ - int err = dpdk_helper_spawn(action); - if (err) { - char errbuf[ERR_BUF_SIZE]; - ERROR("dpdkstat: error spawning helper %s", - sstrerror(errno, errbuf, sizeof(errbuf))); - return -1; - } - } + memcpy(&tmp_ctx, ctx, sizeof(dpdk_stats_ctx_t)); + dpdk_helper_eal_config_get(g_hc, &tmp_eal); - pid_t ws = waitpid(g_configuration->helper_pid, NULL, WNOHANG); - /* - * Conditions under which to respawn helper: - * waitpid() fails, helper process died (or quit), so respawn - */ - _Bool respawn_helper = 0; - if (ws != 0) { - respawn_helper = 1; - } + dpdk_helper_shutdown(g_hc); - char buf[DPDKSTAT_MAX_BUFFER_SIZE]; - char out[DPDKSTAT_MAX_BUFFER_SIZE]; + g_hc = NULL; - /* non blocking check on helper logging pipe */ - struct pollfd fds = { - .fd = g_configuration->helper_pipes[0], .events = POLLIN, - }; - int data_avail = poll(&fds, 1, 0); - if (data_avail < 0) { + int ret; + ret = dpdk_helper_init(g_shm_name, data_size, &g_hc); + if (ret != 0) { char errbuf[ERR_BUF_SIZE]; - if (errno != EINTR || errno != EAGAIN) - ERROR("dpdkstats: poll(2) failed: %s", - sstrerror(errno, errbuf, sizeof(errbuf))); - } - while (data_avail) { - int nbytes = read(g_configuration->helper_pipes[0], buf, sizeof(buf)); - if (nbytes <= 0) - break; - ssnprintf(out, nbytes, "%s", buf); - DEBUG("dpdkstat: helper-proc: %s", out); + ERROR("%s: failed to initialize %s helper(error: %s)", DPDK_STATS_PLUGIN, + g_shm_name, sstrerror(errno, errbuf, sizeof(errbuf))); + return ret; } - if (respawn_helper) { - if (g_configuration->helper_pid) - dpdk_helper_stop(RESET); - dpdk_helper_spawn(DPDK_HELPER_ACTION_COUNT_STATS); + ctx = DPDK_STATS_CTX_GET(g_hc); + memcpy(ctx, &tmp_ctx, sizeof(dpdk_stats_ctx_t)); + DPDK_STATS_CTX_INIT(ctx); + dpdk_helper_eal_config_set(g_hc, &tmp_eal); + + return ret; +} + +static int dpdk_stats_read(user_data_t *ud) { + DPDK_STATS_TRACE(); + + int ret = 0; + + if (g_hc == NULL) { + ERROR("dpdk stats plugin not initialized"); + return -EINVAL; } - /* Kick helper process through SHM */ - sem_post(&g_configuration->sema_helper_get_stats); + dpdk_stats_ctx_t *ctx = DPDK_STATS_CTX_GET(g_hc); - cdtime_t now = cdtime(); - ret = sem_timedwait(&g_configuration->sema_stats_in_shm, - &CDTIME_T_TO_TIMESPEC(now + g_configuration->interval)); - if (ret == -1) { - if (errno == ETIMEDOUT) - DEBUG( - "dpdkstat: timeout in collectd thread: is a DPDK Primary running? "); + int result = 0; + ret = dpdk_helper_command(g_hc, DPDK_CMD_GET_STATS, &result, + ctx->config.interval); + if (ret != 0) { return 0; } - /* Dispatch the stats.*/ - uint32_t count = 0, port_num = 0; - - for (uint32_t i = 0; i < g_configuration->num_ports; i++) { - char dev_name[64]; - cdtime_t port_read_time = g_configuration->port_read_time[i]; - uint32_t counters_num = g_configuration->num_stats_in_port[i]; - size_t ports_max = CHAR_BIT * sizeof(g_configuration->enabled_port_mask); - for (size_t j = port_num; j < ports_max; j++) { - if ((g_configuration->enabled_port_mask & (1 << j)) != 0) - break; - port_num++; - } + if (result == -ENOBUFS) { + dpdk_stats_reinit_helper(); + } else if (result == -ENODEV) { + dpdk_helper_shutdown(g_hc); + } else if (result == 0) { + dpdk_stats_counters_dispatch(g_hc); + } - if (g_configuration->port_name[i][0] != 0) - ssnprintf(dev_name, sizeof(dev_name), "%s", - g_configuration->port_name[i]); - else - ssnprintf(dev_name, sizeof(dev_name), "port.%" PRIu32, port_num); - dpdk_submit_xstats(dev_name, count, counters_num, port_read_time); - count += counters_num; - port_num++; - } /* for each port */ return 0; } -static int dpdk_shm_cleanup(void) { - int ret = munmap(g_configuration, sizeof(dpdk_config_t)); - g_configuration = 0; - if (ret) { - ERROR("dpdkstat: munmap returned %d", ret); - return ret; - } - ret = shm_unlink(DPDK_SHM_NAME); - if (ret) { - ERROR("dpdkstat: shm_unlink returned %d", ret); +static int dpdk_stats_init(void) { + DPDK_STATS_TRACE(); + int ret = 0; + + ret = dpdk_stats_preinit(); + if (ret != 0) { return ret; } + return 0; } -static int dpdk_shutdown(void) { +static int dpdk_stats_shutdown(void) { + DPDK_STATS_TRACE(); + int ret = 0; - char errbuf[ERR_BUF_SIZE]; - close(g_configuration->helper_pipes[1]); - int err = kill(g_configuration->helper_pid, SIGKILL); - if (err) { - ERROR("dpdkstat: error sending sigkill to helper %s", - sstrerror(errno, errbuf, sizeof(errbuf))); - ret = -1; - } - err = dpdk_shm_cleanup(); - if (err) { - ERROR("dpdkstat: error cleaning up SHM: %s", - sstrerror(errno, errbuf, sizeof(errbuf))); - ret = -1; + + ret = dpdk_helper_shutdown(g_hc); + g_hc = NULL; + if (ret != 0) { + ERROR("%s: failed to cleanup %s helper", DPDK_STATS_PLUGIN, g_shm_name); + return ret; } return ret; } void module_register(void) { - plugin_register_complex_config("dpdkstat", dpdk_config); - plugin_register_init("dpdkstat", dpdk_init); - plugin_register_complex_read(NULL, "dpdkstat", dpdk_read, 0, NULL); - plugin_register_shutdown("dpdkstat", dpdk_shutdown); + plugin_register_init(DPDK_STATS_PLUGIN, dpdk_stats_init); + plugin_register_complex_config(DPDK_STATS_PLUGIN, dpdk_stats_config); + plugin_register_complex_read(NULL, DPDK_STATS_PLUGIN, dpdk_stats_read, 0, + NULL); + plugin_register_shutdown(DPDK_STATS_PLUGIN, dpdk_stats_shutdown); } diff --git a/src/email.c b/src/email.c index 34e99984..72a8d6e7 100644 --- a/src/email.c +++ b/src/email.c @@ -719,5 +719,3 @@ void module_register(void) { plugin_register_read("email", email_read); plugin_register_shutdown("email", email_shutdown); } /* void module_register */ - -/* vim: set sw=4 ts=4 tw=78 noexpandtab : */ diff --git a/src/ethstat.c b/src/ethstat.c index bd55252f..4b053008 100644 --- a/src/ethstat.c +++ b/src/ethstat.c @@ -325,5 +325,3 @@ void module_register(void) { plugin_register_read("ethstat", ethstat_read); plugin_register_shutdown("ethstat", ethstat_shutdown); } - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/exec.c b/src/exec.c index d34f9d91..df057189 100644 --- a/src/exec.c +++ b/src/exec.c @@ -866,7 +866,3 @@ void module_register(void) { /* user_data = */ NULL); plugin_register_shutdown("exec", exec_shutdown); } /* void module_register */ - -/* - * vim:shiftwidth=2:softtabstop=2:tabstop=8:fdm=marker - */ diff --git a/src/filecount.c b/src/filecount.c index a78b8800..608218df 100644 --- a/src/filecount.c +++ b/src/filecount.c @@ -511,7 +511,3 @@ void module_register(void) { plugin_register_init("filecount", fc_init); plugin_register_read("filecount", fc_read); } /* void module_register */ - -/* - * vim: set sw=2 sts=2 et : - */ diff --git a/src/fscache.c b/src/fscache.c index c410ea39..618bb22f 100644 --- a/src/fscache.c +++ b/src/fscache.c @@ -217,5 +217,3 @@ static int fscache_read(void) { void module_register(void) { plugin_register_read("fscache", fscache_read); } /* void module_register */ - -/* vim: set sw=4 sts=4 et : */ diff --git a/src/gmond.c b/src/gmond.c index fc9a2326..7bfb18d8 100644 --- a/src/gmond.c +++ b/src/gmond.c @@ -1030,5 +1030,3 @@ void module_register(void) { plugin_register_init("gmond", gmond_init); plugin_register_shutdown("gmond", gmond_shutdown); } - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/grpc.cc b/src/grpc.cc index 0ae80bb8..2f16dbcb 100644 --- a/src/grpc.cc +++ b/src/grpc.cc @@ -26,8 +26,8 @@ * Florian octo Forster **/ -#include #include +#include #include #include @@ -61,10 +61,10 @@ using google::protobuf::util::TimeUtil; */ struct Listener { - grpc::string addr; - grpc::string port; + grpc::string addr; + grpc::string port; - grpc::SslServerCredentialsOptions *ssl; + grpc::SslServerCredentialsOptions *ssl; }; static std::vector listeners; static grpc::string default_addr("0.0.0.0:50051"); @@ -73,189 +73,187 @@ static grpc::string default_addr("0.0.0.0:50051"); * helper functions */ -static bool ident_matches(const value_list_t *vl, const value_list_t *matcher) -{ - if (fnmatch(matcher->host, vl->host, 0)) - return false; +static bool ident_matches(const value_list_t *vl, const value_list_t *matcher) { + if (fnmatch(matcher->host, vl->host, 0)) + return false; - if (fnmatch(matcher->plugin, vl->plugin, 0)) - return false; - if (fnmatch(matcher->plugin_instance, vl->plugin_instance, 0)) - return false; + if (fnmatch(matcher->plugin, vl->plugin, 0)) + return false; + if (fnmatch(matcher->plugin_instance, vl->plugin_instance, 0)) + return false; - if (fnmatch(matcher->type, vl->type, 0)) - return false; - if (fnmatch(matcher->type_instance, vl->type_instance, 0)) - return false; + if (fnmatch(matcher->type, vl->type, 0)) + return false; + if (fnmatch(matcher->type_instance, vl->type_instance, 0)) + return false; - return true; + return true; } /* ident_matches */ -static grpc::string read_file(const char *filename) -{ - std::ifstream f; - grpc::string s, content; - - f.open(filename); - if (!f.is_open()) { - ERROR("grpc: Failed to open '%s'", filename); - return ""; - } - - while (std::getline(f, s)) { - content += s; - content.push_back('\n'); - } - f.close(); - return content; +static grpc::string read_file(const char *filename) { + std::ifstream f; + grpc::string s, content; + + f.open(filename); + if (!f.is_open()) { + ERROR("grpc: Failed to open '%s'", filename); + return ""; + } + + while (std::getline(f, s)) { + content += s; + content.push_back('\n'); + } + f.close(); + return content; } /* read_file */ /* * proto conversion */ -static void marshal_ident(const value_list_t *vl, collectd::types::Identifier *msg) -{ - msg->set_host(vl->host); - msg->set_plugin(vl->plugin); - if (vl->plugin_instance[0] != '\0') - msg->set_plugin_instance(vl->plugin_instance); - msg->set_type(vl->type); - if (vl->type_instance[0] != '\0') - msg->set_type_instance(vl->type_instance); +static void marshal_ident(const value_list_t *vl, + collectd::types::Identifier *msg) { + msg->set_host(vl->host); + msg->set_plugin(vl->plugin); + if (vl->plugin_instance[0] != '\0') + msg->set_plugin_instance(vl->plugin_instance); + msg->set_type(vl->type); + if (vl->type_instance[0] != '\0') + msg->set_type_instance(vl->type_instance); } /* marshal_ident */ -static grpc::Status unmarshal_ident(const collectd::types::Identifier &msg, value_list_t *vl, - bool require_fields) -{ - std::string s; +static grpc::Status unmarshal_ident(const collectd::types::Identifier &msg, + value_list_t *vl, bool require_fields) { + std::string s; - s = msg.host(); - if (!s.length() && require_fields) - return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, - grpc::string("missing host name")); - sstrncpy(vl->host, s.c_str(), sizeof(vl->host)); + s = msg.host(); + if (!s.length() && require_fields) + return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, + grpc::string("missing host name")); + sstrncpy(vl->host, s.c_str(), sizeof(vl->host)); - s = msg.plugin(); - if (!s.length() && require_fields) - return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, - grpc::string("missing plugin name")); - sstrncpy(vl->plugin, s.c_str(), sizeof(vl->plugin)); + s = msg.plugin(); + if (!s.length() && require_fields) + return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, + grpc::string("missing plugin name")); + sstrncpy(vl->plugin, s.c_str(), sizeof(vl->plugin)); - s = msg.type(); - if (!s.length() && require_fields) - return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, - grpc::string("missing type name")); - sstrncpy(vl->type, s.c_str(), sizeof(vl->type)); + s = msg.type(); + if (!s.length() && require_fields) + return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, + grpc::string("missing type name")); + sstrncpy(vl->type, s.c_str(), sizeof(vl->type)); - s = msg.plugin_instance(); - sstrncpy(vl->plugin_instance, s.c_str(), sizeof(vl->plugin_instance)); + s = msg.plugin_instance(); + sstrncpy(vl->plugin_instance, s.c_str(), sizeof(vl->plugin_instance)); - s = msg.type_instance(); - sstrncpy(vl->type_instance, s.c_str(), sizeof(vl->type_instance)); + s = msg.type_instance(); + sstrncpy(vl->type_instance, s.c_str(), sizeof(vl->type_instance)); - return grpc::Status::OK; + return grpc::Status::OK; } /* unmarshal_ident() */ -static grpc::Status marshal_value_list(const value_list_t *vl, collectd::types::ValueList *msg) -{ - auto id = msg->mutable_identifier(); - marshal_ident(vl, id); - - auto ds = plugin_get_ds(vl->type); - if ((ds == NULL) || (ds->ds_num != vl->values_len)) { - return grpc::Status(grpc::StatusCode::INTERNAL, - grpc::string("failed to retrieve data-set for values")); - } - - auto t = TimeUtil::NanosecondsToTimestamp(CDTIME_T_TO_NS(vl->time)); - auto d = TimeUtil::NanosecondsToDuration(CDTIME_T_TO_NS(vl->interval)); - msg->set_allocated_time(new google::protobuf::Timestamp(t)); - msg->set_allocated_interval(new google::protobuf::Duration(d)); - - for (size_t i = 0; i < vl->values_len; ++i) { - auto v = msg->add_values(); - switch (ds->ds[i].type) { - case DS_TYPE_COUNTER: - v->set_counter(vl->values[i].counter); - break; - case DS_TYPE_GAUGE: - v->set_gauge(vl->values[i].gauge); - break; - case DS_TYPE_DERIVE: - v->set_derive(vl->values[i].derive); - break; - case DS_TYPE_ABSOLUTE: - v->set_absolute(vl->values[i].absolute); - break; - default: - return grpc::Status(grpc::StatusCode::INTERNAL, - grpc::string("unknown value type")); - } - - auto name = msg->add_ds_names(); - name->assign(ds->ds[i].name); - } - - return grpc::Status::OK; +static grpc::Status marshal_value_list(const value_list_t *vl, + collectd::types::ValueList *msg) { + auto id = msg->mutable_identifier(); + marshal_ident(vl, id); + + auto ds = plugin_get_ds(vl->type); + if ((ds == NULL) || (ds->ds_num != vl->values_len)) { + return grpc::Status(grpc::StatusCode::INTERNAL, + grpc::string("failed to retrieve data-set for values")); + } + + auto t = TimeUtil::NanosecondsToTimestamp(CDTIME_T_TO_NS(vl->time)); + auto d = TimeUtil::NanosecondsToDuration(CDTIME_T_TO_NS(vl->interval)); + msg->set_allocated_time(new google::protobuf::Timestamp(t)); + msg->set_allocated_interval(new google::protobuf::Duration(d)); + + for (size_t i = 0; i < vl->values_len; ++i) { + auto v = msg->add_values(); + switch (ds->ds[i].type) { + case DS_TYPE_COUNTER: + v->set_counter(vl->values[i].counter); + break; + case DS_TYPE_GAUGE: + v->set_gauge(vl->values[i].gauge); + break; + case DS_TYPE_DERIVE: + v->set_derive(vl->values[i].derive); + break; + case DS_TYPE_ABSOLUTE: + v->set_absolute(vl->values[i].absolute); + break; + default: + return grpc::Status(grpc::StatusCode::INTERNAL, + grpc::string("unknown value type")); + } + + auto name = msg->add_ds_names(); + name->assign(ds->ds[i].name); + } + + return grpc::Status::OK; } /* marshal_value_list */ -static grpc::Status unmarshal_value_list(const collectd::types::ValueList &msg, value_list_t *vl) -{ - vl->time = NS_TO_CDTIME_T(TimeUtil::TimestampToNanoseconds(msg.time())); - vl->interval = NS_TO_CDTIME_T(TimeUtil::DurationToNanoseconds(msg.interval())); - - auto status = unmarshal_ident(msg.identifier(), vl, true); - if (!status.ok()) - return status; - - value_t *values = NULL; - size_t values_len = 0; - - status = grpc::Status::OK; - for (auto v : msg.values()) { - value_t *val = (value_t *)realloc(values, (values_len + 1) * sizeof(*values)); - if (!val) { - status = grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, - grpc::string("failed to allocate values array")); - break; - } - - values = val; - val = values + values_len; - values_len++; - - switch (v.value_case()) { - case collectd::types::Value::ValueCase::kCounter: - val->counter = counter_t(v.counter()); - break; - case collectd::types::Value::ValueCase::kGauge: - val->gauge = gauge_t(v.gauge()); - break; - case collectd::types::Value::ValueCase::kDerive: - val->derive = derive_t(v.derive()); - break; - case collectd::types::Value::ValueCase::kAbsolute: - val->absolute = absolute_t(v.absolute()); - break; - default: - status = grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, - grpc::string("unknown value type")); - break; - } - - if (!status.ok()) - break; - } - if (status.ok()) { - vl->values = values; - vl->values_len = values_len; - } - else if (values) { - free(values); - } - - return status; +static grpc::Status unmarshal_value_list(const collectd::types::ValueList &msg, + value_list_t *vl) { + vl->time = NS_TO_CDTIME_T(TimeUtil::TimestampToNanoseconds(msg.time())); + vl->interval = + NS_TO_CDTIME_T(TimeUtil::DurationToNanoseconds(msg.interval())); + + auto status = unmarshal_ident(msg.identifier(), vl, true); + if (!status.ok()) + return status; + + value_t *values = NULL; + size_t values_len = 0; + + status = grpc::Status::OK; + for (auto v : msg.values()) { + value_t *val = + (value_t *)realloc(values, (values_len + 1) * sizeof(*values)); + if (!val) { + status = grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED, + grpc::string("failed to allocate values array")); + break; + } + + values = val; + val = values + values_len; + values_len++; + + switch (v.value_case()) { + case collectd::types::Value::ValueCase::kCounter: + val->counter = counter_t(v.counter()); + break; + case collectd::types::Value::ValueCase::kGauge: + val->gauge = gauge_t(v.gauge()); + break; + case collectd::types::Value::ValueCase::kDerive: + val->derive = derive_t(v.derive()); + break; + case collectd::types::Value::ValueCase::kAbsolute: + val->absolute = absolute_t(v.absolute()); + break; + default: + status = grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, + grpc::string("unknown value type")); + break; + } + + if (!status.ok()) + break; + } + if (status.ok()) { + vl->values = values; + vl->values_len = values_len; + } else if (values) { + free(values); + } + + return status; } /* unmarshal_value_list() */ /* @@ -263,200 +261,200 @@ static grpc::Status unmarshal_value_list(const collectd::types::ValueList &msg, */ class CollectdImpl : public collectd::Collectd::Service { public: - grpc::Status QueryValues(grpc::ServerContext *ctx, QueryValuesRequest const *req, grpc::ServerWriter *writer) override { - value_list_t match; - auto status = unmarshal_ident(req->identifier(), &match, false); - if (!status.ok()) { - return status; - } - - std::queue value_lists; - status = this->queryValuesRead(&match, &value_lists); - if (status.ok()) { - status = this->queryValuesWrite(ctx, writer, &value_lists); - } - - while (!value_lists.empty()) { - auto vl = value_lists.front(); - value_lists.pop(); - sfree(vl.values); - } - - return status; - } - - grpc::Status PutValues(grpc::ServerContext *ctx, - grpc::ServerReader *reader, - PutValuesResponse *res) override { - PutValuesRequest req; - - while (reader->Read(&req)) { - value_list_t vl = {0}; - auto status = unmarshal_value_list(req.value_list(), &vl); - if (!status.ok()) - return status; - - if (plugin_dispatch_values(&vl)) - return grpc::Status(grpc::StatusCode::INTERNAL, - grpc::string("failed to enqueue values for writing")); - } - - res->Clear(); - return grpc::Status::OK; - } + grpc::Status + QueryValues(grpc::ServerContext *ctx, QueryValuesRequest const *req, + grpc::ServerWriter *writer) override { + value_list_t match; + auto status = unmarshal_ident(req->identifier(), &match, false); + if (!status.ok()) { + return status; + } + + std::queue value_lists; + status = this->queryValuesRead(&match, &value_lists); + if (status.ok()) { + status = this->queryValuesWrite(ctx, writer, &value_lists); + } + + while (!value_lists.empty()) { + auto vl = value_lists.front(); + value_lists.pop(); + sfree(vl.values); + } + + return status; + } + + grpc::Status PutValues(grpc::ServerContext *ctx, + grpc::ServerReader *reader, + PutValuesResponse *res) override { + PutValuesRequest req; + + while (reader->Read(&req)) { + value_list_t vl = {0}; + auto status = unmarshal_value_list(req.value_list(), &vl); + if (!status.ok()) + return status; + + if (plugin_dispatch_values(&vl)) + return grpc::Status( + grpc::StatusCode::INTERNAL, + grpc::string("failed to enqueue values for writing")); + } + + res->Clear(); + return grpc::Status::OK; + } private: - grpc::Status queryValuesRead(value_list_t const *match, std::queue *value_lists) { - uc_iter_t *iter; - if ((iter = uc_get_iterator()) == NULL) { - return grpc::Status(grpc::StatusCode::INTERNAL, - grpc::string("failed to query values: cannot create iterator")); - } - - grpc::Status status = grpc::Status::OK; - char *name = NULL; - while (uc_iterator_next(iter, &name) == 0) { - value_list_t vl; - if (parse_identifier_vl(name, &vl) != 0) { - status = grpc::Status(grpc::StatusCode::INTERNAL, - grpc::string("failed to parse identifier")); - break; - } - - if (!ident_matches(&vl, match)) - continue; - - if (uc_iterator_get_time(iter, &vl.time) < 0) { - status = grpc::Status(grpc::StatusCode::INTERNAL, - grpc::string("failed to retrieve value timestamp")); - break; - } - if (uc_iterator_get_interval(iter, &vl.interval) < 0) { - status = grpc::Status(grpc::StatusCode::INTERNAL, - grpc::string("failed to retrieve value interval")); - break; - } - if (uc_iterator_get_values(iter, &vl.values, &vl.values_len) < 0) { - status = grpc::Status(grpc::StatusCode::INTERNAL, - grpc::string("failed to retrieve values")); - break; - } - - value_lists->push(vl); - } // while (uc_iterator_next(iter, &name) == 0) - - uc_iterator_destroy(iter); - return status; - } - - grpc::Status queryValuesWrite(grpc::ServerContext *ctx, - grpc::ServerWriter *writer, - std::queue *value_lists) { - while (!value_lists->empty()) { - auto vl = value_lists->front(); - QueryValuesResponse res; - res.Clear(); - - auto status = marshal_value_list(&vl, res.mutable_value_list()); - if (!status.ok()) { - return status; - } - - if (!writer->Write(res)) { - return grpc::Status::CANCELLED; - } - - value_lists->pop(); - sfree(vl.values); - } - - return grpc::Status::OK; - } + grpc::Status queryValuesRead(value_list_t const *match, + std::queue *value_lists) { + uc_iter_t *iter; + if ((iter = uc_get_iterator()) == NULL) { + return grpc::Status( + grpc::StatusCode::INTERNAL, + grpc::string("failed to query values: cannot create iterator")); + } + + grpc::Status status = grpc::Status::OK; + char *name = NULL; + while (uc_iterator_next(iter, &name) == 0) { + value_list_t vl; + if (parse_identifier_vl(name, &vl) != 0) { + status = grpc::Status(grpc::StatusCode::INTERNAL, + grpc::string("failed to parse identifier")); + break; + } + + if (!ident_matches(&vl, match)) + continue; + + if (uc_iterator_get_time(iter, &vl.time) < 0) { + status = + grpc::Status(grpc::StatusCode::INTERNAL, + grpc::string("failed to retrieve value timestamp")); + break; + } + if (uc_iterator_get_interval(iter, &vl.interval) < 0) { + status = + grpc::Status(grpc::StatusCode::INTERNAL, + grpc::string("failed to retrieve value interval")); + break; + } + if (uc_iterator_get_values(iter, &vl.values, &vl.values_len) < 0) { + status = grpc::Status(grpc::StatusCode::INTERNAL, + grpc::string("failed to retrieve values")); + break; + } + + value_lists->push(vl); + } // while (uc_iterator_next(iter, &name) == 0) + + uc_iterator_destroy(iter); + return status; + } + + grpc::Status queryValuesWrite(grpc::ServerContext *ctx, + grpc::ServerWriter *writer, + std::queue *value_lists) { + while (!value_lists->empty()) { + auto vl = value_lists->front(); + QueryValuesResponse res; + res.Clear(); + + auto status = marshal_value_list(&vl, res.mutable_value_list()); + if (!status.ok()) { + return status; + } + + if (!writer->Write(res)) { + return grpc::Status::CANCELLED; + } + + value_lists->pop(); + sfree(vl.values); + } + + return grpc::Status::OK; + } }; /* * gRPC server implementation */ -class CollectdServer final -{ +class CollectdServer final { public: - void Start() - { - auto auth = grpc::InsecureServerCredentials(); - - grpc::ServerBuilder builder; - - if (listeners.empty()) { - builder.AddListeningPort(default_addr, auth); - INFO("grpc: Listening on %s", default_addr.c_str()); - } - else { - for (auto l : listeners) { - grpc::string addr = l.addr + ":" + l.port; - - auto use_ssl = grpc::string(""); - auto a = auth; - if (l.ssl != nullptr) { - use_ssl = grpc::string(" (SSL enabled)"); - a = grpc::SslServerCredentials(*l.ssl); - } - - builder.AddListeningPort(addr, a); - INFO("grpc: Listening on %s%s", addr.c_str(), use_ssl.c_str()); - } - } - - builder.RegisterService(&collectd_service_); - - server_ = builder.BuildAndStart(); - } /* Start() */ - - void Shutdown() - { - server_->Shutdown(); - } /* Shutdown() */ + void Start() { + auto auth = grpc::InsecureServerCredentials(); + + grpc::ServerBuilder builder; + + if (listeners.empty()) { + builder.AddListeningPort(default_addr, auth); + INFO("grpc: Listening on %s", default_addr.c_str()); + } else { + for (auto l : listeners) { + grpc::string addr = l.addr + ":" + l.port; + + auto use_ssl = grpc::string(""); + auto a = auth; + if (l.ssl != nullptr) { + use_ssl = grpc::string(" (SSL enabled)"); + a = grpc::SslServerCredentials(*l.ssl); + } + + builder.AddListeningPort(addr, a); + INFO("grpc: Listening on %s%s", addr.c_str(), use_ssl.c_str()); + } + } + + builder.RegisterService(&collectd_service_); + + server_ = builder.BuildAndStart(); + } /* Start() */ + + void Shutdown() { server_->Shutdown(); } /* Shutdown() */ private: - CollectdImpl collectd_service_; + CollectdImpl collectd_service_; - std::unique_ptr server_; + std::unique_ptr server_; }; /* class CollectdServer */ -class CollectdClient final -{ +class CollectdClient final { public: - CollectdClient(std::shared_ptr channel) : stub_(Collectd::NewStub(channel)) { - } - - int PutValues(value_list_t const *vl) { - grpc::ClientContext ctx; - - PutValuesRequest req; - auto status = marshal_value_list(vl, req.mutable_value_list()); - if (!status.ok()) { - ERROR("grpc: Marshalling value_list_t failed."); - return -1; - } - - PutValuesResponse res; - auto stream = stub_->PutValues(&ctx, &res); - if (!stream->Write(req)) { - NOTICE("grpc: Broken stream."); - /* intentionally not returning. */ - } - - stream->WritesDone(); - status = stream->Finish(); - if (!status.ok()) { - ERROR ("grpc: Error while closing stream."); - return -1; - } - - return 0; - } /* int PutValues */ + CollectdClient(std::shared_ptr channel) + : stub_(Collectd::NewStub(channel)) {} + + int PutValues(value_list_t const *vl) { + grpc::ClientContext ctx; + + PutValuesRequest req; + auto status = marshal_value_list(vl, req.mutable_value_list()); + if (!status.ok()) { + ERROR("grpc: Marshalling value_list_t failed."); + return -1; + } + + PutValuesResponse res; + auto stream = stub_->PutValues(&ctx, &res); + if (!stream->Write(req)) { + NOTICE("grpc: Broken stream."); + /* intentionally not returning. */ + } + + stream->WritesDone(); + status = stream->Finish(); + if (!status.ok()) { + ERROR("grpc: Error while closing stream."); + return -1; + } + + return 0; + } /* int PutValues */ private: - std::unique_ptr stub_; + std::unique_ptr stub_; }; static CollectdServer *server = nullptr; @@ -465,216 +463,194 @@ static CollectdServer *server = nullptr; * collectd plugin interface */ extern "C" { - static void c_grpc_destroy_write_callback (void *ptr) { - delete (CollectdClient *) ptr; - } - - static int c_grpc_write(__attribute__((unused)) data_set_t const *ds, - value_list_t const *vl, - user_data_t *ud) { - CollectdClient *c = (CollectdClient *) ud->data; - return c->PutValues(vl); - } - - static int c_grpc_config_listen(oconfig_item_t *ci) - { - if ((ci->values_num != 2) - || (ci->values[0].type != OCONFIG_TYPE_STRING) - || (ci->values[1].type != OCONFIG_TYPE_STRING)) { - ERROR("grpc: The `%s` config option needs exactly " - "two string argument (address and port).", ci->key); - return -1; - } - - auto listener = Listener(); - listener.addr = grpc::string(ci->values[0].value.string); - listener.port = grpc::string(ci->values[1].value.string); - listener.ssl = nullptr; - - auto ssl_opts = new(grpc::SslServerCredentialsOptions); - grpc::SslServerCredentialsOptions::PemKeyCertPair pkcp = {}; - bool use_ssl = false; - - for (int i = 0; i < ci->children_num; i++) { - oconfig_item_t *child = ci->children + i; - - if (!strcasecmp("EnableSSL", child->key)) { - if (cf_util_get_boolean(child, &use_ssl)) { - ERROR("grpc: Option `%s` expects a boolean value", - child->key); - return -1; - } - } - else if (!strcasecmp("SSLCACertificateFile", child->key)) { - char *certs = NULL; - if (cf_util_get_string(child, &certs)) { - ERROR("grpc: Option `%s` expects a string value", - child->key); - return -1; - } - ssl_opts->pem_root_certs = read_file(certs); - } - else if (!strcasecmp("SSLCertificateKeyFile", child->key)) { - char *key = NULL; - if (cf_util_get_string(child, &key)) { - ERROR("grpc: Option `%s` expects a string value", - child->key); - return -1; - } - pkcp.private_key = read_file(key); - } - else if (!strcasecmp("SSLCertificateFile", child->key)) { - char *cert = NULL; - if (cf_util_get_string(child, &cert)) { - ERROR("grpc: Option `%s` expects a string value", - child->key); - return -1; - } - pkcp.cert_chain = read_file(cert); - } - else { - WARNING("grpc: Option `%s` not allowed in <%s> block.", - child->key, ci->key); - } - } - - ssl_opts->pem_key_cert_pairs.push_back(pkcp); - if (use_ssl) - listener.ssl = ssl_opts; - else - delete(ssl_opts); - - listeners.push_back(listener); - return 0; - } /* c_grpc_config_listen() */ - - static int c_grpc_config_server(oconfig_item_t *ci) - { - if ((ci->values_num != 2) - || (ci->values[0].type != OCONFIG_TYPE_STRING) - || (ci->values[1].type != OCONFIG_TYPE_STRING)) { - ERROR("grpc: The `%s` config option needs exactly " - "two string argument (address and port).", ci->key); - return -1; - } - - grpc::SslCredentialsOptions ssl_opts; - bool use_ssl = false; - - for (int i = 0; i < ci->children_num; i++) { - oconfig_item_t *child = ci->children + i; - - if (!strcasecmp("EnableSSL", child->key)) { - if (cf_util_get_boolean(child, &use_ssl)) { - return -1; - } - } - else if (!strcasecmp("SSLCACertificateFile", child->key)) { - char *certs = NULL; - if (cf_util_get_string(child, &certs)) { - return -1; - } - ssl_opts.pem_root_certs = read_file(certs); - } - else if (!strcasecmp("SSLCertificateKeyFile", child->key)) { - char *key = NULL; - if (cf_util_get_string(child, &key)) { - return -1; - } - ssl_opts.pem_private_key = read_file(key); - } - else if (!strcasecmp("SSLCertificateFile", child->key)) { - char *cert = NULL; - if (cf_util_get_string(child, &cert)) { - return -1; - } - ssl_opts.pem_cert_chain = read_file(cert); - } - else { - WARNING("grpc: Option `%s` not allowed in <%s> block.", - child->key, ci->key); - } - } - - auto node = grpc::string(ci->values[0].value.string); - auto service = grpc::string(ci->values[1].value.string); - auto addr = node + ":" + service; - - CollectdClient *client; - if (use_ssl) { - auto channel_creds = grpc::SslCredentials(ssl_opts); - auto channel = grpc::CreateChannel(addr, channel_creds); - client = new CollectdClient(channel); - } else { - auto channel = grpc::CreateChannel(addr, grpc::InsecureChannelCredentials()); - client = new CollectdClient(channel); - } - - auto callback_name = grpc::string("grpc/") + addr; - user_data_t ud = { - .data = client, - .free_func = c_grpc_destroy_write_callback, - }; - - plugin_register_write (callback_name.c_str(), c_grpc_write, &ud); - return 0; - } /* c_grpc_config_server() */ - - static int c_grpc_config(oconfig_item_t *ci) - { - int i; - - for (i = 0; i < ci->children_num; i++) { - oconfig_item_t *child = ci->children + i; - - if (!strcasecmp("Listen", child->key)) { - if (c_grpc_config_listen(child)) - return -1; - } - else if (!strcasecmp("Server", child->key)) { - if (c_grpc_config_server(child)) - return -1; - } - - else { - WARNING("grpc: Option `%s` not allowed here.", child->key); - } - } - - return 0; - } /* c_grpc_config() */ - - static int c_grpc_init(void) - { - server = new CollectdServer(); - if (!server) { - ERROR("grpc: Failed to create server"); - return -1; - } - - server->Start(); - return 0; - } /* c_grpc_init() */ - - static int c_grpc_shutdown(void) - { - if (!server) - return 0; - - server->Shutdown(); - - delete server; - server = nullptr; - - return 0; - } /* c_grpc_shutdown() */ - - void module_register(void) - { - plugin_register_complex_config("grpc", c_grpc_config); - plugin_register_init("grpc", c_grpc_init); - plugin_register_shutdown("grpc", c_grpc_shutdown); - } /* module_register() */ -} /* extern "C" */ +static void c_grpc_destroy_write_callback(void *ptr) { + delete (CollectdClient *)ptr; +} -/* vim: set sw=4 ts=4 tw=78 noexpandtab : */ +static int c_grpc_write(__attribute__((unused)) data_set_t const *ds, + value_list_t const *vl, user_data_t *ud) { + CollectdClient *c = (CollectdClient *)ud->data; + return c->PutValues(vl); +} + +static int c_grpc_config_listen(oconfig_item_t *ci) { + if ((ci->values_num != 2) || (ci->values[0].type != OCONFIG_TYPE_STRING) || + (ci->values[1].type != OCONFIG_TYPE_STRING)) { + ERROR("grpc: The `%s` config option needs exactly " + "two string argument (address and port).", + ci->key); + return -1; + } + + auto listener = Listener(); + listener.addr = grpc::string(ci->values[0].value.string); + listener.port = grpc::string(ci->values[1].value.string); + listener.ssl = nullptr; + + auto ssl_opts = new (grpc::SslServerCredentialsOptions); + grpc::SslServerCredentialsOptions::PemKeyCertPair pkcp = {}; + bool use_ssl = false; + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (!strcasecmp("EnableSSL", child->key)) { + if (cf_util_get_boolean(child, &use_ssl)) { + ERROR("grpc: Option `%s` expects a boolean value", child->key); + return -1; + } + } else if (!strcasecmp("SSLCACertificateFile", child->key)) { + char *certs = NULL; + if (cf_util_get_string(child, &certs)) { + ERROR("grpc: Option `%s` expects a string value", child->key); + return -1; + } + ssl_opts->pem_root_certs = read_file(certs); + } else if (!strcasecmp("SSLCertificateKeyFile", child->key)) { + char *key = NULL; + if (cf_util_get_string(child, &key)) { + ERROR("grpc: Option `%s` expects a string value", child->key); + return -1; + } + pkcp.private_key = read_file(key); + } else if (!strcasecmp("SSLCertificateFile", child->key)) { + char *cert = NULL; + if (cf_util_get_string(child, &cert)) { + ERROR("grpc: Option `%s` expects a string value", child->key); + return -1; + } + pkcp.cert_chain = read_file(cert); + } else { + WARNING("grpc: Option `%s` not allowed in <%s> block.", child->key, + ci->key); + } + } + + ssl_opts->pem_key_cert_pairs.push_back(pkcp); + if (use_ssl) + listener.ssl = ssl_opts; + else + delete (ssl_opts); + + listeners.push_back(listener); + return 0; +} /* c_grpc_config_listen() */ + +static int c_grpc_config_server(oconfig_item_t *ci) { + if ((ci->values_num != 2) || (ci->values[0].type != OCONFIG_TYPE_STRING) || + (ci->values[1].type != OCONFIG_TYPE_STRING)) { + ERROR("grpc: The `%s` config option needs exactly " + "two string argument (address and port).", + ci->key); + return -1; + } + + grpc::SslCredentialsOptions ssl_opts; + bool use_ssl = false; + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (!strcasecmp("EnableSSL", child->key)) { + if (cf_util_get_boolean(child, &use_ssl)) { + return -1; + } + } else if (!strcasecmp("SSLCACertificateFile", child->key)) { + char *certs = NULL; + if (cf_util_get_string(child, &certs)) { + return -1; + } + ssl_opts.pem_root_certs = read_file(certs); + } else if (!strcasecmp("SSLCertificateKeyFile", child->key)) { + char *key = NULL; + if (cf_util_get_string(child, &key)) { + return -1; + } + ssl_opts.pem_private_key = read_file(key); + } else if (!strcasecmp("SSLCertificateFile", child->key)) { + char *cert = NULL; + if (cf_util_get_string(child, &cert)) { + return -1; + } + ssl_opts.pem_cert_chain = read_file(cert); + } else { + WARNING("grpc: Option `%s` not allowed in <%s> block.", child->key, + ci->key); + } + } + + auto node = grpc::string(ci->values[0].value.string); + auto service = grpc::string(ci->values[1].value.string); + auto addr = node + ":" + service; + + CollectdClient *client; + if (use_ssl) { + auto channel_creds = grpc::SslCredentials(ssl_opts); + auto channel = grpc::CreateChannel(addr, channel_creds); + client = new CollectdClient(channel); + } else { + auto channel = + grpc::CreateChannel(addr, grpc::InsecureChannelCredentials()); + client = new CollectdClient(channel); + } + + auto callback_name = grpc::string("grpc/") + addr; + user_data_t ud = { + .data = client, .free_func = c_grpc_destroy_write_callback, + }; + + plugin_register_write(callback_name.c_str(), c_grpc_write, &ud); + return 0; +} /* c_grpc_config_server() */ + +static int c_grpc_config(oconfig_item_t *ci) { + int i; + + for (i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (!strcasecmp("Listen", child->key)) { + if (c_grpc_config_listen(child)) + return -1; + } else if (!strcasecmp("Server", child->key)) { + if (c_grpc_config_server(child)) + return -1; + } + + else { + WARNING("grpc: Option `%s` not allowed here.", child->key); + } + } + + return 0; +} /* c_grpc_config() */ + +static int c_grpc_init(void) { + server = new CollectdServer(); + if (!server) { + ERROR("grpc: Failed to create server"); + return -1; + } + + server->Start(); + return 0; +} /* c_grpc_init() */ + +static int c_grpc_shutdown(void) { + if (!server) + return 0; + + server->Shutdown(); + + delete server; + server = nullptr; + + return 0; +} /* c_grpc_shutdown() */ + +void module_register(void) { + plugin_register_complex_config("grpc", c_grpc_config); + plugin_register_init("grpc", c_grpc_init); + plugin_register_shutdown("grpc", c_grpc_shutdown); +} /* module_register() */ +} /* extern "C" */ diff --git a/src/intel_rdt.c b/src/intel_rdt.c index 73288366..fc2a5f17 100644 --- a/src/intel_rdt.c +++ b/src/intel_rdt.c @@ -252,14 +252,13 @@ static int cgroup_set(rdt_core_group_t *cg, char *desc, uint64_t *cores, * `item' Config option containing core groups. * `groups' Table of core groups to set values in. * `max_groups' Maximum number of core groups allowed. - * `max_core' Maximum allowed core value. * * RETURN VALUE * On success, the number of core groups set up. On error, appropriate * negative error value. */ static int oconfig_to_cgroups(oconfig_item_t *item, rdt_core_group_t *groups, - size_t max_groups, uint64_t max_core) { + size_t max_groups) { int index = 0; assert(groups != NULL); @@ -285,14 +284,6 @@ static int oconfig_to_cgroups(oconfig_item_t *item, rdt_core_group_t *groups, return (-EINVAL); } - for (int i = 0; i < n; i++) { - if (cores[i] > max_core) { - ERROR(RDT_PLUGIN ": Core group (%s) contains invalid core id (%d)", - item->values[j].value.string, (int)cores[i]); - return (-EINVAL); - } - } - /* set core group info */ ret = cgroup_set(&groups[index], item->values[j].value.string, cores, n); if (ret < 0) @@ -395,6 +386,15 @@ static int rdt_default_cgroups(void) { return g_rdt->pqos_cpu->num_cores; } +static int rdt_is_core_id_valid(int core_id) { + + for (int i = 0; i < g_rdt->pqos_cpu->num_cores; i++) + if (core_id == g_rdt->pqos_cpu->cores[i].lcore) + return 1; + + return 0; +} + static int rdt_config_cgroups(oconfig_item_t *item) { int n = 0; enum pqos_mon_event events = 0; @@ -413,14 +413,27 @@ static int rdt_config_cgroups(oconfig_item_t *item) { DEBUG(RDT_PLUGIN ": [%d]: %s", j, item->values[j].value.string); } - n = oconfig_to_cgroups(item, g_rdt->cgroups, RDT_MAX_CORES, - g_rdt->pqos_cpu->num_cores - 1); + n = oconfig_to_cgroups(item, g_rdt->cgroups, g_rdt->pqos_cpu->num_cores); if (n < 0) { rdt_free_cgroups(); ERROR(RDT_PLUGIN ": Error parsing core groups configuration."); return (-EINVAL); } + /* validate configured core id values */ + for (int group_idx = 0; group_idx < n; group_idx++) { + for (int core_idx = 0; core_idx < g_rdt->cgroups[group_idx].num_cores; + core_idx++) { + if (!rdt_is_core_id_valid(g_rdt->cgroups[group_idx].cores[core_idx])) { + ERROR(RDT_PLUGIN ": Core group '%s' contains invalid core id '%d'", + g_rdt->cgroups[group_idx].desc, + (int)g_rdt->cgroups[group_idx].cores[core_idx]); + rdt_free_cgroups(); + return (-EINVAL); + } + } + } + if (n == 0) { /* create default core groups if "Cores" config option is empty */ n = rdt_default_cgroups(); @@ -467,6 +480,10 @@ static int rdt_config_cgroups(oconfig_item_t *item) { return (0); } +static void rdt_pqos_log(void *context, const size_t size, const char *msg) { + DEBUG(RDT_PLUGIN ": %s", msg); +} + static int rdt_preinit(void) { int ret; @@ -481,15 +498,12 @@ static int rdt_preinit(void) { return (-ENOMEM); } - /* In case previous instance of the application was not closed properly - * call fini and ignore return code. */ - pqos_fini(); + struct pqos_config pqos = {.fd_log = -1, + .callback_log = rdt_pqos_log, + .context_log = NULL, + .verbose = 0}; - /* TODO: - * stdout should not be used here. Will be reworked when support of log - * callback is added to PQoS library. - */ - ret = pqos_init(&(struct pqos_config){.fd_log = STDOUT_FILENO}); + ret = pqos_init(&pqos); if (ret != PQOS_RETVAL_OK) { ERROR(RDT_PLUGIN ": Error initializing PQoS library!"); goto rdt_preinit_error1; @@ -514,6 +528,9 @@ static int rdt_preinit(void) { goto rdt_preinit_error2; } + /* Reset pqos monitoring groups registers */ + pqos_mon_reset(); + return (0); rdt_preinit_error2: diff --git a/src/ipc.c b/src/ipc.c index c9fb003e..8222efba 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -319,5 +319,3 @@ void module_register(void) /* {{{ */ plugin_register_read("ipc", ipc_read); } /* }}} */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/ipmi.c b/src/ipmi.c index 1bbaf412..f3636fc8 100644 --- a/src/ipmi.c +++ b/src/ipmi.c @@ -621,5 +621,3 @@ void module_register(void) { plugin_register_read("ipmi", c_ipmi_read); plugin_register_shutdown("ipmi", c_ipmi_shutdown); } /* void module_register */ - -/* vim: set sw=2 sts=2 ts=8 fdm=marker et : */ diff --git a/src/ipvs.c b/src/ipvs.c index 2446bd13..a8c4a1d2 100644 --- a/src/ipvs.c +++ b/src/ipvs.c @@ -321,5 +321,3 @@ void module_register(void) { plugin_register_shutdown("ipvs", cipvs_shutdown); return; } /* module_register */ - -/* vim: set sw=4 ts=4 tw=78 noexpandtab : */ diff --git a/src/java.c b/src/java.c index 63b5e317..2e4d88a6 100644 --- a/src/java.c +++ b/src/java.c @@ -2841,5 +2841,3 @@ void module_register(void) { plugin_register_init("java", cjni_init); plugin_register_shutdown("java", cjni_shutdown); } /* void module_register (void) */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/libcollectdclient/Makefile.am b/src/libcollectdclient/Makefile.am deleted file mode 100644 index e81a5943..00000000 --- a/src/libcollectdclient/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -AUTOMAKE_OPTIONS = foreign no-dependencies - -pkginclude_HEADERS = collectd/client.h collectd/network.h collectd/network_buffer.h collectd/lcc_features.h -lib_LTLIBRARIES = libcollectdclient.la -nodist_pkgconfig_DATA = libcollectdclient.pc - -BUILT_SOURCES = collectd/lcc_features.h - -libcollectdclient_la_SOURCES = client.c network.c network_buffer.c -libcollectdclient_la_CPPFLAGS = $(AM_CPPFLAGS) \ - -I$(top_srcdir)/src/libcollectdclient/collectd \ - -I$(top_builddir)/src/libcollectdclient/collectd \ - -I$(top_srcdir)/src/daemon -libcollectdclient_la_LDFLAGS = -version-info 1:0:0 -libcollectdclient_la_LIBADD = -if BUILD_WITH_LIBGCRYPT -libcollectdclient_la_CPPFLAGS += $(GCRYPT_CPPFLAGS) -libcollectdclient_la_LDFLAGS += $(GCRYPT_LDFLAGS) -libcollectdclient_la_LIBADD += $(GCRYPT_LIBS) -endif diff --git a/src/libcollectdclient/client.c b/src/libcollectdclient/client.c index f61e9678..a8f5d0d5 100644 --- a/src/libcollectdclient/client.c +++ b/src/libcollectdclient/client.c @@ -1021,5 +1021,3 @@ int lcc_sort_identifiers(lcc_connection_t *c, /* {{{ */ qsort(idents, idents_num, sizeof(*idents), lcc_identifier_compare); return (0); } /* }}} int lcc_sort_identifiers */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/libcollectdclient/collectd/client.h b/src/libcollectdclient/collectd/client.h index 36aaf921..8604ff6b 100644 --- a/src/libcollectdclient/collectd/client.h +++ b/src/libcollectdclient/collectd/client.h @@ -39,9 +39,7 @@ /* * Includes (for data types) */ -#if HAVE_STDINT_H #include -#endif #include #include @@ -141,5 +139,4 @@ int lcc_sort_identifiers(lcc_connection_t *c, lcc_identifier_t *idents, LCC_END_DECLS -/* vim: set sw=2 sts=2 et : */ #endif /* LIBCOLLECTD_COLLECTDCLIENT_H */ diff --git a/src/libcollectdclient/collectd/lcc_features.h.in b/src/libcollectdclient/collectd/lcc_features.h.in index 0e6fcd43..304845e2 100644 --- a/src/libcollectdclient/collectd/lcc_features.h.in +++ b/src/libcollectdclient/collectd/lcc_features.h.in @@ -62,6 +62,3 @@ const char *lcc_version_extra (void); LCC_END_DECLS #endif /* ! LIBCOLLECTD_LCC_FEATURES_H */ - -/* vim: set sw=4 ts=4 tw=78 noexpandtab : */ - diff --git a/src/libcollectdclient/collectd/network.h b/src/libcollectdclient/collectd/network.h index fdb9b33f..35fd7d62 100644 --- a/src/libcollectdclient/collectd/network.h +++ b/src/libcollectdclient/collectd/network.h @@ -73,5 +73,4 @@ int lcc_network_notification_send (lcc_network_t *net, const lcc_notification_t *notif); #endif -/* vim: set sw=2 sts=2 et : */ #endif /* LIBCOLLECTDCLIENT_NETWORK_H */ diff --git a/src/libcollectdclient/collectd/network_buffer.h b/src/libcollectdclient/collectd/network_buffer.h index 5612458b..9f393103 100644 --- a/src/libcollectdclient/collectd/network_buffer.h +++ b/src/libcollectdclient/collectd/network_buffer.h @@ -55,4 +55,3 @@ int lcc_network_buffer_get(lcc_network_buffer_t *nb, void *buffer, size_t *buffer_size); #endif /* LIBCOLLECTDCLIENT_NETWORK_BUFFER_H */ -/* vim: set sw=2 sts=2 et : */ diff --git a/src/libcollectdclient/network.c b/src/libcollectdclient/network.c index a21799c2..d096f186 100644 --- a/src/libcollectdclient/network.c +++ b/src/libcollectdclient/network.c @@ -446,5 +446,3 @@ int lcc_network_values_send(lcc_network_t *net, /* {{{ */ return (0); } /* }}} int lcc_network_values_send */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/libcollectdclient/network_buffer.c b/src/libcollectdclient/network_buffer.c index aa4941d8..866c4cc7 100644 --- a/src/libcollectdclient/network_buffer.c +++ b/src/libcollectdclient/network_buffer.c @@ -35,7 +35,7 @@ #include -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H #if defined __APPLE__ /* default xcode compiler throws warnings even when deprecated functionality * is not used. -Werror breaks the build because of erroneous warnings. @@ -106,7 +106,7 @@ struct lcc_network_buffer_s { char *username; char *password; -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H gcry_cipher_hd_t encr_cypher; size_t encr_header_len; char encr_iv[16]; @@ -131,7 +131,7 @@ static _Bool have_gcrypt(void) /* {{{ */ return (result); need_init = 0; -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H #if GCRYPT_VERSION_NUMBER < 0x010600 if (gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread)) return (0); @@ -475,7 +475,7 @@ static int nb_add_value_list(lcc_network_buffer_t *nb, /* {{{ */ return (0); } /* }}} int nb_add_value_list */ -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H static int nb_add_signature(lcc_network_buffer_t *nb) /* {{{ */ { char *buffer; @@ -688,7 +688,7 @@ int lcc_network_buffer_initialize(lcc_network_buffer_t *nb) /* {{{ */ nb->ptr = nb->buffer; nb->free = nb->size; -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H if (nb->seclevel == SIGN) { size_t username_len; uint16_t pkg_type = htons(TYPE_SIGN_SHA256); @@ -739,7 +739,7 @@ int lcc_network_buffer_finalize(lcc_network_buffer_t *nb) /* {{{ */ if (nb == NULL) return (EINVAL); -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H if (nb->seclevel == SIGN) return nb_add_signature(nb); else if (nb->seclevel == ENCRYPT) @@ -779,5 +779,3 @@ int lcc_network_buffer_get(lcc_network_buffer_t *nb, /* {{{ */ return (0); } /* }}} int lcc_network_buffer_get */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/liboconfig/Makefile.am b/src/liboconfig/Makefile.am deleted file mode 100644 index 5ac0ef34..00000000 --- a/src/liboconfig/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -BUILT_SOURCES = parser.h -#CLEANFILES = parser.[ch] scanner.c -AM_YFLAGS = -d - -noinst_LTLIBRARIES = liboconfig.la - -liboconfig_la_LDFLAGS = -avoid-version $(LEXLIB) -liboconfig_la_SOURCES = oconfig.c oconfig.h aux_types.h scanner.l parser.y diff --git a/src/liboconfig/oconfig.c b/src/liboconfig/oconfig.c index 76134dbe..079adcf8 100644 --- a/src/liboconfig/oconfig.c +++ b/src/liboconfig/oconfig.c @@ -196,7 +196,3 @@ void oconfig_free(oconfig_item_t *ci) { oconfig_free_all(ci); free(ci); } - -/* - * vim:shiftwidth=2:tabstop=8:softtabstop=2:fdm=marker - */ diff --git a/src/liboconfig/oconfig.h b/src/liboconfig/oconfig.h index d27f6f53..3b81062e 100644 --- a/src/liboconfig/oconfig.h +++ b/src/liboconfig/oconfig.h @@ -67,7 +67,4 @@ oconfig_item_t *oconfig_clone(const oconfig_item_t *ci); void oconfig_free(oconfig_item_t *ci); -/* - * vim: shiftwidth=2:tabstop=8:softtabstop=2 - */ #endif /* OCONFIG_H */ diff --git a/src/log_logstash.c b/src/log_logstash.c index 8df43136..06059304 100644 --- a/src/log_logstash.c +++ b/src/log_logstash.c @@ -339,5 +339,3 @@ void module_register(void) { plugin_register_notification("log_logstash", log_logstash_notification, /* user_data = */ NULL); } /* void module_register (void) */ - -/* vim: set sw=4 ts=4 tw=78 noexpandtab : */ diff --git a/src/logfile.c b/src/logfile.c index 6629c0b3..eca8c347 100644 --- a/src/logfile.c +++ b/src/logfile.c @@ -204,5 +204,3 @@ void module_register(void) { plugin_register_notification("logfile", logfile_notification, /* user_data = */ NULL); } /* void module_register (void) */ - -/* vim: set sw=4 ts=4 tw=78 noexpandtab : */ diff --git a/src/lpar.c b/src/lpar.c index df4424c8..c0192279 100644 --- a/src/lpar.c +++ b/src/lpar.c @@ -243,5 +243,3 @@ void module_register(void) { plugin_register_init("lpar", lpar_init); plugin_register_read("lpar", lpar_read); } /* void module_register */ - -/* vim: set sw=8 noet : */ diff --git a/src/lua.c b/src/lua.c index 2bd56a16..9eda7d5b 100644 --- a/src/lua.c +++ b/src/lua.c @@ -583,5 +583,3 @@ void module_register(void) { plugin_register_complex_config("lua", lua_config); plugin_register_shutdown("lua", lua_shutdown); } - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/match_empty_counter.c b/src/match_empty_counter.c index 67c55789..0b2ab126 100644 --- a/src/match_empty_counter.c +++ b/src/match_empty_counter.c @@ -79,5 +79,3 @@ void module_register(void) { .create = mec_create, .destroy = mec_destroy, .match = mec_match, }); } /* module_register */ - -/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ diff --git a/src/match_hashed.c b/src/match_hashed.c index fad52718..9c8d34f9 100644 --- a/src/match_hashed.c +++ b/src/match_hashed.c @@ -166,5 +166,3 @@ void module_register(void) { mproc.match = mh_match; fc_register_match("hashed", mproc); } /* module_register */ - -/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ diff --git a/src/match_regex.c b/src/match_regex.c index 209f7736..ea7fcf01 100644 --- a/src/match_regex.c +++ b/src/match_regex.c @@ -364,5 +364,3 @@ void module_register(void) { mproc.match = mr_match; fc_register_match("regex", mproc); } /* module_register */ - -/* vim: set sw=4 ts=4 tw=78 noexpandtab fdm=marker : */ diff --git a/src/match_timediff.c b/src/match_timediff.c index 6d00ed29..f0a456b9 100644 --- a/src/match_timediff.c +++ b/src/match_timediff.c @@ -141,5 +141,3 @@ void module_register(void) { mproc.match = mt_match; fc_register_match("timediff", mproc); } /* module_register */ - -/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ diff --git a/src/match_value.c b/src/match_value.c index 3c943757..45745bac 100644 --- a/src/match_value.c +++ b/src/match_value.c @@ -316,5 +316,3 @@ void module_register(void) { mproc.match = mv_match; fc_register_match("value", mproc); } /* module_register */ - -/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ diff --git a/src/mcelog.c b/src/mcelog.c new file mode 100644 index 00000000..4e6a6fd1 --- /dev/null +++ b/src/mcelog.c @@ -0,0 +1,551 @@ +/*- + * collectd - src/mcelog.c + * MIT License + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + + * Authors: + * Maryam Tahhan + * Volodymyr Mytnyk + * Taras Chornyi + * Krzysztof Matczak + */ + +#include "common.h" +#include "collectd.h" + +#include +#include +#include +#include + +#define MCELOG_PLUGIN "mcelog" +#define MCELOG_BUFF_SIZE 1024 +#define MCELOG_POLL_TIMEOUT 1000 /* ms */ +#define MCELOG_SOCKET_STR "SOCKET" +#define MCELOG_DIMM_NAME "DMI_NAME" +#define MCELOG_CORRECTED_ERR "corrected memory errors" +#define MCELOG_UNCORRECTED_ERR "uncorrected memory errors" + +typedef struct mcelog_config_s { + char logfile[PATH_MAX]; /* mcelog logfile */ + pthread_t tid; /* poll thread id */ +} mcelog_config_t; + +typedef struct socket_adapter_s socket_adapter_t; + +struct socket_adapter_s { + int sock_fd; /* mcelog server socket fd */ + struct sockaddr_un unix_sock; /* mcelog client socket */ + pthread_rwlock_t lock; + /* function pointers for socket operations */ + int (*write)(socket_adapter_t *self, const char *msg, const size_t len); + int (*reinit)(socket_adapter_t *self); + int (*receive)(socket_adapter_t *self, FILE **p_file); + int (*close)(socket_adapter_t *self); +}; + +typedef struct mcelog_memory_rec_s { + int corrected_err_total; /* x total*/ + int corrected_err_timed; /* x in 24h*/ + char corrected_err_timed_period[DATA_MAX_NAME_LEN]; + int uncorrected_err_total; /* x total*/ + int uncorrected_err_timed; /* x in 24h*/ + char uncorrected_err_timed_period[DATA_MAX_NAME_LEN]; + char location[DATA_MAX_NAME_LEN]; /* SOCKET x CHANNEL x DIMM x*/ + char dimm_name[DATA_MAX_NAME_LEN]; /* DMI_NAME "DIMM_F1" */ +} mcelog_memory_rec_t; + +static int socket_close(socket_adapter_t *self); +static int socket_write(socket_adapter_t *self, const char *msg, + const size_t len); +static int socket_reinit(socket_adapter_t *self); +static int socket_receive(socket_adapter_t *self, FILE **p_file); + +static mcelog_config_t g_mcelog_config = {.logfile = "/var/log/mcelog"}; + +static socket_adapter_t socket_adapter = { + .sock_fd = -1, + .unix_sock = + { + .sun_family = AF_UNIX, .sun_path = "/var/run/mcelog-client", + }, + .lock = PTHREAD_RWLOCK_INITIALIZER, + .close = socket_close, + .write = socket_write, + .reinit = socket_reinit, + .receive = socket_receive, +}; + +static _Bool mcelog_thread_running; + +static int mcelog_config(oconfig_item_t *ci) { + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + if (strcasecmp("McelogClientSocket", child->key) == 0) { + if (cf_util_get_string_buffer(child, socket_adapter.unix_sock.sun_path, + sizeof(socket_adapter.unix_sock.sun_path)) < + 0) { + ERROR(MCELOG_PLUGIN ": Invalid configuration option: \"%s\".", + child->key); + return (-1); + } + } else if (strcasecmp("McelogLogfile", child->key) == 0) { + if (cf_util_get_string_buffer(child, g_mcelog_config.logfile, + sizeof(g_mcelog_config.logfile)) < 0) { + ERROR(MCELOG_PLUGIN ": Invalid configuration option: \"%s\".", + child->key); + return (-1); + } + } else { + ERROR(MCELOG_PLUGIN ": Invalid configuration option: \"%s\".", + child->key); + return (-1); + } + } + return (0); +} + +static int socket_close(socket_adapter_t *self) { + int ret = 0; + pthread_rwlock_rdlock(&self->lock); + if (fcntl(self->sock_fd, F_GETFL) != -1) { + char errbuf[MCELOG_BUFF_SIZE]; + if (shutdown(self->sock_fd, SHUT_RDWR) != 0) { + ERROR(MCELOG_PLUGIN ": Socket shutdown failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + ret = -1; + } + if (close(self->sock_fd) != 0) { + ERROR(MCELOG_PLUGIN ": Socket close failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + ret = -1; + } + } + pthread_rwlock_unlock(&self->lock); + return (ret); +} + +static int socket_write(socket_adapter_t *self, const char *msg, + const size_t len) { + int ret = 0; + pthread_rwlock_rdlock(&self->lock); + if (swrite(self->sock_fd, msg, len) < 0) + ret = -1; + pthread_rwlock_unlock(&self->lock); + return (ret); +} + +static void mcelog_dispatch_notification(notification_t *n) { + if (!n) { + ERROR(MCELOG_PLUGIN ": %s: NULL pointer", __FUNCTION__); + return; + } + + sstrncpy(n->host, hostname_g, sizeof(n->host)); + sstrncpy(n->type, "gauge", sizeof(n->type)); + plugin_dispatch_notification(n); + if (n->meta) + plugin_notification_meta_free(n->meta); +} + +static int socket_reinit(socket_adapter_t *self) { + char errbuff[MCELOG_BUFF_SIZE]; + int ret = -1; + cdtime_t interval = plugin_get_interval(); + struct timeval socket_timeout = CDTIME_T_TO_TIMEVAL(interval); + + /* synchronization via write lock since sock_fd may be changed here */ + pthread_rwlock_wrlock(&self->lock); + self->sock_fd = + socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0); + if (self->sock_fd < 0) { + ERROR(MCELOG_PLUGIN ": Could not create a socket. %s", + sstrerror(errno, errbuff, sizeof(errbuff))); + pthread_rwlock_unlock(&self->lock); + return (ret); + } + + /* Set socket timeout option */ + if (setsockopt(self->sock_fd, SOL_SOCKET, SO_SNDTIMEO, &socket_timeout, + sizeof(socket_timeout)) < 0) + ERROR(MCELOG_PLUGIN ": Failed to set the socket timeout option."); + + /* downgrading to read lock due to possible recursive read locks + * in self->close(self) call */ + pthread_rwlock_unlock(&self->lock); + pthread_rwlock_rdlock(&self->lock); + if (connect(self->sock_fd, (struct sockaddr *)&(self->unix_sock), + sizeof(self->unix_sock)) < 0) { + ERROR(MCELOG_PLUGIN ": Failed to connect to mcelog server. %s", + sstrerror(errno, errbuff, sizeof(errbuff))); + self->close(self); + ret = -1; + } else { + ret = 0; + mcelog_dispatch_notification( + &(notification_t){.severity = NOTIF_OKAY, + .time = cdtime(), + .message = "Connected to mcelog server", + .plugin = MCELOG_PLUGIN, + .type_instance = "mcelog_status"}); + } + pthread_rwlock_unlock(&self->lock); + return (ret); +} + +static int mcelog_prepare_notification(notification_t *n, + const mcelog_memory_rec_t *mr) { + if (n == NULL || mr == NULL) + return (-1); + + if ((mr->location[0] != '\0') && + (plugin_notification_meta_add_string(n, MCELOG_SOCKET_STR, mr->location) < + 0)) { + ERROR(MCELOG_PLUGIN ": add memory location meta data failed"); + return (-1); + } + if ((mr->dimm_name[0] != '\0') && + (plugin_notification_meta_add_string(n, MCELOG_DIMM_NAME, mr->dimm_name) < + 0)) { + ERROR(MCELOG_PLUGIN ": add DIMM name meta data failed"); + plugin_notification_meta_free(n->meta); + return (-1); + } + if (plugin_notification_meta_add_signed_int(n, MCELOG_CORRECTED_ERR, + mr->corrected_err_total) < 0) { + ERROR(MCELOG_PLUGIN ": add corrected errors meta data failed"); + plugin_notification_meta_free(n->meta); + return (-1); + } + if (plugin_notification_meta_add_signed_int( + n, "corrected memory timed errors", mr->corrected_err_timed) < 0) { + ERROR(MCELOG_PLUGIN ": add corrected timed errors meta data failed"); + plugin_notification_meta_free(n->meta); + return (-1); + } + if ((mr->corrected_err_timed_period[0] != '\0') && + (plugin_notification_meta_add_string(n, "corrected errors time period", + mr->corrected_err_timed_period) < + 0)) { + ERROR(MCELOG_PLUGIN ": add corrected errors period meta data failed"); + plugin_notification_meta_free(n->meta); + return (-1); + } + if (plugin_notification_meta_add_signed_int(n, MCELOG_UNCORRECTED_ERR, + mr->uncorrected_err_total) < 0) { + ERROR(MCELOG_PLUGIN ": add corrected errors meta data failed"); + plugin_notification_meta_free(n->meta); + return (-1); + } + if (plugin_notification_meta_add_signed_int(n, + "uncorrected memory timed errors", + mr->uncorrected_err_timed) < 0) { + ERROR(MCELOG_PLUGIN ": add corrected timed errors meta data failed"); + plugin_notification_meta_free(n->meta); + return (-1); + } + if ((mr->uncorrected_err_timed_period[0] != '\0') && + (plugin_notification_meta_add_string(n, "uncorrected errors time period", + mr->uncorrected_err_timed_period) < + 0)) { + ERROR(MCELOG_PLUGIN ": add corrected errors period meta data failed"); + plugin_notification_meta_free(n->meta); + return (-1); + } + + return (0); +} + +static int mcelog_submit(const mcelog_memory_rec_t *mr) { + + if (!mr) { + ERROR(MCELOG_PLUGIN ": %s: NULL pointer", __FUNCTION__); + return (-1); + } + + value_list_t vl = { + .values_len = 1, + .values = &(value_t){.derive = (derive_t)mr->corrected_err_total}, + .time = cdtime(), + .plugin = MCELOG_PLUGIN, + .type = "errors", + .type_instance = "corrected_memory_errors"}; + + if (mr->dimm_name[0] != '\0') + ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s_%s", + mr->location, mr->dimm_name); + else + sstrncpy(vl.plugin_instance, mr->location, sizeof(vl.plugin_instance)); + + plugin_dispatch_values(&vl); + + ssnprintf(vl.type_instance, sizeof(vl.type_instance), + "corrected_memory_errors_in_%s", mr->corrected_err_timed_period); + vl.values = &(value_t){.derive = (derive_t)mr->corrected_err_timed}; + plugin_dispatch_values(&vl); + + sstrncpy(vl.type_instance, "uncorrected_memory_errors", + sizeof(vl.type_instance)); + vl.values = &(value_t){.derive = (derive_t)mr->uncorrected_err_total}; + plugin_dispatch_values(&vl); + + ssnprintf(vl.type_instance, sizeof(vl.type_instance), + "uncorrected_memory_errors_in_%s", + mr->uncorrected_err_timed_period); + vl.values = &(value_t){.derive = (derive_t)mr->uncorrected_err_timed}; + plugin_dispatch_values(&vl); + + return (0); +} + +static int parse_memory_info(FILE *p_file, mcelog_memory_rec_t *memory_record) { + char buf[DATA_MAX_NAME_LEN] = {0}; + while (fgets(buf, sizeof(buf), p_file)) { + /* Got empty line or "done" */ + if ((!strncmp("\n", buf, strlen(buf))) || + (!strncmp(buf, "done\n", strlen(buf)))) + return (1); + if (strlen(buf) < 5) + continue; + if (!strncmp(buf, MCELOG_SOCKET_STR, strlen(MCELOG_SOCKET_STR))) { + sstrncpy(memory_record->location, buf, strlen(buf)); + /* replace spaces with '_' */ + for (size_t i = 0; i < strlen(memory_record->location); i++) + if (memory_record->location[i] == ' ') + memory_record->location[i] = '_'; + DEBUG(MCELOG_PLUGIN ": Got SOCKET INFO %s", memory_record->location); + } + if (!strncmp(buf, MCELOG_DIMM_NAME, strlen(MCELOG_DIMM_NAME))) { + char *name = NULL; + char *saveptr = NULL; + name = strtok_r(buf, "\"", &saveptr); + if (name != NULL && saveptr != NULL) { + name = strtok_r(NULL, "\"", &saveptr); + if (name != NULL) { + sstrncpy(memory_record->dimm_name, name, + sizeof(memory_record->dimm_name)); + DEBUG(MCELOG_PLUGIN ": Got DIMM NAME %s", memory_record->dimm_name); + } + } + } + if (!strncmp(buf, MCELOG_CORRECTED_ERR, strlen(MCELOG_CORRECTED_ERR))) { + /* Get next line*/ + if (fgets(buf, sizeof(buf), p_file) != NULL) { + sscanf(buf, "\t%d total", &(memory_record->corrected_err_total)); + DEBUG(MCELOG_PLUGIN ": Got corrected error total %d", + memory_record->corrected_err_total); + } + if (fgets(buf, sizeof(buf), p_file) != NULL) { + sscanf(buf, "\t%d in %s", &(memory_record->corrected_err_timed), + memory_record->corrected_err_timed_period); + DEBUG(MCELOG_PLUGIN ": Got timed corrected errors %d in %s", + memory_record->corrected_err_total, + memory_record->corrected_err_timed_period); + } + } + if (!strncmp(buf, MCELOG_UNCORRECTED_ERR, strlen(MCELOG_UNCORRECTED_ERR))) { + if (fgets(buf, sizeof(buf), p_file) != NULL) { + sscanf(buf, "\t%d total", &(memory_record->uncorrected_err_total)); + DEBUG(MCELOG_PLUGIN ": Got uncorrected error total %d", + memory_record->uncorrected_err_total); + } + if (fgets(buf, sizeof(buf), p_file) != NULL) { + sscanf(buf, "\t%d in %s", &(memory_record->uncorrected_err_timed), + memory_record->uncorrected_err_timed_period); + DEBUG(MCELOG_PLUGIN ": Got timed uncorrected errors %d in %s", + memory_record->uncorrected_err_total, + memory_record->uncorrected_err_timed_period); + } + } + memset(buf, 0, sizeof(buf)); + } + /* parsing definitely finished */ + return (0); +} + +static void poll_worker_cleanup(void *arg) { + mcelog_thread_running = 0; + FILE *p_file = *((FILE **)arg); + if (p_file != NULL) + fclose(p_file); + free(arg); +} + +static int socket_receive(socket_adapter_t *self, FILE **pp_file) { + int res = -1; + pthread_rwlock_rdlock(&self->lock); + struct pollfd poll_fd = { + .fd = self->sock_fd, .events = POLLIN | POLLPRI, + }; + + if ((res = poll(&poll_fd, 1, MCELOG_POLL_TIMEOUT)) <= 0) { + if (res != 0 && errno != EINTR) { + char errbuf[MCELOG_BUFF_SIZE]; + ERROR("mcelog: poll failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + } + pthread_rwlock_unlock(&self->lock); + return (res); + } + + if (poll_fd.revents & (POLLERR | POLLHUP | POLLNVAL)) { + /* connection is broken */ + ERROR(MCELOG_PLUGIN ": Connection to socket is broken"); + if (poll_fd.revents & (POLLERR | POLLHUP)) { + mcelog_dispatch_notification( + &(notification_t){.severity = NOTIF_FAILURE, + .time = cdtime(), + .message = "Connection to mcelog socket is broken.", + .plugin = MCELOG_PLUGIN, + .type_instance = "mcelog_status"}); + } + pthread_rwlock_unlock(&self->lock); + return (-1); + } + + if (!(poll_fd.revents & (POLLIN | POLLPRI))) { + INFO(MCELOG_PLUGIN ": No data to read"); + pthread_rwlock_unlock(&self->lock); + return (0); + } + + if ((*pp_file = fdopen(dup(self->sock_fd), "r")) == NULL) + res = -1; + + pthread_rwlock_unlock(&self->lock); + return (res); +} + +static void *poll_worker(__attribute__((unused)) void *arg) { + char errbuf[MCELOG_BUFF_SIZE]; + mcelog_thread_running = 1; + FILE **pp_file = calloc(1, sizeof(*pp_file)); + if (pp_file == NULL) { + ERROR("mcelog: memory allocation failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + pthread_exit((void *)1); + } + + pthread_cleanup_push(poll_worker_cleanup, pp_file); + + while (1) { + /* blocking call */ + int res = socket_adapter.receive(&socket_adapter, pp_file); + if (res < 0) { + socket_adapter.close(&socket_adapter); + while (socket_adapter.reinit(&socket_adapter) != 0) { + nanosleep(&CDTIME_T_TO_TIMESPEC(MS_TO_CDTIME_T(MCELOG_POLL_TIMEOUT)), + NULL); + } + continue; + } + /* timeout or no data to read */ + else if (res == 0) + continue; + + if (*pp_file == NULL) + continue; + + mcelog_memory_rec_t memory_record = {0}; + while (parse_memory_info(*pp_file, &memory_record)) { + /* Check if location was successfully parsed */ + if (memory_record.location[0] == '\0') { + memset(&memory_record, 0, sizeof(memory_record)); + continue; + } + + notification_t n = {.severity = NOTIF_OKAY, + .time = cdtime(), + .message = "Got memory errors info.", + .plugin = MCELOG_PLUGIN, + .type_instance = "memory_erros"}; + + if (mcelog_prepare_notification(&n, &memory_record) == 0) + mcelog_dispatch_notification(&n); + if (mcelog_submit(&memory_record) != 0) + ERROR(MCELOG_PLUGIN ": Failed to submit memory errors"); + memset(&memory_record, 0, sizeof(memory_record)); + } + + fclose(*pp_file); + *pp_file = NULL; + } + + mcelog_thread_running = 0; + pthread_cleanup_pop(1); + return (NULL); +} + +static int mcelog_init(void) { + if (socket_adapter.reinit(&socket_adapter) != 0) { + ERROR(MCELOG_PLUGIN ": Cannot connect to client socket"); + return (-1); + } + + if (plugin_thread_create(&g_mcelog_config.tid, NULL, poll_worker, NULL, + NULL) != 0) { + ERROR(MCELOG_PLUGIN ": Error creating poll thread."); + return (-1); + } + return (0); +} + +static int get_memory_machine_checks(void) { + static const char dump[] = "dump all bios\n"; + int ret = socket_adapter.write(&socket_adapter, dump, sizeof(dump)); + if (ret != 0) + ERROR(MCELOG_PLUGIN ": SENT DUMP REQUEST FAILED"); + else + DEBUG(MCELOG_PLUGIN ": SENT DUMP REQUEST OK"); + return (ret); +} + +static int mcelog_read(__attribute__((unused)) user_data_t *ud) { + DEBUG(MCELOG_PLUGIN ": %s", __FUNCTION__); + + if (get_memory_machine_checks() != 0) + ERROR(MCELOG_PLUGIN ": MACHINE CHECK INFO NOT AVAILABLE"); + + return (0); +} + +static int mcelog_shutdown(void) { + int ret = 0; + if (mcelog_thread_running) { + pthread_cancel(g_mcelog_config.tid); + if (pthread_join(g_mcelog_config.tid, NULL) != 0) { + ERROR(MCELOG_PLUGIN ": Stopping thread failed."); + ret = -1; + } + } + + ret = socket_adapter.close(&socket_adapter) || ret; + pthread_rwlock_destroy(&(socket_adapter.lock)); + return (-ret); +} + +void module_register(void) { + plugin_register_complex_config(MCELOG_PLUGIN, mcelog_config); + plugin_register_init(MCELOG_PLUGIN, mcelog_init); + plugin_register_complex_read(NULL, MCELOG_PLUGIN, mcelog_read, 0, NULL); + plugin_register_shutdown(MCELOG_PLUGIN, mcelog_shutdown); +} diff --git a/src/memcachec.c b/src/memcachec.c index bebbe401..19228efe 100644 --- a/src/memcachec.c +++ b/src/memcachec.c @@ -479,5 +479,3 @@ void module_register(void) { plugin_register_read("memcachec", cmc_read); plugin_register_shutdown("memcachec", cmc_shutdown); } /* void module_register */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/mic.c b/src/mic.c index ab5ffd1b..bc99e679 100644 --- a/src/mic.c +++ b/src/mic.c @@ -366,7 +366,3 @@ void module_register(void) { plugin_register_read("mic", mic_read); plugin_register_config("mic", mic_config, config_keys, config_keys_num); } /* void module_register */ - -/* - * vim: set shiftwidth=8 softtabstop=8 noet textwidth=78 : - */ diff --git a/src/modbus.c b/src/modbus.c index 5d29791d..80a2aca1 100644 --- a/src/modbus.c +++ b/src/modbus.c @@ -982,5 +982,3 @@ void module_register(void) { plugin_register_complex_config("modbus", mb_config); plugin_register_shutdown("modbus", mb_shutdown); } /* void module_register */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/mqtt.c b/src/mqtt.c index 315974b6..a962514c 100644 --- a/src/mqtt.c +++ b/src/mqtt.c @@ -757,5 +757,3 @@ void module_register(void) { plugin_register_complex_config("mqtt", mqtt_config); plugin_register_init("mqtt", mqtt_init); } /* void module_register */ - -/* vim: set sw=4 sts=4 et fdm=marker : */ diff --git a/src/multimeter.c b/src/multimeter.c index 913e277e..93ab3d29 100644 --- a/src/multimeter.c +++ b/src/multimeter.c @@ -27,8 +27,7 @@ #include "common.h" #include "plugin.h" -#if HAVE_TERMIOS_H && HAVE_SYS_IOCTL_H && HAVE_MATH_H -#include +#if HAVE_TERMIOS_H && HAVE_SYS_IOCTL_H #include #include #else diff --git a/src/netapp.c b/src/netapp.c index 45144bf1..13e1db92 100644 --- a/src/netapp.c +++ b/src/netapp.c @@ -3109,5 +3109,3 @@ void module_register(void) { plugin_register_init("netapp", cna_init); plugin_register_shutdown("netapp", cna_shutdown); } - -/* vim: set sw=2 ts=2 noet fdm=marker : */ diff --git a/src/netlink.c b/src/netlink.c index 8076c1fa..ddae5f26 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -85,6 +85,11 @@ typedef struct ir_ignorelist_s { struct ir_ignorelist_s *next; } ir_ignorelist_t; +struct qos_stats { + struct gnet_stats_basic *bs; + struct gnet_stats_queue *qs; +}; + static int ir_ignorelist_invert = 1; static ir_ignorelist_t *ir_ignorelist_head = NULL; @@ -387,20 +392,30 @@ static int link_filter_cb(const struct nlmsghdr *nlh, #if HAVE_TCA_STATS2 static int qos_attr_cb(const struct nlattr *attr, void *data) { - struct gnet_stats_basic **bs = (struct gnet_stats_basic **)data; + struct qos_stats *q_stats = (struct qos_stats *)data; /* skip unsupported attribute in user-space */ if (mnl_attr_type_valid(attr, TCA_STATS_MAX) < 0) return MNL_CB_OK; if (mnl_attr_get_type(attr) == TCA_STATS_BASIC) { - if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, sizeof(**bs)) < 0) { + if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, sizeof(*q_stats->bs)) < 0) { ERROR("netlink plugin: qos_attr_cb: TCA_STATS_BASIC mnl_attr_validate2 " "failed."); return MNL_CB_ERROR; } - *bs = mnl_attr_get_payload(attr); - return MNL_CB_STOP; + q_stats->bs = mnl_attr_get_payload(attr); + return MNL_CB_OK; + } + + if (mnl_attr_get_type(attr) == TCA_STATS_QUEUE) { + if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, sizeof(*q_stats->qs)) < 0) { + ERROR("netlink plugin: qos_attr_cb: TCA_STATS_QUEUE mnl_attr_validate2 " + "failed."); + return MNL_CB_ERROR; + } + q_stats->qs = mnl_attr_get_payload(attr); + return MNL_CB_OK; } return MNL_CB_OK; @@ -492,7 +507,9 @@ static int qos_filter_cb(const struct nlmsghdr *nlh, void *args) { #if HAVE_TCA_STATS2 mnl_attr_for_each(attr, nlh, sizeof(*tm)) { - struct gnet_stats_basic *bs = NULL; + struct qos_stats q_stats; + + memset(&q_stats, 0x0, sizeof(q_stats)); if (mnl_attr_get_type(attr) != TCA_STATS2) continue; @@ -503,9 +520,9 @@ static int qos_filter_cb(const struct nlmsghdr *nlh, void *args) { return MNL_CB_ERROR; } - mnl_attr_parse_nested(attr, qos_attr_cb, &bs); + mnl_attr_parse_nested(attr, qos_attr_cb, &q_stats); - if (bs != NULL) { + if (q_stats.bs != NULL || q_stats.qs != NULL) { char type_instance[DATA_MAX_NAME_LEN]; stats_submitted = 1; @@ -513,8 +530,13 @@ static int qos_filter_cb(const struct nlmsghdr *nlh, void *args) { ssnprintf(type_instance, sizeof(type_instance), "%s-%s", tc_type, tc_inst); - submit_one(dev, "ipt_bytes", type_instance, bs->bytes); - submit_one(dev, "ipt_packets", type_instance, bs->packets); + if (q_stats.bs != NULL) { + submit_one(dev, "ipt_bytes", type_instance, q_stats.bs->bytes); + submit_one(dev, "ipt_packets", type_instance, q_stats.bs->packets); + } + if (q_stats.qs != NULL) { + submit_one(dev, "if_tx_dropped", type_instance, q_stats.qs->drops); + } } break; @@ -736,7 +758,3 @@ void module_register(void) { plugin_register_read("netlink", ir_read); plugin_register_shutdown("netlink", ir_shutdown); } /* void module_register */ - -/* - * vim: set shiftwidth=2 softtabstop=2 tabstop=8 : - */ diff --git a/src/network.c b/src/network.c index f93f49c7..b5f3d489 100644 --- a/src/network.c +++ b/src/network.c @@ -51,7 +51,7 @@ #include #endif -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H #if defined __APPLE__ /* default xcode compiler throws warnings even when deprecated functionality * is not used. -Werror breaks the build because of erroneous warnings. @@ -96,7 +96,7 @@ GCRY_THREAD_OPTION_PTHREAD_IMPL; * Private data types */ #define SECURITY_LEVEL_NONE 0 -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H #define SECURITY_LEVEL_SIGN 1 #define SECURITY_LEVEL_ENCRYPT 2 #endif @@ -104,7 +104,7 @@ struct sockent_client { int fd; struct sockaddr_storage *addr; socklen_t addrlen; -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H int security_level; char *username; char *password; @@ -118,7 +118,7 @@ struct sockent_client { struct sockent_server { int *fd; size_t fd_num; -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H int security_level; char *auth_file; fbhash_t *userdb; @@ -468,7 +468,7 @@ static int network_dispatch_notification(notification_t *n) /* {{{ */ return (status); } /* }}} int network_dispatch_notification */ -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H static int network_init_gcrypt(void) /* {{{ */ { gcry_error_t err; @@ -570,7 +570,7 @@ static gcry_cipher_hd_t network_get_aes256_cypher(sockent_t *se, /* {{{ */ return (*cyper_ptr); } /* }}} int network_get_aes256_cypher */ -#endif /* HAVE_LIBGCRYPT */ +#endif /* HAVE_GCRYPT_H */ static int write_part_values(char **ret_buffer, size_t *ret_buffer_len, const data_set_t *ds, const value_list_t *vl) { @@ -978,7 +978,7 @@ static int parse_packet(sockent_t *se, void *buffer, size_t buffer_size, buffer_offset += (s); \ } while (0) -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H static int parse_part_sign_sha256(sockent_t *se, /* {{{ */ void **ret_buffer, size_t *ret_buffer_len, int flags) { @@ -1107,9 +1107,9 @@ static int parse_part_sign_sha256(sockent_t *se, /* {{{ */ return (0); } /* }}} int parse_part_sign_sha256 */ -/* #endif HAVE_LIBGCRYPT */ +/* #endif HAVE_GCRYPT_H */ -#else /* if !HAVE_LIBGCRYPT */ +#else /* if !HAVE_GCRYPT_H */ static int parse_part_sign_sha256(sockent_t *se, /* {{{ */ void **ret_buffer, size_t *ret_buffer_size, int flags) { @@ -1151,9 +1151,9 @@ static int parse_part_sign_sha256(sockent_t *se, /* {{{ */ return (0); } /* }}} int parse_part_sign_sha256 */ -#endif /* !HAVE_LIBGCRYPT */ +#endif /* !HAVE_GCRYPT_H */ -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H static int parse_part_encr_aes256(sockent_t *se, /* {{{ */ void **ret_buffer, size_t *ret_buffer_len, int flags) { @@ -1264,9 +1264,9 @@ static int parse_part_encr_aes256(sockent_t *se, /* {{{ */ return (0); } /* }}} int parse_part_encr_aes256 */ -/* #endif HAVE_LIBGCRYPT */ +/* #endif HAVE_GCRYPT_H */ -#else /* if !HAVE_LIBGCRYPT */ +#else /* if !HAVE_GCRYPT_H */ static int parse_part_encr_aes256(sockent_t *se, /* {{{ */ void **ret_buffer, size_t *ret_buffer_size, int flags) { @@ -1308,7 +1308,7 @@ static int parse_part_encr_aes256(sockent_t *se, /* {{{ */ return (0); } /* }}} int parse_part_encr_aes256 */ -#endif /* !HAVE_LIBGCRYPT */ +#endif /* !HAVE_GCRYPT_H */ #undef BUFFER_READ @@ -1320,11 +1320,11 @@ static int parse_packet(sockent_t *se, /* {{{ */ value_list_t vl = VALUE_LIST_INIT; notification_t n = {0}; -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H int packet_was_signed = (flags & PP_SIGNED); int packet_was_encrypted = (flags & PP_ENCRYPTED); int printed_ignore_warning = 0; -#endif /* HAVE_LIBGCRYPT */ +#endif /* HAVE_GCRYPT_H */ memset(&vl, '\0', sizeof(vl)); status = 0; @@ -1357,7 +1357,7 @@ static int parse_packet(sockent_t *se, /* {{{ */ break; } } -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H else if ((se->data.server.security_level == SECURITY_LEVEL_ENCRYPT) && (packet_was_encrypted == 0)) { if (printed_ignore_warning == 0) { @@ -1369,7 +1369,7 @@ static int parse_packet(sockent_t *se, /* {{{ */ buffer_size -= (size_t)pkg_length; continue; } -#endif /* HAVE_LIBGCRYPT */ +#endif /* HAVE_GCRYPT_H */ else if (pkg_type == TYPE_SIGN_SHA256) { status = parse_part_sign_sha256(se, &buffer, &buffer_size, flags); if (status != 0) { @@ -1380,7 +1380,7 @@ static int parse_packet(sockent_t *se, /* {{{ */ break; } } -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H else if ((se->data.server.security_level == SECURITY_LEVEL_SIGN) && (packet_was_encrypted == 0) && (packet_was_signed == 0)) { if (printed_ignore_warning == 0) { @@ -1392,7 +1392,7 @@ static int parse_packet(sockent_t *se, /* {{{ */ buffer_size -= (size_t)pkg_length; continue; } -#endif /* HAVE_LIBGCRYPT */ +#endif /* HAVE_GCRYPT_H */ else if (pkg_type == TYPE_VALUES) { status = parse_part_values(&buffer, &buffer_size, &vl.values, &vl.values_len); @@ -1503,7 +1503,7 @@ static void free_sockent_client(struct sockent_client *sec) /* {{{ */ sec->fd = -1; } sfree(sec->addr); -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H sfree(sec->username); sfree(sec->password); if (sec->cypher != NULL) @@ -1521,7 +1521,7 @@ static void free_sockent_server(struct sockent_server *ses) /* {{{ */ } sfree(ses->fd); -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H sfree(ses->auth_file); fbh_destroy(ses->userdb); if (ses->cypher != NULL) @@ -1850,7 +1850,7 @@ static sockent_t *sockent_create(int type) /* {{{ */ if (type == SOCKENT_TYPE_SERVER) { se->data.server.fd = NULL; se->data.server.fd_num = 0; -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H se->data.server.security_level = SECURITY_LEVEL_NONE; se->data.server.auth_file = NULL; se->data.server.userdb = NULL; @@ -1861,7 +1861,7 @@ static sockent_t *sockent_create(int type) /* {{{ */ se->data.client.addr = NULL; se->data.client.resolve_interval = 0; se->data.client.next_resolve_reconnect = 0; -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H se->data.client.security_level = SECURITY_LEVEL_NONE; se->data.client.username = NULL; se->data.client.password = NULL; @@ -1874,7 +1874,7 @@ static sockent_t *sockent_create(int type) /* {{{ */ static int sockent_init_crypto(sockent_t *se) /* {{{ */ { -#if HAVE_LIBGCRYPT /* {{{ */ +#if HAVE_GCRYPT_H /* {{{ */ if (se->type == SOCKENT_TYPE_CLIENT) { if (se->data.client.security_level > SECURITY_LEVEL_NONE) { if (network_init_gcrypt() < 0) { @@ -1917,7 +1917,7 @@ static int sockent_init_crypto(sockent_t *se) /* {{{ */ } } } -#endif /* }}} HAVE_LIBGCRYPT */ +#endif /* }}} HAVE_GCRYPT_H */ return (0); } /* }}} int sockent_init_crypto */ @@ -2379,7 +2379,7 @@ static void network_send_buffer_plain(sockent_t *se, /* {{{ */ } /* while (42) */ } /* }}} void network_send_buffer_plain */ -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H #define BUFFER_ADD(p, s) \ do { \ memcpy(buffer + buffer_offset, (p), (s)); \ @@ -2529,20 +2529,20 @@ static void network_send_buffer_encrypted(sockent_t *se, /* {{{ */ network_send_buffer_plain(se, buffer, buffer_size); } /* }}} void network_send_buffer_encrypted */ #undef BUFFER_ADD -#endif /* HAVE_LIBGCRYPT */ +#endif /* HAVE_GCRYPT_H */ static void network_send_buffer(char *buffer, size_t buffer_len) /* {{{ */ { DEBUG("network plugin: network_send_buffer: buffer_len = %zu", buffer_len); for (sockent_t *se = sending_sockets; se != NULL; se = se->next) { -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H if (se->data.client.security_level == SECURITY_LEVEL_ENCRYPT) network_send_buffer_encrypted(se, buffer, buffer_len); else if (se->data.client.security_level == SECURITY_LEVEL_SIGN) network_send_buffer_signed(se, buffer, buffer_len); else /* if (se->data.client.security_level == SECURITY_LEVEL_NONE) */ -#endif /* HAVE_LIBGCRYPT */ +#endif /* HAVE_GCRYPT_H */ network_send_buffer_plain(se, buffer, buffer_len); } /* for (sending_sockets) */ } /* }}} void network_send_buffer */ @@ -2735,7 +2735,7 @@ static int network_config_set_buffer_size(const oconfig_item_t *ci) /* {{{ */ return (0); } /* }}} int network_config_set_buffer_size */ -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H static int network_config_set_security_level(oconfig_item_t *ci, /* {{{ */ int *retval) { char *str; @@ -2759,7 +2759,7 @@ static int network_config_set_security_level(oconfig_item_t *ci, /* {{{ */ return (0); } /* }}} int network_config_set_security_level */ -#endif /* HAVE_LIBGCRYPT */ +#endif /* HAVE_GCRYPT_H */ static int network_config_add_listen(const oconfig_item_t *ci) /* {{{ */ { @@ -2788,13 +2788,13 @@ static int network_config_add_listen(const oconfig_item_t *ci) /* {{{ */ for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H if (strcasecmp("AuthFile", child->key) == 0) cf_util_get_string(child, &se->data.server.auth_file); else if (strcasecmp("SecurityLevel", child->key) == 0) network_config_set_security_level(child, &se->data.server.security_level); else -#endif /* HAVE_LIBGCRYPT */ +#endif /* HAVE_GCRYPT_H */ if (strcasecmp("Interface", child->key) == 0) network_config_set_interface(child, &se->interface); else { @@ -2802,7 +2802,7 @@ static int network_config_add_listen(const oconfig_item_t *ci) /* {{{ */ } } -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H if ((se->data.server.security_level > SECURITY_LEVEL_NONE) && (se->data.server.auth_file == NULL)) { ERROR("network plugin: A security level higher than `none' was " @@ -2811,7 +2811,7 @@ static int network_config_add_listen(const oconfig_item_t *ci) /* {{{ */ sockent_destroy(se); return (-1); } -#endif /* HAVE_LIBGCRYPT */ +#endif /* HAVE_GCRYPT_H */ status = sockent_init_crypto(se); if (status != 0) { @@ -2866,7 +2866,7 @@ static int network_config_add_server(const oconfig_item_t *ci) /* {{{ */ for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H if (strcasecmp("Username", child->key) == 0) cf_util_get_string(child, &se->data.client.username); else if (strcasecmp("Password", child->key) == 0) @@ -2874,7 +2874,7 @@ static int network_config_add_server(const oconfig_item_t *ci) /* {{{ */ else if (strcasecmp("SecurityLevel", child->key) == 0) network_config_set_security_level(child, &se->data.client.security_level); else -#endif /* HAVE_LIBGCRYPT */ +#endif /* HAVE_GCRYPT_H */ if (strcasecmp("Interface", child->key) == 0) network_config_set_interface(child, &se->interface); else if (strcasecmp("ResolveInterval", child->key) == 0) @@ -2884,7 +2884,7 @@ static int network_config_add_server(const oconfig_item_t *ci) /* {{{ */ } } -#if HAVE_LIBGCRYPT +#if HAVE_GCRYPT_H if ((se->data.client.security_level > SECURITY_LEVEL_NONE) && ((se->data.client.username == NULL) || (se->data.client.password == NULL))) { @@ -2894,7 +2894,7 @@ static int network_config_add_server(const oconfig_item_t *ci) /* {{{ */ sockent_destroy(se); return (-1); } -#endif /* HAVE_LIBGCRYPT */ +#endif /* HAVE_GCRYPT_H */ status = sockent_init_crypto(se); if (status != 0) { @@ -3227,5 +3227,3 @@ void module_register(void) { plugin_register_flush("network", network_flush, /* user_data = */ NULL); } /* void module_register */ - -/* vim: set fdm=marker : */ diff --git a/src/nginx.c b/src/nginx.c index ffc545c4..72c03637 100644 --- a/src/nginx.c +++ b/src/nginx.c @@ -267,7 +267,3 @@ void module_register(void) { plugin_register_init("nginx", init); plugin_register_read("nginx", nginx_read); } /* void module_register */ - -/* - * vim: set shiftwidth=2 softtabstop=2 tabstop=8 : - */ diff --git a/src/notify_desktop.c b/src/notify_desktop.c index 48404411..d167fbfe 100644 --- a/src/notify_desktop.c +++ b/src/notify_desktop.c @@ -166,5 +166,3 @@ void module_register(void) { plugin_register_init("notify_desktop", c_notify_init); return; } /* module_register */ - -/* vim: set sw=4 ts=4 tw=78 noexpandtab : */ diff --git a/src/notify_email.c b/src/notify_email.c index f42e66c6..aaa165ab 100644 --- a/src/notify_email.c +++ b/src/notify_email.c @@ -290,5 +290,3 @@ void module_register(void) { plugin_register_notification("notify_email", notify_email_notification, /* user_data = */ NULL); } /* void module_register (void) */ - -/* vim: set sw=2 sts=2 ts=8 et : */ diff --git a/src/notify_nagios.c b/src/notify_nagios.c index 13516915..c95f7cb9 100644 --- a/src/notify_nagios.c +++ b/src/notify_nagios.c @@ -153,5 +153,3 @@ void module_register(void) { plugin_register_complex_config("notify_nagios", nagios_config); plugin_register_notification("notify_nagios", nagios_notify, NULL); } /* void module_register (void) */ - -/* vim: set sw=2 sts=2 ts=8 et : */ diff --git a/src/ntpd.c b/src/ntpd.c index 1dc1857b..21b65f58 100644 --- a/src/ntpd.c +++ b/src/ntpd.c @@ -32,9 +32,6 @@ #include "common.h" #include "plugin.h" -#if HAVE_STDINT_H -#include -#endif #if HAVE_NETDB_H #include #endif diff --git a/src/numa.c b/src/numa.c index 049daeee..01d74e1e 100644 --- a/src/numa.c +++ b/src/numa.c @@ -152,5 +152,3 @@ void module_register(void) { plugin_register_init("numa", numa_init); plugin_register_read("numa", numa_read); } /* void module_register */ - -/* vim: set sw=2 sts=2 et : */ diff --git a/src/nut.c b/src/nut.c index d40e0951..5acbdde6 100644 --- a/src/nut.c +++ b/src/nut.c @@ -54,8 +54,11 @@ static nut_ups_t *upslist_head = NULL; static pthread_mutex_t read_lock = PTHREAD_MUTEX_INITIALIZER; static int read_busy = 0; -static const char *config_keys[] = {"UPS"}; +static const char *config_keys[] = {"UPS", "FORCESSL", "VERIFYPEER", "CAPATH"}; static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); +static int force_ssl = 0; // Initialized to default of 0 (false) +static int verify_peer = 0; // Initialized to default of 0 (false) +static char *ca_path = NULL; static void free_nut_ups_t(nut_ups_t *ups) { if (ups->conn != NULL) { @@ -98,9 +101,51 @@ static int nut_add_ups(const char *name) { return (0); } /* int nut_add_ups */ +static int nut_force_ssl(const char *value) { + if (strcasecmp(value, "true") == 0) + force_ssl = 1; + else if (strcasecmp(value, "false") == 0) + force_ssl = 0; // Should already be set to 0 from initialization + else { + force_ssl = 0; + WARNING("nut plugin: nut_force_ssl: invalid FORCESSL value " + "found. Defaulting to false."); + } + return (0); +} /* int nut_parse_force_ssl */ + +static int nut_verify_peer(const char *value) { + if (strcasecmp(value, "true") == 0) + verify_peer = 1; + else if (strcasecmp(value, "false") == 0) + verify_peer = 0; // Should already be set to 0 from initialization + else { + verify_peer = 0; + WARNING("nut plugin: nut_verify_peer: invalid VERIFYPEER value " + "found. Defaulting to false."); + } + return (0); +} /* int nut_verify_peer */ + +static int nut_ca_path(const char *value) { + if (value != NULL && strcmp(value, "") != 0) { + ca_path = malloc(strlen(value) + 1); + strncpy(ca_path, value, (strlen(value) + 1)); + } else { + ca_path = NULL; // Should alread be set to NULL from initialization + } + return (0); +} /* int nut_ca_path */ + static int nut_config(const char *key, const char *value) { if (strcasecmp(key, "UPS") == 0) return (nut_add_ups(value)); + else if (strcasecmp(key, "FORCESSL") == 0) + return (nut_force_ssl(value)); + else if (strcasecmp(key, "VERIFYPEER") == 0) + return (nut_verify_peer(value)); + else if (strcasecmp(key, "CAPATH") == 0) + return (nut_ca_path(value)); else return (-1); } /* int nut_config */ @@ -123,6 +168,119 @@ static void nut_submit(nut_ups_t *ups, const char *type, plugin_dispatch_values(&vl); } /* void nut_submit */ +static int nut_connect(nut_ups_t *ups) { +#ifdef WITH_UPSCLIENT_27 + int status; + int ssl_status; + int ssl_flags; + + if (verify_peer == 1 && force_ssl == 0) { + WARNING("nut plugin: nut_connect: VerifyPeer true but ForceSSL " + "false. Setting ForceSSL to true."); + force_ssl = 1; + } + + if (verify_peer == 1 && ca_path == NULL) { + ERROR("nut plugin: nut_connect: VerifyPeer true but missing " + "CAPath value."); + return (-1); + } + + if (verify_peer == 1) { + status = upscli_init(verify_peer, ca_path, NULL, NULL); + + if (status != 1) { + ERROR("nut plugin: nut_connect: upscli_init (%i, %s) failed: %s", + verify_peer, ca_path, upscli_strerror(ups->conn)); + upscli_cleanup(); + return (-1); + } + } /* if (verify_peer == 1) */ + + if (verify_peer == 1) + ssl_flags = (UPSCLI_CONN_REQSSL | UPSCLI_CONN_CERTVERIF); + else if (force_ssl == 1) + ssl_flags = UPSCLI_CONN_REQSSL; + else + ssl_flags = UPSCLI_CONN_TRYSSL; + + status = upscli_connect(ups->conn, ups->hostname, ups->port, ssl_flags); + + if (status != 0) { + ERROR("nut plugin: nut_connect: upscli_connect (%s, %i) failed: %s", + ups->hostname, ups->port, upscli_strerror(ups->conn)); + sfree(ups->conn); + upscli_cleanup(); + return (-1); + } /* if (status != 0) */ + + INFO("nut plugin: Connection to (%s, %i) established.", ups->hostname, + ups->port); + + // Output INFO or WARNING based on SSL and VERIFICATION + ssl_status = upscli_ssl(ups->conn); // 1 for SSL, 0 for not, -1 for error + if (ssl_status == 1 && verify_peer == 1) { + INFO("nut plugin: Connection is secured with SSL and certificate " + "has been verified."); + } else if (ssl_status == 1) { + INFO("nut plugin: Connection is secured with SSL with no verification " + "of server SSL certificate."); + } else if (ssl_status == 0) { + WARNING("nut plugin: Connection is unsecured (no SSL)."); + } else { + ERROR("nut plugin: nut_connect: upscli_ssl failed: %s", + upscli_strerror(ups->conn)); + sfree(ups->conn); + upscli_cleanup(); + return (-1); + } /* if (ssl_status == 1 && verify_peer == 1) */ + return (0); + +#else /* #ifdef WITH_UPSCLIENT_27 */ + int status; + int ssl_status; + int ssl_flags; + + if (verify_peer == 1 || ca_path != NULL) { + WARNING("nut plugin: nut_connect: Dependency libupsclient version " + "insufficient (<2.7) for VerifyPeer support. Ignoring VerifyPeer " + "and CAPath."); + } + + if (force_ssl == 1) + ssl_flags = UPSCLI_CONN_REQSSL; + else + ssl_flags = UPSCLI_CONN_TRYSSL; + + status = upscli_connect(ups->conn, ups->hostname, ups->port, ssl_flags); + + if (status != 0) { + ERROR("nut plugin: nut_connect: upscli_connect (%s, %i) failed: %s", + ups->hostname, ups->port, upscli_strerror(ups->conn)); + sfree(ups->conn); + return (-1); + } /* if (status != 0) */ + + INFO("nut plugin: Connection to (%s, %i) established.", ups->hostname, + ups->port); + + // Output INFO or WARNING based on SSL + ssl_status = upscli_ssl(ups->conn); // 1 for SSL, 0 for not, -1 for error + if (ssl_status == 1) { + INFO("nut plugin: Connection is secured with SSL with no verification " + "of server SSL certificate."); + } else if (ssl_status == 0) { + WARNING("nut plugin: Connection is unsecured (no SSL)."); + } else { + ERROR("nut plugin: nut_connect: upscli_ssl failed: %s", + upscli_strerror(ups->conn)); + sfree(ups->conn); + return (-1); + } /* if (ssl_status == 1 && verify_peer == 1) */ + return (0); +#endif +} + static int nut_read_one(nut_ups_t *ups) { const char *query[3] = {"VAR", ups->upsname, NULL}; unsigned int query_num = 2; @@ -138,17 +296,10 @@ static int nut_read_one(nut_ups_t *ups) { return (-1); } - status = - upscli_connect(ups->conn, ups->hostname, ups->port, UPSCLI_CONN_TRYSSL); - if (status != 0) { - ERROR("nut plugin: nut_read_one: upscli_connect (%s, %i) failed: %s", - ups->hostname, ups->port, upscli_strerror(ups->conn)); - sfree(ups->conn); - return (-1); - } + status = nut_connect(ups); + if (status == -1) + return -1; - INFO("nut plugin: Connection to (%s, %i) established.", ups->hostname, - ups->port); } /* if (ups->conn == NULL) */ /* nut plugin: nut_read_one: upscli_list_start (adpos) failed: Protocol @@ -159,6 +310,9 @@ static int nut_read_one(nut_ups_t *ups) { ups->upsname, upscli_strerror(ups->conn)); upscli_disconnect(ups->conn); sfree(ups->conn); +#ifdef WITH_UPSCLIENT_27 + upscli_cleanup(); +#endif return (-1); } @@ -246,6 +400,9 @@ static int nut_shutdown(void) { free_nut_ups_t(this); this = next; } +#ifdef WITH_UPSCLIENT_27 + upscli_cleanup(); +#endif return (0); } /* int nut_shutdown */ @@ -255,5 +412,3 @@ void module_register(void) { plugin_register_read("nut", nut_read); plugin_register_shutdown("nut", nut_shutdown); } /* void module_register */ - -/* vim: set sw=2 ts=8 sts=2 tw=78 : */ diff --git a/src/olsrd.c b/src/olsrd.c index d1caf461..816a70b2 100644 --- a/src/olsrd.c +++ b/src/olsrd.c @@ -631,5 +631,3 @@ void module_register(void) { plugin_register_read("olsrd", olsrd_read); plugin_register_shutdown("olsrd", olsrd_shutdown); } /* void module_register */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/onewire.c b/src/onewire.c index 10fa5ca1..407e8574 100644 --- a/src/onewire.c +++ b/src/onewire.c @@ -534,5 +534,3 @@ void module_register(void) { plugin_register_config("onewire", cow_load_config, config_keys, config_keys_num); } - -/* vim: set sw=2 sts=2 ts=8 et fdm=marker cindent : */ diff --git a/src/openvpn.c b/src/openvpn.c index 90694b78..1045d500 100644 --- a/src/openvpn.c +++ b/src/openvpn.c @@ -715,5 +715,3 @@ void module_register(void) { config_keys_num); plugin_register_init("openvpn", openvpn_init); } /* void module_register */ - -/* vim: set sw=2 ts=2 : */ diff --git a/src/oracle.c b/src/oracle.c index 4eacc543..cdeebfef 100644 --- a/src/oracle.c +++ b/src/oracle.c @@ -471,13 +471,13 @@ static int o_read_database_query(o_database_t *db, /* {{{ */ oci_defines = NULL; ALLOC_OR_FAIL(column_names, column_num * sizeof(char *)); - ALLOC_OR_FAIL(column_names[0], column_num * DATA_MAX_NAME_LEN * sizeof(char)); + ALLOC_OR_FAIL(column_names[0], column_num * DATA_MAX_NAME_LEN); for (size_t i = 1; i < column_num; i++) column_names[i] = column_names[i - 1] + DATA_MAX_NAME_LEN; ALLOC_OR_FAIL(column_values, column_num * sizeof(char *)); ALLOC_OR_FAIL(column_values[0], - column_num * DATA_MAX_NAME_LEN * sizeof(char)); + column_num * DATA_MAX_NAME_LEN); for (size_t i = 1; i < column_num; i++) column_values[i] = column_values[i - 1] + DATA_MAX_NAME_LEN; @@ -706,7 +706,3 @@ void module_register(void) /* {{{ */ plugin_register_read("oracle", o_read); plugin_register_shutdown("oracle", o_shutdown); } /* }}} void module_register */ - -/* - * vim: shiftwidth=2 softtabstop=2 et fdm=marker - */ diff --git a/src/ovs_events.c b/src/ovs_events.c new file mode 100644 index 00000000..d372b87a --- /dev/null +++ b/src/ovs_events.c @@ -0,0 +1,658 @@ +/** + * 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 + **/ + +#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 = {.send_notification = 1, /* send notification by default */ + .ovs_db_node = "localhost", /* use default OVS DB node */ + .ovs_db_serv = "6640"} /* use default OVS DB service */ +}; + +/* Forward declaration */ +static int ovs_events_plugin_read(user_data_t *u); + +/* This function is used only by "OVS_EVENTS_CTX_LOCK" define (see above). + * It always returns 1 when context is locked. + */ +static int ovs_events_ctx_lock() { + pthread_mutex_lock(&ovs_events_ctx.mutex); + return (1); +} + +/* This function is used only by "OVS_EVENTS_CTX_LOCK" define (see above). + * It always returns 0 when context is unlocked. + */ +static int ovs_events_ctx_unlock() { + pthread_mutex_unlock(&ovs_events_ctx.mutex); + return (0); +} + +/* Check if given interface name exists in configuration file. It + * returns 1 if exists otherwise 0. If no interfaces are configured, + * -1 is returned + */ +static int ovs_events_config_iface_exists(const char *ifname) { + if (ovs_events_ctx.config.ifaces == NULL) + return (-1); + + /* check if given interface exists */ + for (ovs_events_iface_list_t *iface = ovs_events_ctx.config.ifaces; iface; + iface = iface->next) + if (strcmp(ifname, iface->name) == 0) + return (1); + + return (0); +} + +/* Get OVS DB select parameter request based on rfc7047, + * "Transact" & "Select" section + */ +static char *ovs_events_get_select_params() { + size_t buff_size = 0; + size_t buff_off = 0; + char *opt_buff = NULL; + static const char params_fmt[] = "[\"Open_vSwitch\"%s]"; + static const char option_fmt[] = + ",{\"op\":\"select\",\"table\":\"Interface\"," + "\"where\":[[\"name\",\"==\",\"%s\"]]," + "\"columns\":[\"link_state\",\"external_ids\"," + "\"name\",\"_uuid\"]}"; + static const char default_opt[] = + ",{\"op\":\"select\",\"table\":\"Interface\"," + "\"where\":[],\"columns\":[\"link_state\"," + "\"external_ids\",\"name\",\"_uuid\"]}"; + /* setup OVS DB interface condition */ + for (ovs_events_iface_list_t *iface = ovs_events_ctx.config.ifaces; iface; + iface = iface->next) { + /* allocate new buffer (format size + ifname len is good enough) */ + buff_size += sizeof(option_fmt) + strlen(iface->name); + char *new_buff = realloc(opt_buff, buff_size); + if (new_buff == NULL) { + sfree(opt_buff); + return NULL; + } + opt_buff = new_buff; + int ret = ssnprintf(opt_buff + buff_off, buff_size - buff_off, option_fmt, + iface->name); + if (ret < 0) { + sfree(opt_buff); + return NULL; + } + buff_off += ret; + } + /* if no interfaces are configured, use default params */ + if (opt_buff == NULL) + if ((opt_buff = strdup(default_opt)) == NULL) + return NULL; + + /* allocate memory for OVS DB select params */ + size_t params_size = sizeof(params_fmt) + strlen(opt_buff); + char *params_buff = calloc(1, params_size); + if (params_buff == NULL) { + sfree(opt_buff); + return NULL; + } + + /* create OVS DB select params */ + if (ssnprintf(params_buff, params_size, params_fmt, opt_buff) < 0) + sfree(params_buff); + + sfree(opt_buff); + return params_buff; +} + +/* Release memory allocated for configuration data */ +static void ovs_events_config_free() { + ovs_events_iface_list_t *del_iface = NULL; + sfree(ovs_events_ctx.ovs_db_select_params); + while (ovs_events_ctx.config.ifaces) { + del_iface = ovs_events_ctx.config.ifaces; + ovs_events_ctx.config.ifaces = ovs_events_ctx.config.ifaces->next; + sfree(del_iface); + } +} + +/* Parse/process "Interfaces" configuration option. Returns 0 if success + * otherwise -1 (error) + */ +static int ovs_events_config_get_interfaces(const oconfig_item_t *ci) { + for (int j = 0; j < ci->values_num; j++) { + /* check interface name type */ + if (ci->values[j].type != OCONFIG_TYPE_STRING) { + ERROR(OVS_EVENTS_PLUGIN + ": given interface name is not a string [idx=%d]", j); + return (-1); + } + /* allocate memory for configured interface */ + ovs_events_iface_list_t *new_iface = calloc(1, sizeof(*new_iface)); + if (new_iface == NULL) { + ERROR(OVS_EVENTS_PLUGIN ": calloc () copy interface name fail"); + return (-1); + } else { + /* store interface name */ + sstrncpy(new_iface->name, ci->values[j].value.string, + sizeof(new_iface->name)); + new_iface->next = ovs_events_ctx.config.ifaces; + ovs_events_ctx.config.ifaces = new_iface; + DEBUG(OVS_EVENTS_PLUGIN ": found monitored interface \"%s\"", + new_iface->name); + } + } + return (0); +} + +/* Parse plugin configuration file and store the config + * in allocated memory. Returns negative value in case of error. + */ +static int ovs_events_plugin_config(oconfig_item_t *ci) { + _Bool dispatch_values = 0; + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + if (strcasecmp("SendNotification", child->key) == 0) { + if (cf_util_get_boolean(child, + &ovs_events_ctx.config.send_notification) != 0) { + ovs_events_config_free(); + return (-1); + } + } else if (strcasecmp("Address", child->key) == 0) { + if (cf_util_get_string_buffer( + child, ovs_events_ctx.config.ovs_db_node, + sizeof(ovs_events_ctx.config.ovs_db_node)) != 0) { + ovs_events_config_free(); + return (-1); + } + } else if (strcasecmp("Port", child->key) == 0) { + char *service = NULL; + if (cf_util_get_service(child, &service) != 0) { + ovs_events_config_free(); + return (-1); + } + strncpy(ovs_events_ctx.config.ovs_db_serv, service, + sizeof(ovs_events_ctx.config.ovs_db_serv)); + sfree(service); + } else if (strcasecmp("Socket", child->key) == 0) { + if (cf_util_get_string_buffer( + child, ovs_events_ctx.config.ovs_db_unix, + sizeof(ovs_events_ctx.config.ovs_db_unix)) != 0) { + ovs_events_config_free(); + return (-1); + } + } else if (strcasecmp("Interfaces", child->key) == 0) { + if (ovs_events_config_get_interfaces(child) != 0) { + ovs_events_config_free(); + return (-1); + } + } else if (strcasecmp("DispatchValues", child->key) == 0) { + if (cf_util_get_boolean(child, &dispatch_values) != 0) { + ovs_events_config_free(); + return (-1); + } + } else { + ERROR(OVS_EVENTS_PLUGIN ": option '%s' is not allowed here", child->key); + ovs_events_config_free(); + return (-1); + } + } + /* Check and warn about invalid configuration */ + if (!ovs_events_ctx.config.send_notification && !dispatch_values) { + WARNING(OVS_EVENTS_PLUGIN ": send notification and dispatch values " + "options are disabled. No information will be dispatched by the " + "plugin. Please check your configuration"); + } + /* Dispatch link status values if configured */ + if (dispatch_values) + return plugin_register_complex_read(NULL, OVS_EVENTS_PLUGIN, + ovs_events_plugin_read, 0, NULL); + + return (0); +} + +/* Dispatch OVS interface link status event to collectd */ +static void ovs_events_dispatch_notification(const ovs_events_iface_info_t *ifinfo) { + const char *msg_link_status = NULL; + notification_t n = { + NOTIF_FAILURE, cdtime(), "", "", OVS_EVENTS_PLUGIN, "", "", "", NULL}; + + /* convert link status to message string */ + switch (ifinfo->link_status) { + case UP: + msg_link_status = "UP"; + n.severity = NOTIF_OKAY; + break; + case DOWN: + msg_link_status = "DOWN"; + n.severity = NOTIF_WARNING; + break; + default: + ERROR(OVS_EVENTS_PLUGIN ": unknown interface link status"); + return; + } + + /* add interface metadata to the notification */ + if (plugin_notification_meta_add_string(&n, "uuid", ifinfo->uuid) < 0) { + ERROR(OVS_EVENTS_PLUGIN ": add interface uuid meta data failed"); + return; + } + + if (strlen(ifinfo->ext_vm_uuid) > 0) { + if (plugin_notification_meta_add_string(&n, "vm-uuid", + ifinfo->ext_vm_uuid) < 0) { + ERROR(OVS_EVENTS_PLUGIN ": add interface vm-uuid meta data failed"); + return; + } + } + + if (strlen(ifinfo->ext_iface_id) > 0) { + if (plugin_notification_meta_add_string(&n, "iface-id", + ifinfo->ext_iface_id) < 0) { + ERROR(OVS_EVENTS_PLUGIN ": add interface iface-id meta data failed"); + return; + } + } + + /* fill the notification data */ + ssnprintf(n.message, sizeof(n.message), + "link state of \"%s\" interface has been changed to \"%s\"", + ifinfo->name, msg_link_status); + sstrncpy(n.host, hostname_g, sizeof(n.host)); + sstrncpy(n.plugin_instance, ifinfo->name, sizeof(n.plugin_instance)); + sstrncpy(n.type, "gauge", sizeof(n.type)); + sstrncpy(n.type_instance, "link_status", sizeof(n.type_instance)); + plugin_dispatch_notification(&n); +} + +/* Dispatch OVS interface link status value to collectd */ +static void ovs_events_link_status_submit(const ovs_events_iface_info_t *ifinfo) { + value_list_t vl = VALUE_LIST_INIT; + meta_data_t *meta = NULL; + + /* add interface metadata to the submit value */ + if ((meta = meta_data_create()) != NULL) { + if (meta_data_add_string(meta, "uuid", ifinfo->uuid) < 0) + ERROR(OVS_EVENTS_PLUGIN ": add interface uuid meta data failed"); + + if (strlen(ifinfo->ext_vm_uuid) > 0) + if (meta_data_add_string(meta, "vm-uuid", ifinfo->ext_vm_uuid) < 0) + ERROR(OVS_EVENTS_PLUGIN ": add interface vm-uuid meta data failed"); + + if (strlen(ifinfo->ext_iface_id) > 0) + if (meta_data_add_string(meta, "iface-id", ifinfo->ext_iface_id) < 0) + ERROR(OVS_EVENTS_PLUGIN ": add interface iface-id meta data failed"); + vl.meta = meta; + } else + ERROR(OVS_EVENTS_PLUGIN ": create metadata failed"); + + vl.time = cdtime(); + vl.values = &(value_t){.gauge = (gauge_t)ifinfo->link_status}; + vl.values_len = 1; + sstrncpy(vl.plugin, OVS_EVENTS_PLUGIN, sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, ifinfo->name, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, "gauge", sizeof(vl.type)); + sstrncpy(vl.type_instance, "link_status", sizeof(vl.type_instance)); + plugin_dispatch_values(&vl); + meta_data_destroy(meta); +} + +/* Dispatch OVS DB terminate connection event to collectd */ +static void ovs_events_dispatch_terminate_notification(const char *msg) { + notification_t n = { + NOTIF_FAILURE, cdtime(), "", "", OVS_EVENTS_PLUGIN, "", "", "", NULL}; + sstrncpy(n.message, msg, sizeof(n.message)); + sstrncpy(n.host, hostname_g, sizeof(n.host)); + plugin_dispatch_notification(&n); +} + +/* Get OVS DB interface information and stores it into + * ovs_events_iface_info_t structure */ +static int ovs_events_get_iface_info(yajl_val jobject, + ovs_events_iface_info_t *ifinfo) { + yajl_val jexternal_ids = NULL; + yajl_val jvalue = NULL; + yajl_val juuid = NULL; + const char *state = NULL; + + /* check YAJL type */ + if (!YAJL_IS_OBJECT(jobject)) + return (-1); + + /* zero the interface info structure */ + memset(ifinfo, 0, sizeof(*ifinfo)); + + /* try to find external_ids, name and link_state fields */ + jexternal_ids = ovs_utils_get_value_by_key(jobject, "external_ids"); + if (jexternal_ids == NULL || ifinfo == NULL) + return (-1); + + /* get iface-id from external_ids field */ + jvalue = ovs_utils_get_map_value(jexternal_ids, "iface-id"); + if (jvalue != NULL && YAJL_IS_STRING(jvalue)) + sstrncpy(ifinfo->ext_iface_id, YAJL_GET_STRING(jvalue), + sizeof(ifinfo->ext_iface_id)); + + /* get vm-uuid from external_ids field */ + jvalue = ovs_utils_get_map_value(jexternal_ids, "vm-uuid"); + if (jvalue != NULL && YAJL_IS_STRING(jvalue)) + sstrncpy(ifinfo->ext_vm_uuid, YAJL_GET_STRING(jvalue), + sizeof(ifinfo->ext_vm_uuid)); + + /* get interface uuid */ + jvalue = ovs_utils_get_value_by_key(jobject, "_uuid"); + if (jvalue == NULL || !YAJL_IS_ARRAY(jvalue) || + YAJL_GET_ARRAY(jvalue)->len != 2) + return (-1); + juuid = YAJL_GET_ARRAY(jvalue)->values[1]; + if (juuid == NULL || !YAJL_IS_STRING(juuid)) + return (-1); + sstrncpy(ifinfo->uuid, YAJL_GET_STRING(juuid), sizeof(ifinfo->uuid)); + + /* get interface name */ + jvalue = ovs_utils_get_value_by_key(jobject, "name"); + if (jvalue == NULL || !YAJL_IS_STRING(jvalue)) + return (-1); + sstrncpy(ifinfo->name, YAJL_GET_STRING(jvalue), sizeof(ifinfo->name)); + + /* get OVS DB interface link status */ + jvalue = ovs_utils_get_value_by_key(jobject, "link_state"); + if (jvalue != NULL && ((state = YAJL_GET_STRING(jvalue)) != NULL)) { + /* convert OVS table link state to link status */ + if (strcmp(state, "up") == 0) + ifinfo->link_status = UP; + else if (strcmp(state, "down") == 0) + ifinfo->link_status = DOWN; + } + return (0); +} + +/* Process OVS DB update table event. It handles link status update event(s) + * and dispatches the value(s) to collectd if interface name matches one of + * interfaces specified in configuration file. + */ +static void ovs_events_table_update_cb(yajl_val jupdates) { + yajl_val jnew_val = NULL; + yajl_val jupdate = NULL; + yajl_val jrow_update = NULL; + ovs_events_iface_info_t ifinfo; + + /* JSON "Interface" table update example: + * --------------------------------- + * {"Interface": + * { + * "9adf1db2-29ca-4140-ab22-ae347a4484de": + * { + * "new": + * { + * "name":"br0", + * "link_state":"up" + * }, + * "old": + * { + * "link_state":"down" + * } + * } + * } + * } + */ + if (!YAJL_IS_OBJECT(jupdates) || !(YAJL_GET_OBJECT(jupdates)->len > 0)) { + ERROR(OVS_EVENTS_PLUGIN ": unexpected OVS DB update event received"); + return; + } + /* verify if this is a table event */ + jupdate = YAJL_GET_OBJECT(jupdates)->values[0]; + if (!YAJL_IS_OBJECT(jupdate)) { + ERROR(OVS_EVENTS_PLUGIN ": unexpected table update event received"); + return; + } + /* go through all row updates */ + for (size_t row_index = 0; row_index < YAJL_GET_OBJECT(jupdate)->len; + ++row_index) { + jrow_update = YAJL_GET_OBJECT(jupdate)->values[row_index]; + + /* check row update */ + jnew_val = ovs_utils_get_value_by_key(jrow_update, "new"); + if (jnew_val == NULL) { + ERROR(OVS_EVENTS_PLUGIN ": unexpected row update received"); + return; + } + /* get OVS DB interface information */ + if (ovs_events_get_iface_info(jnew_val, &ifinfo) < 0) { + ERROR(OVS_EVENTS_PLUGIN + " :unexpected interface information data received"); + return; + } + if (ovs_events_config_iface_exists(ifinfo.name) != 0) { + DEBUG("name=%s, uuid=%s, ext_iface_id=%s, ext_vm_uuid=%s", ifinfo.name, + ifinfo.uuid, ifinfo.ext_iface_id, ifinfo.ext_vm_uuid); + /* dispatch notification */ + ovs_events_dispatch_notification(&ifinfo); + } + } +} + +/* OVS DB reply callback. It parses reply, receives + * interface information and dispatches the info to + * collectd + */ +static void ovs_events_poll_result_cb(yajl_val jresult, yajl_val jerror) { + yajl_val *jvalues = NULL; + yajl_val jvalue = NULL; + ovs_events_iface_info_t ifinfo; + + if (!YAJL_IS_NULL(jerror)) { + ERROR(OVS_EVENTS_PLUGIN "error received by OVS DB server"); + return; + } + + /* result should be an array */ + if (!YAJL_IS_ARRAY(jresult)) { + ERROR(OVS_EVENTS_PLUGIN "invalid data (array is expected)"); + return; + } + + /* go through all rows and get interface info */ + jvalues = YAJL_GET_ARRAY(jresult)->values; + for (size_t i = 0; i < YAJL_GET_ARRAY(jresult)->len; i++) { + jvalue = ovs_utils_get_value_by_key(jvalues[i], "rows"); + if (jvalue == NULL || !YAJL_IS_ARRAY(jvalue)) { + ERROR(OVS_EVENTS_PLUGIN "invalid data (array of rows is expected)"); + return; + } + /* get interfaces info */ + for (size_t j = 0; j < YAJL_GET_ARRAY(jvalue)->len; j++) { + if (ovs_events_get_iface_info(YAJL_GET_ARRAY(jvalue)->values[j], + &ifinfo) < 0) { + ERROR(OVS_EVENTS_PLUGIN + "unexpected interface information data received"); + return; + } + DEBUG("name=%s, uuid=%s, ext_iface_id=%s, ext_vm_uuid=%s", ifinfo.name, + ifinfo.uuid, ifinfo.ext_iface_id, ifinfo.ext_vm_uuid); + ovs_events_link_status_submit(&ifinfo); + } + } +} + +/* Setup OVS DB table callback. It subscribes to OVS DB 'Interface' table + * to receive link status event(s). + */ +static void ovs_events_conn_initialize(ovs_db_t *pdb) { + const char tb_name[] = "Interface"; + const char *columns[] = {"_uuid", "external_ids", "name", "link_state", NULL}; + + /* register update link status event if needed */ + if (ovs_events_ctx.config.send_notification) { + int ret = ovs_db_table_cb_register(pdb, tb_name, columns, + ovs_events_table_update_cb, NULL, + OVS_DB_TABLE_CB_FLAG_MODIFY); + if (ret < 0) { + ERROR(OVS_EVENTS_PLUGIN ": register OVS DB update callback failed"); + return; + } + } + OVS_EVENTS_CTX_LOCK { ovs_events_ctx.is_db_available = 1; } + DEBUG(OVS_EVENTS_PLUGIN ": OVS DB connection has been initialized"); +} + +/* OVS DB terminate connection notification callback */ +static void ovs_events_conn_terminate() { + const char msg[] = "OVS DB connection has been lost"; + if (ovs_events_ctx.config.send_notification) + ovs_events_dispatch_terminate_notification(msg); + WARNING(OVS_EVENTS_PLUGIN ": %s", msg); + OVS_EVENTS_CTX_LOCK { ovs_events_ctx.is_db_available = 0; } +} + +/* Read OVS DB interface link status callback */ +static int ovs_events_plugin_read(__attribute__((unused)) user_data_t *u) { + _Bool is_connected = 0; + OVS_EVENTS_CTX_LOCK { is_connected = ovs_events_ctx.is_db_available; } + if (is_connected) + if (ovs_db_send_request(ovs_events_ctx.ovs_db, "transact", + ovs_events_ctx.ovs_db_select_params, + ovs_events_poll_result_cb) < 0) { + ERROR(OVS_EVENTS_PLUGIN ": get interface info failed"); + return (-1); + } + return (0); +} + +/* Initialize OVS plugin */ +static int ovs_events_plugin_init(void) { + ovs_db_t *ovs_db = NULL; + ovs_db_callback_t cb = {.post_conn_init = ovs_events_conn_initialize, + .post_conn_terminate = ovs_events_conn_terminate}; + + DEBUG(OVS_EVENTS_PLUGIN ": OVS DB address=%s, service=%s, unix=%s", + ovs_events_ctx.config.ovs_db_node, ovs_events_ctx.config.ovs_db_serv, + ovs_events_ctx.config.ovs_db_unix); + + /* generate OVS DB select condition based on list on configured interfaces */ + ovs_events_ctx.ovs_db_select_params = ovs_events_get_select_params(); + if (ovs_events_ctx.ovs_db_select_params == NULL) { + ERROR(OVS_EVENTS_PLUGIN ": fail to get OVS DB select condition"); + goto ovs_events_failure; + } + + /* initialize OVS DB */ + ovs_db = ovs_db_init(ovs_events_ctx.config.ovs_db_node, + ovs_events_ctx.config.ovs_db_serv, + ovs_events_ctx.config.ovs_db_unix, &cb); + if (ovs_db == NULL) { + ERROR(OVS_EVENTS_PLUGIN ": fail to connect to OVS DB server"); + goto ovs_events_failure; + } + + /* store OVS DB handler */ + OVS_EVENTS_CTX_LOCK { ovs_events_ctx.ovs_db = ovs_db; } + + DEBUG(OVS_EVENTS_PLUGIN ": plugin has been initialized"); + return (0); + +ovs_events_failure: + ERROR(OVS_EVENTS_PLUGIN ": plugin initialize failed"); + /* release allocated memory */ + ovs_events_config_free(); + return (-1); +} + +/* Shutdown OVS plugin */ +static int ovs_events_plugin_shutdown(void) { + /* destroy OVS DB */ + if (ovs_db_destroy(ovs_events_ctx.ovs_db)) + ERROR(OVS_EVENTS_PLUGIN ": OVSDB object destroy failed"); + + /* release memory allocated for config */ + ovs_events_config_free(); + + DEBUG(OVS_EVENTS_PLUGIN ": plugin has been destroyed"); + return (0); +} + +/* Register OVS plugin callbacks */ +void module_register(void) { + plugin_register_complex_config(OVS_EVENTS_PLUGIN, ovs_events_plugin_config); + plugin_register_init(OVS_EVENTS_PLUGIN, ovs_events_plugin_init); + plugin_register_shutdown(OVS_EVENTS_PLUGIN, ovs_events_plugin_shutdown); +} diff --git a/src/ovs_stats.c b/src/ovs_stats.c new file mode 100644 index 00000000..23b7533c --- /dev/null +++ b/src/ovs_stats.c @@ -0,0 +1,990 @@ +/* + * collectd - src/ovs_stats.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: + * Taras Chornyi + */ + +#include "common.h" + +#include "utils_ovs.h" /* OvS helpers */ + +/* Plugin name */ +static const char plugin_name[] = "ovs_stats"; + +typedef enum iface_counter { + not_supported = -1, + collisions, + rx_bytes, + rx_crc_err, + rx_dropped, + rx_errors, + rx_frame_err, + rx_over_err, + rx_packets, + tx_bytes, + tx_dropped, + tx_errors, + tx_packets, + rx_1_to_64_packets, + rx_65_to_127_packets, + rx_128_to_255_packets, + rx_256_to_511_packets, + rx_512_to_1023_packets, + rx_1024_to_1522_packets, + rx_1523_to_max_packets, + tx_1_to_64_packets, + tx_65_to_127_packets, + tx_128_to_255_packets, + tx_256_to_511_packets, + tx_512_to_1023_packets, + tx_1024_to_1522_packets, + tx_1523_to_max_packets, + tx_multicast_packets, + rx_broadcast_packets, + tx_broadcast_packets, + rx_undersized_errors, + rx_oversize_errors, + rx_fragmented_errors, + rx_jabber_errors, + __iface_counter_max +} iface_counter; + +#define IFACE_COUNTER_MAX (__iface_counter_max - 1) +#define IFACE_COUNTER_COUNT (__iface_counter_max) +#define PORT_NAME_SIZE_MAX 255 +#define UUID_SIZE 64 + +typedef struct port_s { + char name[PORT_NAME_SIZE_MAX]; /* Port name */ + char port_uuid[UUID_SIZE]; /* Port table _uuid */ + char iface_uuid[UUID_SIZE]; /* Interface table uuid */ + char ex_iface_id[UUID_SIZE]; /* External iface id */ + char ex_vm_id[UUID_SIZE]; /* External vm id */ + int64_t stats[IFACE_COUNTER_COUNT]; /* Port statistics */ + struct bridge_list_s *br; /* Pointer to bridge */ + struct port_s *next; /* Next port */ +} port_list_t; + +typedef struct bridge_list_s { + char *name; /* Bridge name */ + struct bridge_list_s *next; /* Next bridge*/ +} bridge_list_t; + +static const char *const iface_counter_table[IFACE_COUNTER_COUNT] = { + [collisions] = "collisions", + [rx_bytes] = "rx_bytes", + [rx_crc_err] = "rx_crc_err", + [rx_dropped] = "rx_dropped", + [rx_errors] = "rx_errors", + [rx_frame_err] = "rx_frame_err", + [rx_over_err] = "rx_over_err", + [rx_packets] = "rx_packets", + [tx_bytes] = "tx_bytes", + [tx_dropped] = "tx_dropped", + [tx_errors] = "tx_errors", + [tx_packets] = "tx_packets", + [rx_1_to_64_packets] = "rx_1_to_64_packets", + [rx_65_to_127_packets] = "rx_65_to_127_packets", + [rx_128_to_255_packets] = "rx_128_to_255_packets", + [rx_256_to_511_packets] = "rx_256_to_511_packets", + [rx_512_to_1023_packets] = "rx_512_to_1023_packets", + [rx_1024_to_1522_packets] = "rx_1024_to_1518_packets", + [rx_1523_to_max_packets] = "rx_1523_to_max_packets", + [tx_1_to_64_packets] = "tx_1_to_64_packets", + [tx_65_to_127_packets] = "tx_65_to_127_packets", + [tx_128_to_255_packets] = "tx_128_to_255_packets", + [tx_256_to_511_packets] = "tx_256_to_511_packets", + [tx_512_to_1023_packets] = "tx_512_to_1023_packets", + [tx_1024_to_1522_packets] = "tx_1024_to_1518_packets", + [tx_1523_to_max_packets] = "tx_1523_to_max_packets", + [tx_multicast_packets] = "tx_multicast_packets", + [rx_broadcast_packets] = "rx_broadcast_packets", + [tx_broadcast_packets] = "tx_broadcast_packets", + [rx_undersized_errors] = "rx_undersized_errors", + [rx_oversize_errors] = "rx_oversize_errors", + [rx_fragmented_errors] = "rx_fragmented_errors", + [rx_jabber_errors] = "rx_jabber_errors", +}; + +/* Entry into the list of network bridges */ +static bridge_list_t *g_bridge_list_head; + +/* Entry into the list of monitored network bridges */ +static bridge_list_t *g_monitored_bridge_list_head; + +/* entry into the list of network bridges */ +static port_list_t *g_port_list_head; + +/* lock for statistics cache */ +static pthread_mutex_t g_stats_lock; + +/* OvS DB socket */ +static ovs_db_t *g_ovs_db; + +/* OVS stats configuration data */ +struct ovs_stats_config_s { + 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 */ +}; +typedef struct ovs_stats_config_s ovs_stats_config_t; + +static ovs_stats_config_t ovs_stats_cfg = { + .ovs_db_node = "localhost", /* use default OVS DB node */ + .ovs_db_serv = "6640", /* use default OVS DB service */ +}; + +static iface_counter ovs_stats_counter_name_to_type(const char *counter) { + iface_counter index = not_supported; + + if (counter == NULL) + return not_supported; + + for (int i = 0; i < IFACE_COUNTER_COUNT; i++) { + if (strncmp(iface_counter_table[i], counter, + strlen(iface_counter_table[i])) == 0) { + index = i; + break; + } + } + return index; +} + +static void ovs_stats_submit_one(const char *dev, const char *type, + const char *type_instance, derive_t value, + meta_data_t *meta) { + /* if counter is less than 0 - skip it*/ + if (value < 0) + return; + value_list_t vl = VALUE_LIST_INIT; + + vl.values = &(value_t){.derive = value}; + vl.values_len = 1; + vl.meta = meta; + + sstrncpy(vl.plugin, plugin_name, sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, dev, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); + + if (type_instance != NULL) + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); +} + +static void ovs_stats_submit_two(const char *dev, const char *type, + const char *type_instance, derive_t rx, + derive_t tx, meta_data_t *meta) { + /* if counter is less than 0 - skip it*/ + if (rx < 0 || tx < 0) + return; + value_list_t vl = VALUE_LIST_INIT; + value_t values[] = {{.derive = rx}, {.derive = tx}}; + + vl.values = values; + vl.values_len = STATIC_ARRAY_SIZE(values); + vl.meta = meta; + + sstrncpy(vl.plugin, plugin_name, sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, dev, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); + + if (type_instance != NULL) + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); +} + +static port_list_t *ovs_stats_get_port(const char *uuid) { + if (uuid == NULL) + return NULL; + + for (port_list_t *port = g_port_list_head; port != NULL; port = port->next) { + if (strncmp(port->port_uuid, uuid, strlen(port->port_uuid)) == 0) + return port; + } + return NULL; +} + +static port_list_t *ovs_stats_get_port_by_name(const char *name) { + if (name == NULL) + return NULL; + + for (port_list_t *port = g_port_list_head; port != NULL; port = port->next) + if ((strncmp(port->name, name, strlen(port->name)) == 0) && + strlen(name) == strlen(port->name)) + return port; + return NULL; +} + +/* Create or get port by port uuid */ +static port_list_t *ovs_stats_new_port(bridge_list_t *bridge, + const char *uuid) { + port_list_t *port = ovs_stats_get_port(uuid); + + if (port == NULL) { + port = (port_list_t *)calloc(1, sizeof(port_list_t)); + if (!port) { + ERROR("%s: Error allocating port", plugin_name); + return NULL; + } + memset(port->stats, -1, sizeof(int64_t[IFACE_COUNTER_COUNT])); + sstrncpy(port->port_uuid, uuid, sizeof(port->port_uuid)); + pthread_mutex_lock(&g_stats_lock); + port->next = g_port_list_head; + g_port_list_head = port; + pthread_mutex_unlock(&g_stats_lock); + } + if (bridge != NULL) { + pthread_mutex_lock(&g_stats_lock); + port->br = bridge; + pthread_mutex_unlock(&g_stats_lock); + } + return port; +} + +/* Get bridge by name*/ +static bridge_list_t *ovs_stats_get_bridge(bridge_list_t *head, + const char *name) { + if (name == NULL) + return NULL; + + for (bridge_list_t *bridge = head; bridge != NULL; bridge = bridge->next) { + if ((strncmp(bridge->name, name, strlen(bridge->name)) == 0) && + strlen(name) == strlen(bridge->name)) + return bridge; + } + return NULL; +} + +/* Delete bridge */ +static int ovs_stats_del_bridge(yajl_val bridge) { + const char *old[] = {"old", NULL}; + const char *name[] = {"name", NULL}; + + yajl_val row; + + if (bridge && YAJL_IS_OBJECT(bridge)) { + row = yajl_tree_get(bridge, old, yajl_t_object); + if (row && YAJL_IS_OBJECT(row)) { + yajl_val br_name = yajl_tree_get(row, name, yajl_t_string); + if (br_name && YAJL_IS_STRING(br_name)) { + bridge_list_t *prev_br = g_bridge_list_head; + for (bridge_list_t *br = g_bridge_list_head; br != NULL; + prev_br = br, br = br->next) { + if ((strncmp(br->name, br_name->u.string, strlen(br->name)) == 0) && + strlen(br->name) == strlen(br_name->u.string)) { + if (br == g_bridge_list_head) + g_bridge_list_head = br->next; + else + prev_br->next = br->next; + sfree(br->name); + sfree(br); + break; + } + } + } + } + } else + WARNING("%s: Incorrect data for deleting bridge", plugin_name); + return (0); +} + +/* Update Bridge. Create bridge ports*/ +static int ovs_stats_update_bridge(yajl_val bridge) { + const char *new[] = {"new", NULL}; + const char *name[] = {"name", NULL}; + const char *ports[] = {"ports", NULL}; + bridge_list_t *br = NULL; + + if (bridge && YAJL_IS_OBJECT(bridge)) { + yajl_val row = yajl_tree_get(bridge, new, yajl_t_object); + if (row && YAJL_IS_OBJECT(row)) { + yajl_val br_name = yajl_tree_get(row, name, yajl_t_string); + yajl_val br_ports = yajl_tree_get(row, ports, yajl_t_array); + if (br_name && YAJL_IS_STRING(br_name)) { + br = ovs_stats_get_bridge(g_bridge_list_head, YAJL_GET_STRING(br_name)); + pthread_mutex_lock(&g_stats_lock); + if (br == NULL) { + br = (bridge_list_t *)calloc(1, sizeof(bridge_list_t)); + if (!br) { + ERROR("%s: Error allocating memory for bridge", plugin_name); + return (-1); + } + char *tmp = YAJL_GET_STRING(br_name); + + if (tmp != NULL) + br->name = strdup(tmp); + if (br->name == NULL) { + sfree(br); + pthread_mutex_unlock(&g_stats_lock); + return (-1); + } + br->next = g_bridge_list_head; + g_bridge_list_head = br; + } + pthread_mutex_unlock(&g_stats_lock); + } + if (br_ports && YAJL_IS_ARRAY(br_ports)) { + char *tmp = YAJL_GET_STRING(br_ports->u.array.values[0]); + if (tmp != NULL && strcmp("set", tmp) == 0) { + yajl_val *array = YAJL_GET_ARRAY(br_ports)->values; + size_t array_len = YAJL_GET_ARRAY(br_ports)->len; + if (array != NULL && array_len > 0 && YAJL_IS_ARRAY(array[1])) { + yajl_val *ports_arr = YAJL_GET_ARRAY(array[1])->values; + size_t ports_num = YAJL_GET_ARRAY(array[1])->len; + for (size_t i = 0; i < ports_num && ports_arr != NULL; i++) + ovs_stats_new_port( + br, YAJL_GET_STRING(ports_arr[i]->u.array.values[1])); + } + } else + ovs_stats_new_port(br, YAJL_GET_STRING(br_ports->u.array.values[1])); + } + } + } else { + ERROR("Incorrect JSON Bridge data"); + return (-1); + } + return (0); +} + +/* Handle JSON with Bridge Table change event */ +static void ovs_stats_bridge_table_change_cb(yajl_val jupdates) { + /* Bridge Table update example JSON data + { + "Bridge": { + "bb1f8965-5775-46d9-b820-236ca8edbedc": { + "new": { + "name": "br0", + "ports": [ + "set", + [ + [ + "uuid", + "117f1a07-7ef0-458a-865c-ec7fbb85bc01" + ], + [ + "uuid", + "12fd8bdc-e950-4281-aaa9-46e185658f79" + ] + ] + ] + } + } + } + } + */ + const char *path[] = {"Bridge", NULL}; + + yajl_val bridges = yajl_tree_get(jupdates, path, yajl_t_object); + + if (bridges && YAJL_IS_OBJECT(bridges)) { + for (size_t i = 0; i < YAJL_GET_OBJECT(bridges)->len; i++) { + yajl_val bridge = YAJL_GET_OBJECT(bridges)->values[i]; + ovs_stats_update_bridge(bridge); + } + } +} + +/* Handle Bridge Table delete event */ +static void ovs_stats_bridge_table_delete_cb(yajl_val jupdates) { + const char *path[] = {"Bridge", NULL}; + yajl_val bridges = yajl_tree_get(jupdates, path, yajl_t_object); + yajl_val bridge; + if (bridges && YAJL_IS_OBJECT(bridges)) { + pthread_mutex_lock(&g_stats_lock); + for (size_t i = 0; i < YAJL_GET_OBJECT(bridges)->len; i++) { + bridge = YAJL_GET_OBJECT(bridges)->values[i]; + ovs_stats_del_bridge(bridge); + } + pthread_mutex_unlock(&g_stats_lock); + } + return; +} + +/* Handle JSON with Bridge table initial values */ +static void ovs_stats_bridge_table_result_cb(yajl_val jresult, + yajl_val jerror) { + if (YAJL_IS_NULL(jerror)) + ovs_stats_bridge_table_change_cb(jresult); + else + ERROR("%s: Error received from OvSDB. Table: Bridge", plugin_name); + return; +} + +/* Update port name */ +static int ovs_stats_update_port(const char *uuid, yajl_val port) { + const char *new[] = {"new", NULL}; + const char *name[] = {"name", NULL}; + yajl_val row; + port_list_t *portentry = NULL; + if (port && YAJL_IS_OBJECT(port)) { + row = yajl_tree_get(port, new, yajl_t_object); + if (row && YAJL_IS_OBJECT(row)) { + yajl_val port_name = yajl_tree_get(row, name, yajl_t_string); + if (port_name && YAJL_IS_STRING(port_name)) { + portentry = ovs_stats_get_port(uuid); + if (portentry == NULL) + portentry = ovs_stats_new_port(NULL, uuid); + if (portentry) { + pthread_mutex_lock(&g_stats_lock); + sstrncpy(portentry->name, YAJL_GET_STRING(port_name), + sizeof(portentry->name)); + pthread_mutex_unlock(&g_stats_lock); + } + } + } + } else { + ERROR("Incorrect JSON Port data"); + return (-1); + } + return (0); +} + +/* Delete port from global port list */ +static int ovs_stats_del_port(const char *uuid) { + port_list_t *prev_port = g_port_list_head; + for (port_list_t *port = g_port_list_head; port != NULL; + prev_port = port, port = port->next) { + if (strncmp(port->port_uuid, uuid, strlen(port->port_uuid)) == 0) { + if (port == g_port_list_head) + g_port_list_head = port->next; + else + prev_port->next = port->next; + sfree(port); + break; + } + } + return (0); +} + +/* Handle JSON with Port Table change event */ +static void ovs_stats_port_table_change_cb(yajl_val jupdates) { + /* Port Table update example JSON data + { + "Port": { + "ab107d6f-28a1-4257-b1cc-5b742821db8a": { + "new": { + "name": "br1", + "interfaces": [ + "uuid", + "33a289a0-1d34-4e46-a3c2-3e4066fbecc6" + ] + } + } + } + } + */ + const char *path[] = {"Port", NULL}; + yajl_val ports = yajl_tree_get(jupdates, path, yajl_t_object); + yajl_val port; + if (ports && YAJL_IS_OBJECT(ports)) { + for (size_t i = 0; i < YAJL_GET_OBJECT(ports)->len; i++) { + port = YAJL_GET_OBJECT(ports)->values[i]; + ovs_stats_update_port(YAJL_GET_OBJECT(ports)->keys[i], port); + } + } + return; +} + +/* Handle JSON with Port table initial values */ +static void ovs_stats_port_table_result_cb(yajl_val jresult, yajl_val jerror) { + if (YAJL_IS_NULL(jerror)) + ovs_stats_port_table_change_cb(jresult); + else + ERROR("%s: Error received from OvSDB. Table: Port", plugin_name); + return; +} + +/* Handle Port Table delete event */ +static void ovs_stats_port_table_delete_cb(yajl_val jupdates) { + const char *path[] = {"Port", NULL}; + yajl_val ports = yajl_tree_get(jupdates, path, yajl_t_object); + pthread_mutex_lock(&g_stats_lock); + if (ports && YAJL_IS_OBJECT(ports)) + for (size_t i = 0; i < YAJL_GET_OBJECT(ports)->len; i++) { + ovs_stats_del_port(YAJL_GET_OBJECT(ports)->keys[i]); + } + pthread_mutex_unlock(&g_stats_lock); + return; +} + +/* Update interface statistics */ +static int ovs_stats_update_iface_stats(port_list_t *port, yajl_val stats) { + yajl_val stat; + iface_counter counter_index = 0; + char *counter_name = NULL; + int64_t counter_value = 0; + if (stats && YAJL_IS_ARRAY(stats)) + for (size_t i = 0; i < YAJL_GET_ARRAY(stats)->len; i++) { + stat = YAJL_GET_ARRAY(stats)->values[i]; + if (!YAJL_IS_ARRAY(stat)) + return (-1); + counter_name = YAJL_GET_STRING(YAJL_GET_ARRAY(stat)->values[0]); + counter_index = ovs_stats_counter_name_to_type(counter_name); + counter_value = YAJL_GET_INTEGER(YAJL_GET_ARRAY(stat)->values[1]); + if (counter_index == not_supported) + continue; + port->stats[counter_index] = counter_value; + } + + return (0); +} + +/* Update interface external_ids */ +static int ovs_stats_update_iface_ext_ids(port_list_t *port, yajl_val ext_ids) { + yajl_val ext_id; + char *key; + char *value; + + if (ext_ids && YAJL_IS_ARRAY(ext_ids)) + for (size_t i = 0; i < YAJL_GET_ARRAY(ext_ids)->len; i++) { + ext_id = YAJL_GET_ARRAY(ext_ids)->values[i]; + if (!YAJL_IS_ARRAY(ext_id)) + return (-1); + key = YAJL_GET_STRING(YAJL_GET_ARRAY(ext_id)->values[0]); + value = YAJL_GET_STRING(YAJL_GET_ARRAY(ext_id)->values[1]); + if (key && value) { + if (strncmp(key, "iface-id", strlen(key)) == 0) + sstrncpy(port->ex_iface_id, value, sizeof(port->ex_iface_id)); + else if (strncmp(key, "vm-uuid", strlen(key)) == 0) + sstrncpy(port->ex_vm_id, value, sizeof(port->ex_vm_id)); + } + } + + return (0); +} + +/* Get interface statistic and external_ids */ +static int ovs_stats_update_iface(yajl_val iface) { + yajl_val row; + port_list_t *port = NULL; + if (iface && YAJL_IS_OBJECT(iface)) { + row = ovs_utils_get_value_by_key(iface, "new"); + if (row && YAJL_IS_OBJECT(row)) { + yajl_val iface_name = ovs_utils_get_value_by_key(row, "name"); + yajl_val iface_stats = ovs_utils_get_value_by_key(row, "statistics"); + yajl_val iface_ext_ids = ovs_utils_get_value_by_key(row, "external_ids"); + yajl_val iface_uuid = ovs_utils_get_value_by_key(row, "_uuid"); + if (iface_name && YAJL_IS_STRING(iface_name)) { + port = ovs_stats_get_port_by_name(YAJL_GET_STRING(iface_name)); + if (port == NULL) + return (0); + } + /* + * { + "statistics": [ + "map", + [ + [ + "collisions", + 0 + ], + . . . + [ + "tx_packets", + 0 + ] + ] + ] + } + Check that statistics is an array with 2 elements + */ + if (iface_stats && YAJL_IS_ARRAY(iface_stats) && + YAJL_GET_ARRAY(iface_stats)->len == 2) + ovs_stats_update_iface_stats(port, + YAJL_GET_ARRAY(iface_stats)->values[1]); + if (iface_ext_ids && YAJL_IS_ARRAY(iface_ext_ids)) + ovs_stats_update_iface_ext_ids( + port, YAJL_GET_ARRAY(iface_ext_ids)->values[1]); + if (iface_uuid && YAJL_IS_ARRAY(iface_uuid) && + YAJL_GET_ARRAY(iface_uuid)->len == 2) + sstrncpy(port->iface_uuid, + YAJL_GET_STRING(YAJL_GET_ARRAY(iface_uuid)->values[1]), + sizeof(port->iface_uuid)); + } + } else { + ERROR("Incorrect JSON Port data"); + return (-1); + } + return (0); +} + +/* Handle JSON with Interface Table change event */ +static void ovs_stats_interface_table_change_cb(yajl_val jupdates) { + /* Interface Table update example JSON data + { + "Interface": { + "33a289a0-1d34-4e46-a3c2-3e4066fbecc6": { + "new": { + "name": "br1", + "statistics": [ + "map", + [ + [ + "collisions", + 0 + ], + [ + "rx_bytes", + 0 + ], + . . . + [ + "tx_packets", + 12617 + ] + ] + ], + "_uuid": [ + "uuid", + "33a289a0-1d34-4e46-a3c2-3e4066fbecc6" + ] + "external_ids": [ + "map", + [ + [ + "attached-mac", + "fa:16:3e:7c:1c:4b" + ], + [ + "iface-id", + "a61b7e2b-6951-488a-b4c6-6e91343960b2" + ], + [ + "iface-status", + "active" + ] + ] + ] + } + } + } + } + */ + const char *path[] = {"Interface", NULL}; + yajl_val ports = yajl_tree_get(jupdates, path, yajl_t_object); + pthread_mutex_lock(&g_stats_lock); + if (ports && YAJL_IS_OBJECT(ports)) + for (size_t i = 0; i < YAJL_GET_OBJECT(ports)->len; i++) + ovs_stats_update_iface(YAJL_GET_OBJECT(ports)->values[i]); + pthread_mutex_unlock(&g_stats_lock); + return; +} + +/* Handle JSON with Interface table initial values */ +static void ovs_stats_interface_table_result_cb(yajl_val jresult, + yajl_val jerror) { + if (YAJL_IS_NULL(jerror)) + ovs_stats_interface_table_change_cb(jresult); + else + ERROR("%s: Error received from OvSDB. Table: Interface", plugin_name); + return; +} + +/* Setup OVS DB table callbacks */ +static void ovs_stats_initialize(ovs_db_t *pdb) { + const char *bridge_columns[] = {"name", "ports", NULL}; + const char *port_columns[] = {"name", "interfaces", NULL}; + const char *interface_columns[] = {"name", "statistics", "_uuid", + "external_ids", NULL}; + + /* subscribe to a tables */ + ovs_db_table_cb_register(pdb, "Bridge", bridge_columns, + ovs_stats_bridge_table_change_cb, + ovs_stats_bridge_table_result_cb, + OVS_DB_TABLE_CB_FLAG_INITIAL | + OVS_DB_TABLE_CB_FLAG_INSERT | + OVS_DB_TABLE_CB_FLAG_MODIFY); + + ovs_db_table_cb_register(pdb, "Bridge", bridge_columns, + ovs_stats_bridge_table_delete_cb, NULL, + OVS_DB_TABLE_CB_FLAG_DELETE); + + ovs_db_table_cb_register(pdb, "Port", port_columns, + ovs_stats_port_table_change_cb, + ovs_stats_port_table_result_cb, + OVS_DB_TABLE_CB_FLAG_INITIAL | + OVS_DB_TABLE_CB_FLAG_INSERT | + OVS_DB_TABLE_CB_FLAG_MODIFY); + + ovs_db_table_cb_register(pdb, "Port", port_columns, + ovs_stats_port_table_delete_cb, NULL, + OVS_DB_TABLE_CB_FLAG_DELETE); + + ovs_db_table_cb_register(pdb, "Interface", interface_columns, + ovs_stats_interface_table_change_cb, + ovs_stats_interface_table_result_cb, + OVS_DB_TABLE_CB_FLAG_INITIAL | + OVS_DB_TABLE_CB_FLAG_INSERT | + OVS_DB_TABLE_CB_FLAG_MODIFY); +} + +/* Check if bridge is configured to be monitored in config file */ +static int ovs_stats_is_monitored_bridge(const char *br_name) { + /* if no bridges are configured, return true */ + if (g_monitored_bridge_list_head == NULL) + return (1); + + /* check if given bridge exists */ + if (ovs_stats_get_bridge(g_monitored_bridge_list_head, br_name) != NULL) + return (1); + + return 0; +} + +/* Delete all ports from port list */ +static void ovs_stats_free_port_list(port_list_t *head) { + for (port_list_t *i = head; i != NULL;) { + port_list_t *del = i; + i = i->next; + sfree(del); + } +} + +/* Delete all bridges from bridge list */ +static void ovs_stats_free_bridge_list(bridge_list_t *head) { + for (bridge_list_t *i = head; i != NULL;) { + bridge_list_t *del = i; + i = i->next; + sfree(del->name); + sfree(del); + } +} + +/* Handle OVSDB lost connection callback */ +static void ovs_stats_conn_terminate() { + WARNING("Lost connection to OVSDB server"); + pthread_mutex_lock(&g_stats_lock); + ovs_stats_free_bridge_list(g_bridge_list_head); + g_bridge_list_head = NULL; + ovs_stats_free_port_list(g_port_list_head); + g_port_list_head = NULL; + pthread_mutex_unlock(&g_stats_lock); +} + +/* Parse plugin configuration file and store the config + * in allocated memory. Returns negative value in case of error. + */ +static int ovs_stats_plugin_config(oconfig_item_t *ci) { + bridge_list_t *bridge; + char *br_name; + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + if (strcasecmp("Address", child->key) == 0) { + if (cf_util_get_string_buffer(child, ovs_stats_cfg.ovs_db_node, + OVS_DB_ADDR_NODE_SIZE) != 0) { + ERROR("%s: parse '%s' option failed", plugin_name, child->key); + return (-1); + } + } else if (strcasecmp("Port", child->key) == 0) { + if (cf_util_get_string_buffer(child, ovs_stats_cfg.ovs_db_serv, + OVS_DB_ADDR_SERVICE_SIZE) != 0) { + ERROR("%s: parse '%s' option failed", plugin_name, child->key); + return (-1); + } + } else if (strcasecmp("Socket", child->key) == 0) { + if (cf_util_get_string_buffer(child, ovs_stats_cfg.ovs_db_unix, + OVS_DB_ADDR_UNIX_SIZE) != 0) { + ERROR("%s: parse '%s' option failed", plugin_name, child->key); + return (-1); + } + } else if (strcasecmp("Bridges", child->key) == 0) { + for (int j = 0; j < child->values_num; j++) { + /* check value type */ + if (child->values[j].type != OCONFIG_TYPE_STRING) { + ERROR("%s: Wrong bridge name [idx=%d]. " + "Bridge name should be string", + plugin_name, j); + goto cleanup_fail; + } + /* get value */ + if ((br_name = strdup(child->values[j].value.string)) == NULL) { + ERROR("%s: strdup() copy bridge name fail", plugin_name); + goto cleanup_fail; + } + if ((bridge = ovs_stats_get_bridge(g_monitored_bridge_list_head, + br_name)) == NULL) { + if ((bridge = calloc(1, sizeof(bridge_list_t))) == NULL) { + ERROR("%s: Error allocating memory for bridge", plugin_name); + goto cleanup_fail; + } else { + pthread_mutex_lock(&g_stats_lock); + /* store bridge name */ + bridge->name = br_name; + bridge->next = g_monitored_bridge_list_head; + g_monitored_bridge_list_head = bridge; + pthread_mutex_unlock(&g_stats_lock); + DEBUG("%s: found monitored interface \"%s\"", plugin_name, br_name); + } + } + } + } else { + WARNING("%s: option '%s' not allowed here", plugin_name, child->key); + goto cleanup_fail; + } + } + return (0); + +cleanup_fail: + ovs_stats_free_bridge_list(g_monitored_bridge_list_head); + return (-1); +} + +/* Initialize OvS Stats plugin*/ +static int ovs_stats_plugin_init(void) { + ovs_db_callback_t cb = {.post_conn_init = ovs_stats_initialize, + .post_conn_terminate = ovs_stats_conn_terminate}; + + INFO("%s: Connecting to OVS DB using address=%s, service=%s, unix=%s", + plugin_name, ovs_stats_cfg.ovs_db_node, ovs_stats_cfg.ovs_db_serv, + ovs_stats_cfg.ovs_db_unix); + /* connect to OvS DB */ + if ((g_ovs_db = ovs_db_init (ovs_stats_cfg.ovs_db_node, + ovs_stats_cfg.ovs_db_serv, + ovs_stats_cfg.ovs_db_unix, &cb)) == NULL) { + ERROR("%s: plugin: failed to connect to OvS DB server", plugin_name); + return (-1); + } + int err = pthread_mutex_init(&g_stats_lock, NULL); + if (err < 0) { + ERROR("%s: plugin: failed to initialize cache lock", plugin_name); + ovs_db_destroy(g_ovs_db); + return (-1); + } + return (0); +} + +/* OvS stats read callback. Read bridge/port information and submit it*/ +static int ovs_stats_plugin_read(__attribute__((unused)) user_data_t *ud) { + bridge_list_t *bridge; + port_list_t *port; + char devname[PORT_NAME_SIZE_MAX * 2]; + + pthread_mutex_lock(&g_stats_lock); + for (bridge = g_bridge_list_head; bridge != NULL; bridge = bridge->next) { + if (ovs_stats_is_monitored_bridge(bridge->name)) { + for (port = g_port_list_head; port != NULL; port = port->next) + if (port->br == bridge) { + if (strlen(port->name) == 0) + /* Skip port w/o name. This is possible when read callback + * is called after Interface Table update callback but before + * Port table Update callback. Will add this port on next read */ + continue; + meta_data_t *meta = meta_data_create(); + if (meta != NULL) { + meta_data_add_string(meta, "uuid", port->iface_uuid); + if (strlen(port->ex_vm_id)) + meta_data_add_string(meta, "vm-uuid", port->ex_vm_id); + if (strlen(port->ex_iface_id)) + meta_data_add_string(meta, "iface-id", port->ex_iface_id); + } + snprintf(devname, sizeof(devname), "%s.%s", bridge->name, port->name); + ovs_stats_submit_one(devname, "if_collisions", NULL, + port->stats[collisions], meta); + ovs_stats_submit_two(devname, "if_dropped", NULL, + port->stats[rx_dropped], port->stats[tx_dropped], + meta); + ovs_stats_submit_two(devname, "if_errors", NULL, + port->stats[rx_errors], port->stats[tx_errors], + meta); + ovs_stats_submit_two(devname, "if_packets", NULL, + port->stats[rx_packets], port->stats[tx_packets], + meta); + ovs_stats_submit_one(devname, "if_rx_errors", "crc", + port->stats[rx_crc_err], meta); + ovs_stats_submit_one(devname, "if_rx_errors", "frame", + port->stats[rx_frame_err], meta); + ovs_stats_submit_one(devname, "if_rx_errors", "over", + port->stats[rx_over_err], meta); + ovs_stats_submit_one(devname, "if_rx_octets", NULL, + port->stats[rx_bytes], meta); + ovs_stats_submit_one(devname, "if_tx_octets", NULL, + port->stats[tx_bytes], meta); + ovs_stats_submit_two(devname, "if_packets", "1_to_64_packets", + port->stats[rx_1_to_64_packets], + port->stats[tx_1_to_64_packets], meta); + ovs_stats_submit_two(devname, "if_packets", "65_to_127_packets", + port->stats[rx_65_to_127_packets], + port->stats[tx_65_to_127_packets], meta); + ovs_stats_submit_two(devname, "if_packets", "128_to_255_packets", + port->stats[rx_128_to_255_packets], + port->stats[tx_128_to_255_packets], meta); + ovs_stats_submit_two(devname, "if_packets", "256_to_511_packets", + port->stats[rx_256_to_511_packets], + port->stats[tx_256_to_511_packets], meta); + ovs_stats_submit_two(devname, "if_packets", "512_to_1023_packets", + port->stats[rx_512_to_1023_packets], + port->stats[tx_512_to_1023_packets], meta); + ovs_stats_submit_two(devname, "if_packets", "1024_to_1518_packets", + port->stats[rx_1024_to_1522_packets], + port->stats[tx_1024_to_1522_packets], meta); + ovs_stats_submit_two(devname, "if_packets", "1523_to_max_packets", + port->stats[rx_1523_to_max_packets], + port->stats[tx_1523_to_max_packets], meta); + ovs_stats_submit_two(devname, "if_packets", "broadcast_packets", + port->stats[rx_broadcast_packets], + port->stats[tx_broadcast_packets], meta); + ovs_stats_submit_one(devname, "if_multicast", "tx_multicast_packets", + port->stats[tx_multicast_packets], meta); + ovs_stats_submit_one(devname, "if_rx_errors", "rx_undersized_errors", + port->stats[rx_undersized_errors], meta); + ovs_stats_submit_one(devname, "if_rx_errors", "rx_oversize_errors", + port->stats[rx_oversize_errors], meta); + ovs_stats_submit_one(devname, "if_rx_errors", "rx_fragmented_errors", + port->stats[rx_fragmented_errors], meta); + ovs_stats_submit_one(devname, "if_rx_errors", "rx_jabber_errors", + port->stats[rx_jabber_errors], meta); + + meta_data_destroy(meta); + } + } else + continue; + } + pthread_mutex_unlock(&g_stats_lock); + return (0); +} + +/* Shutdown OvS Stats plugin */ +static int ovs_stats_plugin_shutdown(void) { + pthread_mutex_lock(&g_stats_lock); + DEBUG("OvS Statistics plugin shutting down"); + ovs_db_destroy(g_ovs_db); + ovs_stats_free_bridge_list(g_bridge_list_head); + ovs_stats_free_bridge_list(g_monitored_bridge_list_head); + ovs_stats_free_port_list(g_port_list_head); + pthread_mutex_unlock(&g_stats_lock); + pthread_mutex_destroy(&g_stats_lock); + return (0); +} + +/* Register OvS Stats plugin callbacks */ +void module_register(void) { + plugin_register_complex_config(plugin_name, ovs_stats_plugin_config); + plugin_register_init(plugin_name, ovs_stats_plugin_init); + plugin_register_complex_read(NULL, plugin_name, ovs_stats_plugin_read, 0, + NULL); + plugin_register_shutdown(plugin_name, ovs_stats_plugin_shutdown); +} diff --git a/src/perl.c b/src/perl.c index 59109133..c79cfd2f 100644 --- a/src/perl.c +++ b/src/perl.c @@ -38,9 +38,7 @@ #undef DONT_POISON_SPRINTF_YET -#if HAVE_STDBOOL_H #include -#endif #include #include @@ -2711,5 +2709,3 @@ void module_register(void) { plugin_register_complex_config("perl", perl_config); return; } /* void module_register (void) */ - -/* vim: set sw=4 ts=4 tw=78 noexpandtab : */ diff --git a/src/pinba.c b/src/pinba.c index 7fd23a02..97eeb0d6 100644 --- a/src/pinba.c +++ b/src/pinba.c @@ -685,5 +685,3 @@ void module_register(void) /* {{{ */ plugin_register_read("pinba", plugin_read); plugin_register_shutdown("pinba", plugin_shutdown); } /* }}} void module_register */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/ping.c b/src/ping.c index 82de59f0..6d9545f3 100644 --- a/src/ping.c +++ b/src/ping.c @@ -679,5 +679,3 @@ void module_register(void) { plugin_register_read("ping", ping_read); plugin_register_shutdown("ping", ping_shutdown); } /* void module_register */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/postgresql.c b/src/postgresql.c index 2af89886..3a388a5a 100644 --- a/src/postgresql.c +++ b/src/postgresql.c @@ -1265,5 +1265,3 @@ void module_register(void) { plugin_register_complex_config("postgresql", c_psql_config); plugin_register_shutdown("postgresql", c_psql_shutdown); } /* module_register */ - -/* vim: set sw=4 ts=4 tw=78 noexpandtab : */ diff --git a/src/powerdns.c b/src/powerdns.c index f2149ef2..85621087 100644 --- a/src/powerdns.c +++ b/src/powerdns.c @@ -960,5 +960,3 @@ void module_register(void) { plugin_register_read("powerdns", powerdns_read); plugin_register_shutdown("powerdns", powerdns_shutdown); } /* void module_register */ - -/* vim: set sw=2 sts=2 ts=8 fdm=marker : */ diff --git a/src/processes.c b/src/processes.c index 87c96c88..6e472e60 100644 --- a/src/processes.c +++ b/src/processes.c @@ -32,6 +32,7 @@ * Manuel Sanmartin * Clément Stenac * Cosmin Ioiart + * Pavel Rochnyack **/ #include "collectd.h" @@ -159,12 +160,14 @@ #endif #endif -typedef struct procstat_entry_s { +#define PROCSTAT_NAME_LEN 256 +typedef struct process_entry_s { unsigned long id; - unsigned long age; + char name[PROCSTAT_NAME_LEN]; unsigned long num_proc; unsigned long num_lwp; + unsigned long num_fd; unsigned long vmem_size; unsigned long vmem_rss; unsigned long vmem_data; @@ -188,10 +191,31 @@ typedef struct procstat_entry_s { derive_t cswitch_invol; _Bool has_cswitch; + _Bool has_fd; +} process_entry_t; + +typedef struct procstat_entry_s { + unsigned long id; + unsigned long age; + + derive_t vmem_minflt_counter; + derive_t vmem_majflt_counter; + + derive_t cpu_user_counter; + derive_t cpu_system_counter; + + /* io data */ + derive_t io_rchar; + derive_t io_wchar; + derive_t io_syscr; + derive_t io_syscw; + + derive_t cswitch_vol; + derive_t cswitch_invol; + struct procstat_entry_s *next; } procstat_entry_t; -#define PROCSTAT_NAME_LEN 256 typedef struct procstat { char name[PROCSTAT_NAME_LEN]; #if HAVE_REGEX_H @@ -200,6 +224,7 @@ typedef struct procstat { unsigned long num_proc; unsigned long num_lwp; + unsigned long num_fd; unsigned long vmem_size; unsigned long vmem_rss; unsigned long vmem_data; @@ -221,6 +246,9 @@ typedef struct procstat { derive_t cswitch_vol; derive_t cswitch_invol; + _Bool report_fd_num; + _Bool report_ctx_switch; + struct procstat *next; struct procstat_entry_s *instances; } procstat_t; @@ -229,6 +257,7 @@ static procstat_t *list_head_g = NULL; static _Bool want_init = 1; static _Bool report_ctx_switch = 0; +static _Bool report_fd_num = 0; #if HAVE_THREAD_INFO static mach_port_t port_host_self; @@ -240,7 +269,7 @@ static mach_msg_type_number_t pset_list_len; #elif KERNEL_LINUX static long pagesize_g; -static void ps_fill_details(const procstat_t *ps, procstat_entry_t *entry); +static void ps_fill_details(const procstat_t *ps, process_entry_t *entry); /* #endif KERNEL_LINUX */ #elif HAVE_LIBKVM_GETPROCS && \ @@ -265,7 +294,7 @@ int getargs(void *processBuffer, int bufferLen, char *argsBuffer, int argsLen); /* put name of process from config to list_head_g tree * list_head_g is a list of 'procstat_t' structs with * processes names we want to watch */ -static void ps_list_register(const char *name, const char *regexp) { +static procstat_t *ps_list_register(const char *name, const char *regexp) { procstat_t *new; procstat_t *ptr; int status; @@ -273,10 +302,20 @@ static void ps_list_register(const char *name, const char *regexp) { new = calloc(1, sizeof(*new)); if (new == NULL) { ERROR("processes plugin: ps_list_register: calloc failed."); - return; + return (NULL); } sstrncpy(new->name, name, sizeof(new->name)); + new->io_rchar = -1; + new->io_wchar = -1; + new->io_syscr = -1; + new->io_syscw = -1; + new->cswitch_vol = -1; + new->cswitch_invol = -1; + + new->report_fd_num = report_fd_num; + new->report_ctx_switch = report_ctx_switch; + #if HAVE_REGEX_H if (regexp != NULL) { DEBUG("ProcessMatch: adding \"%s\" as criteria to process %s.", regexp, @@ -285,7 +324,7 @@ static void ps_list_register(const char *name, const char *regexp) { if (new->re == NULL) { ERROR("processes plugin: ps_list_register: malloc failed."); sfree(new); - return; + return (NULL); } status = regcomp(new->re, regexp, REG_EXTENDED | REG_NOSUB); @@ -294,7 +333,7 @@ static void ps_list_register(const char *name, const char *regexp) { regexp); sfree(new->re); sfree(new); - return; + return (NULL); } } #else @@ -305,7 +344,7 @@ static void ps_list_register(const char *name, const char *regexp) { "has been disabled at compile time.", regexp); sfree(new); - return; + return (NULL); } #endif @@ -320,7 +359,7 @@ static void ps_list_register(const char *name, const char *regexp) { sfree(new->re); #endif sfree(new); - return; + return (NULL); } if (ptr->next == NULL) @@ -331,6 +370,8 @@ static void ps_list_register(const char *name, const char *regexp) { list_head_g = new; else ptr->next = new; + + return (new); } /* void ps_list_register */ /* try to match name against entry, returns 1 if success */ @@ -375,13 +416,16 @@ static void ps_update_counter(derive_t *group_counter, derive_t *curr_counter, else curr_value = new_counter - *curr_counter; + if (*group_counter == -1) + *group_counter = 0; + *curr_counter = new_counter; *group_counter += curr_value; } /* add process entry to 'instances' of process 'name' (or refresh it) */ static void ps_list_add(const char *name, const char *cmdline, - procstat_entry_t *entry) { + process_entry_t *entry) { procstat_entry_t *pse; if (entry->id == 0) @@ -416,35 +460,32 @@ static void ps_list_add(const char *name, const char *cmdline, } pse->age = 0; - pse->num_proc = entry->num_proc; - pse->num_lwp = entry->num_lwp; - pse->vmem_size = entry->vmem_size; - pse->vmem_rss = entry->vmem_rss; - pse->vmem_data = entry->vmem_data; - pse->vmem_code = entry->vmem_code; - pse->stack_size = entry->stack_size; - pse->io_rchar = entry->io_rchar; - pse->io_wchar = entry->io_wchar; - pse->io_syscr = entry->io_syscr; - pse->io_syscw = entry->io_syscw; - pse->cswitch_vol = entry->cswitch_vol; - pse->cswitch_invol = entry->cswitch_invol; - - ps->num_proc += pse->num_proc; - ps->num_lwp += pse->num_lwp; - ps->vmem_size += pse->vmem_size; - ps->vmem_rss += pse->vmem_rss; - ps->vmem_data += pse->vmem_data; - ps->vmem_code += pse->vmem_code; - ps->stack_size += pse->stack_size; - - ps->io_rchar += ((pse->io_rchar == -1) ? 0 : pse->io_rchar); - ps->io_wchar += ((pse->io_wchar == -1) ? 0 : pse->io_wchar); - ps->io_syscr += ((pse->io_syscr == -1) ? 0 : pse->io_syscr); - ps->io_syscw += ((pse->io_syscw == -1) ? 0 : pse->io_syscw); - - ps->cswitch_vol += ((pse->cswitch_vol == -1) ? 0 : pse->cswitch_vol); - ps->cswitch_invol += ((pse->cswitch_invol == -1) ? 0 : pse->cswitch_invol); + + ps->num_proc += entry->num_proc; + ps->num_lwp += entry->num_lwp; + ps->num_fd += entry->num_fd; + ps->vmem_size += entry->vmem_size; + ps->vmem_rss += entry->vmem_rss; + ps->vmem_data += entry->vmem_data; + ps->vmem_code += entry->vmem_code; + ps->stack_size += entry->stack_size; + + if ((entry->io_rchar != -1) && (entry->io_wchar != -1)) { + ps_update_counter(&ps->io_rchar, &pse->io_rchar, entry->io_rchar); + ps_update_counter(&ps->io_wchar, &pse->io_wchar, entry->io_wchar); + } + + if ((entry->io_syscr != -1) && (entry->io_syscw != -1)) { + ps_update_counter(&ps->io_syscr, &pse->io_syscr, entry->io_syscr); + ps_update_counter(&ps->io_syscw, &pse->io_syscw, entry->io_syscw); + } + + if ((entry->cswitch_vol != -1) && (entry->cswitch_vol != -1)) { + ps_update_counter(&ps->cswitch_vol, &pse->cswitch_vol, + entry->cswitch_vol); + ps_update_counter(&ps->cswitch_invol, &pse->cswitch_invol, + entry->cswitch_invol); + } ps_update_counter(&ps->vmem_minflt_counter, &pse->vmem_minflt_counter, entry->vmem_minflt_counter); @@ -466,17 +507,12 @@ static void ps_list_reset(void) { for (procstat_t *ps = list_head_g; ps != NULL; ps = ps->next) { ps->num_proc = 0; ps->num_lwp = 0; + ps->num_fd = 0; ps->vmem_size = 0; ps->vmem_rss = 0; ps->vmem_data = 0; ps->vmem_code = 0; ps->stack_size = 0; - ps->io_rchar = -1; - ps->io_wchar = -1; - ps->io_syscr = -1; - ps->io_syscw = -1; - ps->cswitch_vol = -1; - ps->cswitch_invol = -1; pse_prev = NULL; pse = ps->instances; @@ -504,6 +540,20 @@ static void ps_list_reset(void) { } /* for (ps = list_head_g; ps != NULL; ps = ps->next) */ } +static void ps_tune_instance(oconfig_item_t *ci, procstat_t *ps) { + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *c = ci->children + i; + + if (strcasecmp(c->key, "CollectContextSwitch") == 0) + cf_util_get_boolean(c, &ps->report_ctx_switch); + else if (strcasecmp(c->key, "CollectFileDescriptor") == 0) + cf_util_get_boolean(c, &ps->report_fd_num); + else { + ERROR("processes plugin: Option `%s' not allowed here.", c->key); + } + } /* for (ci->children) */ +} /* void ps_tune_instance */ + /* put all pre-defined 'Process' names from config to list_head_g tree */ static int ps_config(oconfig_item_t *ci) { #if KERNEL_LINUX @@ -512,6 +562,8 @@ static int ps_config(oconfig_item_t *ci) { const size_t max_procname_len = MAXCOMLEN - 1; #endif + procstat_t *ps; + for (int i = 0; i < ci->children_num; ++i) { oconfig_item_t *c = ci->children + i; @@ -523,13 +575,6 @@ static int ps_config(oconfig_item_t *ci) { continue; } - if (c->children_num != 0) { - WARNING("processes plugin: the `Process' config option " - "does not expect any child elements -- ignoring " - "content (%i elements) of the block.", - c->children_num, c->values[0].value.string); - } - #if KERNEL_LINUX || KERNEL_SOLARIS || KERNEL_FREEBSD if (strlen(c->values[0].value.string) > max_procname_len) { WARNING("processes plugin: this platform has a %zu character limit " @@ -539,7 +584,10 @@ static int ps_config(oconfig_item_t *ci) { } #endif - ps_list_register(c->values[0].value.string, NULL); + ps = ps_list_register(c->values[0].value.string, NULL); + + if (c->children_num != 0 && ps != NULL) + ps_tune_instance(c, ps); } else if (strcasecmp(c->key, "ProcessMatch") == 0) { if ((c->values_num != 2) || (OCONFIG_TYPE_STRING != c->values[0].type) || (OCONFIG_TYPE_STRING != c->values[1].type)) { @@ -549,18 +597,15 @@ static int ps_config(oconfig_item_t *ci) { continue; } - if (c->children_num != 0) { - WARNING("processes plugin: the `ProcessMatch' config option " - "does not expect any child elements -- ignoring " - "content (%i elements) of the " - "block.", - c->children_num, c->values[0].value.string, - c->values[1].value.string); - } + ps = ps_list_register(c->values[0].value.string, + c->values[1].value.string); - ps_list_register(c->values[0].value.string, c->values[1].value.string); + if (c->children_num != 0 && ps != NULL) + ps_tune_instance(c, ps); } else if (strcasecmp(c->key, "CollectContextSwitch") == 0) { cf_util_get_boolean(c, &report_ctx_switch); + } else if (strcasecmp(c->key, "CollectFileDescriptor") == 0) { + cf_util_get_boolean(c, &report_fd_num); } else { ERROR("processes plugin: The `%s' configuration option is not " "understood and will be ignored.", @@ -695,7 +740,14 @@ static void ps_submit_proc_list(procstat_t *ps) { plugin_dispatch_values(&vl); } - if (report_ctx_switch) { + if (ps->num_fd > 0) { + sstrncpy(vl.type, "file_handles", sizeof(vl.type)); + vl.values[0].gauge = ps->num_fd; + vl.values_len = 1; + plugin_dispatch_values(&vl); + } + + if ((ps->cswitch_vol != -1) && (ps->cswitch_invol != -1)) { sstrncpy(vl.type, "contextswitch", sizeof(vl.type)); sstrncpy(vl.type_instance, "voluntary", sizeof(vl.type_instance)); vl.values[0].derive = ps->cswitch_vol; @@ -709,7 +761,7 @@ static void ps_submit_proc_list(procstat_t *ps) { plugin_dispatch_values(&vl); } - DEBUG("name = %s; num_proc = %lu; num_lwp = %lu; " + DEBUG("name = %s; num_proc = %lu; num_lwp = %lu; num_fd = %lu; " "vmem_size = %lu; vmem_rss = %lu; vmem_data = %lu; " "vmem_code = %lu; " "vmem_minflt_counter = %" PRIi64 "; vmem_majflt_counter = %" PRIi64 "; " @@ -717,8 +769,8 @@ static void ps_submit_proc_list(procstat_t *ps) { "io_rchar = %" PRIi64 "; io_wchar = %" PRIi64 "; " "io_syscr = %" PRIi64 "; io_syscw = %" PRIi64 "; " "cswitch_vol = %" PRIi64 "; cswitch_invol = %" PRIi64 ";", - ps->name, ps->num_proc, ps->num_lwp, ps->vmem_size, ps->vmem_rss, - ps->vmem_data, ps->vmem_code, ps->vmem_minflt_counter, + ps->name, ps->num_proc, ps->num_lwp, ps->num_fd, ps->vmem_size, + ps->vmem_rss, ps->vmem_data, ps->vmem_code, ps->vmem_minflt_counter, ps->vmem_majflt_counter, ps->cpu_user_counter, ps->cpu_system_counter, ps->io_rchar, ps->io_wchar, ps->io_syscr, ps->io_syscw, ps->cswitch_vol, ps->cswitch_invol); @@ -741,7 +793,7 @@ static void ps_submit_fork_rate(derive_t value) { /* ------- additional functions for KERNEL_LINUX/HAVE_THREAD_INFO ------- */ #if KERNEL_LINUX -static int ps_read_tasks_status(procstat_entry_t *ps) { +static int ps_read_tasks_status(process_entry_t *ps) { char dirname[64]; DIR *dh; char filename[64]; @@ -815,7 +867,7 @@ static int ps_read_tasks_status(procstat_entry_t *ps) { } /* int *ps_read_tasks_status */ /* Read data from /proc/pid/status */ -static procstat_t *ps_read_status(long pid, procstat_t *ps) { +static int ps_read_status(long pid, process_entry_t *ps) { FILE *fh; char buffer[1024]; char filename[64]; @@ -828,7 +880,7 @@ static procstat_t *ps_read_status(long pid, procstat_t *ps) { ssnprintf(filename, sizeof(filename), "/proc/%li/status", pid); if ((fh = fopen(filename, "r")) == NULL) - return (NULL); + return (-1); while (fgets(buffer, sizeof(buffer), fh) != NULL) { unsigned long tmp; @@ -868,10 +920,10 @@ static procstat_t *ps_read_status(long pid, procstat_t *ps) { if (threads != 0) ps->num_lwp = threads; - return (ps); -} /* procstat_t *ps_read_vmem */ + return (0); +} /* int *ps_read_status */ -static int ps_read_io(procstat_entry_t *ps) { +static int ps_read_io(process_entry_t *ps) { FILE *fh; char buffer[1024]; char filename[64]; @@ -880,8 +932,10 @@ static int ps_read_io(procstat_entry_t *ps) { int numfields; ssnprintf(filename, sizeof(filename), "/proc/%li/io", ps->id); - if ((fh = fopen(filename, "r")) == NULL) + if ((fh = fopen(filename, "r")) == NULL) { + DEBUG("ps_read_io: Failed to open file `%s'", filename); return (-1); + } while (fgets(buffer, sizeof(buffer), fh) != NULL) { derive_t *val = NULL; @@ -920,32 +974,52 @@ static int ps_read_io(procstat_entry_t *ps) { return (0); } /* int ps_read_io (...) */ -static void ps_fill_details(const procstat_t *ps, procstat_entry_t *entry) { - if (entry->has_io == 0 && ps_read_io(entry) != 0) { - /* no io data */ - entry->io_rchar = -1; - entry->io_wchar = -1; - entry->io_syscr = -1; - entry->io_syscw = -1; +static int ps_count_fd(int pid) { + char dirname[64]; + DIR *dh; + struct dirent *ent; + int count = 0; + + ssnprintf(dirname, sizeof(dirname), "/proc/%i/fd", pid); - DEBUG("ps_read_process: not get io data for pid %li", entry->id); + if ((dh = opendir(dirname)) == NULL) { + DEBUG("Failed to open directory `%s'", dirname); + return (-1); } - entry->has_io = 1; + while ((ent = readdir(dh)) != NULL) { + if (!isdigit((int)ent->d_name[0])) + continue; + else + count++; + } + closedir(dh); - if (report_ctx_switch) { - if (entry->has_cswitch == 0 && ps_read_tasks_status(entry) != 0) { - entry->cswitch_vol = -1; - entry->cswitch_invol = -1; + return ((count >= 1) ? count : 1); +} /* int ps_count_fd (pid) */ - DEBUG("ps_read_tasks_status: not get context " - "switch data for pid %li", - entry->id); +static void ps_fill_details(const procstat_t *ps, process_entry_t *entry) { + if (entry->has_io == 0) { + ps_read_io(entry); + entry->has_io = 1; + } + + if (ps->report_ctx_switch) { + if (entry->has_cswitch == 0) { + ps_read_tasks_status(entry); + entry->has_cswitch = 1; + } + } + + if (ps->report_fd_num) { + int num_fd; + if (entry->has_fd == 0 && (num_fd = ps_count_fd(entry->id)) > 0) { + entry->num_fd = num_fd; } - entry->has_cswitch = 1; + entry->has_fd = 1; } } /* void ps_fill_details (...) */ -static int ps_read_process(long pid, procstat_t *ps, char *state) { +static int ps_read_process(long pid, process_entry_t *ps, char *state) { char filename[64]; char buffer[1024]; @@ -967,8 +1041,6 @@ static int ps_read_process(long pid, procstat_t *ps, char *state) { ssize_t status; - memset(ps, 0, sizeof(procstat_t)); - ssnprintf(filename, sizeof(filename), "/proc/%li/stat", pid); status = read_file_contents(filename, buffer, sizeof(buffer) - 1); @@ -1023,7 +1095,7 @@ static int ps_read_process(long pid, procstat_t *ps, char *state) { ps->num_proc = 0; } else { ps->num_lwp = strtoul(fields[17], /* endptr = */ NULL, /* base = */ 10); - if ((ps_read_status(pid, ps)) == NULL) { + if ((ps_read_status(pid, ps)) != 0) { /* No VMem data */ ps->vmem_data = -1; ps->vmem_code = -1; @@ -1068,6 +1140,15 @@ static int ps_read_process(long pid, procstat_t *ps, char *state) { ps->vmem_rss = (unsigned long)vmem_rss; ps->stack_size = (unsigned long)stack_size; + /* no data by default. May be filled by ps_fill_details () */ + ps->io_rchar = -1; + ps->io_wchar = -1; + ps->io_syscr = -1; + ps->io_syscw = -1; + + ps->cswitch_vol = -1; + ps->cswitch_invol = -1; + /* success */ return (0); } /* int ps_read_process (...) */ @@ -1239,7 +1320,7 @@ static char *ps_get_cmdline(long pid, * The values for input and ouput chars are calculated "by hand" * Added a few "solaris" specific process states as well */ -static int ps_read_process(long pid, procstat_t *ps, char *state) { +static int ps_read_process(long pid, process_entry_t *ps, char *state) { char filename[64]; char f_psinfo[64], f_usage[64]; char *buffer; @@ -1304,6 +1385,11 @@ static int ps_read_process(long pid, procstat_t *ps, char *state) { ps->stack_size = myStatus->pr_stksize; /* + * TODO: File descriptor count for Solaris + */ + ps->num_fd = 0; + + /* * Calculating input/ouput chars * Formula used is total chars / total blocks => chars/block * then convert input/output blocks to chars @@ -1444,7 +1530,7 @@ static int ps_read(void) { int blocked = 0; procstat_t *ps; - procstat_entry_t pse; + process_entry_t pse; ps_list_reset(); @@ -1526,6 +1612,14 @@ static int ps_read(void) { pse.vmem_data = 0; pse.vmem_code = 0; + pse.io_rchar = -1; + pse.io_wchar = -1; + pse.io_syscr = -1; + pse.io_syscw = -1; + + /* File descriptor count not implemented */ + pse.num_fd = 0; + pse.vmem_minflt_counter = task_events_info.cow_faults; pse.vmem_majflt_counter = task_events_info.faults; @@ -1657,8 +1751,7 @@ static int ps_read(void) { char cmdline[CMDLINE_BUFFER_SIZE]; int status; - procstat_t ps; - procstat_entry_t pse; + process_entry_t pse; char state; running = sleeping = zombies = stopped = paging = blocked = 0; @@ -1677,38 +1770,15 @@ static int ps_read(void) { if ((pid = atol(ent->d_name)) < 1) continue; - status = ps_read_process(pid, &ps, &state); + memset(&pse, 0, sizeof(pse)); + pse.id = pid; + + status = ps_read_process(pid, &pse, &state); if (status != 0) { DEBUG("ps_read_process failed: %i", status); continue; } - memset(&pse, 0, sizeof(pse)); - pse.id = pid; - pse.age = 0; - - pse.num_proc = ps.num_proc; - pse.num_lwp = ps.num_lwp; - pse.vmem_size = ps.vmem_size; - pse.vmem_rss = ps.vmem_rss; - pse.vmem_data = ps.vmem_data; - pse.vmem_code = ps.vmem_code; - pse.stack_size = ps.stack_size; - - pse.vmem_minflt_counter = ps.vmem_minflt_counter; - pse.vmem_majflt_counter = ps.vmem_majflt_counter; - - pse.cpu_user_counter = ps.cpu_user_counter; - pse.cpu_system_counter = ps.cpu_system_counter; - - pse.io_rchar = ps.io_rchar; - pse.io_wchar = ps.io_wchar; - pse.io_syscr = ps.io_syscr; - pse.io_syscw = ps.io_syscw; - - pse.cswitch_vol = ps.cswitch_vol; - pse.cswitch_invol = ps.cswitch_invol; - switch (state) { case 'R': running++; @@ -1730,8 +1800,8 @@ static int ps_read(void) { break; } - ps_list_add(ps.name, ps_get_cmdline(pid, ps.name, cmdline, sizeof(cmdline)), - &pse); + ps_list_add(pse.name, + ps_get_cmdline(pid, pse.name, cmdline, sizeof(cmdline)), &pse); } closedir(proc); @@ -1764,7 +1834,7 @@ static int ps_read(void) { struct kinfo_proc *proc_ptr = NULL; int count; /* returns number of processes */ - procstat_entry_t pse; + process_entry_t pse; ps_list_reset(); @@ -1814,8 +1884,8 @@ static int ps_read(void) { } } /* if (process has argument list) */ + memset(&pse, 0, sizeof(pse)); pse.id = procs[i].ki_pid; - pse.age = 0; pse.num_proc = 1; pse.num_lwp = procs[i].ki_numthreads; @@ -1850,6 +1920,9 @@ static int ps_read(void) { pse.io_syscr = -1; pse.io_syscw = -1; + /* file descriptor count not implemented */ + pse.num_fd = 0; + /* context switch counters not implemented */ pse.cswitch_vol = -1; pse.cswitch_invol = -1; @@ -1911,12 +1984,12 @@ static int ps_read(void) { struct kinfo_proc *proc_ptr = NULL; int count; /* returns number of processes */ - procstat_entry_t pse; + process_entry_t pse; ps_list_reset(); /* Open the kvm interface, get a descriptor */ - kd = kvm_open(NULL, NULL, NULL, 0, errbuf); + kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf); if (kd == NULL) { ERROR("processes plugin: Cannot open kvm interface: %s", errbuf); return (0); @@ -1963,7 +2036,6 @@ static int ps_read(void) { memset(&pse, 0, sizeof(pse)); pse.id = procs[i].p_pid; - pse.age = 0; pse.num_proc = 1; pse.num_lwp = 1; /* XXX: accumulate p_tid values for a single p_pid ? */ @@ -1987,6 +2059,9 @@ static int ps_read(void) { pse.io_syscr = -1; pse.io_syscw = -1; + /* file descriptor count not implemented */ + pse.num_fd = 0; + /* context switch counters not implemented */ pse.cswitch_vol = -1; pse.cswitch_invol = -1; @@ -2045,7 +2120,7 @@ static int ps_read(void) { pid_t pindex = 0; int nprocs; - procstat_entry_t pse; + process_entry_t pse; ps_list_reset(); while ((nprocs = getprocs64(procentry, sizeof(struct procentry64), @@ -2085,8 +2160,9 @@ static int ps_read(void) { } } + memset(&pse, 0, sizeof(pse)); + pse.id = procentry[i].pi_pid; - pse.age = 0; pse.num_lwp = procentry[i].pi_thcount; pse.num_proc = 1; @@ -2136,7 +2212,7 @@ static int ps_read(void) { pse.vmem_size = procentry[i].pi_tsize + procentry[i].pi_dvm * pagesize; pse.vmem_rss = (procentry[i].pi_drss + procentry[i].pi_trss) * pagesize; - /* Not supported */ + /* Not supported/implemented */ pse.vmem_data = 0; pse.vmem_code = 0; pse.stack_size = 0; @@ -2146,6 +2222,8 @@ static int ps_read(void) { pse.io_syscr = -1; pse.io_syscw = -1; + pse.num_fd = 0; + pse.cswitch_vol = -1; pse.cswitch_invol = -1; @@ -2198,8 +2276,7 @@ static int ps_read(void) { while ((ent = readdir(proc)) != NULL) { long pid; - struct procstat ps; - procstat_entry_t pse; + process_entry_t pse; char *endptr; if (!isdigit((int)ent->d_name[0])) @@ -2209,38 +2286,15 @@ static int ps_read(void) { if (*endptr != 0) /* value didn't completely parse as a number */ continue; - status = ps_read_process(pid, &ps, &state); + memset(&pse, 0, sizeof(pse)); + pse.id = pid; + + status = ps_read_process(pid, &pse, &state); if (status != 0) { DEBUG("ps_read_process failed: %i", status); continue; } - memset(&pse, 0, sizeof(pse)); - pse.id = pid; - pse.age = 0; - - pse.num_proc = ps.num_proc; - pse.num_lwp = ps.num_lwp; - pse.vmem_size = ps.vmem_size; - pse.vmem_rss = ps.vmem_rss; - pse.vmem_data = ps.vmem_data; - pse.vmem_code = ps.vmem_code; - pse.stack_size = ps.stack_size; - - pse.vmem_minflt_counter = ps.vmem_minflt_counter; - pse.vmem_majflt_counter = ps.vmem_majflt_counter; - - pse.cpu_user_counter = ps.cpu_user_counter; - pse.cpu_system_counter = ps.cpu_system_counter; - - pse.io_rchar = ps.io_rchar; - pse.io_wchar = ps.io_wchar; - pse.io_syscr = ps.io_syscr; - pse.io_syscw = ps.io_syscw; - - pse.cswitch_vol = -1; - pse.cswitch_invol = -1; - switch (state) { case 'R': running++; @@ -2268,8 +2322,8 @@ static int ps_read(void) { break; } - ps_list_add(ps.name, ps_get_cmdline(pid, ps.name, cmdline, sizeof(cmdline)), - &pse); + ps_list_add(pse.name, + ps_get_cmdline(pid, pse.name, cmdline, sizeof(cmdline)), &pse); } /* while(readdir) */ closedir(proc); diff --git a/src/protocols.c b/src/protocols.c index 64735e60..12fbf45f 100644 --- a/src/protocols.c +++ b/src/protocols.c @@ -213,5 +213,3 @@ void module_register(void) { config_keys_num); plugin_register_read("protocols", protocols_read); } /* void module_register */ - -/* vim: set sw=2 sts=2 et : */ diff --git a/src/redis.c b/src/redis.c index 7875c7ea..ea888ca6 100644 --- a/src/redis.c +++ b/src/redis.c @@ -451,5 +451,3 @@ void module_register(void) /* {{{ */ * X elements */ } /* }}} */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/routeros.c b/src/routeros.c index 07493c75..5c978dcc 100644 --- a/src/routeros.c +++ b/src/routeros.c @@ -409,5 +409,3 @@ static int cr_config(oconfig_item_t *ci) { void module_register(void) { plugin_register_complex_config("routeros", cr_config); } /* void module_register */ - -/* vim: set sw=2 noet fdm=marker : */ diff --git a/src/rrdcached.c b/src/rrdcached.c index 6eb67d4f..5cf17c1e 100644 --- a/src/rrdcached.c +++ b/src/rrdcached.c @@ -529,7 +529,3 @@ void module_register(void) { plugin_register_init("rrdcached", rc_init); plugin_register_shutdown("rrdcached", rc_shutdown); } /* void module_register */ - -/* - * vim: set sw=2 sts=2 et : - */ diff --git a/src/snmp.c b/src/snmp.c index 3bfec47d..ff75edbe 100644 --- a/src/snmp.c +++ b/src/snmp.c @@ -1695,7 +1695,3 @@ void module_register(void) { plugin_register_init("snmp", csnmp_init); plugin_register_shutdown("snmp", csnmp_shutdown); } /* void module_register */ - -/* - * vim: shiftwidth=2 softtabstop=2 tabstop=8 fdm=marker - */ diff --git a/src/statsd.c b/src/statsd.c index 47e01d80..aa4e35c5 100644 --- a/src/statsd.c +++ b/src/statsd.c @@ -914,5 +914,3 @@ void module_register(void) { plugin_register_read("statsd", statsd_read); plugin_register_shutdown("statsd", statsd_shutdown); } - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/swap.c b/src/swap.c index cbe1ab11..19eed46a 100644 --- a/src/swap.c +++ b/src/swap.c @@ -738,5 +738,3 @@ void module_register(void) { plugin_register_init("swap", swap_init); plugin_register_read("swap", swap_read); } /* void module_register */ - -/* vim: set fdm=marker : */ diff --git a/src/table.c b/src/table.c index 3e8feada..578e019e 100644 --- a/src/table.c +++ b/src/table.c @@ -520,5 +520,3 @@ void module_register(void) { plugin_register_complex_config("table", tbl_config); plugin_register_init("table", tbl_init); } /* module_register */ - -/* vim: set sw=4 ts=4 tw=78 noexpandtab : */ diff --git a/src/tail.c b/src/tail.c index bb4eb30b..466dbffe 100644 --- a/src/tail.c +++ b/src/tail.c @@ -337,5 +337,3 @@ void module_register(void) { plugin_register_init("tail", ctail_init); plugin_register_shutdown("tail", ctail_shutdown); } /* void module_register */ - -/* vim: set sw=2 sts=2 ts=8 : */ diff --git a/src/tail_csv.c b/src/tail_csv.c index b1a3292d..425c101e 100644 --- a/src/tail_csv.c +++ b/src/tail_csv.c @@ -551,5 +551,3 @@ void module_register(void) { plugin_register_init("tail_csv", tcsv_init); plugin_register_shutdown("tail_csv", tcsv_shutdown); } - -/* vim: set sw=4 sts=4 et : */ diff --git a/src/target_notification.c b/src/target_notification.c index dc93b98b..7c82c794 100644 --- a/src/target_notification.c +++ b/src/target_notification.c @@ -260,5 +260,3 @@ void module_register(void) { tproc.invoke = tn_invoke; fc_register_target("notification", tproc); } /* module_register */ - -/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ diff --git a/src/target_replace.c b/src/target_replace.c index b43a025b..2bdb3b80 100644 --- a/src/target_replace.c +++ b/src/target_replace.c @@ -561,5 +561,3 @@ void module_register(void) { tproc.invoke = tr_invoke; fc_register_target("replace", tproc); } /* module_register */ - -/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ diff --git a/src/target_scale.c b/src/target_scale.c index 347d6272..4cce8dd1 100644 --- a/src/target_scale.c +++ b/src/target_scale.c @@ -457,5 +457,3 @@ void module_register(void) { tproc.invoke = ts_invoke; fc_register_target("scale", tproc); } /* module_register */ - -/* vim: set sw=2 ts=2 tw=78 fdm=marker : */ diff --git a/src/target_set.c b/src/target_set.c index a40273c0..e9dbc1d0 100644 --- a/src/target_set.c +++ b/src/target_set.c @@ -420,5 +420,3 @@ void module_register(void) { tproc.invoke = ts_invoke; fc_register_target("set", tproc); } /* module_register */ - -/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ diff --git a/src/target_v5upgrade.c b/src/target_v5upgrade.c index 54e37e16..27bca399 100644 --- a/src/target_v5upgrade.c +++ b/src/target_v5upgrade.c @@ -451,5 +451,3 @@ void module_register(void) { tproc.invoke = v5_invoke; fc_register_target("v5upgrade", tproc); } /* module_register */ - -/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ diff --git a/src/tcpconns.c b/src/tcpconns.c index f949d34e..08838fbe 100644 --- a/src/tcpconns.c +++ b/src/tcpconns.c @@ -62,11 +62,15 @@ #include "common.h" #include "plugin.h" -#if defined(__OpenBSD__) || defined(__NetBSD__) +#if defined(__OpenBSD__) +#define HAVE_KVM_GETFILES 1 +#endif + +#if defined(__NetBSD__) #undef HAVE_SYSCTLBYNAME /* force HAVE_LIBKVM_NLIST path */ #endif -#if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME && !HAVE_LIBKVM_NLIST && !KERNEL_AIX +#if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME && !HAVE_KVM_GETFILES && !HAVE_LIBKVM_NLIST && !KERNEL_AIX #error "No applicable input method." #endif @@ -105,15 +109,27 @@ #include /* #endif HAVE_SYSCTLBYNAME */ -/* This is for OpenBSD and NetBSD. */ +#elif HAVE_KVM_GETFILES +#include +#include +#define _KERNEL /* for DTYPE_SOCKET */ +#include +#undef _KERNEL + +#include + +#include +/* #endif HAVE_KVM_GETFILES */ + +/* This is for NetBSD. */ #elif HAVE_LIBKVM_NLIST #include #include #include #include +#include #include #include -#include #include #include #include @@ -169,6 +185,19 @@ static const char *tcp_state[] = {"CLOSED", "LISTEN", "SYN_SENT", #define TCP_STATE_MAX 10 /* #endif HAVE_SYSCTLBYNAME */ +#elif HAVE_KVM_GETFILES +static const char *tcp_state[] = {"CLOSED", "LISTEN", "SYN_SENT", + "SYN_RECV", "ESTABLISHED", "CLOSE_WAIT", + "FIN_WAIT1", "CLOSING", "LAST_ACK", + "FIN_WAIT2", "TIME_WAIT"}; + +#define TCP_STATE_LISTEN 1 +#define TCP_STATE_MIN 0 +#define TCP_STATE_MAX 10 + +static kvm_t *kvmd; +/* #endif HAVE_KVM_GETFILES */ + #elif HAVE_LIBKVM_NLIST static const char *tcp_state[] = {"CLOSED", "LISTEN", "SYN_SENT", "SYN_RECV", "ESTABLISHED", "CLOSE_WAIT", @@ -775,6 +804,49 @@ static int conn_read(void) { } /* int conn_read */ /* #endif HAVE_SYSCTLBYNAME */ +#elif HAVE_KVM_GETFILES + +static int conn_init(void) { + char buf[_POSIX2_LINE_MAX]; + + kvmd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, buf); + if (kvmd == NULL) { + ERROR("tcpconns plugin: kvm_openfiles failed: %s", buf); + return (-1); + } + + return (0); +} /* int conn_init */ + +static int conn_read(void) { + struct kinfo_file *kf; + int i, fcnt; + + conn_reset_port_entry(); + + kf = kvm_getfiles(kvmd, KERN_FILE_BYFILE, DTYPE_SOCKET, + sizeof(*kf), &fcnt); + if (kf == NULL) { + ERROR("tcpconns plugin: kvm_getfiles failed."); + return (-1); + } + + for (i = 0; i < fcnt; i++) { + if (kf[i].so_protocol != IPPROTO_TCP) + continue; + if (kf[i].inp_fport == 0) + continue; + conn_handle_ports(ntohs(kf[i].inp_lport), ntohs(kf[i].inp_fport), + kf[i].t_state); + } + + conn_submit_all(); + + return (0); +} +/* int conn_read */ +/* #endif HAVE_KVM_GETFILES */ + #elif HAVE_LIBKVM_NLIST static int kread(u_long addr, void *buf, int size) { int status; @@ -958,7 +1030,3 @@ void module_register(void) { #endif plugin_register_read("tcpconns", conn_read); } /* void module_register */ - -/* - * vim: set shiftwidth=2 softtabstop=2 tabstop=8 fdm=marker : - */ diff --git a/src/teamspeak2.c b/src/teamspeak2.c index 960d6464..a959cddc 100644 --- a/src/teamspeak2.c +++ b/src/teamspeak2.c @@ -728,5 +728,3 @@ void module_register(void) { plugin_register_read("teamspeak2", tss2_read); plugin_register_shutdown("teamspeak2", tss2_shutdown); } /* void module_register */ - -/* vim: set sw=4 ts=4 : */ diff --git a/src/ted.c b/src/ted.c index cccb3dbb..fbfd95db 100644 --- a/src/ted.c +++ b/src/ted.c @@ -39,8 +39,7 @@ #include "common.h" #include "plugin.h" -#if HAVE_TERMIOS_H && HAVE_SYS_IOCTL_H && HAVE_MATH_H -#include +#if HAVE_TERMIOS_H && HAVE_SYS_IOCTL_H #include #include #else @@ -300,5 +299,3 @@ void module_register(void) { plugin_register_read("ted", ted_read); plugin_register_shutdown("ted", ted_shutdown); } /* void module_register */ - -/* vim: set sw=4 et : */ diff --git a/src/threshold.c b/src/threshold.c index 743db28d..a4a999f5 100644 --- a/src/threshold.c +++ b/src/threshold.c @@ -834,5 +834,3 @@ static int ut_config(oconfig_item_t *ci) { /* {{{ */ void module_register(void) { plugin_register_complex_config("threshold", ut_config); } - -/* vim: set sw=2 ts=8 sts=2 tw=78 et fdm=marker : */ diff --git a/src/tokyotyrant.c b/src/tokyotyrant.c index cb366d38..09ee25d7 100644 --- a/src/tokyotyrant.c +++ b/src/tokyotyrant.c @@ -150,5 +150,3 @@ void module_register(void) { plugin_register_read("tokyotyrant", tt_read); plugin_register_shutdown("tokyotyrant", tt_shutdown); } - -/* vim: set sw=8 ts=8 tw=78 : */ diff --git a/src/types.db b/src/types.db index 68551875..0a5413bb 100644 --- a/src/types.db +++ b/src/types.db @@ -37,6 +37,7 @@ contextswitch value:DERIVE:0:U count value:GAUGE:0:U counter value:COUNTER:U:U cpu value:DERIVE:0:U +cpu_affinity value:GAUGE:0:1 cpufreq value:GAUGE:0:U current value:GAUGE:U:U current_connections value:GAUGE:0:U @@ -47,6 +48,7 @@ df used:GAUGE:0:1125899906842623, free:GAUGE:0:112589990684 df_complex value:GAUGE:0:U df_inodes value:GAUGE:0:U dilution_of_precision value:GAUGE:0:U +disk_error value:GAUGE:0:U disk_io_time io_time:DERIVE:0:U, weighted_io_time:DERIVE:0:U disk_latency read:GAUGE:0:U, write:GAUGE:0:U disk_merged read:DERIVE:0:U, write:DERIVE:0:U @@ -70,6 +72,7 @@ dns_response value:DERIVE:0:U dns_transfer value:DERIVE:0:U dns_update value:DERIVE:0:U dns_zops value:DERIVE:0:U +domain_state state:GAUGE:0:U, reason:GAUGE:0:U drbd_resource value:DERIVE:0:U duration seconds:GAUGE:0:U email_check value:GAUGE:0:U @@ -119,6 +122,7 @@ ipc value:GAUGE:0:U ipt_bytes value:DERIVE:0:U ipt_packets value:DERIVE:0:U irq value:DERIVE:0:U +job_stats value:DERIVE:0:U latency value:GAUGE:0:U links value:GAUGE:0:U load shortterm:GAUGE:0:5000, midterm:GAUGE:0:5000, longterm:GAUGE:0:5000 @@ -168,6 +172,7 @@ pending_operations value:GAUGE:0:U percent value:GAUGE:0:100.1 percent_bytes value:GAUGE:0:100.1 percent_inodes value:GAUGE:0:100.1 +perf value:DERIVE:0:U pf_counters value:DERIVE:0:U pf_limits value:DERIVE:0:U pf_source value:DERIVE:0:U diff --git a/src/unixsock.c b/src/unixsock.c index f61360ef..b08c89f1 100644 --- a/src/unixsock.c +++ b/src/unixsock.c @@ -429,5 +429,3 @@ void module_register(void) { plugin_register_init("unixsock", us_init); plugin_register_shutdown("unixsock", us_shutdown); } /* void module_register (void) */ - -/* vim: set sw=4 ts=4 sts=4 tw=78 : */ diff --git a/src/utils_cmd_flush.c b/src/utils_cmd_flush.c index a8de21a6..25a55122 100644 --- a/src/utils_cmd_flush.c +++ b/src/utils_cmd_flush.c @@ -136,23 +136,21 @@ cmd_status_t cmd_handle_flush(FILE *fh, char *buffer) { for (size_t j = 0; (j == 0) || (j < cmd.cmd.flush.identifiers_num); j++) { char *identifier = NULL; - char buffer[1024]; - int status; + char buf[1024]; if (cmd.cmd.flush.identifiers_num != 0) { identifier_t *id = cmd.cmd.flush.identifiers + j; - if (format_name(buffer, sizeof(buffer), id->host, id->plugin, + if (format_name(buf, sizeof(buf), id->host, id->plugin, id->plugin_instance, id->type, id->type_instance) != 0) { error++; continue; } - identifier = buffer; + identifier = buf; } - status = plugin_flush(plugin, DOUBLE_TO_CDTIME_T(cmd.cmd.flush.timeout), - identifier); - if (status == 0) + if (plugin_flush(plugin, DOUBLE_TO_CDTIME_T(cmd.cmd.flush.timeout), + identifier) == 0) success++; else error++; @@ -177,5 +175,3 @@ void cmd_destroy_flush(cmd_flush_t *flush) { sfree(flush->identifiers); flush->identifiers_num = 0; } /* void cmd_destroy_flush */ - -/* vim: set sw=4 ts=4 tw=78 noexpandtab : */ diff --git a/src/utils_cmd_flush.h b/src/utils_cmd_flush.h index d9b4e1b2..129aa85e 100644 --- a/src/utils_cmd_flush.h +++ b/src/utils_cmd_flush.h @@ -40,5 +40,3 @@ cmd_status_t cmd_handle_flush(FILE *fh, char *buffer); void cmd_destroy_flush(cmd_flush_t *flush); #endif /* UTILS_CMD_FLUSH_H */ - -/* vim: set sw=4 ts=4 tw=78 noexpandtab : */ diff --git a/src/utils_cmd_getthreshold.c b/src/utils_cmd_getthreshold.c index 926375d6..063548b7 100644 --- a/src/utils_cmd_getthreshold.c +++ b/src/utils_cmd_getthreshold.c @@ -181,5 +181,3 @@ int handle_getthreshold(FILE *fh, char *buffer) { return (0); } /* int handle_getthreshold */ - -/* vim: set sw=2 sts=2 ts=8 et : */ diff --git a/src/utils_cmd_getthreshold.h b/src/utils_cmd_getthreshold.h index dd4e5cf8..78700ee2 100644 --- a/src/utils_cmd_getthreshold.h +++ b/src/utils_cmd_getthreshold.h @@ -32,5 +32,3 @@ int handle_getthreshold(FILE *fh, char *buffer); #endif /* UTILS_CMD_GETTHRESHOLD_H */ - -/* vim: set sw=2 sts=2 ts=8 : */ diff --git a/src/utils_cmd_getval.c b/src/utils_cmd_getval.c index c23650b3..e5f17b63 100644 --- a/src/utils_cmd_getval.c +++ b/src/utils_cmd_getval.c @@ -164,5 +164,3 @@ void cmd_destroy_getval(cmd_getval_t *getval) { sfree(getval->raw_identifier); } /* void cmd_destroy_getval */ - -/* vim: set sw=2 sts=2 ts=8 : */ diff --git a/src/utils_cmd_getval.h b/src/utils_cmd_getval.h index 8d488b31..5c03fa4c 100644 --- a/src/utils_cmd_getval.h +++ b/src/utils_cmd_getval.h @@ -41,5 +41,3 @@ cmd_status_t cmd_handle_getval(FILE *fh, char *buffer); void cmd_destroy_getval(cmd_getval_t *getval); #endif /* UTILS_CMD_GETVAL_H */ - -/* vim: set sw=2 sts=2 ts=8 : */ diff --git a/src/utils_cmd_listval.c b/src/utils_cmd_listval.c index f8638893..4e603a2f 100644 --- a/src/utils_cmd_listval.c +++ b/src/utils_cmd_listval.c @@ -108,5 +108,3 @@ cmd_status_t cmd_handle_listval(FILE *fh, char *buffer) { void cmd_destroy_listval(cmd_listval_t *listval __attribute__((unused))) { /* nothing to do */ } /* void cmd_destroy_listval */ - -/* vim: set sw=2 sts=2 ts=8 : */ diff --git a/src/utils_cmd_listval.h b/src/utils_cmd_listval.h index 8a4e8c8b..6abdeee3 100644 --- a/src/utils_cmd_listval.h +++ b/src/utils_cmd_listval.h @@ -41,5 +41,3 @@ cmd_status_t cmd_handle_listval(FILE *fh, char *buffer); void cmd_destroy_listval(cmd_listval_t *listval); #endif /* UTILS_CMD_LISTVAL_H */ - -/* vim: set sw=2 sts=2 ts=8 : */ diff --git a/src/utils_cmd_putnotif.c b/src/utils_cmd_putnotif.c index 0edfbb86..8f687fd8 100644 --- a/src/utils_cmd_putnotif.c +++ b/src/utils_cmd_putnotif.c @@ -180,5 +180,3 @@ int handle_putnotif(FILE *fh, char *buffer) { return (0); } /* int handle_putnotif */ - -/* vim: set shiftwidth=2 softtabstop=2 tabstop=8 : */ diff --git a/src/utils_cmd_putnotif.h b/src/utils_cmd_putnotif.h index af0b93e0..7ad0f1a5 100644 --- a/src/utils_cmd_putnotif.h +++ b/src/utils_cmd_putnotif.h @@ -31,6 +31,4 @@ int handle_putnotif(FILE *fh, char *buffer); -/* vim: set shiftwidth=2 softtabstop=2 tabstop=8 : */ - #endif /* UTILS_CMD_PUTNOTIF_H */ diff --git a/src/utils_cmds.c b/src/utils_cmds.c index 3ea7c9d0..31a9a6fb 100644 --- a/src/utils_cmds.c +++ b/src/utils_cmds.c @@ -309,5 +309,3 @@ void cmd_error_fh(void *ud, cmd_status_t status, const char *format, fflush(fh); } /* void cmd_error_fh */ - -/* vim: set sw=4 ts=4 tw=78 noexpandtab : */ diff --git a/src/utils_db_query.c b/src/utils_db_query.c index 9a582272..c8030296 100644 --- a/src/utils_db_query.c +++ b/src/utils_db_query.c @@ -1059,5 +1059,3 @@ void udb_query_delete_preparation_area( free(q_area); } /* }}} void udb_query_delete_preparation_area */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/utils_db_query.h b/src/utils_db_query.h index 8f069185..4d6129a1 100644 --- a/src/utils_db_query.h +++ b/src/utils_db_query.h @@ -83,4 +83,3 @@ udb_query_allocate_preparation_area(udb_query_t *q); void udb_query_delete_preparation_area(udb_query_preparation_area_t *q_area); #endif /* UTILS_DB_QUERY_H */ -/* vim: set sw=2 sts=2 et : */ diff --git a/src/utils_dns.c b/src/utils_dns.c index a4a5784b..2bda965f 100644 --- a/src/utils_dns.c +++ b/src/utils_dns.c @@ -1169,6 +1169,3 @@ main(int argc, char *argv[]) return 0; } /* static int main(int argc, char *argv[]) */ #endif -/* - * vim:shiftwidth=4:tabstop=8:softtabstop=4 - */ diff --git a/src/utils_dpdk.c b/src/utils_dpdk.c new file mode 100644 index 00000000..e3c73793 --- /dev/null +++ b/src/utils_dpdk.c @@ -0,0 +1,872 @@ +/* + * collectd - src/utils_dpdk.c + * MIT License + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Maryam Tahhan + * Harry van Haaren + * Taras Chornyi + * Serhiy Pshyk + * Krzysztof Matczak + */ + +#include "collectd.h" + +#include +#include +#include + +#include +#include +#include + +#include "common.h" +#include "utils_dpdk.h" + +#define DPDK_DEFAULT_RTE_CONFIG "/var/run/.rte_config" +#define DPDK_EAL_ARGC 5 +#define DPDK_MAX_BUFFER_SIZE (4096 * 4) +#define DPDK_CDM_DEFAULT_TIMEOUT 10000 + +enum DPDK_HELPER_STATUS { + DPDK_HELPER_NOT_INITIALIZED = 0, + DPDK_HELPER_INITIALIZING, + DPDK_HELPER_WAITING_ON_PRIMARY, + DPDK_HELPER_INITIALIZING_EAL, + DPDK_HELPER_ALIVE_SENDING_EVENTS, + DPDK_HELPER_GRACEFUL_QUIT, +}; + +#define DPDK_HELPER_TRACE(_name) \ + DEBUG("%s:%s:%d pid=%ld", _name, __FUNCTION__, __LINE__, (long)getpid()) + +struct dpdk_helper_ctx_s { + + dpdk_eal_config_t eal_config; + int eal_initialized; + + size_t shm_size; + const char *shm_name; + + sem_t sema_cmd_start; + sem_t sema_cmd_complete; + cdtime_t cmd_wait_time; + + pid_t pid; + int pipes[2]; + int status; + + int cmd; + int cmd_result; + + char priv_data[]; +}; + +static int dpdk_shm_init(const char *name, size_t size, void **map); +static void dpdk_shm_cleanup(const char *name, size_t size, void *map); + +static int dpdk_helper_spawn(dpdk_helper_ctx_t *phc); +static int dpdk_helper_worker(dpdk_helper_ctx_t *phc); +static int dpdk_helper_eal_init(dpdk_helper_ctx_t *phc); +static int dpdk_helper_cmd_wait(dpdk_helper_ctx_t *phc, pid_t ppid); +static int dpdk_helper_exit_command(dpdk_helper_ctx_t *phc, + enum DPDK_HELPER_STATUS status); +static int dpdk_helper_exit(dpdk_helper_ctx_t *phc, + enum DPDK_HELPER_STATUS status); +static int dpdk_helper_status_check(dpdk_helper_ctx_t *phc); +static void dpdk_helper_config_default(dpdk_helper_ctx_t *phc); +static const char *dpdk_helper_status_str(enum DPDK_HELPER_STATUS status); + +static void dpdk_helper_config_default(dpdk_helper_ctx_t *phc) { + if (phc == NULL) + return; + + DPDK_HELPER_TRACE(phc->shm_name); + + ssnprintf(phc->eal_config.coremask, DATA_MAX_NAME_LEN, "%s", "0xf"); + ssnprintf(phc->eal_config.memory_channels, DATA_MAX_NAME_LEN, "%s", "1"); + ssnprintf(phc->eal_config.process_type, DATA_MAX_NAME_LEN, "%s", "secondary"); + ssnprintf(phc->eal_config.file_prefix, DATA_MAX_NAME_LEN, "%s", + DPDK_DEFAULT_RTE_CONFIG); +} + +int dpdk_helper_eal_config_set(dpdk_helper_ctx_t *phc, dpdk_eal_config_t *ec) { + if (phc == NULL) { + ERROR("Invalid argument (phc)"); + return -EINVAL; + } + + DPDK_HELPER_TRACE(phc->shm_name); + + if (ec == NULL) { + ERROR("Invalid argument (ec)"); + return -EINVAL; + } + + memcpy(&phc->eal_config, ec, sizeof(phc->eal_config)); + + return 0; +} + +int dpdk_helper_eal_config_get(dpdk_helper_ctx_t *phc, dpdk_eal_config_t *ec) { + if (phc == NULL) { + ERROR("Invalid argument (phc)"); + return -EINVAL; + } + + DPDK_HELPER_TRACE(phc->shm_name); + + if (ec == NULL) { + ERROR("Invalid argument (ec)"); + return -EINVAL; + } + + memcpy(ec, &phc->eal_config, sizeof(*ec)); + + return 0; +} + +int dpdk_helper_eal_config_parse(dpdk_helper_ctx_t *phc, oconfig_item_t *ci) { + DPDK_HELPER_TRACE(phc->shm_name); + + if (phc == NULL) { + ERROR("Invalid argument (phc)"); + return -EINVAL; + } + + if (ci == NULL) { + ERROR("Invalid argument (ci)"); + return -EINVAL; + } + + int status = 0; + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + if (strcasecmp("Coremask", child->key) == 0) { + status = cf_util_get_string_buffer(child, phc->eal_config.coremask, + sizeof(phc->eal_config.coremask)); + DEBUG("dpdk_common: EAL:Coremask %s", phc->eal_config.coremask); + } else if (strcasecmp("MemoryChannels", child->key) == 0) { + status = + cf_util_get_string_buffer(child, phc->eal_config.memory_channels, + sizeof(phc->eal_config.memory_channels)); + DEBUG("dpdk_common: EAL:Memory Channels %s", + phc->eal_config.memory_channels); + } else if (strcasecmp("SocketMemory", child->key) == 0) { + status = cf_util_get_string_buffer(child, phc->eal_config.socket_memory, + sizeof(phc->eal_config.socket_memory)); + DEBUG("dpdk_common: EAL:Socket memory %s", phc->eal_config.socket_memory); + } else if (strcasecmp("ProcessType", child->key) == 0) { + status = cf_util_get_string_buffer(child, phc->eal_config.process_type, + sizeof(phc->eal_config.process_type)); + DEBUG("dpdk_common: EAL:Process type %s", phc->eal_config.process_type); + } else if ((strcasecmp("FilePrefix", child->key) == 0) && + (child->values[0].type == OCONFIG_TYPE_STRING)) { + ssnprintf(phc->eal_config.file_prefix, DATA_MAX_NAME_LEN, + "/var/run/.%s_config", child->values[0].value.string); + DEBUG("dpdk_common: EAL:File prefix %s", phc->eal_config.file_prefix); + } else { + ERROR("dpdk_common: Invalid '%s' configuration option", child->key); + status = -EINVAL; + } + + if (status != 0) { + ERROR("dpdk_common: Parsing EAL configuration failed"); + break; + } + } + + return status; +} + +static int dpdk_shm_init(const char *name, size_t size, void **map) { + DPDK_HELPER_TRACE(name); + + char errbuf[ERR_BUF_SIZE]; + + int fd = shm_open(name, O_CREAT | O_TRUNC | O_RDWR, 0666); + if (fd < 0) { + WARNING("dpdk_shm_init: Failed to open %s as SHM:%s", name, + sstrerror(errno, errbuf, sizeof(errbuf))); + *map = NULL; + return -1; + } + + int ret = ftruncate(fd, size); + if (ret != 0) { + WARNING("dpdk_shm_init: Failed to resize SHM:%s", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(fd); + *map = NULL; + dpdk_shm_cleanup(name, size, NULL); + return -1; + } + + *map = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (*map == MAP_FAILED) { + WARNING("dpdk_shm_init:Failed to mmap SHM:%s", + sstrerror(errno, errbuf, sizeof(errbuf))); + close(fd); + *map = NULL; + dpdk_shm_cleanup(name, size, NULL); + return -1; + } + /* File descriptor no longer needed for shared memory operations */ + close(fd); + memset(*map, 0, size); + + return 0; +} + +static void dpdk_shm_cleanup(const char *name, size_t size, void *map) { + DPDK_HELPER_TRACE(name); + char errbuf[ERR_BUF_SIZE]; + + if (map != NULL) { + if (munmap(map, size)) + ERROR("munmap failure %s", sstrerror(errno, errbuf, sizeof(errbuf))); + } + + if (shm_unlink(name)) + ERROR("shm_unlink failure %s", sstrerror(errno, errbuf, sizeof(errbuf))); +} + +void *dpdk_helper_priv_get(dpdk_helper_ctx_t *phc) { + if (phc) + return phc->priv_data; + + return NULL; +} + +int dpdk_helper_data_size_get(dpdk_helper_ctx_t *phc) { + if (phc == NULL) { + DPDK_CHILD_LOG("Invalid argument(phc)\n"); + return -EINVAL; + } + + return (phc->shm_size - sizeof(dpdk_helper_ctx_t)); +} + +int dpdk_helper_init(const char *name, size_t data_size, + dpdk_helper_ctx_t **pphc) { + dpdk_helper_ctx_t *phc = NULL; + size_t shm_size = sizeof(dpdk_helper_ctx_t) + data_size; + char errbuf[ERR_BUF_SIZE]; + + if (pphc == NULL) { + ERROR("%s:Invalid argument(pphc)", __FUNCTION__); + return -EINVAL; + } + + if (name == NULL) { + ERROR("%s:Invalid argument(name)", __FUNCTION__); + return -EINVAL; + } + + DPDK_HELPER_TRACE(name); + + /* Allocate dpdk_helper_ctx_t and + * initialize a POSIX SHared Memory (SHM) object. + */ + int err = dpdk_shm_init(name, shm_size, (void **)&phc); + if (err != 0) { + return -errno; + } + + err = sem_init(&phc->sema_cmd_start, 1, 0); + if (err != 0) { + ERROR("sema_cmd_start semaphore init failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + int errno_m = errno; + dpdk_shm_cleanup(name, shm_size, (void *)phc); + return -errno_m; + } + + err = sem_init(&phc->sema_cmd_complete, 1, 0); + if (err != 0) { + ERROR("sema_cmd_complete semaphore init failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + sem_destroy(&phc->sema_cmd_start); + int errno_m = errno; + dpdk_shm_cleanup(name, shm_size, (void *)phc); + return -errno_m; + } + + phc->shm_size = shm_size; + phc->shm_name = name; + + dpdk_helper_config_default(phc); + + *pphc = phc; + + return 0; +} + +int dpdk_helper_shutdown(dpdk_helper_ctx_t *phc) { + if (phc == NULL) { + ERROR("%s:Invalid argument(phc)", __FUNCTION__); + return -EINVAL; + } + + DPDK_HELPER_TRACE(phc->shm_name); + + close(phc->pipes[1]); + + if (phc->status != DPDK_HELPER_NOT_INITIALIZED) { + dpdk_helper_exit_command(phc, DPDK_HELPER_GRACEFUL_QUIT); + } + + sem_destroy(&phc->sema_cmd_start); + sem_destroy(&phc->sema_cmd_complete); + dpdk_shm_cleanup(phc->shm_name, phc->shm_size, (void *)phc); + + return 0; +} + +static int dpdk_helper_spawn(dpdk_helper_ctx_t *phc) { + char errbuf[ERR_BUF_SIZE]; + if (phc == NULL) { + ERROR("Invalid argument(phc)"); + return -EINVAL; + } + + DPDK_HELPER_TRACE(phc->shm_name); + + phc->eal_initialized = 0; + phc->cmd_wait_time = MS_TO_CDTIME_T(DPDK_CDM_DEFAULT_TIMEOUT); + + /* + * Create a pipe for helper stdout back to collectd. This is necessary for + * logging EAL failures, as rte_eal_init() calls rte_panic(). + */ + if (phc->pipes[1]) { + DEBUG("dpdk_helper_spawn: collectd closing helper pipe %d", phc->pipes[1]); + } else { + DEBUG("dpdk_helper_spawn: collectd helper pipe %d, not closing", + phc->pipes[1]); + } + + if (pipe(phc->pipes) != 0) { + DEBUG("dpdk_helper_spawn: Could not create helper pipe: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return -1; + } + + int pipe0_flags = fcntl(phc->pipes[0], F_GETFL, 0); + int pipe1_flags = fcntl(phc->pipes[1], F_GETFL, 0); + if (pipe0_flags == -1 || pipe1_flags == -1) { + WARNING("dpdk_helper_spawn: error setting up pipe flags: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + } + int pipe0_err = fcntl(phc->pipes[0], F_SETFL, pipe1_flags | O_NONBLOCK); + int pipe1_err = fcntl(phc->pipes[1], F_SETFL, pipe0_flags | O_NONBLOCK); + if (pipe0_err == -1 || pipe1_err == -1) { + WARNING("dpdk_helper_spawn: error setting up pipes: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + } + + pid_t pid = fork(); + if (pid > 0) { + phc->pid = pid; + close(phc->pipes[1]); + DEBUG("%s:dpdk_helper_spawn: helper pid %lu", phc->shm_name, + (long)phc->pid); + } else if (pid == 0) { + /* Replace stdout with a pipe to collectd. */ + close(phc->pipes[0]); + close(STDOUT_FILENO); + dup2(phc->pipes[1], STDOUT_FILENO); + DPDK_CHILD_TRACE(phc->shm_name); + dpdk_helper_worker(phc); + exit(0); + } else { + ERROR("dpdk_helper_start: Failed to fork helper process: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return -1; + } + + return 0; +} + +static int dpdk_helper_exit(dpdk_helper_ctx_t *phc, + enum DPDK_HELPER_STATUS status) { + DPDK_CHILD_LOG("%s:%s:%d %s\n", phc->shm_name, __FUNCTION__, __LINE__, + dpdk_helper_status_str(status)); + + close(phc->pipes[1]); + + phc->status = status; + + exit(0); + + return 0; +} + +static int dpdk_helper_exit_command(dpdk_helper_ctx_t *phc, + enum DPDK_HELPER_STATUS status) { + char errbuf[ERR_BUF_SIZE]; + DPDK_HELPER_TRACE(phc->shm_name); + + close(phc->pipes[1]); + + if (phc->status == DPDK_HELPER_ALIVE_SENDING_EVENTS) { + phc->status = status; + DEBUG("%s:%s:%d %s", phc->shm_name, __FUNCTION__, __LINE__, + dpdk_helper_status_str(status)); + + int ret = dpdk_helper_command(phc, DPDK_CMD_QUIT, NULL, 0); + if (ret != 0) { + DEBUG("%s:%s:%d kill helper (pid=%lu)", phc->shm_name, __FUNCTION__, + __LINE__, (long)phc->pid); + + int err = kill(phc->pid, SIGKILL); + if (err) { + ERROR("%s error sending kill to helper: %s", __FUNCTION__, + sstrerror(errno, errbuf, sizeof(errbuf))); + } + } + } else { + + DEBUG("%s:%s:%d kill helper (pid=%lu)", phc->shm_name, __FUNCTION__, + __LINE__, (long)phc->pid); + + int err = kill(phc->pid, SIGKILL); + if (err) { + ERROR("%s error sending kill to helper: %s", __FUNCTION__, + sstrerror(errno, errbuf, sizeof(errbuf))); + } + } + + return 0; +} + +static int dpdk_helper_eal_init(dpdk_helper_ctx_t *phc) { + phc->status = DPDK_HELPER_INITIALIZING_EAL; + DPDK_CHILD_LOG("%s:%s:%d DPDK_HELPER_INITIALIZING_EAL (start)\n", + phc->shm_name, __FUNCTION__, __LINE__); + + char *argp[DPDK_EAL_ARGC * 2 + 1]; + int argc = 0; + + /* EAL config must be initialized */ + assert(phc->eal_config.coremask[0] != 0); + assert(phc->eal_config.memory_channels[0] != 0); + assert(phc->eal_config.process_type[0] != 0); + assert(phc->eal_config.file_prefix[0] != 0); + + argp[argc++] = "collectd-dpdk"; + + argp[argc++] = "-c"; + argp[argc++] = phc->eal_config.coremask; + + argp[argc++] = "-n"; + argp[argc++] = phc->eal_config.memory_channels; + + if (strcasecmp(phc->eal_config.socket_memory, "") != 0) { + argp[argc++] = "--socket-mem"; + argp[argc++] = phc->eal_config.socket_memory; + } + + if (strcasecmp(phc->eal_config.file_prefix, DPDK_DEFAULT_RTE_CONFIG) != 0) { + argp[argc++] = "--file-prefix"; + argp[argc++] = phc->eal_config.file_prefix; + } + + argp[argc++] = "--proc-type"; + argp[argc++] = phc->eal_config.process_type; + + assert(argc <= (DPDK_EAL_ARGC * 2 + 1)); + + int ret = rte_eal_init(argc, argp); + + if (ret < 0) { + + phc->eal_initialized = 0; + + DPDK_CHILD_LOG("dpdk_helper_eal_init: ERROR initializing EAL ret=%d\n", + ret); + + printf("dpdk_helper_eal_init: EAL arguments: "); + for (int i = 0; i < argc; i++) { + printf("%s ", argp[i]); + } + printf("\n"); + + return ret; + } + + phc->eal_initialized = 1; + + DPDK_CHILD_LOG("%s:%s:%d DPDK_HELPER_INITIALIZING_EAL (done)\n", + phc->shm_name, __FUNCTION__, __LINE__); + + return 0; +} + +static int dpdk_helper_cmd_wait(dpdk_helper_ctx_t *phc, pid_t ppid) { + DPDK_CHILD_TRACE(phc->shm_name); + + struct timespec ts; + cdtime_t now = cdtime(); + cdtime_t cmd_wait_time = MS_TO_CDTIME_T(1500) + phc->cmd_wait_time * 2; + ts = CDTIME_T_TO_TIMESPEC(now + cmd_wait_time); + + int ret = sem_timedwait(&phc->sema_cmd_start, &ts); + DPDK_CHILD_LOG("%s:%s:%d pid=%lu got sema_cmd_start (ret=%d, errno=%d)\n", + phc->shm_name, __FUNCTION__, __LINE__, (long)getpid(), ret, + errno); + + if (phc->cmd == DPDK_CMD_QUIT) { + DPDK_CHILD_LOG("%s:%s:%d pid=%lu exiting\n", phc->shm_name, __FUNCTION__, + __LINE__, (long)getpid()); + exit(0); + } else if (ret == -1 && errno == ETIMEDOUT) { + if (phc->status == DPDK_HELPER_ALIVE_SENDING_EVENTS) { + DPDK_CHILD_LOG("%s:dpdk_helper_cmd_wait: sem timedwait()" + " timeout, did collectd terminate?\n", + phc->shm_name); + dpdk_helper_exit(phc, DPDK_HELPER_GRACEFUL_QUIT); + } + } +#if COLLECT_DEBUG + int val = 0; + if (sem_getvalue(&phc->sema_cmd_start, &val) == 0) + DPDK_CHILD_LOG("%s:%s:%d pid=%lu wait sema_cmd_start (value=%d)\n", + phc->shm_name, __FUNCTION__, __LINE__, (long)getpid(), val); +#endif + + /* Parent PID change means collectd died so quit the helper process. */ + if (ppid != getppid()) { + DPDK_CHILD_LOG("dpdk_helper_cmd_wait: parent PID changed, quitting.\n"); + dpdk_helper_exit(phc, DPDK_HELPER_GRACEFUL_QUIT); + } + + /* Checking for DPDK primary process. */ + if (!rte_eal_primary_proc_alive(phc->eal_config.file_prefix)) { + if (phc->eal_initialized) { + DPDK_CHILD_LOG( + "%s:dpdk_helper_cmd_wait: no primary alive but EAL initialized:" + " quitting.\n", + phc->shm_name); + dpdk_helper_exit(phc, DPDK_HELPER_NOT_INITIALIZED); + } + + phc->status = DPDK_HELPER_WAITING_ON_PRIMARY; + DPDK_CHILD_LOG("%s:%s:%d DPDK_HELPER_WAITING_ON_PRIMARY\n", phc->shm_name, + __FUNCTION__, __LINE__); + + return -1; + } + + if (!phc->eal_initialized) { + int ret = dpdk_helper_eal_init(phc); + if (ret != 0) { + DPDK_CHILD_LOG("Error initializing EAL\n"); + dpdk_helper_exit(phc, DPDK_HELPER_NOT_INITIALIZED); + } + phc->status = DPDK_HELPER_ALIVE_SENDING_EVENTS; + DPDK_CHILD_LOG("%s:%s:%d DPDK_HELPER_ALIVE_SENDING_EVENTS\n", phc->shm_name, + __FUNCTION__, __LINE__); + return -1; + } + + return 0; +} + +static int dpdk_helper_worker(dpdk_helper_ctx_t *phc) { + DPDK_CHILD_TRACE(phc->shm_name); + + pid_t ppid = getppid(); + + while (1) { + if (dpdk_helper_cmd_wait(phc, ppid) == 0) { + DPDK_CHILD_LOG("%s:%s:%d DPDK command handle (cmd=%d, pid=%lu)\n", + phc->shm_name, __FUNCTION__, __LINE__, phc->cmd, + (long)getpid()); + phc->cmd_result = dpdk_helper_command_handler(phc, phc->cmd); + } else { + phc->cmd_result = -1; + } + + /* now kick collectd to get results */ + int err = sem_post(&phc->sema_cmd_complete); + DPDK_CHILD_LOG("%s:%s:%d post sema_cmd_complete (pid=%lu)\n", phc->shm_name, + __FUNCTION__, __LINE__, (long)getpid()); + if (err) { + char errbuf[ERR_BUF_SIZE]; + DPDK_CHILD_LOG("dpdk_helper_worker: error posting sema_cmd_complete " + "semaphore (%s)\n", + sstrerror(errno, errbuf, sizeof(errbuf))); + } + +#if COLLECT_DEBUG + int val = 0; + if (sem_getvalue(&phc->sema_cmd_complete, &val) == 0) + DPDK_CHILD_LOG("%s:%s:%d pid=%lu sema_cmd_complete (value=%d)\n", + phc->shm_name, __FUNCTION__, __LINE__, (long)getpid(), + val); +#endif + + } /* while(1) */ + + return 0; +} + +static const char *dpdk_helper_status_str(enum DPDK_HELPER_STATUS status) { + switch (status) { + case DPDK_HELPER_ALIVE_SENDING_EVENTS: + return "DPDK_HELPER_ALIVE_SENDING_EVENTS"; + case DPDK_HELPER_WAITING_ON_PRIMARY: + return "DPDK_HELPER_WAITING_ON_PRIMARY"; + case DPDK_HELPER_INITIALIZING: + return "DPDK_HELPER_INITIALIZING"; + case DPDK_HELPER_INITIALIZING_EAL: + return "DPDK_HELPER_INITIALIZING_EAL"; + case DPDK_HELPER_GRACEFUL_QUIT: + return "DPDK_HELPER_GRACEFUL_QUIT"; + case DPDK_HELPER_NOT_INITIALIZED: + return "DPDK_HELPER_NOT_INITIALIZED"; + default: + return "UNKNOWN"; + } +} + +static int dpdk_helper_status_check(dpdk_helper_ctx_t *phc) { + DEBUG("%s:%s:%d pid=%u %s", phc->shm_name, __FUNCTION__, __LINE__, getpid(), + dpdk_helper_status_str(phc->status)); + char errbuf[ERR_BUF_SIZE]; + + if (phc->status == DPDK_HELPER_GRACEFUL_QUIT) { + return 0; + } else if (phc->status == DPDK_HELPER_NOT_INITIALIZED) { + phc->status = DPDK_HELPER_INITIALIZING; + DEBUG("%s:%s:%d DPDK_HELPER_INITIALIZING", phc->shm_name, __FUNCTION__, + __LINE__); + int err = dpdk_helper_spawn(phc); + if (err) { + ERROR("dpdkstat: error spawning helper %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + } + return -1; + } + + pid_t ws = waitpid(phc->pid, NULL, WNOHANG); + if (ws != 0) { + phc->status = DPDK_HELPER_INITIALIZING; + DEBUG("%s:%s:%d DPDK_HELPER_INITIALIZING", phc->shm_name, __FUNCTION__, + __LINE__); + int err = dpdk_helper_spawn(phc); + if (err) { + ERROR("dpdkstat: error spawning helper %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + } + return -1; + } + + if (phc->status == DPDK_HELPER_INITIALIZING_EAL) { + return -1; + } + + return 0; +} + +static void dpdk_helper_check_pipe(dpdk_helper_ctx_t *phc) { + char buf[DPDK_MAX_BUFFER_SIZE]; + char out[DPDK_MAX_BUFFER_SIZE]; + + /* non blocking check on helper logging pipe */ + struct pollfd fds = { + .fd = phc->pipes[0], .events = POLLIN, + }; + int data_avail = poll(&fds, 1, 0); + if (data_avail < 0) { + if (errno != EINTR || errno != EAGAIN) { + char errbuf[ERR_BUF_SIZE]; + ERROR("%s: poll(2) failed: %s", phc->shm_name, + sstrerror(errno, errbuf, sizeof(errbuf))); + } + } + while (data_avail) { + int nbytes = read(phc->pipes[0], buf, sizeof(buf)); + if (nbytes <= 0) + break; + sstrncpy(out, buf, nbytes); + DEBUG("%s: helper process:\n%s", phc->shm_name, out); + } +} + +int dpdk_helper_command(dpdk_helper_ctx_t *phc, enum DPDK_CMD cmd, int *result, + cdtime_t cmd_wait_time) { + if (phc == NULL) { + ERROR("Invalid argument(phc)"); + return -EINVAL; + } + + DEBUG("%s:%s:%d pid=%lu, cmd=%d", phc->shm_name, __FUNCTION__, __LINE__, + (long)getpid(), cmd); + + phc->cmd_wait_time = cmd_wait_time; + + int ret = dpdk_helper_status_check(phc); + + dpdk_helper_check_pipe(phc); + + if (ret != 0) { + return ret; + } + + DEBUG("%s: DPDK command execute (cmd=%d)", phc->shm_name, cmd); + + phc->cmd_result = 0; + phc->cmd = cmd; + + /* kick helper to process command */ + int err = sem_post(&phc->sema_cmd_start); + if (err) { + char errbuf[ERR_BUF_SIZE]; + ERROR("dpdk_helper_worker: error posting sema_cmd_start semaphore (%s)", + sstrerror(errno, errbuf, sizeof(errbuf))); + } + +#if COLLECT_DEBUG + int val = 0; + if (sem_getvalue(&phc->sema_cmd_start, &val) == 0) + DEBUG("%s:dpdk_helper_command: post sema_cmd_start (value=%d)", + phc->shm_name, val); +#endif + + if (phc->cmd != DPDK_CMD_QUIT) { + + /* wait for helper to complete processing */ + struct timespec ts; + cdtime_t now = cdtime(); + + if (phc->status != DPDK_HELPER_ALIVE_SENDING_EVENTS) { + cmd_wait_time = MS_TO_CDTIME_T(DPDK_CDM_DEFAULT_TIMEOUT); + } + + ts = CDTIME_T_TO_TIMESPEC(now + cmd_wait_time); + ret = sem_timedwait(&phc->sema_cmd_complete, &ts); + if (ret == -1 && errno == ETIMEDOUT) { + DPDK_HELPER_TRACE(phc->shm_name); + DEBUG("%s:sema_cmd_start: timeout in collectd thread: is a DPDK Primary " + "running?", + phc->shm_name); + return -ETIMEDOUT; + } + +#if COLLECT_DEBUG + val = 0; + if (sem_getvalue(&phc->sema_cmd_complete, &val) == 0) + DEBUG("%s:dpdk_helper_command: wait sema_cmd_complete (value=%d)", + phc->shm_name, val); +#endif + + if (result) { + *result = phc->cmd_result; + } + } + + dpdk_helper_check_pipe(phc); + + DEBUG("%s: DPDK command complete (cmd=%d, result=%d)", phc->shm_name, + phc->cmd, phc->cmd_result); + + return 0; +} + +uint64_t strtoull_safe(const char *str, int *err) { + uint64_t val = 0; + char *endptr; + int res = 0; + + val = strtoull(str, &endptr, 16); + if (*endptr) { + ERROR("%s Failed to parse the value %s, endptr=%c", __FUNCTION__, str, + *endptr); + res = -EINVAL; + } + if (err != NULL) + *err = res; + return val; +} + +uint128_t str_to_uint128(const char *str, int len) { + uint128_t lcore_mask; + int err = 0; + + memset(&lcore_mask, 0, sizeof(lcore_mask)); + + if (len <= 2 || strncmp(str, "0x", 2) != 0) { + ERROR("%s Value %s should be represened in hexadecimal format", + __FUNCTION__, str); + return lcore_mask; + } + /* If str is <= 64 bit long ('0x' + 16 chars = 18 chars) then + * conversion is straightforward. Otherwise str is splitted into 64b long + * blocks */ + if (len <= 18) { + lcore_mask.low = strtoull_safe(str, &err); + if (err) + return lcore_mask; + } else { + char low_str[DATA_MAX_NAME_LEN]; + char high_str[DATA_MAX_NAME_LEN]; + + memset(high_str, 0, sizeof(high_str)); + memset(low_str, 0, sizeof(low_str)); + + strncpy(high_str, str, len - 16); + strncpy(low_str, str + len - 16, 16); + + lcore_mask.low = strtoull_safe(low_str, &err); + if (err) + return lcore_mask; + + lcore_mask.high = strtoull_safe(high_str, &err); + if (err) { + lcore_mask.low = 0; + return lcore_mask; + } + } + return lcore_mask; +} + +uint8_t dpdk_helper_eth_dev_count() { + uint8_t ports = rte_eth_dev_count(); + if (ports == 0) { + ERROR( + "%s:%d: No DPDK ports available. Check bound devices to DPDK driver.\n", + __FUNCTION__, __LINE__); + return ports; + } + + if (ports > RTE_MAX_ETHPORTS) { + ERROR("%s:%d: Number of DPDK ports (%u) is greater than " + "RTE_MAX_ETHPORTS=%d. Ignoring extra ports\n", + __FUNCTION__, __LINE__, ports, RTE_MAX_ETHPORTS); + ports = RTE_MAX_ETHPORTS; + } + + return ports; +} diff --git a/src/utils_dpdk.h b/src/utils_dpdk.h new file mode 100644 index 00000000..f97a6b51 --- /dev/null +++ b/src/utils_dpdk.h @@ -0,0 +1,89 @@ +/* + * collectd - src/utils_dpdk.h + * MIT License + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Maryam Tahhan + * Harry van Haaren + * Taras Chornyi + * Serhiy Pshyk + * Krzysztof Matczak + */ + +#ifndef UTILS_DPDK_H +#define UTILS_DPDK_H + +#include + +#define ERR_BUF_SIZE 1024 + +enum DPDK_CMD { + DPDK_CMD_NONE = 0, + DPDK_CMD_QUIT, + DPDK_CMD_INIT, + DPDK_CMD_GET_STATS, + DPDK_CMD_GET_EVENTS, + __DPDK_CMD_LAST, +}; + +struct dpdk_eal_config_s { + char coremask[DATA_MAX_NAME_LEN]; + char memory_channels[DATA_MAX_NAME_LEN]; + char socket_memory[DATA_MAX_NAME_LEN]; + char process_type[DATA_MAX_NAME_LEN]; + char file_prefix[DATA_MAX_NAME_LEN]; +}; +typedef struct dpdk_eal_config_s dpdk_eal_config_t; + +struct uint128_s { + u_int64_t high; + u_int64_t low; +}; +typedef struct uint128_s uint128_t; + +typedef struct dpdk_helper_ctx_s dpdk_helper_ctx_t; + +int dpdk_helper_init(const char *name, size_t data_size, + dpdk_helper_ctx_t **pphc); +int dpdk_helper_shutdown(dpdk_helper_ctx_t *phc); +int dpdk_helper_eal_config_parse(dpdk_helper_ctx_t *phc, oconfig_item_t *ci); +int dpdk_helper_eal_config_set(dpdk_helper_ctx_t *phc, dpdk_eal_config_t *ec); +int dpdk_helper_eal_config_get(dpdk_helper_ctx_t *phc, dpdk_eal_config_t *ec); +int dpdk_helper_command(dpdk_helper_ctx_t *phc, enum DPDK_CMD cmd, int *result, + cdtime_t cmd_wait_time); +void *dpdk_helper_priv_get(dpdk_helper_ctx_t *phc); +int dpdk_helper_data_size_get(dpdk_helper_ctx_t *phc); +uint8_t dpdk_helper_eth_dev_count(); + +/* forward declaration of handler function that is called by helper from + * child process. not implemented in helper. must be provided by client. */ +int dpdk_helper_command_handler(dpdk_helper_ctx_t *phc, enum DPDK_CMD cmd); + +uint128_t str_to_uint128(const char *str, int len); + +/* logging functions that should be used in child process */ +#define DPDK_CHILD_LOG(...) fprintf(stdout, __VA_ARGS__) +#define DPDK_CHILD_TRACE(_name) \ + fprintf(stdout, "%s:%s:%d pid=%u\n", _name, __FUNCTION__, __LINE__, getpid()) + +#endif /* UTILS_DPDK_H */ diff --git a/src/utils_fbhash.c b/src/utils_fbhash.c index ecc56740..f94e2e5b 100644 --- a/src/utils_fbhash.c +++ b/src/utils_fbhash.c @@ -255,5 +255,3 @@ char *fbh_get(fbhash_t *h, const char *key) /* {{{ */ return (value_copy); } /* }}} char *fbh_get */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/utils_fbhash.h b/src/utils_fbhash.h index 79e9c00f..fcd6e925 100644 --- a/src/utils_fbhash.h +++ b/src/utils_fbhash.h @@ -48,5 +48,3 @@ void fbh_destroy(fbhash_t *h); char *fbh_get(fbhash_t *h, const char *key); #endif /* UTILS_FBHASH_H */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/utils_format_graphite.c b/src/utils_format_graphite.c index 4f509f4a..0436340d 100644 --- a/src/utils_format_graphite.c +++ b/src/utils_format_graphite.c @@ -237,5 +237,3 @@ int format_graphite(char *buffer, size_t buffer_size, data_set_t const *ds, sfree(rates); return (status); } /* int format_graphite */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/utils_format_graphite_test.c b/src/utils_format_graphite_test.c index 415a283e..a82142fa 100644 --- a/src/utils_format_graphite_test.c +++ b/src/utils_format_graphite_test.c @@ -49,12 +49,12 @@ static data_set_t ds_double = { DEF_TEST(metric_name) { struct { - char *plugin_instance; - char *type_instance; - char *prefix; - char *suffix; + const char *plugin_instance; + const char *type_instance; + const char *prefix; + const char *suffix; unsigned int flags; - char *want_name; + const char *want_name; } cases[] = { { .want_name = "example@com.test.single", @@ -157,8 +157,35 @@ DEF_TEST(metric_name) { return 0; } +DEF_TEST(null_termination) { + value_list_t vl = { + .values = &(value_t){.gauge = 1337}, + .values_len = 1, + .time = TIME_T_TO_CDTIME_T_STATIC(1480063672), + .interval = TIME_T_TO_CDTIME_T_STATIC(10), + .host = "example.com", + .plugin = "test", + .type = "single", + }; + char const *want = "example_com.test.single 1337 1480063672\r\n"; + + char buffer[128]; + for (size_t i = 0; i < sizeof(buffer); i++) + buffer[i] = (char)i; + + EXPECT_EQ_INT(0, format_graphite(buffer, sizeof(buffer), &ds_single, &vl, + NULL, NULL, '_', 0)); + EXPECT_EQ_STR(want, buffer); + EXPECT_EQ_INT(0, buffer[strlen(want)]); + for (size_t i = strlen(want) + 1; i < sizeof(buffer); i++) + EXPECT_EQ_INT((int)i, (int)buffer[i]); + + return 0; +} + int main(void) { RUN_TEST(metric_name); + RUN_TEST(null_termination); END_TEST; } diff --git a/src/utils_format_json.c b/src/utils_format_json.c index 0a95a86d..1a0e151d 100644 --- a/src/utils_format_json.c +++ b/src/utils_format_json.c @@ -685,5 +685,3 @@ int format_json_notification(char *buffer, size_t buffer_size, /* {{{ */ return ENOTSUP; } /* }}} int format_json_notification */ #endif - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/utils_format_kairosdb.c b/src/utils_format_kairosdb.c index 4c25d188..2a14f0ed 100644 --- a/src/utils_format_kairosdb.c +++ b/src/utils_format_kairosdb.c @@ -181,7 +181,9 @@ static int values_to_kairosdb(char *buffer, size_t buffer_size, /* {{{ */ static int value_list_to_kairosdb(char *buffer, size_t buffer_size, /* {{{ */ const data_set_t *ds, const value_list_t *vl, - int store_rates) { + int store_rates, + char const *const *http_attrs, + size_t http_attrs_num) { char temp[512]; size_t offset = 0; int status; @@ -231,6 +233,11 @@ static int value_list_to_kairosdb(char *buffer, size_t buffer_size, /* {{{ */ BUFFER_ADD(", \"tags\":\{"); BUFFER_ADD("\"host\": \"%s\"", vl->host); + for (size_t j = 0; j < http_attrs_num; j += 2) { + BUFFER_ADD(", \"%s\":", http_attrs[j]); + BUFFER_ADD(" \"%s\"", http_attrs[j + 1]); + } + if (strlen(vl->plugin_instance)) BUFFER_ADD_KEYVAL("plugin_instance", vl->plugin_instance); BUFFER_ADD_KEYVAL("type", vl->type); @@ -252,11 +259,13 @@ static int value_list_to_kairosdb(char *buffer, size_t buffer_size, /* {{{ */ static int format_kairosdb_value_list_nocheck( char *buffer, /* {{{ */ size_t *ret_buffer_fill, size_t *ret_buffer_free, const data_set_t *ds, - const value_list_t *vl, int store_rates, size_t temp_size) { + const value_list_t *vl, int store_rates, size_t temp_size, + char const *const *http_attrs, size_t http_attrs_num) { char temp[temp_size]; int status; - status = value_list_to_kairosdb(temp, sizeof(temp), ds, vl, store_rates); + status = value_list_to_kairosdb(temp, sizeof(temp), ds, vl, store_rates, + http_attrs, http_attrs_num); if (status != 0) return (status); temp_size = strlen(temp); @@ -324,7 +333,8 @@ int format_kairosdb_finalize(char *buffer, /* {{{ */ int format_kairosdb_value_list(char *buffer, /* {{{ */ size_t *ret_buffer_fill, size_t *ret_buffer_free, const data_set_t *ds, const value_list_t *vl, - int store_rates) { + int store_rates, char const *const *http_attrs, + size_t http_attrs_num) { if ((buffer == NULL) || (ret_buffer_fill == NULL) || (ret_buffer_free == NULL) || (ds == NULL) || (vl == NULL)) return (-EINVAL); @@ -334,7 +344,7 @@ int format_kairosdb_value_list(char *buffer, /* {{{ */ return (format_kairosdb_value_list_nocheck( buffer, ret_buffer_fill, ret_buffer_free, ds, vl, store_rates, - (*ret_buffer_free) - 2)); + (*ret_buffer_free) - 2, http_attrs, http_attrs_num)); } /* }}} int format_kairosdb_value_list */ /* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/utils_format_kairosdb.h b/src/utils_format_kairosdb.h index 9174318d..b6aa39d4 100644 --- a/src/utils_format_kairosdb.h +++ b/src/utils_format_kairosdb.h @@ -39,7 +39,9 @@ int format_kairosdb_initialize(char *buffer, size_t *ret_buffer_fill, size_t *ret_buffer_free); int format_kairosdb_value_list(char *buffer, size_t *ret_buffer_fill, size_t *ret_buffer_free, const data_set_t *ds, - const value_list_t *vl, int store_rates); + const value_list_t *vl, int store_rates, + char const *const *http_attrs, + size_t http_attrs_num); int format_kairosdb_finalize(char *buffer, size_t *ret_buffer_fill, size_t *ret_buffer_free); diff --git a/src/utils_ignorelist.c b/src/utils_ignorelist.c new file mode 100644 index 00000000..9cf6aa1e --- /dev/null +++ b/src/utils_ignorelist.c @@ -0,0 +1,309 @@ +/** + * collectd - src/utils_ignorelist.c + * Copyright (C) 2006 Lubos Stanek + * Copyright (C) 2008 Florian Forster + * + * This program is free software; you can redistribute it and/ + * or modify it under the terms of the GNU General Public Li- + * cence as published by the Free Software Foundation; either + * version 2 of the Licence, or any later version. + * + * This program is distributed in the hope that it will be use- + * ful, but WITHOUT ANY WARRANTY; without even the implied war- + * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public Licence for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: + * Lubos Stanek + * Florian Forster + **/ +/** + * ignorelist handles plugin's list of configured collectable + * entries with global ignore action + **/ +/** + * Usage: + * + * Define plugin's global pointer variable of type ignorelist_t: + * ignorelist_t *myconfig_ignore; + * If you know the state of the global ignore (IgnoreSelected), + * allocate the variable with: + * myconfig_ignore = ignorelist_create (YourKnownIgnore); + * If you do not know the state of the global ignore, + * initialize the global variable and set the ignore flag later: + * myconfig_ignore = ignorelist_init (); + * Append single entries in your cf_register'ed callback function: + * ignorelist_add (myconfig_ignore, newentry); + * When you hit the IgnoreSelected config option, + * offer it to the list: + * ignorelist_ignore (myconfig_ignore, instantly_got_value_of_ignore); + * That is all for the ignorelist initialization. + * Later during read and write (plugin's registered functions) get + * the information whether this entry would be collected or not: + * if (ignorelist_match (myconfig_ignore, thisentry)) + * return; + **/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "common.h" +#include "plugin.h" +#include "utils_ignorelist.h" + +/* + * private prototypes + */ +struct ignorelist_item_s { +#if HAVE_REGEX_H + regex_t *rmatch; /* regular expression entry identification */ +#endif + char *smatch; /* string entry identification */ + struct ignorelist_item_s *next; +}; +typedef struct ignorelist_item_s ignorelist_item_t; + +struct ignorelist_s { + int ignore; /* ignore entries */ + ignorelist_item_t *head; /* pointer to the first entry */ +}; + +/* *** *** *** ********************************************* *** *** *** */ +/* *** *** *** *** *** *** private functions *** *** *** *** *** *** */ +/* *** *** *** ********************************************* *** *** *** */ + +static inline void ignorelist_append(ignorelist_t *il, + ignorelist_item_t *item) { + assert((il != NULL) && (item != NULL)); + + item->next = il->head; + il->head = item; +} + +#if HAVE_REGEX_H +static int ignorelist_append_regex(ignorelist_t *il, const char *re_str) { + regex_t *re; + ignorelist_item_t *entry; + int status; + + re = calloc(1, sizeof(*re)); + if (re == NULL) { + ERROR("ignorelist_append_regex: calloc failed."); + return (ENOMEM); + } + + status = regcomp(re, re_str, REG_EXTENDED); + if (status != 0) { + char errbuf[1024]; + (void)regerror(status, re, errbuf, sizeof(errbuf)); + ERROR("utils_ignorelist: regcomp failed: %s", errbuf); + ERROR("ignorelist_append_regex: Compiling regular expression \"%s\" " + "failed: %s", + re_str, errbuf); + sfree(re); + return (status); + } + + entry = calloc(1, sizeof(*entry)); + if (entry == NULL) { + ERROR("ignorelist_append_regex: calloc failed."); + regfree(re); + sfree(re); + return (ENOMEM); + } + entry->rmatch = re; + + ignorelist_append(il, entry); + return (0); +} /* int ignorelist_append_regex */ +#endif + +static int ignorelist_append_string(ignorelist_t *il, const char *entry) { + ignorelist_item_t *new; + + /* create new entry */ + if ((new = calloc(1, sizeof(*new))) == NULL) { + ERROR("cannot allocate new entry"); + return (1); + } + new->smatch = sstrdup(entry); + + /* append new entry */ + ignorelist_append(il, new); + + return (0); +} /* int ignorelist_append_string(ignorelist_t *il, const char *entry) */ + +#if HAVE_REGEX_H +/* + * check list for entry regex match + * return 1 if found + */ +static int ignorelist_match_regex(ignorelist_item_t *item, const char *entry) { + assert((item != NULL) && (item->rmatch != NULL) && (entry != NULL) && + (strlen(entry) > 0)); + + /* match regex */ + if (regexec(item->rmatch, entry, 0, NULL, 0) == 0) + return (1); + + return (0); +} /* int ignorelist_match_regex (ignorelist_item_t *item, const char *entry) */ +#endif + +/* + * check list for entry string match + * return 1 if found + */ +static int ignorelist_match_string(ignorelist_item_t *item, const char *entry) { + assert((item != NULL) && (item->smatch != NULL) && (entry != NULL) && + (strlen(entry) > 0)); + + if (strcmp(entry, item->smatch) == 0) + return (1); + + return (0); +} /* int ignorelist_match_string (ignorelist_item_t *item, const char *entry) */ + +/* *** *** *** ******************************************** *** *** *** */ +/* *** *** *** *** *** *** public functions *** *** *** *** *** *** */ +/* *** *** *** ******************************************** *** *** *** */ + +/* + * create the ignorelist_t with known ignore state + * return pointer to ignorelist_t + */ +ignorelist_t *ignorelist_create(int invert) { + ignorelist_t *il; + + il = calloc(1, sizeof(*il)); + if (il == NULL) + return NULL; + + /* + * ->ignore == 0 => collect + * ->ignore == 1 => ignore + */ + il->ignore = invert ? 0 : 1; + + return (il); +} /* ignorelist_t *ignorelist_create (int ignore) */ + +/* + * free memory used by ignorelist_t + */ +void ignorelist_free(ignorelist_t *il) { + ignorelist_item_t *this; + ignorelist_item_t *next; + + if (il == NULL) + return; + + for (this = il->head; this != NULL; this = next) { + next = this->next; +#if HAVE_REGEX_H + if (this->rmatch != NULL) { + regfree(this->rmatch); + sfree(this->rmatch); + this->rmatch = NULL; + } +#endif + if (this->smatch != NULL) { + sfree(this->smatch); + this->smatch = NULL; + } + sfree(this); + } + + sfree(il); +} /* void ignorelist_destroy (ignorelist_t *il) */ + +/* + * set ignore state of the ignorelist_t + */ +void ignorelist_set_invert(ignorelist_t *il, int invert) { + if (il == NULL) { + DEBUG("ignore call with ignorelist_t == NULL"); + return; + } + + il->ignore = invert ? 0 : 1; +} /* void ignorelist_set_invert (ignorelist_t *il, int ignore) */ + +/* + * append entry into ignorelist_t + * return 0 for success + */ +int ignorelist_add(ignorelist_t *il, const char *entry) { + size_t len; + + if (il == NULL) { + DEBUG("add called with ignorelist_t == NULL"); + return (1); + } + + len = strlen(entry); + + /* append nothing */ + if (len == 0) { + DEBUG("not appending: empty entry"); + return (1); + } + +#if HAVE_REGEX_H + /* regex string is enclosed in "/.../" */ + if ((len > 2) && (entry[0] == '/') && entry[len - 1] == '/') { + char *copy; + int status; + + /* skip leading slash */ + copy = strdup(entry + 1); + if (copy == NULL) + return ENOMEM; + + /* trim trailing slash */ + copy[strlen(copy) - 1] = 0; + + status = ignorelist_append_regex(il, copy); + sfree(copy); + return status; + } +#endif + + return ignorelist_append_string(il, entry); +} /* int ignorelist_add (ignorelist_t *il, const char *entry) */ + +/* + * check list for entry + * return 1 for ignored entry + */ +int ignorelist_match(ignorelist_t *il, const char *entry) { + /* if no entries, collect all */ + if ((il == NULL) || (il->head == NULL)) + return (0); + + if ((entry == NULL) || (strlen(entry) == 0)) + return (0); + + /* traverse list and check entries */ + for (ignorelist_item_t *traverse = il->head; traverse != NULL; + traverse = traverse->next) { +#if HAVE_REGEX_H + if (traverse->rmatch != NULL) { + if (ignorelist_match_regex(traverse, entry)) + return (il->ignore); + } else +#endif + { + if (ignorelist_match_string(traverse, entry)) + return (il->ignore); + } + } /* for traverse */ + + return (1 - il->ignore); +} /* int ignorelist_match (ignorelist_t *il, const char *entry) */ diff --git a/src/utils_ignorelist.h b/src/utils_ignorelist.h new file mode 100644 index 00000000..a7fa86d5 --- /dev/null +++ b/src/utils_ignorelist.h @@ -0,0 +1,69 @@ +/** + * collectd - src/utils_ignorelist.h + * Copyright (C) 2006 Lubos Stanek + * + * This program is free software; you can redistribute it and/ + * or modify it under the terms of the GNU General Public Li- + * cence as published by the Free Software Foundation; either + * version 2 of the Licence, or any later version. + * + * This program is distributed in the hope that it will be use- + * ful, but WITHOUT ANY WARRANTY; without even the implied war- + * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public Licence for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: + * Lubos Stanek + **/ +/** + * ignorelist handles plugin's list of configured collectable + * entries with global ignore action + **/ + +#ifndef UTILS_IGNORELIST_H +#define UTILS_IGNORELIST_H 1 + +#include "collectd.h" + +#if HAVE_REGEX_H +#include +#endif + +/* public prototypes */ + +struct ignorelist_s; +typedef struct ignorelist_s ignorelist_t; + +/* + * create the ignorelist_t with known ignore state + * return pointer to ignorelist_t + */ +ignorelist_t *ignorelist_create(int invert); + +/* + * free memory used by ignorelist_t + */ +void ignorelist_free(ignorelist_t *il); + +/* + * set ignore state of the ignorelist_t + */ +void ignorelist_set_invert(ignorelist_t *il, int invert); + +/* + * append entry to ignorelist_t + * returns zero on success, non-zero upon failure. + */ +int ignorelist_add(ignorelist_t *il, const char *entry); + +/* + * check list for entry + * return 1 for ignored entry + */ +int ignorelist_match(ignorelist_t *il, const char *entry); + +#endif /* UTILS_IGNORELIST_H */ diff --git a/src/utils_latency.c b/src/utils_latency.c index f0311e84..f30b265b 100644 --- a/src/utils_latency.c +++ b/src/utils_latency.c @@ -342,5 +342,3 @@ double latency_counter_get_rate(const latency_counter_t *lc, /* {{{ */ return sum / (CDTIME_T_TO_DOUBLE(now - lc->start_time)); } /* }}} double latency_counter_get_rate */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/utils_latency.h b/src/utils_latency.h index 85493e1a..9d878dab 100644 --- a/src/utils_latency.h +++ b/src/utils_latency.h @@ -61,5 +61,3 @@ cdtime_t latency_counter_get_percentile(latency_counter_t *lc, double percent); */ double latency_counter_get_rate(const latency_counter_t *lc, cdtime_t lower, cdtime_t upper, const cdtime_t now); - -/* vim: set sw=2 sts=2 et : */ diff --git a/src/utils_latency_test.c b/src/utils_latency_test.c index ef29d8bd..427a1592 100644 --- a/src/utils_latency_test.c +++ b/src/utils_latency_test.c @@ -232,5 +232,3 @@ int main(void) { END_TEST; } - -/* vim: set sw=2 sts=2 et : */ diff --git a/src/utils_lua.c b/src/utils_lua.c index dcb84afa..77101216 100644 --- a/src/utils_lua.c +++ b/src/utils_lua.c @@ -317,5 +317,3 @@ int luaC_pushvaluelist(lua_State *L, const data_set_t *ds, return (0); } /* }}} int luaC_pushvaluelist */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/utils_lua.h b/src/utils_lua.h index 8ff507c7..61d9070e 100644 --- a/src/utils_lua.h +++ b/src/utils_lua.h @@ -53,4 +53,3 @@ int luaC_pushvaluelist(lua_State *L, const data_set_t *ds, const value_list_t *vl); #endif /* UTILS_LUA_H */ -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/utils_match.c b/src/utils_match.c index 11b3f74f..e8add2d8 100644 --- a/src/utils_match.c +++ b/src/utils_match.c @@ -374,5 +374,3 @@ void *match_get_user_data(cu_match_t *obj) { return (NULL); return (obj->user_data); } /* void *match_get_user_data */ - -/* vim: set sw=2 sts=2 ts=8 : */ diff --git a/src/utils_match.h b/src/utils_match.h index 1383530c..1cff1eb7 100644 --- a/src/utils_match.h +++ b/src/utils_match.h @@ -177,5 +177,3 @@ int match_apply(cu_match_t *obj, const char *str); void *match_get_user_data(cu_match_t *obj); #endif /* UTILS_MATCH_H */ - -/* vim: set sw=2 sts=2 ts=8 : */ diff --git a/src/utils_mount_test.c b/src/utils_mount_test.c index 695038dd..76fc8d4a 100644 --- a/src/utils_mount_test.c +++ b/src/utils_mount_test.c @@ -109,5 +109,3 @@ int main(void) { END_TEST; } - -/* vim: set sw=2 sts=2 et : */ diff --git a/src/utils_ovs.c b/src/utils_ovs.c new file mode 100644 index 00000000..65e66795 --- /dev/null +++ b/src/utils_ovs.c @@ -0,0 +1,1378 @@ +/** + * 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 + **/ + +/* 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 +#endif +#if HAVE_ARPA_INET_H +#include +#endif +#if HAVE_POLL_H +#include +#endif +#if HAVE_SYS_UN_H +#include +#endif + +#include + +#define OVS_ERROR(fmt, ...) \ + do { \ + ERROR("ovs_utils: " fmt, ##__VA_ARGS__); \ + } while (0) +#define OVS_DEBUG(fmt, ...) \ + do { \ + DEBUG("%s:%d:%s(): " fmt, __FILE__, __LINE__, __FUNCTION__, \ + ##__VA_ARGS__); \ + } while (0) + +#define OVS_DB_POLL_TIMEOUT 1 /* poll receive timeout (sec) */ +#define OVS_DB_POLL_READ_BLOCK_SIZE 512 /* read block size (bytes) */ +#define OVS_DB_DEFAULT_DB_NAME "Open_vSwitch" + +#define OVS_DB_EVENT_TIMEOUT 5 /* event thread timeout (sec) */ +#define OVS_DB_EVENT_TERMINATE 1 +#define OVS_DB_EVENT_CONN_ESTABLISHED 2 +#define OVS_DB_EVENT_CONN_TERMINATED 3 + +#define OVS_DB_POLL_STATE_RUNNING 1 +#define OVS_DB_POLL_STATE_EXITING 2 + +#define OVS_DB_SEND_REQ_TIMEOUT 5 /* send request timeout (sec) */ + +#define OVS_YAJL_CALL(func, ...) \ + do { \ + yajl_gen_ret = yajl_gen_status_ok; \ + if ((yajl_gen_ret = func(__VA_ARGS__)) != yajl_gen_status_ok) \ + goto yajl_gen_failure; \ + } while (0) +#define OVS_YAJL_ERROR_BUFFER_SIZE 1024 +#define OVS_ERROR_BUFF_SIZE 512 +#define OVS_UID_STR_SIZE 17 /* 64-bit HEX string len + '\0' */ + +/* JSON reader internal data */ +struct ovs_json_reader_s { + char *buff_ptr; + size_t buff_size; + size_t buff_offset; + size_t json_offset; +}; +typedef struct ovs_json_reader_s ovs_json_reader_t; + +/* Result callback declaration */ +struct ovs_result_cb_s { + sem_t sync; + ovs_db_result_cb_t call; +}; +typedef struct ovs_result_cb_s ovs_result_cb_t; + +/* Table callback declaration */ +struct ovs_table_cb_s { + ovs_db_table_cb_t call; +}; +typedef struct ovs_table_cb_s ovs_table_cb_t; + +/* Callback declaration */ +struct ovs_callback_s { + uint64_t uid; + union { + ovs_result_cb_t result; + ovs_table_cb_t table; + }; + struct ovs_callback_s *next; + struct ovs_callback_s *prev; +}; +typedef struct ovs_callback_s ovs_callback_t; + +/* Event thread data declaration */ +struct ovs_event_thread_s { + pthread_t tid; + pthread_mutex_t mutex; + pthread_cond_t cond; + int value; +}; +typedef struct ovs_event_thread_s ovs_event_thread_t; + +/* Poll thread data declaration */ +struct ovs_poll_thread_s { + pthread_t tid; + pthread_mutex_t mutex; + int state; +}; +typedef struct ovs_poll_thread_s ovs_poll_thread_t; + +/* OVS DB internal data declaration */ +struct ovs_db_s { + ovs_poll_thread_t poll_thread; + ovs_event_thread_t event_thread; + pthread_mutex_t mutex; + ovs_callback_t *remote_cb; + ovs_db_callback_t cb; + char service[OVS_DB_ADDR_SERVICE_SIZE]; + char node[OVS_DB_ADDR_NODE_SIZE]; + char unix_path[OVS_DB_ADDR_NODE_SIZE]; + int sock; +}; + +/* Global variables */ +static uint64_t ovs_uid = 0; +static pthread_mutex_t ovs_uid_mutex = PTHREAD_MUTEX_INITIALIZER; + +/* Post an event to event thread. + * Possible events are: + * OVS_DB_EVENT_TERMINATE + * OVS_DB_EVENT_CONN_ESTABLISHED + * OVS_DB_EVENT_CONN_TERMINATED + */ +static void ovs_db_event_post(ovs_db_t *pdb, int event) { + pthread_mutex_lock(&pdb->event_thread.mutex); + pdb->event_thread.value = event; + pthread_mutex_unlock(&pdb->event_thread.mutex); + pthread_cond_signal(&pdb->event_thread.cond); +} + +/* Check if POLL thread is still running. Returns + * 1 if running otherwise 0 is returned */ +static _Bool ovs_db_poll_is_running(ovs_db_t *pdb) { + int state = 0; + pthread_mutex_lock(&pdb->poll_thread.mutex); + state = pdb->poll_thread.state; + pthread_mutex_unlock(&pdb->poll_thread.mutex); + return (state == OVS_DB_POLL_STATE_RUNNING); +} + +/* Generate unique identifier (UID). It is used by OVS DB API + * to set "id" field for any OVS DB JSON request. */ +static uint64_t ovs_uid_generate() { + uint64_t new_uid; + pthread_mutex_lock(&ovs_uid_mutex); + new_uid = ++ovs_uid; + pthread_mutex_unlock(&ovs_uid_mutex); + return new_uid; +} + +/* + * Callback API. These function are used to store + * registered callbacks in OVS DB API. + */ + +/* Add new callback into OVS DB object */ +static void ovs_db_callback_add(ovs_db_t *pdb, ovs_callback_t *new_cb) { + pthread_mutex_lock(&pdb->mutex); + if (pdb->remote_cb) + pdb->remote_cb->prev = new_cb; + new_cb->next = pdb->remote_cb; + new_cb->prev = NULL; + pdb->remote_cb = new_cb; + pthread_mutex_unlock(&pdb->mutex); +} + +/* Remove callback from OVS DB object */ +static void ovs_db_callback_remove(ovs_db_t *pdb, ovs_callback_t *del_cb) { + pthread_mutex_lock(&pdb->mutex); + ovs_callback_t *pre_cb = del_cb->prev; + ovs_callback_t *next_cb = del_cb->next; + + if (next_cb) + next_cb->prev = del_cb->prev; + + if (pre_cb) + pre_cb->next = del_cb->next; + else + pdb->remote_cb = del_cb->next; + + free(del_cb); + pthread_mutex_unlock(&pdb->mutex); +} + +/* Remove all callbacks form OVS DB object */ +static void ovs_db_callback_remove_all(ovs_db_t *pdb) { + pthread_mutex_lock(&pdb->mutex); + for (ovs_callback_t *del_cb = pdb->remote_cb; pdb->remote_cb; + del_cb = pdb->remote_cb) { + pdb->remote_cb = del_cb->next; + free(del_cb); + } + pdb->remote_cb = NULL; + pthread_mutex_unlock(&pdb->mutex); +} + +/* Get/find callback in OVS DB object by UID. Returns pointer + * to requested callback otherwise NULL is returned. + * + * IMPORTANT NOTE: + * The OVS DB mutex MUST be locked by the caller + * to make sure that returned callback is still valid. + */ +static ovs_callback_t *ovs_db_callback_get(ovs_db_t *pdb, uint64_t uid) { + for (ovs_callback_t *cb = pdb->remote_cb; cb != NULL; cb = cb->next) + if (cb->uid == uid) + return cb; + return NULL; +} + +/* Send all requested data to the socket. Returns 0 if + * ALL request data has been sent otherwise negative value + * is returned */ +static int ovs_db_data_send(const ovs_db_t *pdb, const char *data, size_t len) { + ssize_t nbytes = 0; + size_t rem = len; + size_t off = 0; + + while (rem > 0) { + if ((nbytes = send(pdb->sock, data + off, rem, 0)) <= 0) + return (-1); + rem -= (size_t)nbytes; + off += (size_t)nbytes; + } + return (0); +} + +/* + * YAJL (Yet Another JSON Library) helper functions + * Documentation (https://lloyd.github.io/yajl/) + */ + +/* Add null-terminated string into YAJL generator handle (JSON object). + * Similar function to yajl_gen_string() but takes null-terminated string + * instead of string and its length. + * + * jgen - YAJL generator handle allocated by yajl_gen_alloc() + * string - Null-terminated string + */ +static yajl_gen_status ovs_yajl_gen_tstring(yajl_gen hander, + const char *string) { + return yajl_gen_string(hander, (const unsigned char *)string, strlen(string)); +} + +/* Add YAJL value into YAJL generator handle (JSON object) + * + * jgen - YAJL generator handle allocated by yajl_gen_alloc() + * jval - YAJL value usually returned by yajl_tree_get() + */ +static yajl_gen_status ovs_yajl_gen_val(yajl_gen jgen, yajl_val jval) { + size_t array_len = 0; + yajl_val *jvalues = NULL; + yajl_val jobj_value = NULL; + const char *obj_key = NULL; + size_t obj_len = 0; + yajl_gen_status yajl_gen_ret = yajl_gen_status_ok; + + if (jval == NULL) + return yajl_gen_generation_complete; + + if (YAJL_IS_STRING(jval)) + OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, YAJL_GET_STRING(jval)); + else if (YAJL_IS_DOUBLE(jval)) + OVS_YAJL_CALL(yajl_gen_double, jgen, YAJL_GET_DOUBLE(jval)); + else if (YAJL_IS_INTEGER(jval)) + OVS_YAJL_CALL(yajl_gen_double, jgen, YAJL_GET_INTEGER(jval)); + else if (YAJL_IS_TRUE(jval)) + OVS_YAJL_CALL(yajl_gen_bool, jgen, 1); + else if (YAJL_IS_FALSE(jval)) + OVS_YAJL_CALL(yajl_gen_bool, jgen, 0); + else if (YAJL_IS_NULL(jval)) + OVS_YAJL_CALL(yajl_gen_null, jgen); + else if (YAJL_IS_ARRAY(jval)) { + /* create new array and add all elements into the array */ + array_len = YAJL_GET_ARRAY(jval)->len; + jvalues = YAJL_GET_ARRAY(jval)->values; + OVS_YAJL_CALL(yajl_gen_array_open, jgen); + for (size_t i = 0; i < array_len; i++) + OVS_YAJL_CALL(ovs_yajl_gen_val, jgen, jvalues[i]); + OVS_YAJL_CALL(yajl_gen_array_close, jgen); + } else if (YAJL_IS_OBJECT(jval)) { + /* create new object and add all elements into the object */ + OVS_YAJL_CALL(yajl_gen_map_open, jgen); + obj_len = YAJL_GET_OBJECT(jval)->len; + for (size_t i = 0; i < obj_len; i++) { + obj_key = YAJL_GET_OBJECT(jval)->keys[i]; + jobj_value = YAJL_GET_OBJECT(jval)->values[i]; + OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, obj_key); + OVS_YAJL_CALL(ovs_yajl_gen_val, jgen, jobj_value); + } + OVS_YAJL_CALL(yajl_gen_map_close, jgen); + } else { + OVS_ERROR("%s() unsupported value type %d (skip)", __FUNCTION__, + (int)(jval)->type); + goto yajl_gen_failure; + } + return yajl_gen_status_ok; + +yajl_gen_failure: + OVS_ERROR("%s() error to generate value", __FUNCTION__); + return yajl_gen_ret; +} + +/* OVS DB echo request handler. When OVS DB sends + * "echo" request to the client, client should generate + * "echo" replay with the same content received in the + * request */ +static int ovs_db_table_echo_cb(const ovs_db_t *pdb, yajl_val jnode) { + yajl_val jparams; + yajl_val jid; + yajl_gen jgen; + size_t resp_len = 0; + const char *resp = NULL; + const char *params_path[] = {"params", NULL}; + const char *id_path[] = {"id", NULL}; + yajl_gen_status yajl_gen_ret; + + if ((jgen = yajl_gen_alloc(NULL)) == NULL) + return (-1); + + /* check & get request attributes */ + if ((jparams = yajl_tree_get(jnode, params_path, yajl_t_array)) == NULL || + ((jid = yajl_tree_get(jnode, id_path, yajl_t_any)) == NULL)) { + OVS_ERROR("parse echo request failed"); + goto yajl_gen_failure; + } + + /* generate JSON echo response */ + OVS_YAJL_CALL(yajl_gen_map_open, jgen); + + OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "result"); + OVS_YAJL_CALL(ovs_yajl_gen_val, jgen, jparams); + + OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "error"); + OVS_YAJL_CALL(yajl_gen_null, jgen); + + OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "id"); + OVS_YAJL_CALL(ovs_yajl_gen_val, jgen, jid); + + OVS_YAJL_CALL(yajl_gen_map_close, jgen); + OVS_YAJL_CALL(yajl_gen_get_buf, jgen, (const unsigned char **)&resp, + &resp_len); + + /* send the response */ + OVS_DEBUG("response: %s", resp); + if (ovs_db_data_send(pdb, resp, resp_len) < 0) { + OVS_ERROR("send echo reply failed"); + goto yajl_gen_failure; + } + /* clean up and return success */ + yajl_gen_clear(jgen); + return (0); + +yajl_gen_failure: + /* release memory */ + yajl_gen_clear(jgen); + return (-1); +} + +/* Get OVS DB registered callback by YAJL val. The YAJL + * value should be YAJL string (UID). Returns NULL if + * callback hasn't been found. See also ovs_db_callback_get() + * description for addition info. + */ +static ovs_callback_t *ovs_db_table_callback_get(ovs_db_t *pdb, yajl_val jid) { + char *endptr = NULL; + const char *suid = NULL; + uint64_t uid; + + if (jid && YAJL_IS_STRING(jid)) { + suid = YAJL_GET_STRING(jid); + uid = (uint64_t)strtoul(suid, &endptr, 16); + if (*endptr == '\0' && uid) + return ovs_db_callback_get(pdb, uid); + } + + return NULL; +} + +/* OVS DB table update event handler. + * This callback is called by POLL thread if OVS DB + * table update callback is received from the DB + * server. Once registered callback found, it's called + * by this handler. */ +static int ovs_db_table_update_cb(ovs_db_t *pdb, yajl_val jnode) { + ovs_callback_t *cb = NULL; + yajl_val jvalue; + yajl_val jparams; + yajl_val jtable_updates; + const char *params_path[] = {"params", NULL}; + const char *id_path[] = {"id", NULL}; + + /* check & get request attributes */ + if ((jparams = yajl_tree_get(jnode, params_path, yajl_t_array)) == NULL || + (yajl_tree_get(jnode, id_path, yajl_t_null) == NULL)) { + OVS_ERROR("invalid OVS DB request received"); + return (-1); + } + + /* check array length: [, ] */ + 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 */ + 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) { + if ((method = YAJL_GET_STRING(jval)) == NULL) { + yajl_tree_free(jnode); + sfree(sjson); + return (-1); + } + if (strcmp("echo", method) == 0) { + /* echo request from the server */ + if (ovs_db_table_echo_cb(pdb, jnode) < 0) + OVS_ERROR("handle echo request failed"); + } else if (strcmp("update", method) == 0) { + /* update notification */ + if (ovs_db_table_update_cb(pdb, jnode) < 0) + OVS_ERROR("handle update notification failed"); + } + } else if ((jval = yajl_tree_get(jnode, result_path, yajl_t_any)) != NULL) { + /* result notification */ + if (ovs_db_result_cb(pdb, jnode) < 0) + OVS_ERROR("handle result reply failed"); + } else + OVS_ERROR("connot find method or result failed"); + + /* release memory */ + yajl_tree_free(jnode); + sfree(sjson); + return (0); +} + +/* + * JSON reader implementation. + * + * This module process raw JSON data (byte stream) and + * returns fully-fledged JSON data which can be processed + * (parsed) by YAJL later. + */ + +/* Allocate JSON reader instance */ +static ovs_json_reader_t *ovs_json_reader_alloc() { + ovs_json_reader_t *jreader = NULL; + + if ((jreader = calloc(sizeof(ovs_json_reader_t), 1)) == NULL) + return NULL; + + return jreader; +} + +/* Push raw data into into the JSON reader for processing */ +static int ovs_json_reader_push_data(ovs_json_reader_t *jreader, + const char *data, size_t data_len) { + char *new_buff = NULL; + size_t available = jreader->buff_size - jreader->buff_offset; + + /* check/update required memory space */ + if (available < data_len) { + OVS_DEBUG("Reallocate buffer [size=%d, available=%d required=%d]", + (int)jreader->buff_size, (int)available, (int)data_len); + + /* allocate new chunk of memory */ + new_buff = realloc(jreader->buff_ptr, (jreader->buff_size + data_len)); + if (new_buff == NULL) + return (-1); + + /* point to new allocated memory */ + jreader->buff_ptr = new_buff; + jreader->buff_size += data_len; + } + + /* store input data */ + memcpy(jreader->buff_ptr + jreader->buff_offset, data, data_len); + jreader->buff_offset += data_len; + return (0); +} + +/* Pop one fully-fledged JSON if already exists. Returns 0 if + * completed JSON already exists otherwise negative value is + * returned */ +static int ovs_json_reader_pop(ovs_json_reader_t *jreader, + const char **json_ptr, size_t *json_len_ptr) { + size_t nbraces = 0; + size_t json_len = 0; + char *json = NULL; + + /* search open/close brace */ + for (size_t i = jreader->json_offset; i < jreader->buff_offset; i++) { + if (jreader->buff_ptr[i] == '{') { + nbraces++; + } else if (jreader->buff_ptr[i] == '}') + if (nbraces) + if (!(--nbraces)) { + /* JSON data */ + *json_ptr = jreader->buff_ptr + jreader->json_offset; + *json_len_ptr = json_len + 1; + jreader->json_offset = i + 1; + return (0); + } + + /* increase JSON data length */ + if (nbraces) + json_len++; + } + + if (jreader->json_offset) { + if (jreader->json_offset < jreader->buff_offset) { + /* shift data to the beginning of the buffer + * and zero rest of the buffer data */ + json = &jreader->buff_ptr[jreader->json_offset]; + json_len = jreader->buff_offset - jreader->json_offset; + for (size_t i = 0; i < jreader->buff_size; i++) + jreader->buff_ptr[i] = ((i < json_len) ? (json[i]) : (0)); + jreader->buff_offset = json_len; + } else + /* reset the buffer */ + jreader->buff_offset = 0; + + /* data is at the beginning of the buffer */ + jreader->json_offset = 0; + } + + return (-1); +} + +/* Reset JSON reader. It is useful when start processing + * new raw data. E.g.: in case of lost stream connection. + */ +static void ovs_json_reader_reset(ovs_json_reader_t *jreader) { + if (jreader) { + jreader->buff_offset = 0; + jreader->json_offset = 0; + } +} + +/* Release internal data allocated for JSON reader */ +static void ovs_json_reader_free(ovs_json_reader_t *jreader) { + if (jreader) { + free(jreader->buff_ptr); + free(jreader); + } +} + +/* Reconnect to OVS DB and call the OVS DB post connection init callback + * if connection has been established. + */ +static void ovs_db_reconnect(ovs_db_t *pdb) { + const char *node_info = pdb->node; + struct addrinfo *result; + + if (pdb->unix_path[0] != '\0') { + /* use UNIX socket instead of INET address */ + node_info = pdb->unix_path; + result = calloc(1, sizeof(struct addrinfo)); + struct sockaddr_un *sa_unix = calloc(1, sizeof(struct sockaddr_un)); + if (result == NULL || sa_unix == NULL) { + sfree(result); + sfree(sa_unix); + return; + } + result->ai_family = AF_UNIX; + result->ai_socktype = SOCK_STREAM; + result->ai_addrlen = sizeof(*sa_unix); + result->ai_addr = (struct sockaddr *)sa_unix; + sa_unix->sun_family = result->ai_family; + sstrncpy(sa_unix->sun_path, pdb->unix_path, sizeof(sa_unix->sun_path)); + } else { + /* inet socket address */ + struct addrinfo hints; + + /* setup criteria for selecting the socket address */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + /* get socket addresses */ + int ret = getaddrinfo(pdb->node, pdb->service, &hints, &result); + if (ret != 0) { + OVS_ERROR("getaddrinfo(): %s", gai_strerror(ret)); + return; + } + } + /* try to connect to the server */ + for (struct addrinfo *rp = result; rp != NULL; rp = rp->ai_next) { + char errbuff[OVS_ERROR_BUFF_SIZE]; + int sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (sock < 0) { + sstrerror(errno, errbuff, sizeof(errbuff)); + OVS_DEBUG("socket(): %s", errbuff); + continue; + } + if (connect(sock, rp->ai_addr, rp->ai_addrlen) < 0) { + close(sock); + sstrerror(errno, errbuff, sizeof(errbuff)); + OVS_DEBUG("connect(): %s [family=%d]", errbuff, rp->ai_family); + } else { + /* send notification to event thread */ + ovs_db_event_post(pdb, OVS_DB_EVENT_CONN_ESTABLISHED); + pdb->sock = sock; + break; + } + } + + if (pdb->sock < 0) + OVS_ERROR("connect to \"%s\" failed", node_info); + + freeaddrinfo(result); +} + +/* POLL worker thread. + * It listens on OVS DB connection for incoming + * requests/reply/events etc. Also, it reconnects to OVS DB + * if connection has been lost. + */ +static void *ovs_poll_worker(void *arg) { + ovs_db_t *pdb = (ovs_db_t *)arg; /* pointer to OVS DB */ + ovs_json_reader_t *jreader = NULL; + struct pollfd poll_fd = { + .fd = pdb->sock, .events = POLLIN | POLLPRI, .revents = 0, + }; + + /* create JSON reader instance */ + if ((jreader = ovs_json_reader_alloc()) == NULL) { + OVS_ERROR("initialize json reader failed"); + return (NULL); + } + + /* poll data */ + while (ovs_db_poll_is_running(pdb)) { + char errbuff[OVS_ERROR_BUFF_SIZE]; + poll_fd.fd = pdb->sock; + int poll_ret = poll(&poll_fd, 1, /* ms */ OVS_DB_POLL_TIMEOUT * 1000); + if (poll_ret < 0) { + sstrerror(errno, errbuff, sizeof(errbuff)); + OVS_ERROR("poll(): %s", errbuff); + break; + } else if (poll_ret == 0) { + OVS_DEBUG("poll(): timeout"); + if (pdb->sock < 0) + /* invalid fd, so try to reconnect */ + ovs_db_reconnect(pdb); + continue; + } + if (poll_fd.revents & POLLNVAL) { + /* invalid file descriptor, clean-up */ + ovs_db_callback_remove_all(pdb); + ovs_json_reader_reset(jreader); + /* setting poll FD to -1 tells poll() call to ignore this FD. + * In that case poll() call will return timeout all the time */ + pdb->sock = (-1); + } else if ((poll_fd.revents & POLLERR) || (poll_fd.revents & POLLHUP)) { + /* connection is broken */ + close(poll_fd.fd); + ovs_db_event_post(pdb, OVS_DB_EVENT_CONN_TERMINATED); + OVS_ERROR("poll() peer closed its end of the channel"); + } else if ((poll_fd.revents & POLLIN) || (poll_fd.revents & POLLPRI)) { + /* read incoming data */ + char buff[OVS_DB_POLL_READ_BLOCK_SIZE]; + ssize_t nbytes = recv(poll_fd.fd, buff, sizeof(buff), 0); + if (nbytes < 0) { + sstrerror(errno, errbuff, sizeof(errbuff)); + OVS_ERROR("recv(): %s", errbuff); + /* read error? Try to reconnect */ + close(poll_fd.fd); + continue; + } else if (nbytes == 0) { + close(poll_fd.fd); + ovs_db_event_post(pdb, OVS_DB_EVENT_CONN_TERMINATED); + OVS_ERROR("recv() peer has performed an orderly shutdown"); + continue; + } + /* read incoming data */ + size_t json_len = 0; + const char *json = NULL; + OVS_DEBUG("recv(): received %zd bytes of data", nbytes); + ovs_json_reader_push_data(jreader, buff, nbytes); + while (!ovs_json_reader_pop(jreader, &json, &json_len)) + /* process JSON data */ + ovs_db_json_data_process(pdb, json, json_len); + } + } + + OVS_DEBUG("poll thread has been completed"); + ovs_json_reader_free(jreader); + return (NULL); +} + +/* EVENT worker thread. + * Perform task based on incoming events. This + * task can be done asynchronously which allows to + * handle OVS DB callback like 'init_cb'. + */ +static void *ovs_event_worker(void *arg) { + ovs_db_t *pdb = (ovs_db_t *)arg; + + while (pdb->event_thread.value != OVS_DB_EVENT_TERMINATE) { + /* wait for an event */ + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += (OVS_DB_EVENT_TIMEOUT); + int ret = pthread_cond_timedwait(&pdb->event_thread.cond, + &pdb->event_thread.mutex, &ts); + if (!ret) { + /* handle the event */ + OVS_DEBUG("handle event %d", pdb->event_thread.value); + switch (pdb->event_thread.value) { + case OVS_DB_EVENT_CONN_ESTABLISHED: + if (pdb->cb.post_conn_init) + pdb->cb.post_conn_init(pdb); + break; + case OVS_DB_EVENT_CONN_TERMINATED: + if (pdb->cb.post_conn_terminate) + pdb->cb.post_conn_terminate(); + break; + default: + OVS_DEBUG("unknown event received"); + break; + } + } else if (ret == ETIMEDOUT) { + /* wait timeout */ + OVS_DEBUG("no event received (timeout)"); + continue; + } else { + /* unexpected error */ + OVS_ERROR("pthread_cond_timedwait() failed"); + break; + } + } + + OVS_DEBUG("event thread has been completed"); + return (NULL); +} + +/* Initialize EVENT thread */ +static int ovs_db_event_thread_init(ovs_db_t *pdb) { + pdb->event_thread.tid = (pthread_t)-1; + /* init event thread condition variable */ + if (pthread_cond_init(&pdb->event_thread.cond, NULL)) { + return (-1); + } + /* init event thread mutex */ + if (pthread_mutex_init(&pdb->event_thread.mutex, NULL)) { + pthread_cond_destroy(&pdb->event_thread.cond); + return (-1); + } + /* Hold the event thread mutex. It ensures that no events + * will be lost while thread is still starting. Once event + * thread is started and ready to accept events, it will release + * the mutex */ + if (pthread_mutex_lock(&pdb->event_thread.mutex)) { + pthread_mutex_destroy(&pdb->event_thread.mutex); + pthread_cond_destroy(&pdb->event_thread.cond); + return (-1); + } + /* start event thread */ + pthread_t tid; + if (plugin_thread_create(&tid, NULL, ovs_event_worker, pdb, + "utils_ovs:event") != 0) { + pthread_mutex_unlock(&pdb->event_thread.mutex); + pthread_mutex_destroy(&pdb->event_thread.mutex); + pthread_cond_destroy(&pdb->event_thread.cond); + return (-1); + } + pdb->event_thread.tid = tid; + return (0); +} + +/* Destroy EVENT thread */ +static int ovs_db_event_thread_destroy(ovs_db_t *pdb) { + if (pdb->event_thread.tid == (pthread_t)-1) + /* already destroyed */ + return (0); + ovs_db_event_post(pdb, OVS_DB_EVENT_TERMINATE); + if (pthread_join(pdb->event_thread.tid, NULL) != 0) + return (-1); + /* Event thread always holds the thread mutex when + * performs some task (handles event) and releases it when + * while sleeping. Thus, if event thread exits, the mutex + * remains locked */ + pthread_mutex_unlock(&pdb->event_thread.mutex); + pthread_mutex_destroy(&pdb->event_thread.mutex); + pthread_cond_destroy(&pdb->event_thread.cond); + pdb->event_thread.tid = (pthread_t)-1; + return (0); +} + +/* Initialize POLL thread */ +static int ovs_db_poll_thread_init(ovs_db_t *pdb) { + pdb->poll_thread.tid = (pthread_t)-1; + /* init event thread mutex */ + if (pthread_mutex_init(&pdb->poll_thread.mutex, NULL)) { + return (-1); + } + /* start poll thread */ + pthread_t tid; + pdb->poll_thread.state = OVS_DB_POLL_STATE_RUNNING; + if (plugin_thread_create(&tid, NULL, ovs_poll_worker, pdb, + "utils_ovs:poll") != 0) { + pthread_mutex_destroy(&pdb->poll_thread.mutex); + return (-1); + } + pdb->poll_thread.tid = tid; + return (0); +} + +/* Destroy POLL thread */ +static int ovs_db_poll_thread_destroy(ovs_db_t *pdb) { + if (pdb->poll_thread.tid == (pthread_t)-1) + /* already destroyed */ + return (0); + /* change thread state */ + pthread_mutex_lock(&pdb->poll_thread.mutex); + pdb->poll_thread.state = OVS_DB_POLL_STATE_EXITING; + pthread_mutex_unlock(&pdb->poll_thread.mutex); + /* join the thread */ + if (pthread_join(pdb->poll_thread.tid, NULL) != 0) + return (-1); + pthread_mutex_destroy(&pdb->poll_thread.mutex); + pdb->poll_thread.tid = (pthread_t)-1; + return (0); +} + +/* + * Public OVS DB API implementation + */ + +ovs_db_t *ovs_db_init(const char *node, const char *service, + const char *unix_path, ovs_db_callback_t *cb) { + /* sanity check */ + if (node == NULL || service == NULL || unix_path == NULL) + return (NULL); + + /* allocate db data & fill it */ + ovs_db_t *pdb = pdb = calloc(1, sizeof(*pdb)); + if (pdb == NULL) + return (NULL); + + /* store the OVS DB address */ + sstrncpy(pdb->node, node, sizeof(pdb->node)); + sstrncpy(pdb->service, service, sizeof(pdb->service)); + sstrncpy(pdb->unix_path, unix_path, sizeof(pdb->unix_path)); + + /* setup OVS DB callbacks */ + if (cb) + pdb->cb = *cb; + + /* init OVS DB mutex attributes */ + pthread_mutexattr_t mutex_attr; + if (pthread_mutexattr_init(&mutex_attr)) { + OVS_ERROR("OVS DB mutex attribute init failed"); + sfree(pdb); + return (NULL); + } + /* set OVS DB mutex as recursive */ + if (pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE)) { + OVS_ERROR("Failed to set OVS DB mutex as recursive"); + pthread_mutexattr_destroy(&mutex_attr); + sfree(pdb); + return (NULL); + } + /* init OVS DB mutex */ + if (pthread_mutex_init(&pdb->mutex, &mutex_attr)) { + OVS_ERROR("OVS DB mutex init failed"); + pthread_mutexattr_destroy(&mutex_attr); + sfree(pdb); + return (NULL); + } + /* destroy mutex attributes */ + pthread_mutexattr_destroy(&mutex_attr); + + /* init event thread */ + if (ovs_db_event_thread_init(pdb) < 0) { + ovs_db_destroy(pdb); + return (NULL); + } + + /* init polling thread */ + pdb->sock = -1; + if (ovs_db_poll_thread_init(pdb) < 0) { + ovs_db_destroy(pdb); + return (NULL); + } + return pdb; +} + +int ovs_db_send_request(ovs_db_t *pdb, const char *method, const char *params, + ovs_db_result_cb_t cb) { + int ret = 0; + yajl_gen_status yajl_gen_ret; + yajl_val jparams; + yajl_gen jgen; + ovs_callback_t *new_cb = NULL; + uint64_t uid; + char uid_buff[OVS_UID_STR_SIZE]; + const char *req = NULL; + size_t req_len = 0; + struct timespec ts; + + /* sanity check */ + if (!pdb || !method || !params) + return (-1); + + if ((jgen = yajl_gen_alloc(NULL)) == NULL) + return (-1); + + /* try to parse params */ + if ((jparams = yajl_tree_parse(params, NULL, 0)) == NULL) { + OVS_ERROR("params is not a JSON string"); + yajl_gen_clear(jgen); + return (-1); + } + + /* generate method field */ + OVS_YAJL_CALL(yajl_gen_map_open, jgen); + + OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "method"); + OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, method); + + /* generate params field */ + OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "params"); + OVS_YAJL_CALL(ovs_yajl_gen_val, jgen, jparams); + yajl_tree_free(jparams); + + /* generate id field */ + OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "id"); + uid = ovs_uid_generate(); + ssnprintf(uid_buff, sizeof(uid_buff), "%" PRIX64, uid); + OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, uid_buff); + + OVS_YAJL_CALL(yajl_gen_map_close, jgen); + + if (cb) { + /* register result callback */ + if ((new_cb = calloc(1, sizeof(ovs_callback_t))) == NULL) + goto yajl_gen_failure; + + /* add new callback to front */ + sem_init(&new_cb->result.sync, 0, 0); + new_cb->result.call = cb; + new_cb->uid = uid; + ovs_db_callback_add(pdb, new_cb); + } + + /* send the request */ + OVS_YAJL_CALL(yajl_gen_get_buf, jgen, (const unsigned char **)&req, &req_len); + OVS_DEBUG("%s", req); + if (!ovs_db_data_send(pdb, req, req_len)) { + if (cb) { + /* wait for result */ + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += OVS_DB_SEND_REQ_TIMEOUT; + if (sem_timedwait(&new_cb->result.sync, &ts) < 0) { + OVS_ERROR("%s() no replay received within %d sec", __FUNCTION__, + OVS_DB_SEND_REQ_TIMEOUT); + ret = (-1); + } + } + } else { + OVS_ERROR("ovs_db_data_send() failed"); + ret = (-1); + } + +yajl_gen_failure: + if (new_cb) { + /* destroy callback */ + sem_destroy(&new_cb->result.sync); + ovs_db_callback_remove(pdb, new_cb); + } + + /* release memory */ + yajl_gen_clear(jgen); + return (yajl_gen_ret != yajl_gen_status_ok) ? (-1) : ret; +} + +int ovs_db_table_cb_register(ovs_db_t *pdb, const char *tb_name, + const char **tb_column, + ovs_db_table_cb_t update_cb, + ovs_db_result_cb_t result_cb, unsigned int flags) { + yajl_gen jgen; + yajl_gen_status yajl_gen_ret; + ovs_callback_t *new_cb = NULL; + char uid_str[OVS_UID_STR_SIZE]; + char *params; + size_t params_len; + int ovs_db_ret = 0; + + /* sanity check */ + if (pdb == NULL || tb_name == NULL || update_cb == NULL) + return (-1); + + /* allocate new update callback */ + if ((new_cb = calloc(1, sizeof(ovs_callback_t))) == NULL) + return (-1); + + /* init YAJL generator */ + if ((jgen = yajl_gen_alloc(NULL)) == NULL) { + sfree(new_cb); + return (-1); + } + + /* add new callback to front */ + new_cb->table.call = update_cb; + new_cb->uid = ovs_uid_generate(); + ovs_db_callback_add(pdb, new_cb); + + /* make update notification request + * [, , ] */ + OVS_YAJL_CALL(yajl_gen_array_open, jgen); + { + OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, OVS_DB_DEFAULT_DB_NAME); + + /* uid string */ + ssnprintf(uid_str, sizeof(uid_str), "%" PRIX64, new_cb->uid); + OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, uid_str); + + /* */ + 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); + { + /* */ + 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" : + * "key_b" : + * } + */ +yajl_val ovs_utils_get_value_by_key(yajl_val jval, const char *key) { + const char *obj_key = NULL; + + /* check params */ + if (!YAJL_IS_OBJECT(jval) || (key == NULL)) + return NULL; + + /* find a value by key */ + for (size_t i = 0; i < YAJL_GET_OBJECT(jval)->len; i++) { + obj_key = YAJL_GET_OBJECT(jval)->keys[i]; + if (strcmp(obj_key, key) == 0) + return YAJL_GET_OBJECT(jval)->values[i]; + } + + return NULL; +} + +/* Get OVS DB map value by given map key + * + * FROM RFC7047: + * + * + * A 2-element JSON array that represents a pair within a database + * map. The first element is an that represents the key, and + * the second element is an that represents the value. + * + * + * 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 s giving the + * values in the map. All of the s must have the same key and + * value types. + * + * EXAMPLE: + * [ + * "map", [ + * [ "key_a", ], [ "key_b", ], ... + * ] + * ] + */ +yajl_val ovs_utils_get_map_value(yajl_val jval, const char *key) { + size_t map_len = 0; + size_t array_len = 0; + yajl_val *map_values = NULL; + yajl_val *array_values = NULL; + const char *str_val = NULL; + + /* check YAJL array */ + if (!YAJL_IS_ARRAY(jval) || (key == NULL)) + return NULL; + + /* check a database map value (2-element, first one should be a string */ + array_len = YAJL_GET_ARRAY(jval)->len; + array_values = YAJL_GET_ARRAY(jval)->values; + if ((array_len != 2) || (!YAJL_IS_STRING(array_values[0])) || + (!YAJL_IS_ARRAY(array_values[1]))) + return NULL; + + /* check first element of the array */ + str_val = YAJL_GET_STRING(array_values[0]); + if (strcmp("map", str_val) != 0) + return NULL; + + /* try to find map value by map key */ + map_len = YAJL_GET_ARRAY(array_values[1])->len; + map_values = YAJL_GET_ARRAY(array_values[1])->values; + for (size_t i = 0; i < map_len; i++) { + /* check YAJL array */ + if (!YAJL_IS_ARRAY(map_values[i])) + break; + + /* check a database pair value (2-element, first one represents a key + * and it should be a string in our case */ + array_len = YAJL_GET_ARRAY(map_values[i])->len; + array_values = YAJL_GET_ARRAY(map_values[i])->values; + if ((array_len != 2) || (!YAJL_IS_STRING(array_values[0]))) + break; + + /* return map value if given key equals map key */ + str_val = YAJL_GET_STRING(array_values[0]); + if (strcmp(key, str_val) == 0) + return array_values[1]; + } + return NULL; +} diff --git a/src/utils_ovs.h b/src/utils_ovs.h new file mode 100644 index 00000000..52c2f915 --- /dev/null +++ b/src/utils_ovs.h @@ -0,0 +1,236 @@ +/** + * collectd - src/utils_ovs.h + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Volodymyr Mytnyk + * + * 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 +#include + +/* 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 diff --git a/src/utils_parse_option.c b/src/utils_parse_option.c index ba37f03e..a2a73809 100644 --- a/src/utils_parse_option.c +++ b/src/utils_parse_option.c @@ -146,5 +146,3 @@ int parse_option(char **ret_buffer, char **ret_key, char **ret_value) { return (0); } /* int parse_option */ - -/* vim: set sw=2 ts=8 tw=78 et : */ diff --git a/src/utils_parse_option.h b/src/utils_parse_option.h index a638e694..3dd0a792 100644 --- a/src/utils_parse_option.h +++ b/src/utils_parse_option.h @@ -31,5 +31,3 @@ int parse_string(char **ret_buffer, char **ret_string); int parse_option(char **ret_buffer, char **ret_key, char **ret_value); #endif /* UTILS_PARSE_OPTION */ - -/* vim: set sw=2 ts=8 tw=78 et : */ diff --git a/src/utils_rrdcreate.c b/src/utils_rrdcreate.c index 750d2656..ae72575c 100644 --- a/src/utils_rrdcreate.c +++ b/src/utils_rrdcreate.c @@ -664,5 +664,3 @@ int cu_rrd_create_file(const char *filename, /* {{{ */ return (status); } /* }}} int cu_rrd_create_file */ - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/utils_rrdcreate.h b/src/utils_rrdcreate.h index 9bc67aed..d5f9a12a 100644 --- a/src/utils_rrdcreate.h +++ b/src/utils_rrdcreate.h @@ -51,5 +51,3 @@ int cu_rrd_create_file(const char *filename, const data_set_t *ds, const value_list_t *vl, const rrdcreate_config_t *cfg); #endif /* UTILS_RRDCREATE_H */ - -/* vim: set sw=2 sts=2 et : */ diff --git a/src/utils_tail_match.c b/src/utils_tail_match.c index 505c6937..1a99384b 100644 --- a/src/utils_tail_match.c +++ b/src/utils_tail_match.c @@ -336,5 +336,3 @@ int tail_match_read(cu_tail_match_t *obj) { return (0); } /* int tail_match_read */ - -/* vim: set sw=2 sts=2 ts=8 : */ diff --git a/src/utils_tail_match.h b/src/utils_tail_match.h index 09e3d402..03b70e93 100644 --- a/src/utils_tail_match.h +++ b/src/utils_tail_match.h @@ -137,5 +137,3 @@ int tail_match_add_match_simple(cu_tail_match_t *obj, const char *regex, * Zero on success, nonzero on failure. */ int tail_match_read(cu_tail_match_t *obj); - -/* vim: set sw=2 sts=2 ts=8 : */ diff --git a/src/uuid.c b/src/uuid.c index 89c9e7dd..546d481d 100644 --- a/src/uuid.c +++ b/src/uuid.c @@ -33,10 +33,6 @@ #include #endif -#if HAVE_LIBHAL_H -#include -#endif - #define UUID_RAW_LENGTH 16 #define UUID_PRINTABLE_COMPACT_LENGTH (UUID_RAW_LENGTH * 2) #define UUID_PRINTABLE_NORMAL_LENGTH (UUID_PRINTABLE_COMPACT_LENGTH + 4) @@ -127,52 +123,6 @@ static char *uuid_get_from_sysctl(void) { } #endif -#if HAVE_LIBHAL_H - -#define UUID_PATH "/org/freedesktop/Hal/devices/computer" -#define UUID_PROPERTY "smbios.system.uuid" - -static char *uuid_get_from_hal(void) { - LibHalContext *ctx; - - DBusError error; - DBusConnection *con; - - dbus_error_init(&error); - - if (!(con = dbus_bus_get(DBUS_BUS_SYSTEM, &error))) - goto bailout_nobus; - - ctx = libhal_ctx_new(); - libhal_ctx_set_dbus_connection(ctx, con); - - if (!libhal_ctx_init(ctx, &error)) - goto bailout; - - if (!libhal_device_property_exists(ctx, UUID_PATH, UUID_PROPERTY, &error)) - goto bailout; - - char *uuid = - libhal_device_get_property_string(ctx, UUID_PATH, UUID_PROPERTY, &error); - if (looks_like_a_uuid(uuid)) - return (uuid); - -bailout : { - DBusError ctxerror; - dbus_error_init(&ctxerror); - if (!(libhal_ctx_shutdown(ctx, &ctxerror))) - dbus_error_free(&ctxerror); -} - - libhal_ctx_free(ctx); - -bailout_nobus: - if (dbus_error_is_set(&error)) - dbus_error_free(&error); - return (NULL); -} -#endif - static char *uuid_get_from_file(const char *path) { FILE *file; char uuid[UUID_PRINTABLE_NORMAL_LENGTH + 1] = ""; @@ -215,11 +165,6 @@ static char *uuid_get_local(void) { return (uuid); #endif -#if HAVE_LIBHAL_H - if ((uuid = uuid_get_from_hal()) != NULL) - return (uuid); -#endif - if ((uuid = uuid_get_from_dmidecode()) != NULL) return (uuid); @@ -262,17 +207,3 @@ void module_register(void) { STATIC_ARRAY_SIZE(config_keys)); plugin_register_init("uuid", uuid_init); } - -/* - * vim: set tabstop=4: - * vim: set shiftwidth=4: - * vim: set expandtab: - */ -/* - * Local variables: - * indent-tabs-mode: nil - * c-indent-level: 4 - * c-basic-offset: 4 - * tab-width: 4 - * End: - */ diff --git a/src/varnish.c b/src/varnish.c index 41b60d85..3538e7e2 100644 --- a/src/varnish.c +++ b/src/varnish.c @@ -1331,5 +1331,3 @@ void module_register(void) /* {{{ */ plugin_register_complex_config("varnish", varnish_config); plugin_register_init("varnish", varnish_init); } /* }}} */ - -/* vim: set sw=8 noet fdm=marker : */ diff --git a/src/virt.c b/src/virt.c index c3c07a0d..a8f378a2 100644 --- a/src/virt.c +++ b/src/virt.c @@ -17,6 +17,7 @@ * * Authors: * Richard W.M. Jones + * Przemyslaw Szczerbik **/ #include "collectd.h" @@ -32,10 +33,63 @@ #include #include #include +#include /* Plugin name */ #define PLUGIN_NAME "virt" +#ifdef LIBVIR_CHECK_VERSION + +#if LIBVIR_CHECK_VERSION(0, 9, 2) +#define HAVE_DOM_REASON 1 +#endif + +#if LIBVIR_CHECK_VERSION(0, 9, 5) +#define HAVE_BLOCK_STATS_FLAGS 1 +#define HAVE_DOM_REASON_PAUSED_SHUTTING_DOWN 1 +#endif + +#if LIBVIR_CHECK_VERSION(0, 9, 10) +#define HAVE_DISK_ERR 1 +#endif + +#if LIBVIR_CHECK_VERSION(0, 9, 11) +#define HAVE_CPU_STATS 1 +#define HAVE_DOM_STATE_PMSUSPENDED 1 +#define HAVE_DOM_REASON_RUNNING_WAKEUP 1 +#endif + +#if LIBVIR_CHECK_VERSION(1, 0, 1) +#define HAVE_DOM_REASON_PAUSED_SNAPSHOT 1 +#endif + +#if LIBVIR_CHECK_VERSION(1, 1, 1) +#define HAVE_DOM_REASON_PAUSED_CRASHED 1 +#endif + +#if LIBVIR_CHECK_VERSION(1, 2, 9) +#define HAVE_JOB_STATS 1 +#endif + +#if LIBVIR_CHECK_VERSION(1, 2, 10) +#define HAVE_DOM_REASON_CRASHED 1 +#endif + +#if LIBVIR_CHECK_VERSION(1, 2, 11) +#define HAVE_FS_INFO 1 +#endif + +#if LIBVIR_CHECK_VERSION(1, 2, 15) +#define HAVE_DOM_REASON_PAUSED_STARTING_UP 1 +#endif + +#if LIBVIR_CHECK_VERSION(1, 3, 3) +#define HAVE_PERF_STATS 1 +#define HAVE_DOM_REASON_POSTCOPY 1 +#endif + +#endif /* LIBVIR_CHECK_VERSION */ + static const char *config_keys[] = {"Connection", "RefreshInterval", @@ -52,14 +106,148 @@ static const char *config_keys[] = {"Connection", "PluginInstanceFormat", + "Instances", + "ExtraStats", NULL}; + +const char *domain_states[] = { + [VIR_DOMAIN_NOSTATE] = "no state", + [VIR_DOMAIN_RUNNING] = "the domain is running", + [VIR_DOMAIN_BLOCKED] = "the domain is blocked on resource", + [VIR_DOMAIN_PAUSED] = "the domain is paused by user", + [VIR_DOMAIN_SHUTDOWN] = "the domain is being shut down", + [VIR_DOMAIN_SHUTOFF] = "the domain is shut off", + [VIR_DOMAIN_CRASHED] = "the domain is crashed", +#ifdef HAVE_DOM_STATE_PMSUSPENDED + [VIR_DOMAIN_PMSUSPENDED] = + "the domain is suspended by guest power management", +#endif +}; + +#ifdef HAVE_DOM_REASON +#define DOMAIN_STATE_REASON_MAX_SIZE 20 +const char *domain_reasons[][DOMAIN_STATE_REASON_MAX_SIZE] = { + [VIR_DOMAIN_NOSTATE][VIR_DOMAIN_NOSTATE_UNKNOWN] = + "the reason is unknown", + + [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_UNKNOWN] = + "the reason is unknown", + [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_BOOTED] = + "normal startup from boot", + [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_MIGRATED] = + "migrated from another host", + [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_RESTORED] = + "restored from a state file", + [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_FROM_SNAPSHOT] = + "restored from snapshot", + [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_UNPAUSED] = + "returned from paused state", + [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_MIGRATION_CANCELED] = + "returned from migration", + [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_SAVE_CANCELED] = + "returned from failed save process", +#ifdef HAVE_DOM_REASON_RUNNING_WAKEUP + [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_WAKEUP] = + "returned from pmsuspended due to wakeup event", +#endif +#ifdef HAVE_DOM_REASON_CRASHED + [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_CRASHED] = + "resumed from crashed", +#endif +#ifdef HAVE_DOM_REASON_POSTCOPY + [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_POSTCOPY] = + "running in post-copy migration mode", +#endif + + [VIR_DOMAIN_BLOCKED][VIR_DOMAIN_BLOCKED_UNKNOWN] = + "the reason is unknown", + + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_UNKNOWN] = + "the reason is unknown", + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_USER] = "paused on user request", + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_MIGRATION] = + "paused for offline migration", + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_SAVE] = "paused for save", + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_DUMP] = + "paused for offline core dump", + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_IOERROR] = + "paused due to a disk I/O error", + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_WATCHDOG] = + "paused due to a watchdog event", + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_FROM_SNAPSHOT] = + "paused after restoring from snapshot", +#ifdef HAVE_DOM_REASON_PAUSED_SHUTTING_DOWN + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_SHUTTING_DOWN] = + "paused during shutdown process", +#endif +#ifdef HAVE_DOM_REASON_PAUSED_SNAPSHOT + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_SNAPSHOT] = + "paused while creating a snapshot", +#endif +#ifdef HAVE_DOM_REASON_PAUSED_CRASHED + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_CRASHED] = + "paused due to a guest crash", +#endif +#ifdef HAVE_DOM_REASON_PAUSED_STARTING_UP + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_STARTING_UP] = + "the domain is being started", +#endif +#ifdef HAVE_DOM_REASON_POSTCOPY + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_POSTCOPY] = + "paused for post-copy migration", + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_POSTCOPY_FAILED] = + "paused after failed post-copy", +#endif + + [VIR_DOMAIN_SHUTDOWN][VIR_DOMAIN_SHUTDOWN_UNKNOWN] = + "the reason is unknown", + [VIR_DOMAIN_SHUTDOWN][VIR_DOMAIN_SHUTDOWN_USER] = + "shutting down on user request", + + [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_UNKNOWN] = + "the reason is unknown", + [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_SHUTDOWN] = "normal shutdown", + [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_DESTROYED] = "forced poweroff", + [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_CRASHED] = "domain crashed", + [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_MIGRATED] = + "migrated to another host", + [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_SAVED] = "saved to a file", + [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_FAILED] = + "domain failed to start", + [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT] = + "restored from a snapshot which was taken while domain was shutoff", + + [VIR_DOMAIN_CRASHED][VIR_DOMAIN_CRASHED_UNKNOWN] = + "the reason is unknown", +#ifdef VIR_DOMAIN_CRASHED_PANICKED + [VIR_DOMAIN_CRASHED][VIR_DOMAIN_CRASHED_PANICKED] = "domain panicked", +#endif + +#ifdef HAVE_DOM_STATE_PMSUSPENDED + [VIR_DOMAIN_PMSUSPENDED][VIR_DOMAIN_PMSUSPENDED_UNKNOWN] = + "the reason is unknown", +#endif +}; +#endif /* HAVE_DOM_REASON */ + #define NR_CONFIG_KEYS ((sizeof config_keys / sizeof config_keys[0]) - 1) +#define NANOSEC_IN_SEC 1e9 + +#define GET_STATS(_f, _name, ...) \ + do { \ + status = _f(__VA_ARGS__); \ + if (status != 0) \ + ERROR(PLUGIN_NAME ": Failed to get " _name); \ + } while (0) /* Connection. */ static virConnectPtr conn = 0; static char *conn_string = NULL; static c_complain_t conn_complain = C_COMPLAIN_INIT_STATIC; +/* Node information required for %CPU */ +static virNodeInfo nodeinfo; + /* Seconds between list refreshes, 0 disables completely. */ static int interval = 60; @@ -73,25 +261,12 @@ static ignorelist_t *il_interface_devices = NULL; static int ignore_device_match(ignorelist_t *, const char *domname, const char *devpath); -/* Actual list of domains found on last refresh. */ -static virDomainPtr *domains = NULL; -static int nr_domains = 0; - -static void free_domains(void); -static int add_domain(virDomainPtr dom); - /* Actual list of block devices found on last refresh. */ struct block_device { virDomainPtr dom; /* domain */ char *path; /* name of block device */ }; -static struct block_device *block_devices = NULL; -static int nr_block_devices = 0; - -static void free_block_devices(void); -static int add_block_device(virDomainPtr dom, const char *path); - /* Actual list of network interfaces found on last refresh. */ struct interface_device { virDomainPtr dom; /* domain */ @@ -100,12 +275,57 @@ struct interface_device { char *number; /* interface device number */ }; -static struct interface_device *interface_devices = NULL; -static int nr_interface_devices = 0; +typedef struct domain_s { + virDomainPtr ptr; + virDomainInfo info; +} domain_t; + +struct lv_read_state { + /* Actual list of domains found on last refresh. */ + domain_t *domains; + int nr_domains; + + struct block_device *block_devices; + int nr_block_devices; + + struct interface_device *interface_devices; + int nr_interface_devices; +}; + +static void free_domains(struct lv_read_state *state); +static int add_domain(struct lv_read_state *state, virDomainPtr dom); -static void free_interface_devices(void); -static int add_interface_device(virDomainPtr dom, const char *path, - const char *address, unsigned int number); +static void free_block_devices(struct lv_read_state *state); +static int add_block_device(struct lv_read_state *state, virDomainPtr dom, + const char *path); + +static void free_interface_devices(struct lv_read_state *state); +static int add_interface_device(struct lv_read_state *state, virDomainPtr dom, + const char *path, const char *address, + unsigned int number); + +#define METADATA_VM_PARTITION_URI "http://ovirt.org/ovirtmap/tag/1.0" +#define METADATA_VM_PARTITION_ELEMENT "tag" +#define METADATA_VM_PARTITION_PREFIX "ovirtmap" + +#define BUFFER_MAX_LEN 256 +#define PARTITION_TAG_MAX_LEN 32 + +struct lv_read_instance { + struct lv_read_state read_state; + char tag[PARTITION_TAG_MAX_LEN]; + size_t id; +}; + +struct lv_user_data { + struct lv_read_instance inst; + user_data_t ud; +}; + +#define NR_INSTANCES_DEFAULT 1 +#define NR_INSTANCES_MAX 128 +static int nr_instances = NR_INSTANCES_DEFAULT; +static struct lv_user_data lv_read_user_data[NR_INSTANCES_MAX]; /* HostnameFormat. */ #define HF_MAX_FIELDS 3 @@ -128,6 +348,58 @@ enum bd_field { target, source }; /* InterfaceFormat. */ enum if_field { if_address, if_name, if_number }; +/* ExtraStats */ +#define EX_STATS_MAX_FIELDS 15 +enum ex_stats { + ex_stats_none = 0, + ex_stats_disk = 1 << 0, + ex_stats_pcpu = 1 << 1, + ex_stats_cpu_util = 1 << 2, + ex_stats_domain_state = 1 << 3, +#ifdef HAVE_PERF_STATS + ex_stats_perf = 1 << 4, +#endif + ex_stats_vcpupin = 1 << 5, +#ifdef HAVE_DISK_ERR + ex_stats_disk_err = 1 << 6, +#endif +#ifdef HAVE_FS_INFO + ex_stats_fs_info = 1 << 7, +#endif +#ifdef HAVE_JOB_STATS + ex_stats_job_stats_completed = 1 << 8, + ex_stats_job_stats_background = 1 << 9, +#endif +}; + +static unsigned int extra_stats = ex_stats_none; + +struct ex_stats_item { + const char *name; + enum ex_stats flag; +}; +static const struct ex_stats_item ex_stats_table[] = { + {"disk", ex_stats_disk}, + {"pcpu", ex_stats_pcpu}, + {"cpu_util", ex_stats_cpu_util}, + {"domain_state", ex_stats_domain_state}, +#ifdef HAVE_PERF_STATS + {"perf", ex_stats_perf}, +#endif + {"vcpupin", ex_stats_vcpupin}, +#ifdef HAVE_DISK_ERR + {"disk_err", ex_stats_disk_err}, +#endif +#ifdef HAVE_FS_INFO + {"fs_info", ex_stats_fs_info}, +#endif +#ifdef HAVE_JOB_STATS + {"job_stats_completed", ex_stats_job_stats_completed}, + {"job_stats_background", ex_stats_job_stats_background}, +#endif + {NULL, ex_stats_none}, +}; + /* BlockDeviceFormatBasename */ _Bool blockdevice_format_basename = 0; static enum bd_field blockdevice_format = target; @@ -136,7 +408,72 @@ static enum if_field interface_format = if_name; /* Time that we last refreshed. */ static time_t last_refresh = (time_t)0; -static int refresh_lists(void); +static int refresh_lists(struct lv_read_instance *inst); + +struct lv_info { + virDomainInfo di; + unsigned long long total_user_cpu_time; + unsigned long long total_syst_cpu_time; +}; + +struct lv_block_info { + virDomainBlockStatsStruct bi; + + long long rd_total_times; + long long wr_total_times; + + long long fl_req; + long long fl_total_times; +}; + +static void init_block_info(struct lv_block_info *binfo) { + if (binfo == NULL) + return; + + binfo->bi.rd_req = -1; + binfo->bi.wr_req = -1; + binfo->bi.rd_bytes = -1; + binfo->bi.wr_bytes = -1; + + binfo->rd_total_times = -1; + binfo->wr_total_times = -1; + binfo->fl_req = -1; + binfo->fl_total_times = -1; +} + +#ifdef HAVE_BLOCK_STATS_FLAGS + +#define GET_BLOCK_INFO_VALUE(NAME, FIELD) \ + do { \ + if (!strcmp(param[i].field, NAME)) { \ + binfo->FIELD = param[i].value.l; \ + continue; \ + } \ + } while (0) + +static int get_block_info(struct lv_block_info *binfo, + virTypedParameterPtr param, int nparams) { + if (binfo == NULL || param == NULL) + return -1; + + for (int i = 0; i < nparams; ++i) { + /* ignore type. Everything must be LLONG anyway. */ + GET_BLOCK_INFO_VALUE("rd_operations", bi.rd_req); + GET_BLOCK_INFO_VALUE("wr_operations", bi.wr_req); + GET_BLOCK_INFO_VALUE("rd_bytes", bi.rd_bytes); + GET_BLOCK_INFO_VALUE("wr_bytes", bi.wr_bytes); + GET_BLOCK_INFO_VALUE("rd_total_times", rd_total_times); + GET_BLOCK_INFO_VALUE("wr_total_times", wr_total_times); + GET_BLOCK_INFO_VALUE("flush_operations", fl_req); + GET_BLOCK_INFO_VALUE("flush_total_times", fl_total_times); + } + + return 0; +} + +#undef GET_BLOCK_INFO_VALUE + +#endif /* HAVE_BLOCK_STATS_FLAGS */ /* ERROR(...) macro for virterrors. */ #define VIRT_ERROR(conn, s) \ @@ -147,6 +484,54 @@ static int refresh_lists(void); ERROR("%s: %s", (s), err->message); \ } while (0) +static void init_lv_info(struct lv_info *info) { + if (info != NULL) + memset(info, 0, sizeof(*info)); +} + +static int lv_domain_info(virDomainPtr dom, struct lv_info *info) { +#ifdef HAVE_CPU_STATS + virTypedParameterPtr param = NULL; + int nparams = 0; +#endif /* HAVE_CPU_STATS */ + int ret = virDomainGetInfo(dom, &(info->di)); + if (ret != 0) { + return ret; + } + +#ifdef HAVE_CPU_STATS + nparams = virDomainGetCPUStats(dom, NULL, 0, -1, 1, 0); + if (nparams < 0) { + VIRT_ERROR(conn, "getting the CPU params count"); + return -1; + } + + param = calloc(nparams, sizeof(virTypedParameter)); + if (param == NULL) { + ERROR("virt plugin: alloc(%i) for cpu parameters failed.", nparams); + return -1; + } + + ret = virDomainGetCPUStats(dom, param, nparams, -1, 1, 0); // total stats. + if (ret < 0) { + virTypedParamsFree(param, nparams); + VIRT_ERROR(conn, "getting the disk params values"); + return -1; + } + + for (int i = 0; i < nparams; ++i) { + if (!strcmp(param[i].field, "user_time")) + info->total_user_cpu_time = param[i].value.ul; + else if (!strcmp(param[i].field, "system_time")) + info->total_syst_cpu_time = param[i].value.ul; + } + + virTypedParamsFree(param, nparams); +#endif /* HAVE_CPU_STATS */ + + return 0; +} + static void init_value_list(value_list_t *vl, virDomainPtr dom) { int n; const char *name; @@ -219,6 +604,34 @@ static void init_value_list(value_list_t *vl, virDomainPtr dom) { } /* void init_value_list */ +static int init_notif(notification_t *notif, const virDomainPtr domain, + int severity, const char *msg, const char *type, + const char *type_instance) { + value_list_t vl = VALUE_LIST_INIT; + + if (!notif) { + ERROR(PLUGIN_NAME ": init_notif: NULL pointer"); + return -1; + } + + init_value_list(&vl, domain); + notification_init(notif, severity, msg, vl.host, vl.plugin, + vl.plugin_instance, type, type_instance); + notif->time = cdtime(); + return 0; +} + +static void submit_notif(const virDomainPtr domain, int severity, + const char *msg, const char *type, + const char *type_instance) { + notification_t notif; + + init_notif(¬if, domain, severity, msg, type, type_instance); + plugin_dispatch_notification(¬if); + if (notif.meta) + plugin_notification_meta_free(notif.meta); +} + static void submit(virDomainPtr dom, char const *type, char const *type_instance, value_t *values, size_t values_len) { @@ -235,7 +648,7 @@ static void submit(virDomainPtr dom, char const *type, plugin_dispatch_values(&vl); } -static void memory_submit(gauge_t value, virDomainPtr dom) { +static void memory_submit(virDomainPtr dom, gauge_t value) { submit(dom, "memory", "total", &(value_t){.gauge = value}, 1); } @@ -243,9 +656,10 @@ static void memory_stats_submit(gauge_t value, virDomainPtr dom, int tag_index) { static const char *tags[] = {"swap_in", "swap_out", "major_fault", "minor_fault", "unused", "available", - "actual_balloon", "rss"}; + "actual_balloon", "rss", "usable", + "last_update"}; - if ((tag_index < 0) || (tag_index >= STATIC_ARRAY_SIZE(tags))) { + if ((tag_index < 0) || (tag_index >= (int)STATIC_ARRAY_SIZE(tags))) { ERROR("virt plugin: Array index out of bounds: tag_index = %d", tag_index); return; } @@ -253,9 +667,62 @@ static void memory_stats_submit(gauge_t value, virDomainPtr dom, submit(dom, "memory", tags[tag_index], &(value_t){.gauge = value}, 1); } -static void cpu_submit(unsigned long long value, virDomainPtr dom, - const char *type) { - submit(dom, type, NULL, &(value_t){.derive = (derive_t)value}, 1); +static void submit_derive2(const char *type, derive_t v0, derive_t v1, + virDomainPtr dom, const char *devname) { + value_t values[] = { + {.derive = v0}, {.derive = v1}, + }; + + submit(dom, type, devname, values, STATIC_ARRAY_SIZE(values)); +} /* void submit_derive2 */ + +static void pcpu_submit(virDomainPtr dom, struct lv_info *info) { +#ifdef HAVE_CPU_STATS + if (extra_stats & ex_stats_pcpu) + submit_derive2("ps_cputime", info->total_user_cpu_time, + info->total_syst_cpu_time, dom, NULL); +#endif /* HAVE_CPU_STATS */ +} + +static double cpu_ns_to_percent(unsigned int node_cpus, + unsigned long long cpu_time_old, + unsigned long long cpu_time_new) { + double percent = 0.0; + unsigned long long cpu_time_diff = 0; + double time_diff_sec = CDTIME_T_TO_DOUBLE(plugin_get_interval()); + + if (node_cpus != 0 && time_diff_sec != 0 && cpu_time_old != 0) { + cpu_time_diff = cpu_time_new - cpu_time_old; + percent = ((double)(100 * cpu_time_diff)) / + (time_diff_sec * node_cpus * NANOSEC_IN_SEC); + } + + DEBUG(PLUGIN_NAME ": node_cpus=%u cpu_time_old=%llu cpu_time_new=%llu" + "cpu_time_diff=%llu time_diff_sec=%f percent=%f", + node_cpus, cpu_time_old, cpu_time_new, cpu_time_diff, time_diff_sec, + percent); + + return percent; +} + +static void cpu_submit(const domain_t *dom, unsigned long long cpuTime_new) { + + if (!dom) + return; + + if (extra_stats & ex_stats_cpu_util) { + /* Computing %CPU requires 2 samples of cpuTime */ + if (dom->info.cpuTime != 0 && cpuTime_new != 0) { + + submit(dom->ptr, "percent", "virt_cpu_total", + &(value_t){.gauge = cpu_ns_to_percent( + nodeinfo.cpus, dom->info.cpuTime, cpuTime_new)}, + 1); + } + } + + submit(dom->ptr, "virt_cpu_total", NULL, &(value_t){.derive = cpuTime_new}, + 1); } static void vcpu_submit(derive_t value, virDomainPtr dom, int vcpu_nr, @@ -263,24 +730,128 @@ static void vcpu_submit(derive_t value, virDomainPtr dom, int vcpu_nr, char type_instance[DATA_MAX_NAME_LEN]; ssnprintf(type_instance, sizeof(type_instance), "%d", vcpu_nr); - submit(dom, type, type_instance, &(value_t){.derive = value}, 1); } -static void submit_derive2(const char *type, derive_t v0, derive_t v1, - virDomainPtr dom, const char *devname) { - value_t values[] = { - {.derive = v0}, {.derive = v1}, - }; +static void disk_submit(struct lv_block_info *binfo, virDomainPtr dom, + const char *dev) { + char *dev_copy = strdup(dev); + const char *type_instance = dev_copy; - submit(dom, type, devname, values, STATIC_ARRAY_SIZE(values)); -} /* void submit_derive2 */ + if (!dev_copy) + return; -static int lv_init(void) { - if (virInitialize() != 0) - return -1; - else - return 0; + if (blockdevice_format_basename && blockdevice_format == source) + type_instance = basename(dev_copy); + + if (!type_instance) { + sfree(dev_copy); + return; + } + + char flush_type_instance[DATA_MAX_NAME_LEN]; + ssnprintf(flush_type_instance, sizeof(flush_type_instance), "flush-%s", + type_instance); + + if ((binfo->bi.rd_req != -1) && (binfo->bi.wr_req != -1)) + submit_derive2("disk_ops", (derive_t)binfo->bi.rd_req, + (derive_t)binfo->bi.wr_req, dom, type_instance); + + if ((binfo->bi.rd_bytes != -1) && (binfo->bi.wr_bytes != -1)) + submit_derive2("disk_octets", (derive_t)binfo->bi.rd_bytes, + (derive_t)binfo->bi.wr_bytes, dom, type_instance); + + if (extra_stats & ex_stats_disk) { + if ((binfo->rd_total_times != -1) && (binfo->wr_total_times != -1)) + submit_derive2("disk_time", (derive_t)binfo->rd_total_times, + (derive_t)binfo->wr_total_times, dom, type_instance); + + if (binfo->fl_req != -1) + submit(dom, "total_requests", flush_type_instance, + &(value_t){.derive = (derive_t)binfo->fl_req}, 1); + if (binfo->fl_total_times != -1) { + derive_t value = binfo->fl_total_times / 1000; // ns -> ms + submit(dom, "total_time_in_ms", flush_type_instance, + &(value_t){.derive = value}, 1); + } + } + + sfree(dev_copy); +} + +static unsigned int parse_ex_stats_flags(char **exstats, int numexstats) { + unsigned int ex_stats_flags = ex_stats_none; + for (int i = 0; i < numexstats; i++) { + for (int j = 0; ex_stats_table[j].name != NULL; j++) { + if (strcasecmp(exstats[i], ex_stats_table[j].name) == 0) { + DEBUG(PLUGIN_NAME " plugin: enabling extra stats for '%s'", + ex_stats_table[j].name); + ex_stats_flags |= ex_stats_table[j].flag; + break; + } + + if (ex_stats_table[j + 1].name == NULL) { + ERROR(PLUGIN_NAME ": Unmatched ExtraStats option: %s", exstats[i]); + } + } + } + return ex_stats_flags; +} + +static void domain_state_submit(virDomainPtr dom, int state, int reason) { + + if ((state < 0) || (state >= STATIC_ARRAY_SIZE(domain_states))) { + ERROR(PLUGIN_NAME ": Array index out of bounds: state=%d", state); + return; + } + + char msg[DATA_MAX_NAME_LEN]; + const char *state_str = domain_states[state]; +#ifdef HAVE_DOM_REASON + if ((reason < 0) || (reason >= STATIC_ARRAY_SIZE(domain_reasons[0]))) { + ERROR(PLUGIN_NAME ": Array index out of bounds: reason=%d", reason); + return; + } + + const char *reason_str = domain_reasons[state][reason]; + /* Array size for domain reasons is fixed, but different domain states can + * have different number of reasons. We need to check if reason was + * successfully parsed */ + if (!reason_str) { + ERROR(PLUGIN_NAME ": Invalid reason (%d) for domain state: %s", reason, + state_str); + return; + } +#else + const char *reason_str = "N/A"; +#endif + + ssnprintf(msg, sizeof(msg), "Domain state: %s. Reason: %s", state_str, + reason_str); + + int severity; + switch (state) { + case VIR_DOMAIN_NOSTATE: + case VIR_DOMAIN_RUNNING: + case VIR_DOMAIN_SHUTDOWN: + case VIR_DOMAIN_SHUTOFF: + severity = NOTIF_OKAY; + break; + case VIR_DOMAIN_BLOCKED: + case VIR_DOMAIN_PAUSED: +#ifdef DOM_STATE_PMSUSPENDED + case VIR_DOMAIN_PMSUSPENDED: +#endif + severity = NOTIF_WARNING; + break; + case VIR_DOMAIN_CRASHED: + severity = NOTIF_FAILURE; + break; + default: + ERROR(PLUGIN_NAME ": Unrecognized domain state (%d)", state); + return; + } + submit_notif(dom, severity, msg, "domain_state", NULL); } static int lv_config(const char *key, const char *value) { @@ -453,35 +1024,588 @@ static int lv_config(const char *key, const char *value) { return 0; } + if (strcasecmp(key, "Instances") == 0) { + char *eptr = NULL; + double val = strtod(value, &eptr); + + if (*eptr != '\0') { + ERROR(PLUGIN_NAME " plugin: Invalid value for Instances = '%s'", value); + return 1; + } + if (val <= 0) { + ERROR(PLUGIN_NAME " plugin: Instances <= 0 makes no sense."); + return 1; + } + if (val > NR_INSTANCES_MAX) { + ERROR(PLUGIN_NAME " plugin: Instances=%f > NR_INSTANCES_MAX=%i" + " use a lower setting or recompile the plugin.", + val, NR_INSTANCES_MAX); + return 1; + } + + nr_instances = (int)val; + DEBUG(PLUGIN_NAME " plugin: configured %i instances", nr_instances); + return 0; + } + + if (strcasecmp(key, "ExtraStats") == 0) { + char *localvalue = strdup(value); + if (localvalue != NULL) { + char *exstats[EX_STATS_MAX_FIELDS]; + int numexstats = + strsplit(localvalue, exstats, STATIC_ARRAY_SIZE(exstats)); + extra_stats = parse_ex_stats_flags(exstats, numexstats); + sfree(localvalue); + +#ifdef HAVE_JOB_STATS + if ((extra_stats & ex_stats_job_stats_completed) && + (extra_stats & ex_stats_job_stats_background)) { + ERROR(PLUGIN_NAME " plugin: Invalid job stats configuration. Only one " + "type of job statistics can be collected at the same " + "time"); + return 1; + } +#endif + } + } + /* Unrecognised option. */ return -1; } -static int lv_read(void) { - time_t t; - +static int lv_connect(void) { if (conn == NULL) { - /* `conn_string == NULL' is acceptable. */ - conn = virConnectOpenReadOnly(conn_string); +/* `conn_string == NULL' is acceptable */ +#ifdef HAVE_FS_INFO + /* virDomainGetFSInfo requires full read-write access connection */ + if (extra_stats & ex_stats_fs_info) + conn = virConnectOpen(conn_string); + else +#endif + conn = virConnectOpenReadOnly(conn_string); if (conn == NULL) { c_complain(LOG_ERR, &conn_complain, PLUGIN_NAME " plugin: Unable to connect: " - "virConnectOpenReadOnly failed."); + "virConnectOpen failed."); + return -1; + } + int status = virNodeGetInfo(conn, &nodeinfo); + if (status != 0) { + ERROR(PLUGIN_NAME ": virNodeGetInfo 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_domain_block_info(virDomainPtr dom, const char *path, + struct lv_block_info *binfo) { +#ifdef HAVE_BLOCK_STATS_FLAGS + virTypedParameterPtr params = NULL; + int nparams = 0; + int rc = -1; + int ret = virDomainBlockStatsFlags(dom, path, NULL, &nparams, 0); + if (ret < 0 || nparams == 0) { + VIRT_ERROR(conn, "getting the disk params count"); + return -1; + } + + params = calloc(nparams, sizeof(virTypedParameter)); + if (params == NULL) { + ERROR("virt plugin: alloc(%i) for block=%s parameters failed.", nparams, + path); + return -1; + } + ret = virDomainBlockStatsFlags(dom, path, params, &nparams, 0); + if (ret < 0) { + VIRT_ERROR(conn, "getting the disk params values"); + goto done; + } + + rc = get_block_info(binfo, params, nparams); + +done: + virTypedParamsFree(params, nparams); + return rc; +#else + return virDomainBlockStats(dom, path, &(binfo->bi), sizeof(binfo->bi)); +#endif /* HAVE_BLOCK_STATS_FLAGS */ +} + +#ifdef HAVE_PERF_STATS +static void perf_submit(virDomainStatsRecordPtr stats) { + for (int i = 0; i < stats->nparams; ++i) { + /* Replace '.' with '_' in event field to match other metrics' naming + * convention */ + char *c = strchr(stats->params[i].field, '.'); + if (c) + *c = '_'; + submit(stats->dom, "perf", stats->params[i].field, + &(value_t){.derive = stats->params[i].value.ul}, 1); + } +} + +static int get_perf_events(virDomainPtr domain) { + virDomainStatsRecordPtr *stats = NULL; + /* virDomainListGetStats requires a NULL terminated list of domains */ + virDomainPtr domain_array[] = {domain, NULL}; + + int status = + virDomainListGetStats(domain_array, VIR_DOMAIN_STATS_PERF, &stats, 0); + if (status == -1) { + ERROR("virt plugin: virDomainListGetStats failed with status %i.", status); + return status; + } + + for (int i = 0; i < status; ++i) + perf_submit(stats[i]); + + virDomainStatsRecordListFree(stats); + return 0; +} +#endif /* HAVE_PERF_STATS */ + +static void vcpu_pin_submit(virDomainPtr dom, int max_cpus, int vcpu, + unsigned char *cpu_maps, int cpu_map_len) { + for (int cpu = 0; cpu < max_cpus; ++cpu) { + char type_instance[DATA_MAX_NAME_LEN]; + _Bool is_set = VIR_CPU_USABLE(cpu_maps, cpu_map_len, vcpu, cpu) ? 1 : 0; + + ssnprintf(type_instance, sizeof(type_instance), "vcpu_%d-cpu_%d", vcpu, + cpu); + submit(dom, "cpu_affinity", type_instance, &(value_t){.gauge = is_set}, 1); + } +} + +static int get_vcpu_stats(virDomainPtr domain, unsigned short nr_virt_cpu) { + int max_cpus = VIR_NODEINFO_MAXCPUS(nodeinfo); + int cpu_map_len = VIR_CPU_MAPLEN(max_cpus); + + virVcpuInfoPtr vinfo = calloc(nr_virt_cpu, sizeof(vinfo[0])); + if (vinfo == NULL) { + ERROR(PLUGIN_NAME " plugin: malloc failed."); + return -1; + } + + unsigned char *cpumaps = calloc(nr_virt_cpu, cpu_map_len); + if (cpumaps == NULL) { + ERROR(PLUGIN_NAME " plugin: malloc failed."); + sfree(vinfo); + return -1; + } + + int status = + virDomainGetVcpus(domain, vinfo, nr_virt_cpu, cpumaps, cpu_map_len); + if (status < 0) { + ERROR(PLUGIN_NAME " plugin: virDomainGetVcpus failed with status %i.", + status); + sfree(cpumaps); + sfree(vinfo); + return status; + } + + for (int i = 0; i < nr_virt_cpu; ++i) { + vcpu_submit(vinfo[i].cpuTime, domain, vinfo[i].number, "virt_vcpu"); + if (extra_stats & ex_stats_vcpupin) + vcpu_pin_submit(domain, max_cpus, i, cpumaps, cpu_map_len); + } + + sfree(cpumaps); + sfree(vinfo); + return 0; +} + +#ifdef HAVE_DOM_REASON +static int get_domain_state(virDomainPtr domain) { + int domain_state = 0; + int domain_reason = 0; + + int status = virDomainGetState(domain, &domain_state, &domain_reason, 0); + if (status != 0) { + ERROR(PLUGIN_NAME " plugin: virDomainGetState failed with status %i.", + status); + return status; + } + + domain_state_submit(domain, domain_state, domain_reason); + return status; +} +#endif /* HAVE_DOM_REASON */ + +static int get_memory_stats(virDomainPtr domain) { + virDomainMemoryStatPtr minfo = + calloc(VIR_DOMAIN_MEMORY_STAT_NR, sizeof(virDomainMemoryStatStruct)); + if (minfo == NULL) { + ERROR("virt plugin: malloc failed."); + return -1; + } + + int mem_stats = + virDomainMemoryStats(domain, minfo, VIR_DOMAIN_MEMORY_STAT_NR, 0); + if (mem_stats < 0) { + ERROR("virt plugin: virDomainMemoryStats failed with mem_stats %i.", + mem_stats); + sfree(minfo); + return mem_stats; + } + + for (int i = 0; i < mem_stats; i++) + memory_stats_submit((gauge_t)minfo[i].val * 1024, domain, minfo[i].tag); + + sfree(minfo); + return 0; +} + +#ifdef HAVE_DISK_ERR +static void disk_err_submit(virDomainPtr domain, + virDomainDiskErrorPtr disk_err) { + submit(domain, "disk_error", disk_err->disk, + &(value_t){.gauge = disk_err->error}, 1); +} + +static int get_disk_err(virDomainPtr domain) { + /* Get preferred size of disk errors array */ + int disk_err_count = virDomainGetDiskErrors(domain, NULL, 0, 0); + if (disk_err_count == -1) { + ERROR(PLUGIN_NAME + " plugin: failed to get preferred size of disk errors array"); + return -1; + } + + DEBUG(PLUGIN_NAME + " plugin: preferred size of disk errors array: %d for domain %s", + disk_err_count, virDomainGetName(domain)); + virDomainDiskError disk_err[disk_err_count]; + + disk_err_count = virDomainGetDiskErrors(domain, disk_err, disk_err_count, 0); + if (disk_err_count == -1) { + ERROR(PLUGIN_NAME " plugin: virDomainGetDiskErrors failed with status %d", + disk_err_count); + return -1; + } + + DEBUG(PLUGIN_NAME " plugin: detected %d disk errors in domain %s", + disk_err_count, virDomainGetName(domain)); + + for (int i = 0; i < disk_err_count; ++i) { + disk_err_submit(domain, &disk_err[i]); + sfree(disk_err[i].disk); + } + + return 0; +} +#endif /* HAVE_DISK_ERR */ + +static int get_block_stats(struct block_device *block_dev) { + + if (!block_dev) { + ERROR(PLUGIN_NAME " plugin: get_block_stats NULL pointer"); + return -1; + } + + struct lv_block_info binfo; + init_block_info(&binfo); + + if (lv_domain_block_info(block_dev->dom, block_dev->path, &binfo) < 0) { + ERROR(PLUGIN_NAME " plugin: lv_domain_block_info failed"); + return -1; + } + + disk_submit(&binfo, block_dev->dom, block_dev->path); + return 0; +} + +#ifdef HAVE_FS_INFO + +#define NM_ADD_ITEM(_fun, _name, _val) \ + do { \ + ret = _fun(¬if, _name, _val); \ + if (ret != 0) { \ + ERROR(PLUGIN_NAME " plugin: failed to add notification metadata"); \ + goto cleanup; \ + } \ + } while (0) + +#define NM_ADD_STR_ITEMS(_items, _size) \ + do { \ + for (int _i = 0; _i < _size; ++_i) { \ + DEBUG(PLUGIN_NAME \ + " plugin: Adding notification metadata name=%s value=%s", \ + _items[_i].name, _items[_i].value); \ + NM_ADD_ITEM(plugin_notification_meta_add_string, _items[_i].name, \ + _items[_i].value); \ + } \ + } while (0) + +static int fs_info_notify(virDomainPtr domain, virDomainFSInfoPtr fs_info) { + notification_t notif; + int ret = 0; + + /* Local struct, just for the purpose of this function. */ + typedef struct nm_str_item_s { + const char *name; + const char *value; + } nm_str_item_t; + + nm_str_item_t fs_dev_alias[fs_info->ndevAlias]; + nm_str_item_t fs_str_items[] = { + {.name = "mountpoint", .value = fs_info->mountpoint}, + {.name = "name", .value = fs_info->name}, + {.name = "fstype", .value = fs_info->fstype}}; + + for (int i = 0; i < fs_info->ndevAlias; ++i) { + fs_dev_alias[i].name = "devAlias"; + fs_dev_alias[i].value = fs_info->devAlias[i]; + } + + init_notif(¬if, domain, NOTIF_OKAY, "File system information", + "file_system", NULL); + NM_ADD_STR_ITEMS(fs_str_items, STATIC_ARRAY_SIZE(fs_str_items)); + NM_ADD_ITEM(plugin_notification_meta_add_unsigned_int, "ndevAlias", + fs_info->ndevAlias); + NM_ADD_STR_ITEMS(fs_dev_alias, fs_info->ndevAlias); + + plugin_dispatch_notification(¬if); + +cleanup: + if (notif.meta) + plugin_notification_meta_free(notif.meta); + return ret; +} + +#undef RETURN_ON_ERR +#undef NM_ADD_STR_ITEMS + +static int get_fs_info(virDomainPtr domain) { + virDomainFSInfoPtr *fs_info = NULL; + int ret = 0; + + int mount_points_cnt = virDomainGetFSInfo(domain, &fs_info, 0); + if (mount_points_cnt == -1) { + ERROR(PLUGIN_NAME " plugin: virDomainGetFSInfo failed: %d", + mount_points_cnt); + return mount_points_cnt; + } + + for (int i = 0; i < mount_points_cnt; ++i) { + if (fs_info_notify(domain, fs_info[i]) != 0) { + ERROR(PLUGIN_NAME " plugin: failed to send file system notification " + "for mount point %s", + fs_info[i]->mountpoint); + ret = -1; + } + virDomainFSInfoFree(fs_info[i]); + } + + sfree(fs_info); + return ret; +} + +#endif /* HAVE_FS_INFO */ + +#ifdef HAVE_JOB_STATS +static void job_stats_submit(virDomainPtr domain, virTypedParameterPtr param) { + value_t vl = {0}; + + if (param->type == VIR_TYPED_PARAM_INT) + vl.derive = param->value.i; + else if (param->type == VIR_TYPED_PARAM_UINT) + vl.derive = param->value.ui; + else if (param->type == VIR_TYPED_PARAM_LLONG) + vl.derive = param->value.l; + else if (param->type == VIR_TYPED_PARAM_ULLONG) + vl.derive = param->value.ul; + else if (param->type == VIR_TYPED_PARAM_DOUBLE) + vl.derive = param->value.d; + else if (param->type == VIR_TYPED_PARAM_BOOLEAN) + vl.derive = param->value.b; + else if (param->type == VIR_TYPED_PARAM_STRING) { + submit_notif(domain, NOTIF_OKAY, param->value.s, "job_stats", param->field); + return; + } else { + ERROR(PLUGIN_NAME " plugin: unrecognized virTypedParameterType"); + return; + } + + submit(domain, "job_stats", param->field, &vl, 1); +} + +static int get_job_stats(virDomainPtr domain) { + int ret = 0; + int job_type = 0; + int nparams = 0; + virTypedParameterPtr params = NULL; + int flags = (extra_stats & ex_stats_job_stats_completed) + ? VIR_DOMAIN_JOB_STATS_COMPLETED + : 0; + + ret = virDomainGetJobStats(domain, &job_type, ¶ms, &nparams, flags); + if (ret != 0) { + ERROR(PLUGIN_NAME " plugin: virDomainGetJobStats failed: %d", ret); + return ret; + } + + DEBUG(PLUGIN_NAME " plugin: job_type=%d nparams=%d", job_type, nparams); + + for (int i = 0; i < nparams; ++i) { + DEBUG(PLUGIN_NAME " plugin: param[%d] field=%s type=%d", i, params[i].field, + params[i].type); + job_stats_submit(domain, ¶ms[i]); + } + + virTypedParamsFree(params, nparams); + return ret; +} +#endif /* HAVE_JOB_STATS */ + +static int get_domain_metrics(domain_t *domain) { + struct lv_info info; + + if (!domain || !domain->ptr) { + ERROR(PLUGIN_NAME ": get_domain_metrics: NULL pointer"); + return -1; + } + + init_lv_info(&info); + int status = lv_domain_info(domain->ptr, &info); + if (status != 0) { + ERROR(PLUGIN_NAME " plugin: virDomainGetInfo failed with status %i.", + status); + return -1; + } + + if (extra_stats & ex_stats_domain_state) { +#ifdef HAVE_DOM_REASON + /* At this point we already know domain's state from virDomainGetInfo call, + * however it doesn't provide a reason for entering particular state. + * We need to get it from virDomainGetState. + */ + GET_STATS(get_domain_state, "domain reason", domain->ptr); +#else + /* virDomainGetState is not available. Submit 0, which corresponds to + * unknown reason. */ + domain_state_submit(domain->ptr, info.di.state, 0); +#endif + } + + /* Gather remaining stats only for running domains */ + if (info.di.state != VIR_DOMAIN_RUNNING) + return 0; + + pcpu_submit(domain->ptr, &info); + cpu_submit(domain, info.di.cpuTime); + + memory_submit(domain->ptr, (gauge_t)info.di.memory * 1024); + + GET_STATS(get_vcpu_stats, "vcpu stats", domain->ptr, info.di.nrVirtCpu); + GET_STATS(get_memory_stats, "memory stats", domain->ptr); + +#ifdef HAVE_PERF_STATS + if (extra_stats & ex_stats_perf) + GET_STATS(get_perf_events, "performance monitoring events", domain->ptr); +#endif + +#ifdef HAVE_FS_INFO + if (extra_stats & ex_stats_fs_info) + GET_STATS(get_fs_info, "file system info", domain->ptr); +#endif + +#ifdef HAVE_DISK_ERR + if (extra_stats & ex_stats_disk_err) + GET_STATS(get_disk_err, "disk errors", domain->ptr); +#endif + +#ifdef HAVE_JOB_STATS + if (extra_stats & + (ex_stats_job_stats_completed | ex_stats_job_stats_background)) + GET_STATS(get_job_stats, "job stats", domain->ptr); +#endif + + /* Update cached virDomainInfo. It has to be done after cpu_submit */ + memcpy(&domain->info, &info.di, sizeof(domain->info)); + return 0; +} + +static int get_if_dev_stats(struct interface_device *if_dev) { + virDomainInterfaceStatsStruct stats = {0}; + char *display_name = NULL; + + if (!if_dev) { + ERROR(PLUGIN_NAME " plugin: get_if_dev_stats: NULL pointer"); + return -1; + } + + switch (interface_format) { + case if_address: + display_name = if_dev->address; + break; + case if_number: + display_name = if_dev->number; + break; + case if_name: + default: + display_name = if_dev->path; + } + + if (virDomainInterfaceStats(if_dev->dom, if_dev->path, &stats, + sizeof(stats)) != 0) { + ERROR(PLUGIN_NAME " plugin: virDomainInterfaceStats failed"); + return -1; + } + + if ((stats.rx_bytes != -1) && (stats.tx_bytes != -1)) + submit_derive2("if_octets", (derive_t)stats.rx_bytes, + (derive_t)stats.tx_bytes, if_dev->dom, display_name); + + if ((stats.rx_packets != -1) && (stats.tx_packets != -1)) + submit_derive2("if_packets", (derive_t)stats.rx_packets, + (derive_t)stats.tx_packets, if_dev->dom, display_name); + + if ((stats.rx_errs != -1) && (stats.tx_errs != -1)) + submit_derive2("if_errors", (derive_t)stats.rx_errs, + (derive_t)stats.tx_errs, if_dev->dom, display_name); + + if ((stats.rx_drop != -1) && (stats.tx_drop != -1)) + submit_derive2("if_dropped", (derive_t)stats.rx_drop, + (derive_t)stats.tx_drop, if_dev->dom, display_name); + return 0; +} + +static int lv_read(user_data_t *ud) { + time_t t; + struct lv_read_instance *inst = NULL; + struct lv_read_state *state = NULL; + + if (ud->data == NULL) { + ERROR(PLUGIN_NAME " plugin: NULL userdata"); + return -1; + } + + inst = ud->data; + state = &inst->read_state; + + if (inst->id == 0) { + if (lv_connect() < 0) + return -1; + } time(&t); /* Need to refresh domain or device lists? */ if ((last_refresh == (time_t)0) || ((interval > 0) && ((last_refresh + interval) <= t))) { - if (refresh_lists() != 0) { - if (conn != NULL) - virConnectClose(conn); - conn = NULL; + if (refresh_lists(inst) != 0) { + if (inst->id == 0) + lv_disconnect(); return -1; } last_refresh = t; @@ -489,7 +1613,7 @@ static int lv_read(void) { #if 0 for (int i = 0; i < nr_domains; ++i) - fprintf (stderr, "domain %s\n", virDomainGetName (domains[i])); + fprintf (stderr, "domain %s\n", virDomainGetName (state->domains[i].ptr)); for (int i = 0; i < nr_block_devices; ++i) fprintf (stderr, "block device %d %s:%s\n", i, virDomainGetName (block_devices[i].dom), @@ -500,145 +1624,191 @@ static int lv_read(void) { interface_devices[i].path); #endif - /* Get CPU usage, memory, VCPU usage for each domain. */ - for (int i = 0; i < nr_domains; ++i) { - virDomainInfo info; - virVcpuInfoPtr vinfo = NULL; - virDomainMemoryStatPtr minfo = NULL; - int status; + /* Get domains' metrics */ + for (int i = 0; i < state->nr_domains; ++i) { + int status = get_domain_metrics(&state->domains[i]); + if (status != 0) + ERROR(PLUGIN_NAME " failed to get metrics for domain=%s", + virDomainGetName(state->domains[i].ptr)); + } - status = virDomainGetInfo(domains[i], &info); - if (status != 0) { - ERROR(PLUGIN_NAME " plugin: virDomainGetInfo failed with status %i.", - status); - continue; - } + /* Get block device stats for each domain. */ + for (int i = 0; i < state->nr_block_devices; ++i) { + int status = get_block_stats(&state->block_devices[i]); + if (status != 0) + ERROR(PLUGIN_NAME + " failed to get stats for block device (%s) in domain %s", + state->block_devices[i].path, + virDomainGetName(state->domains[i].ptr)); + } - if (info.state != VIR_DOMAIN_RUNNING) { - /* only gather stats for running domains */ - continue; - } + /* Get interface stats for each domain. */ + for (int i = 0; i < state->nr_interface_devices; ++i) { + int status = get_if_dev_stats(&state->interface_devices[i]); + if (status != 0) + ERROR(PLUGIN_NAME + " failed to get interface stats for device (%s) in domain %s", + state->interface_devices[i].path, + virDomainGetName(state->interface_devices[i].dom)); + } - cpu_submit(info.cpuTime, domains[i], "virt_cpu_total"); - memory_submit((gauge_t)info.memory * 1024, domains[i]); + return 0; +} - vinfo = malloc(info.nrVirtCpu * sizeof(vinfo[0])); - if (vinfo == NULL) { - ERROR(PLUGIN_NAME " plugin: malloc failed."); - continue; - } +static int lv_init_instance(size_t i, plugin_read_cb callback) { + struct lv_user_data *lv_ud = &(lv_read_user_data[i]); + struct lv_read_instance *inst = &(lv_ud->inst); - status = virDomainGetVcpus(domains[i], vinfo, info.nrVirtCpu, - /* cpu map = */ NULL, /* cpu map length = */ 0); - if (status < 0) { - ERROR(PLUGIN_NAME " plugin: virDomainGetVcpus failed with status %i.", - status); - sfree(vinfo); - continue; - } + memset(lv_ud, 0, sizeof(*lv_ud)); - for (int j = 0; j < info.nrVirtCpu; ++j) - vcpu_submit(vinfo[j].cpuTime, domains[i], vinfo[j].number, "virt_vcpu"); + ssnprintf(inst->tag, sizeof(inst->tag), "%s-%zu", PLUGIN_NAME, i); + inst->id = i; - sfree(vinfo); + user_data_t *ud = &(lv_ud->ud); + ud->data = inst; + ud->free_func = NULL; - minfo = - malloc(VIR_DOMAIN_MEMORY_STAT_NR * sizeof(virDomainMemoryStatStruct)); - if (minfo == NULL) { - ERROR("virt plugin: malloc failed."); - continue; - } + INFO(PLUGIN_NAME " plugin: reader %s initialized", inst->tag); + return plugin_register_complex_read(NULL, inst->tag, callback, 0, ud); +} - status = - virDomainMemoryStats(domains[i], minfo, VIR_DOMAIN_MEMORY_STAT_NR, 0); +static void lv_clean_read_state(struct lv_read_state *state) { + free_block_devices(state); + free_interface_devices(state); + free_domains(state); +} - if (status < 0) { - ERROR("virt plugin: virDomainMemoryStats failed with status %i.", status); - sfree(minfo); - continue; - } +static void lv_fini_instance(size_t i) { + struct lv_read_instance *inst = &(lv_read_user_data[i].inst); + struct lv_read_state *state = &(inst->read_state); - for (int j = 0; j < status; j++) { - memory_stats_submit((gauge_t)minfo[j].val * 1024, domains[i], - minfo[j].tag); - } + lv_clean_read_state(state); + INFO(PLUGIN_NAME " plugin: reader %s finalized", inst->tag); +} - sfree(minfo); - } +static int lv_init(void) { + if (virInitialize() != 0) + return -1; - /* Get block device stats for each domain. */ - for (int i = 0; i < nr_block_devices; ++i) { - struct _virDomainBlockStats stats; + if (lv_connect() != 0) + return -1; - if (virDomainBlockStats(block_devices[i].dom, block_devices[i].path, &stats, - sizeof stats) != 0) - continue; + DEBUG(PLUGIN_NAME " plugin: starting %i instances", nr_instances); - char *type_instance = NULL; - if (blockdevice_format_basename && blockdevice_format == source) - type_instance = strdup(basename(block_devices[i].path)); - else - type_instance = strdup(block_devices[i].path); + for (int i = 0; i < nr_instances; ++i) + lv_init_instance(i, lv_read); - if ((stats.rd_req != -1) && (stats.wr_req != -1)) - submit_derive2("disk_ops", (derive_t)stats.rd_req, (derive_t)stats.wr_req, - block_devices[i].dom, type_instance); + return 0; +} - if ((stats.rd_bytes != -1) && (stats.wr_bytes != -1)) - submit_derive2("disk_octets", (derive_t)stats.rd_bytes, - (derive_t)stats.wr_bytes, block_devices[i].dom, - type_instance); +/* + * returns 0 on success and <0 on error + */ +static int lv_domain_get_tag(xmlXPathContextPtr xpath_ctx, const char *dom_name, + char *dom_tag) { + char xpath_str[BUFFER_MAX_LEN] = {'\0'}; + xmlXPathObjectPtr xpath_obj = NULL; + xmlNodePtr xml_node = NULL; + int ret = -1; + int err; + + err = xmlXPathRegisterNs(xpath_ctx, + (const xmlChar *)METADATA_VM_PARTITION_PREFIX, + (const xmlChar *)METADATA_VM_PARTITION_URI); + if (err) { + ERROR(PLUGIN_NAME " plugin: xmlXpathRegisterNs(%s, %s) failed on domain %s", + METADATA_VM_PARTITION_PREFIX, METADATA_VM_PARTITION_URI, dom_name); + goto done; + } - sfree(type_instance); - } /* for (nr_block_devices) */ + ssnprintf(xpath_str, sizeof(xpath_str), "/domain/metadata/%s:%s/text()", + METADATA_VM_PARTITION_PREFIX, METADATA_VM_PARTITION_ELEMENT); + xpath_obj = xmlXPathEvalExpression((xmlChar *)xpath_str, xpath_ctx); + if (xpath_obj == NULL) { + ERROR(PLUGIN_NAME " plugin: xmlXPathEval(%s) failed on domain %s", + xpath_str, dom_name); + goto done; + } - /* Get interface stats for each domain. */ - for (int i = 0; i < nr_interface_devices; ++i) { - struct _virDomainInterfaceStats stats; - char *display_name = NULL; + if (xpath_obj->type != XPATH_NODESET) { + ERROR(PLUGIN_NAME " plugin: xmlXPathEval(%s) unexpected return type %d " + "(wanted %d) on domain %s", + xpath_str, xpath_obj->type, XPATH_NODESET, dom_name); + goto done; + } - switch (interface_format) { - case if_address: - display_name = interface_devices[i].address; - break; - case if_number: - display_name = interface_devices[i].number; - break; - case if_name: - default: - display_name = interface_devices[i].path; - } + /* + * from now on there is no real error, it's ok if a domain + * doesn't have the metadata partition tag. + */ + ret = 0; + if (xpath_obj->nodesetval == NULL || xpath_obj->nodesetval->nodeNr != 1) { + DEBUG(PLUGIN_NAME " plugin: xmlXPathEval(%s) return nodeset size=%i " + "expected=1 on domain %s", + xpath_str, + (xpath_obj->nodesetval == NULL) ? 0 : xpath_obj->nodesetval->nodeNr, + dom_name); + } else { + xml_node = xpath_obj->nodesetval->nodeTab[0]; + sstrncpy(dom_tag, (const char *)xml_node->content, PARTITION_TAG_MAX_LEN); + } - if (virDomainInterfaceStats(interface_devices[i].dom, - interface_devices[i].path, &stats, - sizeof stats) != 0) - continue; +done: + /* deregister to clean up */ + err = xmlXPathRegisterNs(xpath_ctx, + (const xmlChar *)METADATA_VM_PARTITION_PREFIX, NULL); + if (err) { + /* we can't really recover here */ + ERROR(PLUGIN_NAME + " plugin: deregistration of namespace %s failed for domain %s", + METADATA_VM_PARTITION_PREFIX, dom_name); + } + if (xpath_obj) + xmlXPathFreeObject(xpath_obj); - if ((stats.rx_bytes != -1) && (stats.tx_bytes != -1)) - submit_derive2("if_octets", (derive_t)stats.rx_bytes, - (derive_t)stats.tx_bytes, interface_devices[i].dom, - display_name); + return ret; +} - if ((stats.rx_packets != -1) && (stats.tx_packets != -1)) - submit_derive2("if_packets", (derive_t)stats.rx_packets, - (derive_t)stats.tx_packets, interface_devices[i].dom, - display_name); +static int is_known_tag(const char *dom_tag) { + for (int i = 0; i < nr_instances; ++i) + if (!strcmp(dom_tag, lv_read_user_data[i].inst.tag)) + return 1; + return 0; +} - if ((stats.rx_errs != -1) && (stats.tx_errs != -1)) - submit_derive2("if_errors", (derive_t)stats.rx_errs, - (derive_t)stats.tx_errs, interface_devices[i].dom, - display_name); +static int lv_instance_include_domain(struct lv_read_instance *inst, + const char *dom_name, + const char *dom_tag) { + if ((dom_tag[0] != '\0') && (strcmp(dom_tag, inst->tag) == 0)) + return 1; - if ((stats.rx_drop != -1) && (stats.tx_drop != -1)) - submit_derive2("if_dropped", (derive_t)stats.rx_drop, - (derive_t)stats.tx_drop, interface_devices[i].dom, - display_name); - } /* for (nr_interface_devices) */ + /* instance#0 will always be there, so it is in charge of extra duties */ + if (inst->id == 0) { + if (dom_tag[0] == '\0' || !is_known_tag(dom_tag)) { + DEBUG(PLUGIN_NAME " plugin#%s: refreshing domain %s " + "with unknown tag '%s'", + inst->tag, dom_name, dom_tag); + return 1; + } + } return 0; } -static int refresh_lists(void) { +/* + virConnectListAllDomains() appeared in 0.10.2 + Note that LIBVIR_CHECK_VERSION appeared a year later, so + in some systems which actually have virConnectListAllDomains() + we can't detect this. + */ +#ifdef LIBVIR_CHECK_VERSION +# if LIBVIR_CHECK_VERSION(0,10,2) +# define HAVE_LIST_ALL_DOMAINS 1 +# endif +#endif + +static int refresh_lists(struct lv_read_instance *inst) { + struct lv_read_state *state = &inst->read_state; int n; n = virConnectNumOfDomains(conn); @@ -647,7 +1817,13 @@ static int refresh_lists(void) { return -1; } + lv_clean_read_state(state); + if (n > 0) { +#ifdef HAVE_LIST_ALL_DOMAINS + virDomainPtr *domains; + n = virConnectListAllDomains (conn, &domains, VIR_CONNECT_LIST_DOMAINS_ACTIVE); +#else int *domids; /* Get list of domains. */ @@ -658,31 +1834,38 @@ static int refresh_lists(void) { } n = virConnectListDomains(conn, domids, n); +#endif + if (n < 0) { VIRT_ERROR(conn, "reading list of domains"); +#ifndef HAVE_LIST_ALL_DOMAINS sfree(domids); +#endif return -1; } - free_block_devices(); - free_interface_devices(); - free_domains(); - /* Fetch each domain and add it to the list, unless ignore. */ for (int i = 0; i < n; ++i) { - virDomainPtr dom = NULL; const char *name; char *xml = NULL; xmlDocPtr xml_doc = NULL; xmlXPathContextPtr xpath_ctx = NULL; xmlXPathObjectPtr xpath_obj = NULL; + char tag[PARTITION_TAG_MAX_LEN] = {'\0'}; + virDomainInfo info; + int status; +#ifdef HAVE_LIST_ALL_DOMAINS + virDomainPtr dom = domains[i]; +#else + virDomainPtr dom = NULL; dom = virDomainLookupByID(conn, domids[i]); if (dom == NULL) { VIRT_ERROR(conn, "virDomainLookupByID"); /* Could be that the domain went away -- ignore it anyway. */ continue; } +#endif name = virDomainGetName(dom); if (name == NULL) { @@ -690,14 +1873,21 @@ static int refresh_lists(void) { goto cont; } - if (il_domains && ignorelist_match(il_domains, name) != 0) - goto cont; + status = virDomainGetInfo(dom, &info); + if (status != 0) { + ERROR(PLUGIN_NAME " plugin: virDomainGetInfo failed with status %i.", + status); + continue; + } - if (add_domain(dom) < 0) { - ERROR(PLUGIN_NAME " plugin: malloc failed."); - goto cont; + if (info.state != VIR_DOMAIN_RUNNING) { + DEBUG(PLUGIN_NAME " plugin: skipping inactive domain %s", name); + continue; } + if (il_domains && ignorelist_match(il_domains, name) != 0) + goto cont; + /* Get a list of devices for this domain. */ xml = virDomainGetXMLDesc(dom, 0); if (!xml) { @@ -714,11 +1904,24 @@ static int refresh_lists(void) { xpath_ctx = xmlXPathNewContext(xml_doc); + if (lv_domain_get_tag(xpath_ctx, name, tag) < 0) { + ERROR(PLUGIN_NAME " plugin: lv_domain_get_tag failed."); + goto cont; + } + + if (!lv_instance_include_domain(inst, name, tag)) + goto cont; + + if (add_domain(state, dom) < 0) { + ERROR(PLUGIN_NAME " plugin: malloc failed."); + goto cont; + } + /* Block devices. */ - char *bd_xmlpath = "/domain/devices/disk/target[@dev]"; + const char *bd_xmlpath = "/domain/devices/disk/target[@dev]"; if (blockdevice_format == source) bd_xmlpath = "/domain/devices/disk/source[@dev]"; - xpath_obj = xmlXPathEval((xmlChar *)bd_xmlpath, xpath_ctx); + xpath_obj = xmlXPathEval((const xmlChar *)bd_xmlpath, xpath_ctx); if (xpath_obj == NULL || xpath_obj->type != XPATH_NODESET || xpath_obj->nodesetval == NULL) @@ -739,7 +1942,7 @@ static int refresh_lists(void) { ignore_device_match(il_block_devices, name, path) != 0) goto cont2; - add_block_device(dom, path); + add_block_device(state, dom, path); cont2: if (path) xmlFree(path); @@ -785,7 +1988,7 @@ static int refresh_lists(void) { ignore_device_match(il_interface_devices, name, address) != 0)) goto cont3; - add_interface_device(dom, path, address, j + 1); + add_interface_device(state, dom, path, address, j + 1); cont3: if (path) xmlFree(path); @@ -803,60 +2006,74 @@ static int refresh_lists(void) { sfree(xml); } +#ifdef HAVE_LIST_ALL_DOMAINS + sfree (domains); +#else sfree(domids); +#endif } + DEBUG(PLUGIN_NAME " plugin#%s: refreshing" + " domains=%i block_devices=%i iface_devices=%i", + inst->tag, state->nr_domains, state->nr_block_devices, + state->nr_interface_devices); + return 0; } -static void free_domains(void) { - if (domains) { - for (int i = 0; i < nr_domains; ++i) - virDomainFree(domains[i]); - sfree(domains); +static void free_domains(struct lv_read_state *state) { + if (state->domains) { + for (int i = 0; i < state->nr_domains; ++i) + virDomainFree(state->domains[i].ptr); + sfree(state->domains); } - domains = NULL; - nr_domains = 0; + state->domains = NULL; + state->nr_domains = 0; } -static int add_domain(virDomainPtr dom) { - virDomainPtr *new_ptr; - int new_size = sizeof(domains[0]) * (nr_domains + 1); +static int add_domain(struct lv_read_state *state, virDomainPtr dom) { + domain_t *new_ptr; + int new_size = sizeof(state->domains[0]) * (state->nr_domains + 1); - if (domains) - new_ptr = realloc(domains, new_size); + if (state->domains) + new_ptr = realloc(state->domains, new_size); else new_ptr = malloc(new_size); if (new_ptr == NULL) return -1; - domains = new_ptr; - domains[nr_domains] = dom; - return nr_domains++; + state->domains = new_ptr; + state->domains[state->nr_domains].ptr = dom; + memset(&state->domains[state->nr_domains].info, 0, + sizeof(state->domains[state->nr_domains].info)); + + return state->nr_domains++; } -static void free_block_devices(void) { - if (block_devices) { - for (int i = 0; i < nr_block_devices; ++i) - sfree(block_devices[i].path); - sfree(block_devices); +static void free_block_devices(struct lv_read_state *state) { + if (state->block_devices) { + for (int i = 0; i < state->nr_block_devices; ++i) + sfree(state->block_devices[i].path); + sfree(state->block_devices); } - block_devices = NULL; - nr_block_devices = 0; + state->block_devices = NULL; + state->nr_block_devices = 0; } -static int add_block_device(virDomainPtr dom, const char *path) { +static int add_block_device(struct lv_read_state *state, virDomainPtr dom, + const char *path) { struct block_device *new_ptr; - int new_size = sizeof(block_devices[0]) * (nr_block_devices + 1); + int new_size = + sizeof(state->block_devices[0]) * (state->nr_block_devices + 1); char *path_copy; path_copy = strdup(path); if (!path_copy) return -1; - if (block_devices) - new_ptr = realloc(block_devices, new_size); + if (state->block_devices) + new_ptr = realloc(state->block_devices, new_size); else new_ptr = malloc(new_size); @@ -864,29 +2081,31 @@ static int add_block_device(virDomainPtr dom, const char *path) { sfree(path_copy); return -1; } - block_devices = new_ptr; - block_devices[nr_block_devices].dom = dom; - block_devices[nr_block_devices].path = path_copy; - return nr_block_devices++; + state->block_devices = new_ptr; + state->block_devices[state->nr_block_devices].dom = dom; + state->block_devices[state->nr_block_devices].path = path_copy; + return state->nr_block_devices++; } -static void free_interface_devices(void) { - if (interface_devices) { - for (int i = 0; i < nr_interface_devices; ++i) { - sfree(interface_devices[i].path); - sfree(interface_devices[i].address); - sfree(interface_devices[i].number); +static void free_interface_devices(struct lv_read_state *state) { + if (state->interface_devices) { + for (int i = 0; i < state->nr_interface_devices; ++i) { + sfree(state->interface_devices[i].path); + sfree(state->interface_devices[i].address); + sfree(state->interface_devices[i].number); } - sfree(interface_devices); + sfree(state->interface_devices); } - interface_devices = NULL; - nr_interface_devices = 0; + state->interface_devices = NULL; + state->nr_interface_devices = 0; } -static int add_interface_device(virDomainPtr dom, const char *path, - const char *address, unsigned int number) { +static int add_interface_device(struct lv_read_state *state, virDomainPtr dom, + const char *path, const char *address, + unsigned int number) { struct interface_device *new_ptr; - int new_size = sizeof(interface_devices[0]) * (nr_interface_devices + 1); + int new_size = + sizeof(state->interface_devices[0]) * (state->nr_interface_devices + 1); char *path_copy, *address_copy, number_string[15]; if ((path == NULL) || (address == NULL)) @@ -904,8 +2123,8 @@ static int add_interface_device(virDomainPtr dom, const char *path, snprintf(number_string, sizeof(number_string), "interface-%u", number); - if (interface_devices) - new_ptr = realloc(interface_devices, new_size); + if (state->interface_devices) + new_ptr = realloc(state->interface_devices, new_size); else new_ptr = malloc(new_size); @@ -914,12 +2133,13 @@ static int add_interface_device(virDomainPtr dom, const char *path, sfree(address_copy); return -1; } - interface_devices = new_ptr; - interface_devices[nr_interface_devices].dom = dom; - interface_devices[nr_interface_devices].path = path_copy; - interface_devices[nr_interface_devices].address = address_copy; - interface_devices[nr_interface_devices].number = strdup(number_string); - return nr_interface_devices++; + state->interface_devices = new_ptr; + state->interface_devices[state->nr_interface_devices].dom = dom; + state->interface_devices[state->nr_interface_devices].path = path_copy; + state->interface_devices[state->nr_interface_devices].address = address_copy; + state->interface_devices[state->nr_interface_devices].number = + strdup(number_string); + return state->nr_interface_devices++; } static int ignore_device_match(ignorelist_t *il, const char *domname, @@ -930,7 +2150,7 @@ static int ignore_device_match(ignorelist_t *il, const char *domname, if ((domname == NULL) || (devpath == NULL)) return 0; - n = sizeof(char) * (strlen(domname) + strlen(devpath) + 2); + n = strlen(domname) + strlen(devpath) + 2; name = malloc(n); if (name == NULL) { ERROR(PLUGIN_NAME " plugin: malloc failed."); @@ -943,13 +2163,11 @@ static int ignore_device_match(ignorelist_t *il, const char *domname, } static int lv_shutdown(void) { - free_block_devices(); - free_interface_devices(); - free_domains(); + for (int i = 0; i < nr_instances; ++i) { + lv_fini_instance(i); + } - if (conn != NULL) - virConnectClose(conn); - conn = NULL; + lv_disconnect(); ignorelist_free(il_domains); il_domains = NULL; @@ -964,10 +2182,5 @@ static int lv_shutdown(void) { void module_register(void) { plugin_register_config(PLUGIN_NAME, lv_config, config_keys, NR_CONFIG_KEYS); plugin_register_init(PLUGIN_NAME, lv_init); - plugin_register_read(PLUGIN_NAME, lv_read); plugin_register_shutdown(PLUGIN_NAME, lv_shutdown); } - -/* - * vim: shiftwidth=4 tabstop=8 softtabstop=4 expandtab fdm=marker - */ diff --git a/src/virt_test.c b/src/virt_test.c new file mode 100644 index 00000000..cb3cc254 --- /dev/null +++ b/src/virt_test.c @@ -0,0 +1,207 @@ +/** + * collectd - src/virt_test.c + * Copyright (C) 2016 Francesco Romani + * Based on + * collectd - src/ceph_test.c + * Copyright (C) 2015 Florian octo Forster + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; only version 2 of the License is applicable. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: + * Florian octo Forster + **/ + +#include "virt.c" /* sic */ +#include "testing.h" + +#include + +static const char minimal_xml[] = + "" + "" + "" + " " + ""; + +static const char minimal_metadata_xml[] = + "" + "" + "" + " " + " virt-0" + " " + ""; + +struct xml_state { + xmlDocPtr xml_doc; + xmlXPathContextPtr xpath_ctx; + xmlXPathObjectPtr xpath_obj; + char tag[PARTITION_TAG_MAX_LEN]; +}; + +static int init_state(struct xml_state *st, const char *xml) { + memset(st, 0, sizeof(*st)); + + st->xml_doc = xmlReadDoc((const xmlChar *)xml, NULL, NULL, XML_PARSE_NONET); + if (st->xml_doc == NULL) { + return -1; + } + st->xpath_ctx = xmlXPathNewContext(st->xml_doc); + if (st->xpath_ctx == NULL) { + return -1; + } + return 0; +} + +static void fini_state(struct xml_state *st) { + if (st->xpath_ctx) { + xmlXPathFreeContext(st->xpath_ctx); + st->xpath_ctx = NULL; + } + if (st->xml_doc) { + xmlFreeDoc(st->xml_doc); + st->xml_doc = NULL; + } +} + +#define TAG "virt-0" + +DEF_TEST(lv_domain_get_tag_no_metadata_xml) { + int err; + struct xml_state st; + err = init_state(&st, minimal_xml); + EXPECT_EQ_INT(0, err); + + err = lv_domain_get_tag(st.xpath_ctx, "test", st.tag); + + EXPECT_EQ_INT(0, err); + EXPECT_EQ_STR("", st.tag); + + fini_state(&st); + return 0; +} + +DEF_TEST(lv_domain_get_tag_valid_xml) { + int err; + struct xml_state st; + err = init_state(&st, minimal_metadata_xml); + EXPECT_EQ_INT(0, err); + + err = lv_domain_get_tag(st.xpath_ctx, "test", st.tag); + + EXPECT_EQ_INT(0, err); + EXPECT_EQ_STR(TAG, st.tag); + + return 0; +} + +DEF_TEST(lv_default_instance_include_domain_without_tag) { + struct lv_read_instance *inst = NULL; + int ret; + + ret = lv_init_instance(0, lv_read); + inst = &(lv_read_user_data[0].inst); + EXPECT_EQ_STR("virt-0", inst->tag); + + ret = lv_instance_include_domain(inst, "testing", ""); + EXPECT_EQ_INT(1, ret); + + lv_fini_instance(0); + return 0; +} + +DEF_TEST(lv_regular_instance_skip_domain_without_tag) { + struct lv_read_instance *inst = NULL; + int ret; + + ret = lv_init_instance(1, lv_read); + inst = &(lv_read_user_data[1].inst); + EXPECT_EQ_STR("virt-1", inst->tag); + + ret = lv_instance_include_domain(inst, "testing", ""); + EXPECT_EQ_INT(0, ret); + + lv_fini_instance(0); + return 0; +} + +DEF_TEST(lv_include_domain_matching_tags) { + struct lv_read_instance *inst = NULL; + int ret; + + ret = lv_init_instance(0, lv_read); + inst = &(lv_read_user_data[0].inst); + EXPECT_EQ_STR("virt-0", inst->tag); + + ret = lv_instance_include_domain(inst, "testing", "virt-0"); + EXPECT_EQ_INT(1, ret); + + ret = lv_init_instance(1, lv_read); + inst = &(lv_read_user_data[1].inst); + EXPECT_EQ_STR("virt-1", inst->tag); + + ret = lv_instance_include_domain(inst, "testing", "virt-1"); + EXPECT_EQ_INT(1, ret); + + lv_fini_instance(0); + lv_fini_instance(1); + return 0; +} + +DEF_TEST(lv_default_instance_include_domain_with_unknown_tag) { + struct lv_read_instance *inst = NULL; + int ret; + + ret = lv_init_instance(0, lv_read); + inst = &(lv_read_user_data[0].inst); + EXPECT_EQ_STR("virt-0", inst->tag); + + ret = lv_instance_include_domain(inst, "testing", "unknownFormat-tag"); + EXPECT_EQ_INT(1, ret); + + lv_fini_instance(0); + return 0; +} + +DEF_TEST(lv_regular_instance_skip_domain_with_unknown_tag) { + struct lv_read_instance *inst = NULL; + int ret; + + ret = lv_init_instance(1, lv_read); + inst = &(lv_read_user_data[1].inst); + EXPECT_EQ_STR("virt-1", inst->tag); + + ret = lv_instance_include_domain(inst, "testing", "unknownFormat-tag"); + EXPECT_EQ_INT(0, ret); + + lv_fini_instance(0); + return 0; +} +#undef TAG + +int main(void) { + RUN_TEST(lv_domain_get_tag_no_metadata_xml); + RUN_TEST(lv_domain_get_tag_valid_xml); + + RUN_TEST(lv_default_instance_include_domain_without_tag); + RUN_TEST(lv_regular_instance_skip_domain_without_tag); + RUN_TEST(lv_include_domain_matching_tags); + RUN_TEST(lv_default_instance_include_domain_with_unknown_tag); + RUN_TEST(lv_regular_instance_skip_domain_with_unknown_tag); + + END_TEST; +} + +/* vim: set sw=2 sts=2 et : */ diff --git a/src/vmem.c b/src/vmem.c index cd9e7d28..0d7769b7 100644 --- a/src/vmem.c +++ b/src/vmem.c @@ -260,5 +260,3 @@ void module_register(void) { plugin_register_config("vmem", vmem_config, config_keys, config_keys_num); plugin_register_read("vmem", vmem_read); } /* void module_register */ - -/* vim: set sw=2 sts=2 ts=8 : */ diff --git a/src/vserver.c b/src/vserver.c index c5a7fb33..96af6fc8 100644 --- a/src/vserver.c +++ b/src/vserver.c @@ -321,5 +321,3 @@ void module_register(void) { plugin_register_init("vserver", vserver_init); plugin_register_read("vserver", vserver_read); } /* void module_register(void) */ - -/* vim: set ts=4 sw=4 noexpandtab : */ diff --git a/src/write_graphite.c b/src/write_graphite.c index b85ab470..3fac9cca 100644 --- a/src/write_graphite.c +++ b/src/write_graphite.c @@ -583,5 +583,3 @@ static int wg_config(oconfig_item_t *ci) { void module_register(void) { plugin_register_complex_config("write_graphite", wg_config); } - -/* vim: set sw=4 ts=4 sts=4 tw=78 et : */ diff --git a/src/write_http.c b/src/write_http.c index c1b3f0b0..c6efe079 100644 --- a/src/write_http.c +++ b/src/write_http.c @@ -81,6 +81,9 @@ struct wh_callback_s { }; typedef struct wh_callback_s wh_callback_t; +static char **http_attrs; +static size_t http_attrs_num; + static void wh_log_http_error(wh_callback_t *cb) { if (!cb->log_http_error) return; @@ -468,9 +471,9 @@ static int wh_write_kairosdb(const data_set_t *ds, } } - status = format_kairosdb_value_list(cb->send_buffer, &cb->send_buffer_fill, - &cb->send_buffer_free, ds, vl, - cb->store_rates); + status = format_kairosdb_value_list( + cb->send_buffer, &cb->send_buffer_fill, &cb->send_buffer_free, ds, vl, + cb->store_rates, (char const *const *)http_attrs, http_attrs_num); if (status == -ENOMEM) { status = wh_flush_nolock(/* timeout = */ 0, cb); if (status != 0) { @@ -479,9 +482,9 @@ static int wh_write_kairosdb(const data_set_t *ds, return (status); } - status = format_kairosdb_value_list(cb->send_buffer, &cb->send_buffer_fill, - &cb->send_buffer_free, ds, vl, - cb->store_rates); + status = format_kairosdb_value_list( + cb->send_buffer, &cb->send_buffer_fill, &cb->send_buffer_free, ds, vl, + cb->store_rates, (char const *const *)http_attrs, http_attrs_num); } if (status != 0) { pthread_mutex_unlock(&cb->send_lock); @@ -703,7 +706,34 @@ static int wh_config_node(oconfig_item_t *ci) /* {{{ */ status = cf_util_get_boolean(child, &cb->log_http_error); else if (strcasecmp("Header", child->key) == 0) status = wh_config_append_string("Header", &cb->headers, child); - else { + else if (strcasecmp("Attribute", child->key) == 0) { + char *key = NULL; + char *val = NULL; + + if (child->values_num != 2) { + WARNING("write_http plugin: Attribute need both a key and a value."); + break; + } + if (child->values[0].type != OCONFIG_TYPE_STRING || + child->values[1].type != OCONFIG_TYPE_STRING) { + WARNING("write_http plugin: Attribute needs string arguments."); + break; + } + if ((key = strdup(child->values[0].value.string)) == NULL) { + WARNING("cannot allocate memory for attribute key."); + break; + } + if ((val = strdup(child->values[1].value.string)) == NULL) { + WARNING("cannot allocate memory for attribute value."); + sfree(key); + break; + } + strarray_add(&http_attrs, &http_attrs_num, key); + strarray_add(&http_attrs, &http_attrs_num, val); + DEBUG("write_http plugin: got attribute: %s => %s", key, val); + sfree(key); + sfree(val); + } else { ERROR("write_http plugin: Invalid configuration " "option: %s.", child->key); @@ -812,5 +842,3 @@ void module_register(void) /* {{{ */ plugin_register_complex_config("write_http", wh_config); plugin_register_init("write_http", wh_init); } /* }}} void module_register */ - -/* vim: set fdm=marker sw=8 ts=8 tw=78 et : */ diff --git a/src/write_log.c b/src/write_log.c index 2d34b21b..5ecb1823 100644 --- a/src/write_log.c +++ b/src/write_log.c @@ -136,5 +136,3 @@ void module_register(void) { /* If config is supplied, the global wl_format will be set. */ plugin_register_write("write_log", wl_write, NULL); } - -/* vim: set sw=4 ts=4 sts=4 tw=78 et : */ diff --git a/src/write_mongodb.c b/src/write_mongodb.c index e175e1f3..44181e93 100644 --- a/src/write_mongodb.c +++ b/src/write_mongodb.c @@ -3,6 +3,7 @@ * Copyright (C) 2010-2013 Florian Forster * Copyright (C) 2010 Akkarit Sangpetch * Copyright (C) 2012 Chris Lundquist + * Copyright (C) 2017 Saikrishna Arcot * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -26,6 +27,7 @@ * Florian Forster * Akkarit Sangpetch * Chris Lundquist + * Saikrishna Arcot **/ #include "collectd.h" @@ -34,17 +36,7 @@ #include "plugin.h" #include "utils_cache.h" -#if HAVE_STDINT_H -#define MONGO_HAVE_STDINT 1 -#else -#define MONGO_USE_LONG_LONG_INT 1 -#endif -#include - -#if (MONGO_MAJOR == 0) && (MONGO_MINOR < 8) -#define bson_alloc() bson_create() -#define bson_dealloc(b) bson_dispose(b) -#endif +#include struct wm_node_s { char name[DATA_MAX_NAME_LEN]; @@ -59,8 +51,10 @@ struct wm_node_s { char *passwd; _Bool store_rates; + _Bool connected; - mongo conn[1]; + mongoc_client_t *client; + mongoc_database_t *database; pthread_mutex_t lock; }; typedef struct wm_node_s wm_node_t; @@ -68,170 +62,235 @@ typedef struct wm_node_s wm_node_t; /* * Functions */ -static bson *wm_create_bson(const data_set_t *ds, /* {{{ */ - const value_list_t *vl, _Bool store_rates) { - bson *ret; +static bson_t *wm_create_bson(const data_set_t *ds, /* {{{ */ + const value_list_t *vl, _Bool store_rates) { + bson_t *ret; + bson_t subarray; gauge_t *rates; - ret = bson_alloc(); /* matched by bson_dealloc() */ - if (ret == NULL) { - ERROR("write_mongodb plugin: bson_create failed."); - return (NULL); + ret = bson_new(); + if (!ret) { + ERROR("write_mongodb plugin: bson_new failed."); + return NULL; } if (store_rates) { rates = uc_get_rate(ds, vl); if (rates == NULL) { ERROR("write_mongodb plugin: uc_get_rate() failed."); - return (NULL); + bson_free(ret); + return NULL; } } else { rates = NULL; } - bson_init(ret); /* matched by bson_destroy() */ - bson_append_date(ret, "time", (bson_date_t)CDTIME_T_TO_MS(vl->time)); - bson_append_string(ret, "host", vl->host); - bson_append_string(ret, "plugin", vl->plugin); - bson_append_string(ret, "plugin_instance", vl->plugin_instance); - bson_append_string(ret, "type", vl->type); - bson_append_string(ret, "type_instance", vl->type_instance); + BSON_APPEND_DATE_TIME(ret, "timestamp", CDTIME_T_TO_MS(vl->time)); + BSON_APPEND_UTF8(ret, "host", vl->host); + BSON_APPEND_UTF8(ret, "plugin", vl->plugin); + BSON_APPEND_UTF8(ret, "plugin_instance", vl->plugin_instance); + BSON_APPEND_UTF8(ret, "type", vl->type); + BSON_APPEND_UTF8(ret, "type_instance", vl->type_instance); - bson_append_start_array(ret, "values"); /* {{{ */ + BSON_APPEND_ARRAY_BEGIN(ret, "values", &subarray); /* {{{ */ for (int i = 0; i < ds->ds_num; i++) { char key[16]; ssnprintf(key, sizeof(key), "%i", i); if (ds->ds[i].type == DS_TYPE_GAUGE) - bson_append_double(ret, key, vl->values[i].gauge); + BSON_APPEND_DOUBLE(&subarray, key, vl->values[i].gauge); else if (store_rates) - bson_append_double(ret, key, (double)rates[i]); + BSON_APPEND_DOUBLE(&subarray, key, (double)rates[i]); else if (ds->ds[i].type == DS_TYPE_COUNTER) - bson_append_long(ret, key, vl->values[i].counter); + BSON_APPEND_INT64(&subarray, key, vl->values[i].counter); else if (ds->ds[i].type == DS_TYPE_DERIVE) - bson_append_long(ret, key, vl->values[i].derive); + BSON_APPEND_INT64(&subarray, key, vl->values[i].derive); else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) - bson_append_long(ret, key, vl->values[i].absolute); - else - assert(23 == 42); + BSON_APPEND_INT64(&subarray, key, vl->values[i].absolute); + else { + ERROR("write_mongodb plugin: Unknown ds_type %d for index %d", + ds->ds[i].type, i); + bson_free(ret); + return NULL; + } } - bson_append_finish_array(ret); /* }}} values */ + bson_append_array_end(ret, &subarray); /* }}} values */ - bson_append_start_array(ret, "dstypes"); /* {{{ */ + BSON_APPEND_ARRAY_BEGIN(ret, "dstypes", &subarray); /* {{{ */ for (int i = 0; i < ds->ds_num; i++) { char key[16]; ssnprintf(key, sizeof(key), "%i", i); if (store_rates) - bson_append_string(ret, key, "gauge"); + BSON_APPEND_UTF8(&subarray, key, "gauge"); else - bson_append_string(ret, key, DS_TYPE_TO_STRING(ds->ds[i].type)); + BSON_APPEND_UTF8(&subarray, key, DS_TYPE_TO_STRING(ds->ds[i].type)); } - bson_append_finish_array(ret); /* }}} dstypes */ + bson_append_array_end(ret, &subarray); /* }}} dstypes */ - bson_append_start_array(ret, "dsnames"); /* {{{ */ + BSON_APPEND_ARRAY_BEGIN(ret, "dsnames", &subarray); /* {{{ */ for (int i = 0; i < ds->ds_num; i++) { char key[16]; ssnprintf(key, sizeof(key), "%i", i); - bson_append_string(ret, key, ds->ds[i].name); + BSON_APPEND_UTF8(&subarray, key, ds->ds[i].name); } - bson_append_finish_array(ret); /* }}} dsnames */ - - bson_finish(ret); + bson_append_array_end(ret, &subarray); /* }}} dsnames */ sfree(rates); - return (ret); + + size_t error_location; + if (!bson_validate(ret, BSON_VALIDATE_UTF8, &error_location)) { + ERROR("write_mongodb plugin: Error in generated BSON document " + "at byte %zu", error_location); + bson_free(ret); + return NULL; + } + + return ret; } /* }}} bson *wm_create_bson */ -static int wm_write(const data_set_t *ds, /* {{{ */ - const value_list_t *vl, user_data_t *ud) { - wm_node_t *node = ud->data; - char collection_name[512]; - bson *bson_record; - int status; +static int wm_initialize(wm_node_t *node) /* {{{ */ +{ + char *uri; + size_t uri_length; + char const *format_string; - ssnprintf(collection_name, sizeof(collection_name), "collectd.%s", - vl->plugin); + if (node->connected) { + return 0; + } - bson_record = wm_create_bson(ds, vl, node->store_rates); - if (bson_record == NULL) - return (ENOMEM); + INFO("write_mongodb plugin: Connecting to [%s]:%i", + (node->host != NULL) ? node->host : "localhost", + (node->port != 0) ? node->port : MONGOC_DEFAULT_PORT); + + if ((node->db != NULL) && (node->user != NULL) && (node->passwd != NULL)) { + format_string = "mongodb://%s:%s@%s:%d/?authSource=%s"; + uri_length = strlen(format_string) + strlen(node->user) + + strlen(node->passwd) + strlen(node->host) + 5 + + strlen(node->db) + 1; + if ((uri = calloc(1, uri_length)) == NULL) { + ERROR("write_mongodb plugin: Not enough memory to assemble " + "authentication string."); + mongoc_client_destroy(node->client); + node->client = NULL; + node->connected = 0; + return -1; + } + ssnprintf(uri, uri_length, format_string, node->user, node->passwd, + node->host, node->port, node->db); - pthread_mutex_lock(&node->lock); + node->client = mongoc_client_new(uri); + if (!node->client) { + ERROR("write_mongodb plugin: Authenticating to [%s]%i for database " + "\"%s\" as user \"%s\" failed.", + (node->host != NULL) ? node->host : "localhost", + (node->port != 0) ? node->port : MONGOC_DEFAULT_PORT, node->db, + node->user); + node->connected = 0; + sfree(uri); + return -1; + } + } else { + format_string = "mongodb://%s:%d"; + uri_length = strlen(format_string) + strlen(node->host) + 5 + 1; + if ((uri = calloc(1, uri_length)) == NULL) { + ERROR("write_mongodb plugin: Not enough memory to assemble " + "authentication string."); + mongoc_client_destroy(node->client); + node->client = NULL; + node->connected = 0; + return -1; + } + snprintf(uri, uri_length, format_string, node->host, node->port); - if (!mongo_is_connected(node->conn)) { - INFO("write_mongodb plugin: Connecting to [%s]:%i", - (node->host != NULL) ? node->host : "localhost", - (node->port != 0) ? node->port : MONGO_DEFAULT_PORT); - status = mongo_connect(node->conn, node->host, node->port); - if (status != MONGO_OK) { + node->client = mongoc_client_new(uri); + if (!node->client) { ERROR("write_mongodb plugin: Connecting to [%s]:%i failed.", (node->host != NULL) ? node->host : "localhost", - (node->port != 0) ? node->port : MONGO_DEFAULT_PORT); - mongo_destroy(node->conn); - pthread_mutex_unlock(&node->lock); - return (-1); + (node->port != 0) ? node->port : MONGOC_DEFAULT_PORT); + node->connected = 0; + sfree(uri); + return -1; } + } + sfree(uri); + + node->database = mongoc_client_get_database(node->client, "collectd"); + if (!node->database) { + ERROR("write_mongodb plugin: error creating/getting database"); + mongoc_client_destroy(node->client); + node->client = NULL; + node->connected = 0; + return -1; + } - if ((node->db != NULL) && (node->user != NULL) && (node->passwd != NULL)) { - status = mongo_cmd_authenticate(node->conn, node->db, node->user, - node->passwd); - if (status != MONGO_OK) { - ERROR("write_mongodb plugin: Authenticating to [%s]%i for database " - "\"%s\" as user \"%s\" failed.", - (node->host != NULL) ? node->host : "localhost", - (node->port != 0) ? node->port : MONGO_DEFAULT_PORT, node->db, - node->user); - mongo_destroy(node->conn); - pthread_mutex_unlock(&node->lock); - return (-1); - } - } + node->connected = 1; + return 0; +} /* }}} int wm_initialize */ - if (node->timeout > 0) { - status = mongo_set_op_timeout(node->conn, node->timeout); - if (status != MONGO_OK) { - WARNING("write_mongodb plugin: mongo_set_op_timeout(%i) failed: %s", - node->timeout, node->conn->errstr); - } - } +static int wm_write(const data_set_t *ds, /* {{{ */ + const value_list_t *vl, user_data_t *ud) { + wm_node_t *node = ud->data; + mongoc_collection_t *collection = NULL; + bson_t *bson_record; + bson_error_t error; + int status; + + bson_record = wm_create_bson(ds, vl, node->store_rates); + if (!bson_record) { + ERROR("write_mongodb plugin: error making insert bson"); + return -1; } - /* Assert if the connection has been established */ - assert(mongo_is_connected(node->conn)); - -#if MONGO_MINOR >= 6 - /* There was an API change in 0.6.0 as linked below */ - /* https://github.com/mongodb/mongo-c-driver/blob/master/HISTORY.md */ - status = mongo_insert(node->conn, collection_name, bson_record, NULL); -#else - status = mongo_insert(node->conn, collection_name, bson_record); -#endif - - if (status != MONGO_OK) { - ERROR("write_mongodb plugin: error inserting record: %d", node->conn->err); - if (node->conn->err != MONGO_BSON_INVALID) - ERROR("write_mongodb plugin: %s", node->conn->errstr); - else - ERROR("write_mongodb plugin: Invalid BSON structure, error = %#x", - (unsigned int)bson_record->err); + pthread_mutex_lock(&node->lock); + if (wm_initialize(node) < 0) { + ERROR("write_mongodb plugin: error making connection to server"); + pthread_mutex_unlock(&node->lock); + bson_free(bson_record); + return -1; + } - /* Disconnect except on data errors. */ - if ((node->conn->err != MONGO_BSON_INVALID) && - (node->conn->err != MONGO_BSON_NOT_FINISHED)) - mongo_destroy(node->conn); + collection = + mongoc_client_get_collection(node->client, "collectd", vl->plugin); + if (!collection) { + ERROR("write_mongodb plugin: error creating/getting collection"); + mongoc_database_destroy(node->database); + mongoc_client_destroy(node->client); + node->database = NULL; + node->client = NULL; + node->connected = 0; + pthread_mutex_unlock(&node->lock); + bson_free(bson_record); + return -1; } - pthread_mutex_unlock(&node->lock); + status = mongoc_collection_insert(collection, MONGOC_INSERT_NONE, bson_record, + NULL, &error); + + if (!status) { + ERROR("write_mongodb plugin: error inserting record: %s", error.message); + mongoc_database_destroy(node->database); + mongoc_client_destroy(node->client); + node->database = NULL; + node->client = NULL; + node->connected = 0; + pthread_mutex_unlock(&node->lock); + bson_free(bson_record); + mongoc_collection_destroy(collection); + return -1; + } /* free our resource as not to leak memory */ - bson_destroy(bson_record); /* matches bson_init() */ - bson_dealloc(bson_record); /* matches bson_alloc() */ + mongoc_collection_destroy(collection); - return (0); + pthread_mutex_unlock(&node->lock); + + bson_free(bson_record); + + return 0; } /* }}} int wm_write */ static void wm_config_free(void *ptr) /* {{{ */ @@ -241,8 +300,11 @@ static void wm_config_free(void *ptr) /* {{{ */ if (node == NULL) return; - if (mongo_is_connected(node->conn)) - mongo_destroy(node->conn); + mongoc_database_destroy(node->database); + mongoc_client_destroy(node->client); + node->database = NULL; + node->client = NULL; + node->connected = 0; sfree(node->host); sfree(node); @@ -256,7 +318,7 @@ static int wm_config_node(oconfig_item_t *ci) /* {{{ */ node = calloc(1, sizeof(*node)); if (node == NULL) return (ENOMEM); - mongo_init(node->conn); + mongoc_init(); node->host = NULL; node->store_rates = 1; pthread_mutex_init(&node->lock, /* attr = */ NULL); @@ -348,5 +410,3 @@ static int wm_config(oconfig_item_t *ci) /* {{{ */ void module_register(void) { plugin_register_complex_config("write_mongodb", wm_config); } - -/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ diff --git a/src/write_prometheus.c b/src/write_prometheus.c index 6b77712e..61c43fed 100644 --- a/src/write_prometheus.c +++ b/src/write_prometheus.c @@ -870,5 +870,3 @@ void module_register() { /* user data = */ NULL); plugin_register_shutdown("write_prometheus", prom_shutdown); } - -/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/write_redis.c b/src/write_redis.c index 0a5c5df1..9cff34a7 100644 --- a/src/write_redis.c +++ b/src/write_redis.c @@ -252,5 +252,3 @@ static int wr_config(oconfig_item_t *ci) /* {{{ */ void module_register(void) { plugin_register_complex_config("write_redis", wr_config); } - -/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ diff --git a/src/write_riemann.c b/src/write_riemann.c index 3835a3d5..a51b4b58 100644 --- a/src/write_riemann.c +++ b/src/write_riemann.c @@ -895,5 +895,3 @@ static int wrr_config(oconfig_item_t *ci) /* {{{ */ void module_register(void) { plugin_register_complex_config("write_riemann", wrr_config); } - -/* vim: set sw=8 sts=8 ts=8 noet : */ diff --git a/src/write_riemann_threshold.c b/src/write_riemann_threshold.c index 452c2910..8f6b4bed 100644 --- a/src/write_riemann_threshold.c +++ b/src/write_riemann_threshold.c @@ -34,8 +34,6 @@ #include "utils_threshold.h" #include "write_riemann_threshold.h" -#include - /* * Threshold management * ==================== @@ -225,5 +223,3 @@ int write_riemann_threshold_check(const data_set_t *ds, const value_list_t *vl, return (0); } /* }}} int ut_check_threshold */ - -/* vim: set sw=2 ts=8 sts=2 tw=78 et fdm=marker : */ diff --git a/src/write_sensu.c b/src/write_sensu.c index 72ed6bc0..6e6517bd 100644 --- a/src/write_sensu.c +++ b/src/write_sensu.c @@ -132,7 +132,7 @@ static int add_str_to_list(struct str_list *strs, ERROR("write_sensu plugin: Unable to alloc memory"); return -1; } - strs->strs = realloc(strs->strs, sizeof(char *) * (strs->nb_strs + 1)); + strs->strs = realloc(strs->strs, strs->nb_strs + 1); if (strs->strs == NULL) { strs->strs = old_strs_ptr; free(newstr); @@ -231,7 +231,7 @@ static char *build_json_str_list(const char *tag, char *ret_str = NULL; char *temp_str; if (list->nb_strs == 0) { - ret_str = malloc(sizeof(char)); + ret_str = malloc(1); if (ret_str == NULL) { ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; @@ -1248,5 +1248,3 @@ static int sensu_config(oconfig_item_t *ci) /* {{{ */ void module_register(void) { plugin_register_complex_config("write_sensu", sensu_config); } - -/* vim: set sw=8 sts=8 ts=8 noet : */ diff --git a/src/write_tsdb.c b/src/write_tsdb.c index 0c87c473..99c84278 100644 --- a/src/write_tsdb.c +++ b/src/write_tsdb.c @@ -45,8 +45,8 @@ #include "common.h" #include "plugin.h" - #include "utils_cache.h" +#include "utils_random.h" #include @@ -71,6 +71,8 @@ * Private variables */ struct wt_callback { + struct addrinfo *ai; + cdtime_t ai_last_update; int sock_fd; char *node; @@ -86,8 +88,15 @@ struct wt_callback { cdtime_t send_buf_init_time; pthread_mutex_t send_lock; + + _Bool connect_failed_log_enabled; + int connect_dns_failed_attempts_remaining; + cdtime_t next_random_ttl; }; +static cdtime_t resolve_interval = 0; +static cdtime_t resolve_jitter = 0; + /* * Functions */ @@ -144,9 +153,16 @@ static int wt_flush_nolock(cdtime_t timeout, struct wt_callback *cb) { return status; } +static cdtime_t new_random_ttl() { + if (resolve_jitter == 0) + return 0; + + return (cdtime_t)cdrand_range(0, (long)resolve_jitter); +} + static int wt_callback_init(struct wt_callback *cb) { - struct addrinfo *ai_list; int status; + cdtime_t now; const char *node = cb->node ? cb->node : WT_DEFAULT_NODE; const char *service = cb->service ? cb->service : WT_DEFAULT_SERVICE; @@ -154,28 +170,68 @@ static int wt_callback_init(struct wt_callback *cb) { if (cb->sock_fd > 0) return 0; - struct addrinfo ai_hints = {.ai_family = AF_UNSPEC, - .ai_flags = AI_ADDRCONFIG, - .ai_socktype = SOCK_STREAM}; + now = cdtime(); + if (cb->ai) { + /* When we are here, we still have the IP in cache. + * If we have remaining attempts without calling the DNS, we update the + * last_update date so we keep the info until next time. + * If there is no more attempts, we need to flush the cache. + */ + + if ((cb->ai_last_update + resolve_interval + cb->next_random_ttl) < now) { + cb->next_random_ttl = new_random_ttl(); + if (cb->connect_dns_failed_attempts_remaining > 0) { + /* Warning : this is run under send_lock mutex. + * This is why we do not use another mutex here. + * */ + cb->ai_last_update = now; + cb->connect_dns_failed_attempts_remaining--; + } else { + freeaddrinfo(cb->ai); + cb->ai = NULL; + } + } + } - status = getaddrinfo(node, service, &ai_hints, &ai_list); - if (status != 0) { - ERROR("write_tsdb plugin: getaddrinfo (%s, %s) failed: %s", node, service, - gai_strerror(status)); - return -1; + if (cb->ai == NULL) { + if ((cb->ai_last_update + resolve_interval + cb->next_random_ttl) >= now) { + DEBUG("write_tsdb plugin: too many getaddrinfo(%s, %s) failures", node, + service); + return (-1); + } + cb->ai_last_update = now; + cb->next_random_ttl = new_random_ttl(); + + struct addrinfo ai_hints = { + .ai_family = AF_UNSPEC, + .ai_flags = AI_ADDRCONFIG, + .ai_socktype = SOCK_STREAM, + }; + + status = getaddrinfo(node, service, &ai_hints, &cb->ai); + if (status != 0) { + if (cb->ai) { + freeaddrinfo(cb->ai); + cb->ai = NULL; + } + if (cb->connect_failed_log_enabled) { + ERROR("write_tsdb plugin: getaddrinfo(%s, %s) failed: %s", node, + service, gai_strerror(status)); + cb->connect_failed_log_enabled = 0; + } + return -1; + } } - assert(ai_list != NULL); - for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; - ai_ptr = ai_ptr->ai_next) { - cb->sock_fd = - socket(ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); + assert(cb->ai != NULL); + for (struct addrinfo *ai = cb->ai; ai != NULL; ai = ai->ai_next) { + cb->sock_fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (cb->sock_fd < 0) continue; set_sock_opts(cb->sock_fd); - status = connect(cb->sock_fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen); + status = connect(cb->sock_fd, ai->ai_addr, ai->ai_addrlen); if (status != 0) { close(cb->sock_fd); cb->sock_fd = -1; @@ -185,8 +241,6 @@ static int wt_callback_init(struct wt_callback *cb) { break; } - freeaddrinfo(ai_list); - if (cb->sock_fd < 0) { char errbuf[1024]; ERROR("write_tsdb plugin: Connecting to %s:%s failed. " @@ -195,6 +249,12 @@ static int wt_callback_init(struct wt_callback *cb) { return -1; } + if (0 == cb->connect_failed_log_enabled) { + WARNING("write_tsdb plugin: Connecting to %s:%s succeeded.", node, service); + cb->connect_failed_log_enabled = 1; + } + cb->connect_dns_failed_attempts_remaining = 1; + wt_reset_buffer(cb); return 0; @@ -522,10 +582,8 @@ static int wt_config_tsd(oconfig_item_t *ci) { return -1; } cb->sock_fd = -1; - cb->node = NULL; - cb->service = NULL; - cb->host_tags = NULL; - cb->store_rates = 0; + cb->connect_failed_log_enabled = 1; + cb->next_random_ttl = new_random_ttl(); pthread_mutex_init(&cb->send_lock, NULL); @@ -564,11 +622,18 @@ static int wt_config_tsd(oconfig_item_t *ci) { } static int wt_config(oconfig_item_t *ci) { + if ((resolve_interval == 0) && (resolve_jitter == 0)) + resolve_interval = resolve_jitter = plugin_get_interval(); + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp("Node", child->key) == 0) wt_config_tsd(child); + else if (strcasecmp("ResolveInterval", child->key) == 0) + cf_util_get_cdtime(child, &resolve_interval); + else if (strcasecmp("ResolveJitter", child->key) == 0) + cf_util_get_cdtime(child, &resolve_jitter); else { ERROR("write_tsdb plugin: Invalid configuration " "option: %s.", @@ -582,5 +647,3 @@ static int wt_config(oconfig_item_t *ci) { void module_register(void) { plugin_register_complex_config("write_tsdb", wt_config); } - -/* vim: set sw=4 ts=4 sts=4 tw=78 et : */ diff --git a/src/xmms.c b/src/xmms.c index 87e3564f..b06434d4 100644 --- a/src/xmms.c +++ b/src/xmms.c @@ -66,7 +66,3 @@ static int cxmms_read(void) { void module_register(void) { plugin_register_read("xmms", cxmms_read); } /* void module_register */ - -/* - * vim: shiftwidth=2:softtabstop=2:textwidth=78 - */ diff --git a/src/zfs_arc.c b/src/zfs_arc.c index af5130aa..aff02b62 100644 --- a/src/zfs_arc.c +++ b/src/zfs_arc.c @@ -75,7 +75,6 @@ static long long get_zfs_value(kstat_t *ksp, const char *key) { e = llist_search(ksp, key); if (e == NULL) { - ERROR("zfs_arc plugin: `llist_search` failed for key: '%s'.", key); return (-1); } @@ -152,7 +151,7 @@ static int za_read_derive(kstat_t *ksp, const char *kstat_value, const char *type, const char *type_instance) { long long tmp = get_zfs_value(ksp, (char *)kstat_value); if (tmp == -1LL) { - WARNING("zfs_arc plugin: Reading kstat value \"%s\" failed.", kstat_value); + DEBUG("zfs_arc plugin: Reading kstat value \"%s\" failed.", kstat_value); return (-1); } @@ -165,7 +164,7 @@ static int za_read_gauge(kstat_t *ksp, const char *kstat_value, const char *type, const char *type_instance) { long long tmp = get_zfs_value(ksp, (char *)kstat_value); if (tmp == -1LL) { - WARNING("zfs_arc plugin: Reading kstat value \"%s\" failed.", kstat_value); + DEBUG("zfs_arc plugin: Reading kstat value \"%s\" failed.", kstat_value); return (-1); } @@ -212,6 +211,21 @@ static int za_read(void) { return (-1); } + // Ignore the first two lines because they contain information about + // the rest of the file. + // See kstat_seq_show_headers module/spl/spl-kstat.c of the spl kernel + // module. + if (fgets(buffer, sizeof(buffer), fh) == NULL) { + ERROR("zfs_arc plugin: \"%s\" does not contain a single line.", ZOL_ARCSTATS_FILE); + fclose(fh); + return (-1); + } + if (fgets(buffer, sizeof(buffer), fh) == NULL) { + ERROR("zfs_arc plugin: \"%s\" does not contain at least two lines.", ZOL_ARCSTATS_FILE); + fclose(fh); + return (-1); + } + while (fgets(buffer, sizeof(buffer), fh) != NULL) { char *fields[3]; value_t v;